[AT-SPI] Fix not working screen reader when rerunning it
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / common / window-impl.cpp
index f3a74fe..e3f6525 100644 (file)
@@ -58,17 +58,17 @@ Debug::Filter* gWindowLogFilter = Debug::Filter::New(Debug::NoLogging, false, "L
 
 } // unnamed namespace
 
-Window* Window::New(const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent)
+Window* Window::New(const PositionSize& positionSize, const std::string& name, const std::string& className, Dali::WindowType type, bool isTransparent)
 {
   Any surface;
-  return Window::New(surface, positionSize, name, className, isTransparent);
+  return Window::New(surface, positionSize, name, className, type, isTransparent);
 }
 
-Window* Window::New(Any surface, const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent)
+Window* Window::New(Any surface, const PositionSize& positionSize, const std::string& name, const std::string& className, Dali::WindowType type, bool isTransparent)
 {
   Window* window         = new Window();
   window->mIsTransparent = isTransparent;
-  window->Initialize(surface, positionSize, name, className);
+  window->Initialize(surface, positionSize, name, className, type);
   return window;
 }
 
@@ -79,8 +79,7 @@ Window::Window()
   mIsFocusAcceptable(true),
   mIconified(false),
   mOpaqueState(false),
-  mResizeEnabled(false),
-  mType(WindowType::NORMAL),
+  mWindowRotationAcknowledgement(false),
   mParentWindow(NULL),
   mPreferredAngle(static_cast<int>(WindowOrientation::NO_ORIENTATION_PREFERENCE)),
   mRotationAngle(0),
@@ -93,19 +92,20 @@ Window::Window()
   mResizeSignal(),
   mVisibilityChangedSignal(),
   mTransitionEffectEventSignal(),
-  mKeyboardRepeatSettingsChangedSignal()
+  mKeyboardRepeatSettingsChangedSignal(),
+  mAuxiliaryMessageSignal()
 {
 }
 
 Window::~Window()
 {
+  auto bridge     = Accessibility::Bridge::GetCurrentBridge();
+  auto rootLayer  = mScene.GetRootLayer();
+  auto accessible = Accessibility::Accessible::Get(rootLayer, true);
+  bridge->RemoveTopLevelWindow(accessible);
+
   if(mAdaptor)
   {
-    auto bridge      = Accessibility::Bridge::GetCurrentBridge();
-    auto accessible2 = mScene.GetRootLayer();
-    auto accessible  = Accessibility::Accessible::Get(accessible2);
-    bridge->RemoveTopLevelWindow(accessible);
-
     mAdaptor->RemoveWindow(this);
   }
 
@@ -115,7 +115,7 @@ Window::~Window()
   }
 }
 
