[Tizen][AT-SPI] do not keep window in ApplicationAccessible
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / common / window-impl.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/window-system/common/window-impl.h>
20
21 // EXTERNAL HEADERS
22 #include <dali/devel-api/adaptor-framework/orientation.h>
23 #include <dali/integration-api/core.h>
24 #include <dali/integration-api/events/touch-event-integ.h>
25 #include <dali/public-api/actors/actor.h>
26 #include <dali/public-api/actors/camera-actor.h>
27 #include <dali/public-api/actors/layer.h>
28 #include <dali/public-api/adaptor-framework/window-enumerations.h>
29 #include <dali/public-api/render-tasks/render-task-list.h>
30 #include <dali/public-api/render-tasks/render-task.h>
31 #include <dali/public-api/rendering/frame-buffer.h>
32 #include <thread>
33
34 // INTERNAL HEADERS
35 #include <dali/devel-api/adaptor-framework/accessibility-impl.h>
36 #include <dali/integration-api/adaptor-framework/render-surface-interface.h>
37 #include <dali/internal/graphics/gles/egl-graphics.h>
38 #include <dali/internal/window-system/common/event-handler.h>
39 #include <dali/internal/window-system/common/orientation-impl.h>
40 #include <dali/internal/window-system/common/render-surface-factory.h>
41 #include <dali/internal/window-system/common/window-base.h>
42 #include <dali/internal/window-system/common/window-factory.h>
43 #include <dali/internal/window-system/common/window-render-surface.h>
44 #include <dali/internal/window-system/common/window-system.h>
45 #include <dali/internal/window-system/common/window-visibility-observer.h>
46
47 namespace Dali
48 {
49 namespace Internal
50 {
51 namespace Adaptor
52 {
53 namespace
54 {
55 #if defined(DEBUG_ENABLED)
56 Debug::Filter* gWindowLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_WINDOW");
57 #endif
58
59 } // unnamed namespace
60
61 Window* Window::New(const PositionSize& positionSize, const std::string& name, const std::string& className, Dali::WindowType type, bool isTransparent)
62 {
63   Any surface;
64   return Window::New(surface, positionSize, name, className, type, isTransparent);
65 }
66
67 Window* Window::New(Any surface, const PositionSize& positionSize, const std::string& name, const std::string& className, Dali::WindowType type, bool isTransparent)
68 {
69   Window* window         = new Window();
70   window->mIsTransparent = isTransparent;
71   window->Initialize(surface, positionSize, name, className, type);
72   return window;
73 }
74
75 Window::Window()
76 : mWindowSurface(nullptr),
77   mWindowBase(),
78   mIsTransparent(false),
79   mIsFocusAcceptable(true),
80   mIconified(false),
81   mOpaqueState(false),
82   mWindowRotationAcknowledgement(false),
83   mFocused(false),
84   mParentWindow(NULL),
85   mPreferredAngle(static_cast<int>(WindowOrientation::NO_ORIENTATION_PREFERENCE)),
86   mRotationAngle(0),
87   mWindowWidth(0),
88   mWindowHeight(0),
89   mOrientationMode(Internal::Adaptor::Window::OrientationMode::PORTRAIT),
90   mNativeWindowId(-1),
91   mDeleteRequestSignal(),
92   mFocusChangeSignal(),
93   mResizeSignal(),
94   mVisibilityChangedSignal(),
95   mTransitionEffectEventSignal(),
96   mKeyboardRepeatSettingsChangedSignal(),
97   mAuxiliaryMessageSignal()
98 {
99 }
100
101 Window::~Window()
102 {
103   if(mScene)
104   {
105     auto bridge     = Accessibility::Bridge::GetCurrentBridge();
106     auto rootLayer  = mScene.GetRootLayer();
107     auto accessible = Accessibility::Accessible::Get(rootLayer, true);
108     bridge->RemoveTopLevelWindow(accessible);
109   }
110
111   if(mAdaptor)
112   {
113     mAdaptor->RemoveWindow(this);
114   }
115
116   if(mEventHandler)
117   {
118     mEventHandler->RemoveObserver(*this);
119   }
120 }
121
122 void Window::Initialize(Any surface, const PositionSize& positionSize, const std::string& name, const std::string& className, WindowType type)
123 {
124   // Create a window render surface
125   auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
126   mSurface                  = renderSurfaceFactory->CreateWindowRenderSurface(positionSize, surface, mIsTransparent);
127   mWindowSurface            = static_cast<WindowRenderSurface*>(mSurface.get());
128
129   // Get a window base
130   mWindowBase = mWindowSurface->GetWindowBase();
131
132   // Set Window Type
133   mWindowBase->SetType(type);
134
135   // Initialize for Ime window type
136   if(type == WindowType::IME)
137   {
138     mWindowBase->InitializeIme();
139     mWindowSurface->InitializeImeSurface();
140   }
141
142   // Connect signals
143   mWindowBase->IconifyChangedSignal().Connect(this, &Window::OnIconifyChanged);
144   mWindowBase->FocusChangedSignal().Connect(this, &Window::OnFocusChanged);
145   mWindowBase->DeleteRequestSignal().Connect(this, &Window::OnDeleteRequest);
146   mWindowBase->TransitionEffectEventSignal().Connect(this, &Window::OnTransitionEffectEvent);
147   mWindowBase->KeyboardRepeatSettingsChangedSignal().Connect(this, &Window::OnKeyboardRepeatSettingsChanged);
148   mWindowBase->WindowRedrawRequestSignal().Connect(this, &Window::OnWindowRedrawRequest);
149   mWindowBase->UpdatePositionSizeSignal().Connect(this, &Window::OnUpdatePositionSize);
150   mWindowBase->AuxiliaryMessageSignal().Connect(this, &Window::OnAuxiliaryMessage);
151
152   mWindowSurface->OutputTransformedSignal().Connect(this, &Window::OnOutputTransformed);
153
154   AddAuxiliaryHint("wm.policy.win.user.geometry", "1");
155
156   SetClass(name, className);
157
158   mOrientation = Orientation::New(this);
159
160   // Get OrientationMode
161   int screenWidth, screenHeight;
162   WindowSystem::GetScreenSize(screenWidth, screenHeight);
163   if(screenWidth > screenHeight)
164   {
165     mOrientationMode = Internal::Adaptor::Window::OrientationMode::LANDSCAPE;
166   }
167   else
168   {
169     mOrientationMode = Internal::Adaptor::Window::OrientationMode::PORTRAIT;
170   }
171   // For Debugging
172   mNativeWindowId = mWindowBase->GetNativeWindowId();
173 }
174
175 void Window::OnAdaptorSet(Dali::Adaptor& adaptor)
176 {
177   mEventHandler = EventHandlerPtr(new EventHandler(mWindowSurface->GetWindowBase(), *mAdaptor));
178   mEventHandler->AddObserver(*this);
179
180   // Add Window to bridge for ATSPI
181   auto bridge = Accessibility::Bridge::GetCurrentBridge();
182   if (bridge->IsUp())
183   {
184     auto rootLayer  = mScene.GetRootLayer();
185     auto accessible = Accessibility::Accessible::Get(rootLayer, true);
186     bridge->AddTopLevelWindow(accessible);
187   }
188
189   bridge->EnabledSignal().Connect(this, &Window::OnAccessibilityEnabled);
190   bridge->DisabledSignal().Connect(this, &Window::OnAccessibilityDisabled);
191
192   // If you call the 'Show' before creating the adaptor, the application cannot know the app resource id.
193   // The show must be called after the adaptor is initialized.
194   Show();
195 }
196
197 void Window::OnSurfaceSet(Dali::RenderSurfaceInterface* surface)
198 {
199   mWindowSurface = static_cast<WindowRenderSurface*>(surface);
200 }
201
202 void Window::SetClass(std::string name, std::string className)
203 {
204   mName      = name;
205   mClassName = className;
206   mWindowBase->SetClass(name, className);
207 }
208
209 std::string Window::GetClassName() const
210 {
211   return mClassName;
212 }
213
214 void Window::Raise()
215 {
216   mWindowBase->Raise();
217
218   mSurface->SetFullSwapNextFrame();
219
220   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Raise() \n", this, mNativeWindowId);
221 }
222
223 void Window::Lower()
224 {
225   mWindowBase->Lower();
226
227   mSurface->SetFullSwapNextFrame();
228
229   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Lower() \n", this, mNativeWindowId);
230 }
231
232 void Window::Activate()
233 {
234   mWindowBase->Activate();
235
236   mSurface->SetFullSwapNextFrame();
237
238   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Activate() \n", this, mNativeWindowId);
239 }
240
241 uint32_t Window::GetLayerCount() const
242 {
243   return mScene.GetLayerCount();
244 }
245
246 Dali::Layer Window::GetLayer(uint32_t depth) const
247 {
248   return mScene.GetLayer(depth);
249 }
250
251 Dali::RenderTaskList Window::GetRenderTaskList() const
252 {
253   return mScene.GetRenderTaskList();
254 }
255
256 void Window::AddAvailableOrientation(WindowOrientation orientation)
257 {
258   if(IsOrientationAvailable(orientation) == false)
259   {
260     return;
261   }
262
263   bool found          = false;
264   int  convertedAngle = ConvertToAngle(orientation);
265   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), AddAvailableOrientation: %d\n", this, mNativeWindowId, convertedAngle);
266   for(std::size_t i = 0; i < mAvailableAngles.size(); i++)
267   {
268     if(mAvailableAngles[i] == convertedAngle)
269     {
270       found = true;
271       break;
272     }
273   }
274
275   if(!found)
276   {
277     mAvailableAngles.push_back(convertedAngle);
278     SetAvailableAnlges(mAvailableAngles);
279   }
280 }
281
282 void Window::RemoveAvailableOrientation(WindowOrientation orientation)
283 {
284   if(IsOrientationAvailable(orientation) == false)
285   {
286     return;
287   }
288
289   int convertedAngle = ConvertToAngle(orientation);
290   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), RemoveAvailableOrientation: %d\n", this, mNativeWindowId, convertedAngle);
291   for(std::vector<int>::iterator iter = mAvailableAngles.begin();
292       iter != mAvailableAngles.end();
293       ++iter)
294   {
295     if(*iter == convertedAngle)
296     {
297       mAvailableAngles.erase(iter);
298       break;
299     }
300   }
301
302   SetAvailableAnlges(mAvailableAngles);
303 }
304
305 void Window::SetPreferredOrientation(WindowOrientation orientation)
306 {
307   if(orientation < WindowOrientation::NO_ORIENTATION_PREFERENCE || orientation > WindowOrientation::LANDSCAPE_INVERSE)
308   {
309     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::CheckOrientation: Invalid input orientation [%d]\n", orientation);
310     return;
311   }
312   mPreferredAngle = ConvertToAngle(orientation);
313   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), SetPreferredOrientation: %d\n", this, mNativeWindowId, mPreferredAngle);
314   mWindowBase->SetPreferredAngle(mPreferredAngle);
315 }
316
317 WindowOrientation Window::GetPreferredOrientation()
318 {
319   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), GetPreferredOrientation: %d\n", this, mNativeWindowId, mPreferredAngle);
320   WindowOrientation preferredOrientation = ConvertToOrientation(mPreferredAngle);
321   return preferredOrientation;
322 }
323
324 void Window::SetPositionSizeWithOrientation(PositionSize positionSize, WindowOrientation orientation)
325 {
326   int angle = ConvertToAngle(orientation);
327   mWindowBase->SetPositionSizeWithAngle(positionSize, angle);
328 }
329
330 void Window::SetAvailableAnlges(const std::vector<int>& angles)
331 {
332   if(angles.size() > 4)
333   {
334     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetAvailableAnlges: Invalid vector size! [%d]\n", angles.size());
335     return;
336   }
337
338   mWindowBase->SetAvailableAnlges(angles);
339 }
340
341 int Window::ConvertToAngle(WindowOrientation orientation)
342 {
343   int convertAngle = static_cast<int>(orientation);
344   if(mOrientationMode == Internal::Adaptor::Window::OrientationMode::LANDSCAPE)
345   {
346     switch(orientation)
347     {
348       case WindowOrientation::LANDSCAPE:
349       {
350         convertAngle = 0;
351         break;
352       }
353       case WindowOrientation::PORTRAIT:
354       {
355         convertAngle = 90;
356         break;
357       }
358       case WindowOrientation::LANDSCAPE_INVERSE:
359       {
360         convertAngle = 180;
361         break;
362       }
363       case WindowOrientation::PORTRAIT_INVERSE:
364       {
365         convertAngle = 270;
366         break;
367       }
368       case WindowOrientation::NO_ORIENTATION_PREFERENCE:
369       {
370         convertAngle = -1;
371         break;
372       }
373     }
374   }
375   return convertAngle;
376 }
377
378 WindowOrientation Window::ConvertToOrientation(int angle) const
379 {
380   WindowOrientation orientation = static_cast<WindowOrientation>(angle);
381   if(mOrientationMode == Internal::Adaptor::Window::OrientationMode::LANDSCAPE)
382   {
383     switch(angle)
384     {
385       case 0:
386       {
387         orientation = WindowOrientation::LANDSCAPE;
388         break;
389       }
390       case 90:
391       {
392         orientation = WindowOrientation::PORTRAIT;
393         break;
394       }
395       case 180:
396       {
397         orientation = WindowOrientation::LANDSCAPE_INVERSE;
398         break;
399       }
400       case 270:
401       {
402         orientation = WindowOrientation::PORTRAIT_INVERSE;
403         break;
404       }
405       case -1:
406       {
407         orientation = WindowOrientation::NO_ORIENTATION_PREFERENCE;
408         break;
409       }
410     }
411   }
412   return orientation;
413 }
414
415 bool Window::IsOrientationAvailable(WindowOrientation orientation) const
416 {
417   if(orientation <= WindowOrientation::NO_ORIENTATION_PREFERENCE || orientation > WindowOrientation::LANDSCAPE_INVERSE)
418   {
419     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::IsOrientationAvailable: Invalid input orientation [%d]\n", orientation);
420     return false;
421   }
422   return true;
423 }
424
425 Dali::Any Window::GetNativeHandle() const
426 {
427   return mWindowSurface->GetNativeWindow();
428 }
429
430 void Window::SetAcceptFocus(bool accept)
431 {
432   mIsFocusAcceptable = accept;
433
434   mWindowBase->SetAcceptFocus(accept);
435 }
436
437 bool Window::IsFocusAcceptable() const
438 {
439   return mIsFocusAcceptable;
440 }
441
442 void Window::Show()
443 {
444   mVisible = true;
445
446   mWindowBase->Show();
447
448   if(!mIconified)
449   {
450     Dali::Window handle(this);
451     mVisibilityChangedSignal.Emit(handle, true);
452     Dali::Accessibility::Bridge::GetCurrentBridge()->WindowShown(handle);
453
454     WindowVisibilityObserver* observer(mAdaptor);
455     observer->OnWindowShown();
456   }
457
458   mSurface->SetFullSwapNextFrame();
459
460   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Show(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible);
461 }
462
463 void Window::Hide()
464 {
465   mVisible = false;
466
467   mWindowBase->Hide();
468
469   if(!mIconified)
470   {
471     Dali::Window handle(this);
472     mVisibilityChangedSignal.Emit(handle, false);
473     Dali::Accessibility::Bridge::GetCurrentBridge()->WindowHidden(handle);
474
475     WindowVisibilityObserver* observer(mAdaptor);
476     observer->OnWindowHidden();
477   }
478
479   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Hide(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible);
480 }
481
482 bool Window::IsVisible() const
483 {
484   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), IsVisible(): iconified = %d, visible = %d\n", this, mNativeWindowId, mIconified, mVisible);
485   return mVisible && !mIconified;
486 }
487
488 unsigned int Window::GetSupportedAuxiliaryHintCount() const
489 {
490   return mWindowBase->GetSupportedAuxiliaryHintCount();
491 }
492
493 std::string Window::GetSupportedAuxiliaryHint(unsigned int index) const
494 {
495   return mWindowBase->GetSupportedAuxiliaryHint(index);
496 }
497
498 unsigned int Window::AddAuxiliaryHint(const std::string& hint, const std::string& value)
499 {
500   return mWindowBase->AddAuxiliaryHint(hint, value);
501 }
502
503 bool Window::RemoveAuxiliaryHint(unsigned int id)
504 {
505   return mWindowBase->RemoveAuxiliaryHint(id);
506 }
507
508 bool Window::SetAuxiliaryHintValue(unsigned int id, const std::string& value)
509 {
510   return mWindowBase->SetAuxiliaryHintValue(id, value);
511 }
512
513 std::string Window::GetAuxiliaryHintValue(unsigned int id) const
514 {
515   return mWindowBase->GetAuxiliaryHintValue(id);
516 }
517
518 unsigned int Window::GetAuxiliaryHintId(const std::string& hint) const
519 {
520   return mWindowBase->GetAuxiliaryHintId(hint);
521 }
522
523 void Window::SetInputRegion(const Rect<int>& inputRegion)
524 {
525   Rect<int> convertRegion = RecalculateRect(inputRegion);
526
527   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);
528
529   mWindowBase->SetInputRegion(convertRegion);
530 }
531
532 void Window::SetType(WindowType type)
533 {
534   mWindowBase->SetType(type);
535 }
536
537 WindowType Window::GetType() const
538 {
539   return mWindowBase->GetType();
540 }
541
542 WindowOperationResult Window::SetNotificationLevel(WindowNotificationLevel level)
543 {
544   WindowType type = mWindowBase->GetType();
545   if(type != WindowType::NOTIFICATION)
546   {
547     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", type);
548     return WindowOperationResult::INVALID_OPERATION;
549   }
550
551   return mWindowBase->SetNotificationLevel(level);
552 }
553
554 WindowNotificationLevel Window::GetNotificationLevel() const
555 {
556   WindowType type = mWindowBase->GetType();
557   if(type != WindowType::NOTIFICATION)
558   {
559     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", type);
560     return WindowNotificationLevel::NONE;
561   }
562
563   return mWindowBase->GetNotificationLevel();
564 }
565
566 void Window::SetOpaqueState(bool opaque)
567 {
568   mOpaqueState = opaque;
569
570   mWindowBase->SetOpaqueState(opaque);
571
572   DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque);
573 }
574
575 bool Window::IsOpaqueState() const
576 {
577   return mOpaqueState;
578 }
579
580 WindowOperationResult Window::SetScreenOffMode(WindowScreenOffMode screenOffMode)
581 {
582   return mWindowBase->SetScreenOffMode(screenOffMode);
583 }
584
585 WindowScreenOffMode Window::GetScreenOffMode() const
586 {
587   return mWindowBase->GetScreenOffMode();
588 }
589
590 WindowOperationResult Window::SetBrightness(int brightness)
591 {
592   if(brightness < 0 || brightness > 100)
593   {
594     DALI_LOG_INFO(gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness);
595     return WindowOperationResult::INVALID_OPERATION;
596   }
597
598   return mWindowBase->SetBrightness(brightness);
599 }
600
601 int Window::GetBrightness() const
602 {
603   return mWindowBase->GetBrightness();
604 }
605
606 void Window::SetSize(Dali::Window::WindowSize size)
607 {
608   PositionSize oldRect = mSurface->GetPositionSize();
609
610   mWindowSurface->MoveResize(PositionSize(oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight()));
611
612   PositionSize newRect = mSurface->GetPositionSize();
613
614   // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
615   if((oldRect.width != newRect.width) || (oldRect.height != newRect.height))
616   {
617     Uint16Pair newSize(newRect.width, newRect.height);
618
619     SurfaceResized();
620
621     mAdaptor->SurfaceResizePrepare(mSurface.get(), newSize);
622
623     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), SetSize(): resize signal [%d x %d]\n", this, mNativeWindowId, newRect.width, newRect.height);
624
625     Dali::Window handle(this);
626     mResizeSignal.Emit(handle, newSize);
627
628     mAdaptor->SurfaceResizeComplete(mSurface.get(), newSize);
629   }
630
631   mSurface->SetFullSwapNextFrame();
632
633   Dali::Accessibility::Accessible::Get(mScene.GetRootLayer(), true)->EmitBoundsChanged(Dali::Rect<>(oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight()));
634 }
635
636 Dali::Window::WindowSize Window::GetSize() const
637 {
638   PositionSize positionSize = mSurface->GetPositionSize();
639
640   return Dali::Window::WindowSize(positionSize.width, positionSize.height);
641 }
642
643 void Window::SetPosition(Dali::Window::WindowPosition position)
644 {
645   PositionSize oldRect = mSurface->GetPositionSize();
646
647   mWindowSurface->MoveResize(PositionSize(position.GetX(), position.GetY(), oldRect.width, oldRect.height));
648
649   mSurface->SetFullSwapNextFrame();
650
651   Dali::Accessibility::Accessible::Get(mScene.GetRootLayer(), true)->EmitBoundsChanged(Dali::Rect<>(position.GetX(), position.GetY(), oldRect.width, oldRect.height));
652 }
653
654 Dali::Window::WindowPosition Window::GetPosition() const
655 {
656   PositionSize positionSize = mSurface->GetPositionSize();
657
658   return Dali::Window::WindowPosition(positionSize.x, positionSize.y);
659 }
660
661 PositionSize Window::GetPositionSize() const
662 {
663   return mSurface->GetPositionSize();
664 }
665
666 void Window::SetPositionSize(PositionSize positionSize)
667 {
668   PositionSize oldRect = mSurface->GetPositionSize();
669
670   mWindowSurface->MoveResize(positionSize);
671
672   PositionSize newRect = mSurface->GetPositionSize();
673
674   // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
675   if((oldRect.width != newRect.width) || (oldRect.height != newRect.height))
676   {
677     Uint16Pair newSize(newRect.width, newRect.height);
678
679     SurfaceResized();
680
681     mAdaptor->SurfaceResizePrepare(mSurface.get(), newSize);
682
683     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), SetPositionSize():resize signal [%d x %d]\n", this, mNativeWindowId, newRect.width, newRect.height);
684     Dali::Window handle(this);
685     mResizeSignal.Emit(handle, newSize);
686     mAdaptor->SurfaceResizeComplete(mSurface.get(), newSize);
687   }
688
689   mSurface->SetFullSwapNextFrame();
690
691   Dali::Accessibility::Accessible::Get(mScene.GetRootLayer(), true)->EmitBoundsChanged(Dali::Rect<>(positionSize.x, positionSize.y, positionSize.width, positionSize.height));
692 }
693
694 Dali::Layer Window::GetRootLayer() const
695 {
696   return mScene.GetRootLayer();
697 }
698
699 void Window::SetTransparency(bool transparent)
700 {
701   mWindowSurface->SetTransparency(transparent);
702 }
703
704 bool Window::GrabKey(Dali::KEY key, KeyGrab::KeyGrabMode grabMode)
705 {
706   return mWindowBase->GrabKey(key, grabMode);
707 }
708
709 bool Window::UngrabKey(Dali::KEY key)
710 {
711   return mWindowBase->UngrabKey(key);
712 }
713
714 bool Window::GrabKeyList(const Dali::Vector<Dali::KEY>& key, const Dali::Vector<KeyGrab::KeyGrabMode>& grabMode, Dali::Vector<bool>& result)
715 {
716   return mWindowBase->GrabKeyList(key, grabMode, result);
717 }
718
719 bool Window::UngrabKeyList(const Dali::Vector<Dali::KEY>& key, Dali::Vector<bool>& result)
720 {
721   return mWindowBase->UngrabKeyList(key, result);
722 }
723
724 void Window::OnIconifyChanged(bool iconified)
725 {
726   if(iconified)
727   {
728     mIconified = true;
729
730     if(mVisible)
731     {
732       Dali::Window handle(this);
733       mVisibilityChangedSignal.Emit(handle, false);
734       Dali::Accessibility::Bridge::GetCurrentBridge()->WindowHidden(handle);
735
736       WindowVisibilityObserver* observer(mAdaptor);
737       observer->OnWindowHidden();
738     }
739
740     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Iconified: visible = %d\n", this, mNativeWindowId, mVisible);
741   }
742   else
743   {
744     mIconified = false;
745
746     if(mVisible)
747     {
748       Dali::Window handle(this);
749       mVisibilityChangedSignal.Emit(handle, true);
750       Dali::Accessibility::Bridge::GetCurrentBridge()->WindowShown(handle);
751
752       WindowVisibilityObserver* observer(mAdaptor);
753       observer->OnWindowShown();
754     }
755
756     DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), Deiconified: visible = %d\n", this, mNativeWindowId, mVisible);
757   }
758
759   mSurface->SetFullSwapNextFrame();
760 }
761
762 void Window::OnFocusChanged(bool focusIn)
763 {
764   Dali::Window handle(this);
765   mFocusChangeSignal.Emit(handle, focusIn);
766
767   mSurface->SetFullSwapNextFrame();
768
769   if(auto bridge = Dali::Accessibility::Bridge::GetCurrentBridge())
770   {
771     if(focusIn)
772     {
773       bridge->WindowFocused(handle);
774     }
775     else
776     {
777       bridge->WindowUnfocused(handle);
778     }
779   }
780   mFocused = focusIn;
781 }
782
783 void Window::OnOutputTransformed()
784 {
785   PositionSize positionSize = mSurface->GetPositionSize();
786
787   int orientation = (mRotationAngle + mWindowBase->GetScreenRotationAngle()) % 360;
788   SurfaceRotated(static_cast<float>(positionSize.width), static_cast<float>(positionSize.height), orientation);
789
790   mAdaptor->SurfaceResizePrepare(mSurface.get(), Adaptor::SurfaceSize(positionSize.width, positionSize.height));
791   mAdaptor->SurfaceResizeComplete(mSurface.get(), Adaptor::SurfaceSize(positionSize.width, positionSize.height));
792 }
793
794 void Window::OnDeleteRequest()
795 {
796   mDeleteRequestSignal.Emit();
797 }
798
799 void Window::OnTransitionEffectEvent(WindowEffectState state, WindowEffectType type)
800 {
801   Dali::Window handle(this);
802   mTransitionEffectEventSignal.Emit(handle, state, type);
803 }
804
805 void Window::OnKeyboardRepeatSettingsChanged()
806 {
807   Dali::Window handle(this);
808   mKeyboardRepeatSettingsChangedSignal.Emit();
809 }
810
811 void Window::OnWindowRedrawRequest()
812 {
813   mAdaptor->RenderOnce();
814 }
815
816 void Window::OnUpdatePositionSize(Dali::PositionSize& positionSize)
817 {
818   SetPositionSize(positionSize);
819 }
820
821 void Window::OnTouchPoint(Dali::Integration::Point& point, int timeStamp)
822 {
823   FeedTouchPoint(point, timeStamp);
824 }
825
826 void Window::OnWheelEvent(Dali::Integration::WheelEvent& wheelEvent)
827 {
828   FeedWheelEvent(wheelEvent);
829 }
830
831 void Window::OnKeyEvent(Dali::Integration::KeyEvent& keyEvent)
832 {
833   FeedKeyEvent(keyEvent);
834 }
835
836 void Window::OnRotation(const RotationEvent& rotation)
837 {
838   mRotationAngle = rotation.angle;
839   mWindowWidth   = rotation.width;
840   mWindowHeight  = rotation.height;
841
842   // Notify that the orientation is changed
843   mOrientation->OnOrientationChange(rotation);
844
845   mWindowSurface->RequestRotation(mRotationAngle, mWindowWidth, mWindowHeight);
846
847   int orientation = (mRotationAngle + mWindowBase->GetScreenRotationAngle()) % 360;
848   SurfaceRotated(mWindowWidth, mWindowHeight, orientation);
849
850   mAdaptor->SurfaceResizePrepare(mSurface.get(), Adaptor::SurfaceSize(mWindowWidth, mWindowHeight));
851
852   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), OnRotation(): resize signal emit [%d x %d]\n", this, mNativeWindowId, mWindowWidth, mWindowHeight);
853   // Emit signal
854   Dali::Window handle(this);
855   mResizeSignal.Emit(handle, Dali::Window::WindowSize(mWindowWidth, mWindowHeight));
856
857   mAdaptor->SurfaceResizeComplete(mSurface.get(), Adaptor::SurfaceSize(mWindowWidth, mWindowHeight));
858 }
859
860 void Window::OnPause()
861 {
862   if(mEventHandler)
863   {
864     mEventHandler->Pause();
865   }
866 }
867
868 void Window::OnResume()
869 {
870   if(mEventHandler)
871   {
872     mEventHandler->Resume();
873   }
874
875   mSurface->SetFullSwapNextFrame();
876 }
877
878 void Window::OnAuxiliaryMessage(const std::string& key, const std::string& value, const Property::Array& options)
879 {
880   mAuxiliaryMessageSignal.Emit(key, value, options);
881 }
882
883 void Window::OnAccessibilityEnabled()
884 {
885   auto bridge     = Accessibility::Bridge::GetCurrentBridge();
886   auto rootLayer  = mScene.GetRootLayer();
887   auto accessible = Accessibility::Accessible::Get(rootLayer, true);
888   bridge->AddTopLevelWindow(accessible);
889
890   if(mFocused)
891   {
892     Dali::Window handle(this);
893     bridge->WindowFocused(handle);
894   }
895 }
896
897 void Window::OnAccessibilityDisabled()
898 {
899   auto bridge     = Accessibility::Bridge::GetCurrentBridge();
900   auto rootLayer  = mScene.GetRootLayer();
901   auto accessible = Accessibility::Accessible::Get(rootLayer, true);
902   bridge->RemoveTopLevelWindow(accessible);
903 }
904
905 void Window::RecalculateTouchPosition(Integration::Point& point)
906 {
907   Vector2 position = point.GetScreenPosition();
908   Vector2 convertedPosition;
909
910   switch(mRotationAngle)
911   {
912     case 90:
913     {
914       convertedPosition.x = static_cast<float>(mWindowWidth) - position.y;
915       convertedPosition.y = position.x;
916       break;
917     }
918     case 180:
919     {
920       convertedPosition.x = static_cast<float>(mWindowWidth) - position.x;
921       convertedPosition.y = static_cast<float>(mWindowHeight) - position.y;
922       break;
923     }
924     case 270:
925     {
926       convertedPosition.x = position.y;
927       convertedPosition.y = static_cast<float>(mWindowHeight) - position.x;
928       break;
929     }
930     default:
931     {
932       convertedPosition = position;
933       break;
934     }
935   }
936
937   point.SetScreenPosition(convertedPosition);
938 }
939
940 Dali::Window Window::Get(Dali::Actor actor)
941 {
942   Internal::Adaptor::Window* windowImpl = nullptr;
943
944   if(Internal::Adaptor::Adaptor::IsAvailable())
945   {
946     Dali::Internal::Adaptor::Adaptor& adaptor = Internal::Adaptor::Adaptor::GetImplementation(Internal::Adaptor::Adaptor::Get());
947     windowImpl                                = dynamic_cast<Internal::Adaptor::Window*>(adaptor.GetWindow(actor));
948     if(windowImpl)
949     {
950       return Dali::Window(windowImpl);
951     }
952   }
953
954   return Dali::Window();
955 }
956
957 void Window::SetParent(Dali::Window& parent)
958 {
959   if(DALI_UNLIKELY(parent))
960   {
961     mParentWindow     = parent;
962     Dali::Window self = Dali::Window(this);
963     // check circular parent window setting
964     if(Dali::DevelWindow::GetParent(parent) == self)
965     {
966       Dali::DevelWindow::Unparent(parent);
967     }
968     mWindowBase->SetParent(GetImplementation(mParentWindow).mWindowBase, false);
969   }
970 }
971
972 void Window::SetParent(Dali::Window& parent, bool belowParent)
973 {
974   if(DALI_UNLIKELY(parent))
975   {
976     mParentWindow     = parent;
977     Dali::Window self = Dali::Window(this);
978     // check circular parent window setting
979     if(Dali::DevelWindow::GetParent(parent) == self)
980     {
981       Dali::DevelWindow::Unparent(parent);
982     }
983     mWindowBase->SetParent(GetImplementation(mParentWindow).mWindowBase, belowParent);
984   }
985 }
986
987 void Window::Unparent()
988 {
989   mWindowBase->SetParent(nullptr, false);
990   mParentWindow.Reset();
991 }
992
993 Dali::Window Window::GetParent()
994 {
995   return mParentWindow;
996 }
997
998 WindowOrientation Window::GetCurrentOrientation() const
999 {
1000   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), GetCurrentOrientation(): %d\n", this, mNativeWindowId, mRotationAngle);
1001   return ConvertToOrientation(mRotationAngle);
1002 }
1003
1004 int Window::GetPhysicalOrientation() const
1005 {
1006   return (mRotationAngle + mWindowBase->GetScreenRotationAngle()) % 360;
1007 }
1008
1009 void Window::SetAvailableOrientations(const Dali::Vector<WindowOrientation>& orientations)
1010 {
1011   Dali::Vector<float>::SizeType count = orientations.Count();
1012   for(Dali::Vector<float>::SizeType index = 0; index < count; ++index)
1013   {
1014     if(IsOrientationAvailable(orientations[index]) == false)
1015     {
1016       DALI_LOG_ERROR("Window::SetAvailableOrientations, invalid orientation: %d\n", orientations[index]);
1017       continue;
1018     }
1019
1020     bool found          = false;
1021     int  convertedAngle = ConvertToAngle(orientations[index]);
1022
1023     for(std::size_t i = 0; i < mAvailableAngles.size(); i++)
1024     {
1025       if(mAvailableAngles[i] == convertedAngle)
1026       {
1027         found = true;
1028         break;
1029       }
1030     }
1031
1032     if(!found)
1033     {
1034       DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), SetAvailableOrientations: %d\n", this, mNativeWindowId, convertedAngle);
1035       mAvailableAngles.push_back(convertedAngle);
1036     }
1037   }
1038   SetAvailableAnlges(mAvailableAngles);
1039 }
1040
1041 int32_t Window::GetNativeId() const
1042 {
1043   return mWindowBase->GetNativeWindowId();
1044 }
1045
1046 void Window::RequestMoveToServer()
1047 {
1048   mWindowBase->RequestMoveToServer();
1049 }
1050
1051 void Window::RequestResizeToServer(WindowResizeDirection direction)
1052 {
1053   mWindowBase->RequestResizeToServer(direction);
1054 }
1055
1056 void Window::EnableFloatingMode(bool enable)
1057 {
1058   mWindowBase->EnableFloatingMode(enable);
1059 }
1060
1061 Rect<int> Window::RecalculateRect(const Rect<int>& rect)
1062 {
1063   Rect<int> newRect;
1064   int screenWidth, screenHeight;
1065
1066   WindowSystem::GetScreenSize(screenWidth, screenHeight);
1067
1068   if(mRotationAngle == 90)
1069   {
1070     newRect.x      = rect.y;
1071     newRect.y      = screenHeight - (rect.x + rect.width);
1072     newRect.width  = rect.height;
1073     newRect.height = rect.width;
1074   }
1075   else if(mRotationAngle == 180)
1076   {
1077     newRect.x      = screenWidth - (rect.x + rect.width);
1078     newRect.y      = screenHeight - (rect.y + rect.height);
1079     newRect.width  = rect.width;
1080     newRect.height = rect.height;
1081   }
1082   else if(mRotationAngle == 270)
1083   {
1084     newRect.x      = screenWidth - (rect.y + rect.height);
1085     newRect.y      = rect.x;
1086     newRect.width  = rect.height;
1087     newRect.height = rect.width;
1088   }
1089   else
1090   {
1091     newRect.x      = rect.x;
1092     newRect.y      = rect.y;
1093     newRect.width  = rect.width;
1094     newRect.height = rect.height;
1095   }
1096   return newRect;
1097 }
1098
1099 void Window::IncludeInputRegion(const Rect<int>& inputRegion)
1100 {
1101   Rect<int> convertRegion = RecalculateRect(inputRegion);
1102
1103   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);
1104   mWindowBase->IncludeInputRegion(convertRegion);
1105 }
1106
1107 void Window::ExcludeInputRegion(const Rect<int>& inputRegion)
1108 {
1109   Rect<int> convertRegion = RecalculateRect(inputRegion);
1110
1111   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);
1112   mWindowBase->ExcludeInputRegion(convertRegion);
1113 }
1114
1115 void Window::SetNeedsRotationCompletedAcknowledgement(bool needAcknowledgement)
1116 {
1117   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), needAcknowledgement(%d) Set needs Rotation Completed Acknowledgement\n", this, mNativeWindowId, needAcknowledgement);
1118   mWindowSurface->SetNeedsRotationCompletedAcknowledgement(needAcknowledgement);
1119   mWindowRotationAcknowledgement = needAcknowledgement;
1120 }
1121
1122 void Window::SendRotationCompletedAcknowledgement()
1123 {
1124   DALI_LOG_RELEASE_INFO("Window (%p), WinId (%d), SendRotationCompletedAcknowledgement(): orientation: %d, mWindowRotationAcknowledgement: %d\n", this, mNativeWindowId, mRotationAngle, mWindowRotationAcknowledgement);
1125   if(mWindowRotationAcknowledgement)
1126   {
1127     SetRotationCompletedAcknowledgement();
1128   }
1129 }
1130
1131 bool Window::IsWindowRotating() const
1132 {
1133   return mWindowSurface->IsWindowRotating();
1134 }
1135
1136 } // namespace Adaptor
1137
1138 } // namespace Internal
1139
1140 } // namespace Dali