-void Window::Initialize(Any surface, const PositionSize& positionSize, const std::string& name, const std::string& className)
+void Window::Initialize(Any surface, const PositionSize& positionSize, const std::string& name, const std::string& className, WindowType type)
 {
   // Create a window render surface
   auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
@@ -125,6 +125,16 @@ void Window::Initialize(Any surface, const PositionSize& positionSize, const std
   // Get a window base
   mWindowBase = mWindowSurface->GetWindowBase();
 
+  // Set Window Type
+  mWindowBase->SetType(type);
+
+  // Initialize for Ime window type
+  if(type == WindowType::IME)
+  {
+    mWindowBase->InitializeIme();
+    mWindowSurface->InitializeImeSurface();
+  }
+
   // Connect signals
   mWindowBase->IconifyChangedSignal().Connect(this, &Window::OnIconifyChanged);
   mWindowBase->FocusChangedSignal().Connect(this, &Window::OnFocusChanged);
@@ -132,19 +142,15 @@ void Window::Initialize(Any surface, const PositionSize& positionSize, const std
   mWindowBase->TransitionEffectEventSignal().Connect(this, &Window::OnTransitionEffectEvent);
   mWindowBase->KeyboardRepeatSettingsChangedSignal().Connect(this, &Window::OnKeyboardRepeatSettingsChanged);
   mWindowBase->WindowRedrawRequestSignal().Connect(this, &Window::OnWindowRedrawRequest);
+  mWindowBase->UpdatePositionSizeSignal().Connect(this, &Window::OnUpdatePositionSize);
+  mWindowBase->AuxiliaryMessageSignal().Connect(this, &Window::OnAuxiliaryMessage);
 
   mWindowSurface->OutputTransformedSignal().Connect(this, &Window::OnOutputTransformed);
 
-  if(!positionSize.IsEmpty())
-  {
-    AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
-    mResizeEnabled = true;
-  }
+  AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
 
   SetClass(name, className);
 
-  mWindowSurface->Map();
-
   mOrientation = Orientation::New(this);
 
   // Get OrientationMode
@@ -167,12 +173,17 @@ void Window::OnAdaptorSet(Dali::Adaptor& adaptor)
   mEventHandler = EventHandlerPtr(new EventHandler(mWindowSurface->GetWindowBase(), *mAdaptor));
   mEventHandler->AddObserver(*this);
 
+  // Add Window to bridge for ATSPI
   auto bridge     = Accessibility::Bridge::GetCurrentBridge();
-  auto v          = mScene.GetRootLayer();
-  auto accessible = Accessibility::Accessible::Get(v, true);
+  auto rootLayer  = mScene.GetRootLayer();
+  auto accessible = Accessibility::Accessible::Get(rootLayer, true);
   bridge->AddTopLevelWindow(accessible);
 
-  //FIXME: line below is temporary solution for missing "activate" signal and should be removed
+  bridge->EnabledSignal().Connect(this, &Window::OnAccessibilityEnabled);
+  bridge->DisabledSignal().Connect(this, &Window::OnAccessibilityDisabled);
+
+  // If you call the 'Show' before creating the adaptor, the application cannot know the app resource id.
+  // The show must be called after the adaptor is initialized.
   Show();
 }
 
@@ -303,6 +314,12 @@ WindowOrientation Window::GetPreferredOrientation()
   return preferredOrientation;
 }
 
+void Window::SetPositionSizeWithOrientation(PositionSize positionSize, WindowOrientation orientation)
+{
+  int angle = ConvertToAngle(orientation);
+  mWindowBase->SetPositionSizeWithAngle(positionSize, angle);
+}
+
 void Window::SetAvailableAnlges(const std::vector<int>& angles)
 {
   if(angles.size() > 4)
@@ -423,11 +440,11 @@ void Window::Show()
 
   if(!mIconified)
   {
-    WindowVisibilityObserver* observer(mAdaptor);
-    observer->OnWindowShown();
-
     Dali::Window handle(this);
     mVisibilityChangedSignal.Emit(handle, true);
+
+    WindowVisibilityObserver* observer(mAdaptor);
+    observer->OnWindowShown();
   }
 
   mSurface->SetFullSwapNextFrame();
@@ -443,11 +460,11 @@ void Window::Hide()
 
   if(!mIconified)
   {
-    WindowVisibilityObserver* observer(mAdaptor);
-    observer->OnWindowHidden();
-
     Dali::Window handle(this);
     mVisibilityChangedSignal.Emit(handle, false);
+
+    WindowVisibilityObserver* observer(mAdaptor);
+    observer->OnWindowHidden();
   }
 
   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Hide(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible);
@@ -496,32 +513,30 @@ unsigned int Window::GetAuxiliaryHintId(const std::string& hint) const
 
 void Window::SetInputRegion(const Rect<int>& inputRegion)
 {
-  mWindowBase->SetInputRegion(inputRegion);
+  Rect<int> convertRegion = RecalculateRect(inputRegion);
+
+  DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window (%p), WinId (%d), SetInputRegion, RecalculateRegion, (%d,%d), (%d x %d)\n", this, mNativeWindowId, convertRegion.x, convertRegion.y, convertRegion.width, convertRegion.height);
 
-  DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetInputRegion: x = %d, y = %d, w = %d, h = %d\n", inputRegion.x, inputRegion.y, inputRegion.width, inputRegion.height);
+  mWindowBase->SetInputRegion(convertRegion);
 }
 
 void Window::SetType(WindowType type)
 {
-  if(type != mType)
-  {
-    mWindowBase->SetType(type);
-
-    mType = type;
-  }
+  mWindowBase->SetType(type);
 }
 
 WindowType Window::GetType() const
 {
-  return mType;
+  return mWindowBase->GetType();
 }
 
-bool Window::SetNotificationLevel(WindowNotificationLevel level)
+WindowOperationResult Window::SetNotificationLevel(WindowNotificationLevel level)
 {
-  if(mType != WindowType::NOTIFICATION)
+  WindowType type = mWindowBase->GetType();
+  if(type != WindowType::NOTIFICATION)
   {
-    DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType);
-    return false;
+    DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", type);
+    return WindowOperationResult::INVALID_OPERATION;
   }
 
   return mWindowBase->SetNotificationLevel(level);
@@ -529,9 +544,10 @@ bool Window::SetNotificationLevel(WindowNotificationLevel level)
 
 WindowNotificationLevel Window::GetNotificationLevel() const
 {
-  if(mType != WindowType::NOTIFICATION)
+  WindowType type = mWindowBase->GetType();
+  if(type != WindowType::NOTIFICATION)
   {
-    DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", mType);
+    DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", type);
     return WindowNotificationLevel::NONE;
   }
 
@@ -552,7 +568,7 @@ bool Window::IsOpaqueState() const
   return mOpaqueState;
 }
 
-bool Window::SetScreenOffMode(WindowScreenOffMode screenOffMode)
+WindowOperationResult Window::SetScreenOffMode(WindowScreenOffMode screenOffMode)
 {
   return mWindowBase->SetScreenOffMode(screenOffMode);
 }
@@ -562,12 +578,12 @@ WindowScreenOffMode Window::GetScreenOffMode() const
   return mWindowBase->GetScreenOffMode();
 }
 
-bool Window::SetBrightness(int brightness)
+WindowOperationResult Window::SetBrightness(int brightness)
 {
   if(brightness < 0 || brightness > 100)
   {
     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness);
-    return false;
+    return WindowOperationResult::INVALID_OPERATION;
   }
 
   return mWindowBase->SetBrightness(brightness);
@@ -580,12 +596,6 @@ int Window::GetBrightness() const
 
 void Window::SetSize(Dali::Window::WindowSize size)
 {
-  if(!mResizeEnabled)
-  {
-    AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
-    mResizeEnabled = true;
-  }
-
   PositionSize oldRect = mSurface->GetPositionSize();
 
   mWindowSurface->MoveResize(PositionSize(oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight()));
@@ -610,6 +620,8 @@ void Window::SetSize(Dali::Window::WindowSize size)
   }
 
   mSurface->SetFullSwapNextFrame();
+
+  Dali::Accessibility::Accessible::Get(mScene.GetRootLayer(), true)->EmitBoundsChanged(Dali::Rect<>(oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight()));
 }
 
 Dali::Window::WindowSize Window::GetSize() const
@@ -621,17 +633,13 @@ Dali::Window::WindowSize Window::GetSize() const
 
 void Window::SetPosition(Dali::Window::WindowPosition position)
 {
-  if(!mResizeEnabled)
-  {
-    AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
-    mResizeEnabled = true;
-  }
-
   PositionSize oldRect = mSurface->GetPositionSize();
 
   mWindowSurface->MoveResize(PositionSize(position.GetX(), position.GetY(), oldRect.width, oldRect.height));
 
   mSurface->SetFullSwapNextFrame();
+
+  Dali::Accessibility::Accessible::Get(mScene.GetRootLayer(), true)->EmitBoundsChanged(Dali::Rect<>(position.GetX(), position.GetY(), oldRect.width, oldRect.height));
 }
 
 Dali::Window::WindowPosition Window::GetPosition() const
@@ -641,14 +649,13 @@ Dali::Window::WindowPosition Window::GetPosition() const
   return Dali::Window::WindowPosition(positionSize.x, positionSize.y);
 }
 
-void Window::SetPositionSize(PositionSize positionSize)
+PositionSize Window::GetPositionSize() const
 {
-  if(!mResizeEnabled)
-  {
-    AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
-    mResizeEnabled = true;
-  }
+  return mSurface->GetPositionSize();
+}
 
+void Window::SetPositionSize(PositionSize positionSize)
+{
   PositionSize oldRect = mSurface->GetPositionSize();
 
   mWindowSurface->MoveResize(positionSize);
@@ -671,6 +678,8 @@ void Window::SetPositionSize(PositionSize positionSize)
   }
 
   mSurface->SetFullSwapNextFrame();
+
+  Dali::Accessibility::Accessible::Get(mScene.GetRootLayer(), true)->EmitBoundsChanged(Dali::Rect<>(positionSize.x, positionSize.y, positionSize.width, positionSize.height));
 }
 
 Dali::Layer Window::GetRootLayer() const
@@ -711,11 +720,11 @@ void Window::OnIconifyChanged(bool iconified)
 
     if(mVisible)
     {
-      WindowVisibilityObserver* observer(mAdaptor);
-      observer->OnWindowHidden();
-
       Dali::Window handle(this);
       mVisibilityChangedSignal.Emit(handle, false);
+
+      WindowVisibilityObserver* observer(mAdaptor);
+      observer->OnWindowHidden();
     }
 
     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Iconified: visible = %d\n", this, mNativeWindowId, mVisible);
@@ -726,11 +735,11 @@ void Window::OnIconifyChanged(bool iconified)
 
     if(mVisible)
     {
-      WindowVisibilityObserver* observer(mAdaptor);
-      observer->OnWindowShown();
-
       Dali::Window handle(this);
       mVisibilityChangedSignal.Emit(handle, true);
+
+      WindowVisibilityObserver* observer(mAdaptor);
+      observer->OnWindowShown();
     }
 
     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Deiconified: visible = %d\n", this, mNativeWindowId, mVisible);
@@ -746,15 +755,15 @@ void Window::OnFocusChanged(bool focusIn)
 
   mSurface->SetFullSwapNextFrame();
 
-  if(auto b = Dali::Accessibility::Bridge::GetCurrentBridge())
+  if(auto bridge = Dali::Accessibility::Bridge::GetCurrentBridge())
   {
     if(focusIn)
     {
-      b->ApplicationShown();
+      bridge->WindowFocused(handle);
     }
     else
     {
-      b->ApplicationHidden();
+      bridge->WindowUnfocused(handle);
     }
   }
 }
@@ -792,6 +801,11 @@ void Window::OnWindowRedrawRequest()
   mAdaptor->RenderOnce();
 }
 
+void Window::OnUpdatePositionSize(Dali::PositionSize& positionSize)
+{
+  SetPositionSize(positionSize);
+}
+
 void Window::OnTouchPoint(Dali::Integration::Point& point, int timeStamp)
 {
   FeedTouchPoint(point, timeStamp);
@@ -849,6 +863,27 @@ void Window::OnResume()
   mSurface->SetFullSwapNextFrame();
 }
 
+void Window::OnAuxiliaryMessage(const std::string& key, const std::string& value, const Property::Array& options)
+{
+  mAuxiliaryMessageSignal.Emit(key, value, options);
+}
+
+void Window::OnAccessibilityEnabled()
+{
+  auto bridge     = Accessibility::Bridge::GetCurrentBridge();
+  auto rootLayer  = mScene.GetRootLayer();
+  auto accessible = Accessibility::Accessible::Get(rootLayer, true);
+  bridge->AddTopLevelWindow(accessible);
+}
+
+void Window::OnAccessibilityDisabled()
+{
+  auto bridge     = Accessibility::Bridge::GetCurrentBridge();
+  auto rootLayer  = mScene.GetRootLayer();
+  auto accessible = Accessibility::Accessible::Get(rootLayer, true);
+  bridge->RemoveTopLevelWindow(accessible);
+}
+
 void Window::RecalculateTouchPosition(Integration::Point& point)
 {
   Vector2 position = point.GetScreenPosition();
@@ -912,13 +947,28 @@ void Window::SetParent(Dali::Window& parent)
     {
       Dali::DevelWindow::Unparent(parent);
     }
-    mWindowBase->SetParent(GetImplementation(mParentWindow).mWindowBase);
+    mWindowBase->SetParent(GetImplementation(mParentWindow).mWindowBase, false);
+  }
+}
+
+void Window::SetParent(Dali::Window& parent, bool belowParent)
+{
+  if(DALI_UNLIKELY(parent))
+  {
+    mParentWindow     = parent;
+    Dali::Window self = Dali::Window(this);
+    // check circular parent window setting
+    if(Dali::DevelWindow::GetParent(parent) == self)
+    {
+      Dali::DevelWindow::Unparent(parent);
+    }
+    mWindowBase->SetParent(GetImplementation(mParentWindow).mWindowBase, belowParent);
   }
 }
 
 void Window::Unparent()
 {
-  mWindowBase->SetParent(nullptr);
+  mWindowBase->SetParent(nullptr, false);
   mParentWindow.Reset();
 }
 
@@ -933,6 +983,11 @@ WindowOrientation Window::GetCurrentOrientation() const
   return ConvertToOrientation(mRotationAngle);
 }
 
+int Window::GetPhysicalOrientation() const
+{
+  return (mRotationAngle + mWindowBase->GetScreenRotationAngle()) % 360;
+}
+
 void Window::SetAvailableOrientations(const Dali::Vector<WindowOrientation>& orientations)
 {
   Dali::Vector<float>::SizeType count = orientations.Count();
@@ -970,6 +1025,91 @@ int32_t Window::GetNativeId() const
   return mWindowBase->GetNativeWindowId();
 }
 
+void Window::RequestMoveToServer()
+{
+  mWindowBase->RequestMoveToServer();
+}
+
+void Window::RequestResizeToServer(WindowResizeDirection direction)
+{
+  mWindowBase->RequestResizeToServer(direction);
+}
+
+void Window::EnableFloatingMode(bool enable)
+{
+  mWindowBase->EnableFloatingMode(enable);
+}
+
+Rect<int> Window::RecalculateRect(const Rect<int>& rect)
+{
+  Rect<int> newRect;
+  int screenWidth, screenHeight;
+
+  WindowSystem::GetScreenSize(screenWidth, screenHeight);
+
+  if(mRotationAngle == 90)
+  {
+    newRect.x      = rect.y;
+    newRect.y      = screenHeight - (rect.x + rect.width);
+    newRect.width  = rect.height;
+    newRect.height = rect.width;
+  }
+  else if(mRotationAngle == 180)
+  {
+    newRect.x      = screenWidth - (rect.x + rect.width);
+    newRect.y      = screenHeight - (rect.y + rect.height);
+    newRect.width  = rect.width;
+    newRect.height = rect.height;
+  }
+  else if(mRotationAngle == 270)
+  {
+    newRect.x      = screenWidth - (rect.y + rect.height);
+    newRect.y      = rect.x;
+    newRect.width  = rect.height;
+    newRect.height = rect.width;
+  }
+  else
+  {
+    newRect.x      = rect.x;
+    newRect.y      = rect.y;
+    newRect.width  = rect.width;
+    newRect.height = rect.height;
+  }
+  return newRect;
+}
+
+void Window::IncludeInputRegion(const Rect<int>& inputRegion)
+{
+  Rect<int> convertRegion = RecalculateRect(inputRegion);
+
+  DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), IncludeInputRegion, RecalculateRegion, (%d,%d), (%d x %d)\n", this, mNativeWindowId, convertRegion.x, convertRegion.y, convertRegion.width, convertRegion.height);
+  mWindowBase->IncludeInputRegion(convertRegion);
+}
+
+void Window::ExcludeInputRegion(const Rect<int>& inputRegion)
+{
+  Rect<int> convertRegion = RecalculateRect(inputRegion);
+
+  DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), ExcludeInputRegion, RecalculateRegion, (%d,%d), (%d x %d)\n", this, mNativeWindowId, convertRegion.x, convertRegion.y, convertRegion.width, convertRegion.height);
+  mWindowBase->ExcludeInputRegion(convertRegion);
+}
+
+void Window::SetNeedsRotationCompletedAcknowledgement(bool needAcknowledgement)
+{
+  DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), needAcknowledgement(%d) Set needs Rotation Completed Acknowledgement\n", this, mNativeWindowId, needAcknowledgement);
+  mWindowSurface->SetNeedsRotationCompletedAcknowledgement(needAcknowledgement);
+  mWindowRotationAcknowledgement = needAcknowledgement;
+}
+
+void Window::SendRotationCompletedAcknowledgement()
+{
+  DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), SendRotationCompletedAcknowledgement(): orientation: %d, mWindowRotationAcknowledgement: %d\n", this, mNativeWindowId, mRotationAngle, mWindowRotationAcknowledgement);
+  if(mWindowRotationAcknowledgement)
+  {
+    SetRotationCompletedAcknowledgement();
+  }
+}
+
 } // namespace Adaptor
 
 } // namespace Internal