2ef09622963b2d151c19cbc603e7a933eeca488e
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / common / window-impl.cpp
1 /*
2  * Copyright (c) 2019 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/integration-api/core.h>
23 #include <dali/public-api/actors/actor.h>
24 #include <dali/public-api/actors/layer.h>
25 #include <dali/public-api/actors/camera-actor.h>
26 #include <dali/public-api/render-tasks/render-task.h>
27 #include <dali/public-api/render-tasks/render-task-list.h>
28 #include <dali/public-api/rendering/frame-buffer.h>
29 #include <dali/devel-api/adaptor-framework/orientation.h>
30 #include <dali/integration-api/events/touch-event-integ.h>
31
32 #ifdef DALI_ADAPTOR_COMPILATION
33 #include <dali/integration-api/render-surface-interface.h>
34 #else
35 #include <dali/integration-api/adaptors/render-surface-interface.h>
36 #endif
37
38 // INTERNAL HEADERS
39 #include <dali/internal/window-system/common/event-handler.h>
40 #include <dali/internal/window-system/common/orientation-impl.h>
41 #include <dali/internal/window-system/common/render-surface-factory.h>
42 #include <dali/internal/window-system/common/window-factory.h>
43 #include <dali/internal/window-system/common/window-base.h>
44 #include <dali/internal/window-system/common/window-render-surface.h>
45 #include <dali/internal/window-system/common/window-visibility-observer.h>
46 #include <dali/devel-api/adaptor-framework/accessibility.h>
47
48 namespace Dali
49 {
50 namespace Internal
51 {
52 namespace Adaptor
53 {
54
55 namespace
56 {
57
58 #if defined(DEBUG_ENABLED)
59 Debug::Filter* gWindowLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW" );
60 #endif
61
62 } // unnamed namespace
63
64 Window* Window::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
65 {
66   Window* window = new Window();
67   window->mIsTransparent = isTransparent;
68   window->Initialize( positionSize, name, className );
69   return window;
70 }
71
72 Window::Window()
73 : mWindowSurface( nullptr ),
74   mWindowBase(),
75   mIsTransparent( false ),
76   mIsFocusAcceptable( true ),
77   mIconified( false ),
78   mOpaqueState( false ),
79   mResizeEnabled( false ),
80   mType( Dali::Window::NORMAL ),
81   mParentWindow( NULL ),
82   mPreferredOrientation( Dali::Window::PORTRAIT ),
83   mRotationAngle( 0 ),
84   mWindowWidth( 0 ),
85   mWindowHeight( 0 ),
86   mFocusChangedSignal(),
87   mResizedSignal(),
88   mDeleteRequestSignal(),
89   mFocusChangeSignal(),
90   mResizeSignal()
91 {
92 }
93
94 Window::~Window()
95 {
96   if ( mAdaptor )
97   {
98                 auto bridge = Accessibility::Bridge::GetCurrentBridge();
99                 auto accessible2 = mScene.GetRootLayer();
100                 auto accessible = Accessibility::Accessible::Get( accessible2 );
101                 bridge->RemoveTopLevelWindow( accessible );
102
103     mAdaptor->RemoveWindow( this );
104     mAdaptor = NULL;
105   }
106
107   if ( mEventHandler )
108   {
109     mEventHandler->RemoveObserver( *this );
110   }
111 }
112
113 void Window::Initialize(const PositionSize& positionSize, const std::string& name, const std::string& className)
114 {
115   // Create a window render surface
116   Any surface;
117   auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
118   mSurface = renderSurfaceFactory->CreateWindowRenderSurface( positionSize, surface, mIsTransparent );
119   mWindowSurface = static_cast<WindowRenderSurface*>( mSurface.get() );
120
121   // Get a window base
122   mWindowBase = mWindowSurface->GetWindowBase();
123
124   // Connect signals
125   mWindowBase->IconifyChangedSignal().Connect( this, &Window::OnIconifyChanged );
126   mWindowBase->FocusChangedSignal().Connect( this, &Window::OnFocusChanged );
127   mWindowBase->DeleteRequestSignal().Connect( this, &Window::OnDeleteRequest );
128
129   mWindowSurface->OutputTransformedSignal().Connect( this, &Window::OnOutputTransformed );
130
131   if( !positionSize.IsEmpty() )
132   {
133     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
134     mResizeEnabled = true;
135   }
136
137   SetClass( name, className );
138
139   mWindowSurface->Map();
140
141   mOrientation = Orientation::New( this );
142 }
143
144 void Window::OnAdaptorSet(Dali::Adaptor& adaptor)
145 {
146   mEventHandler = EventHandlerPtr(new EventHandler( mWindowSurface, *mAdaptor ) );
147   mEventHandler->AddObserver( *this );
148
149   auto bridge = Accessibility::Bridge::GetCurrentBridge();
150   auto v = mScene.GetRootLayer();
151   auto accessible = Accessibility::Accessible::Get( v, true );
152   bridge->AddTopLevelWindow( accessible );
153
154   //FIXME: line below is temporary solution for missing "activate" signal and should be removed
155   Show();
156 }
157
158 void Window::OnSurfaceSet( Dali::RenderSurfaceInterface* surface )
159 {
160   mWindowSurface = static_cast<WindowRenderSurface*>( surface );
161 }
162
163 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
164 {
165 }
166
167 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
168 {
169 }
170
171 void Window::RotateIndicator( Dali::Window::WindowOrientation orientation )
172 {
173 }
174
175 void Window::SetClass( std::string name, std::string className )
176 {
177   mName = name;
178   mClassName = className;
179   mWindowBase->SetClass( name, className );
180 }
181
182 std::string Window::GetClassName() const
183 {
184   return mClassName;
185 }
186
187 void Window::Raise()
188 {
189   mWindowBase->Raise();
190   DALI_LOG_RELEASE_INFO( "Window (%p) Raise() \n", this );
191 }
192
193 void Window::Lower()
194 {
195   mWindowBase->Lower();
196   DALI_LOG_RELEASE_INFO( "Window (%p) Lower() \n", this );
197 }
198
199 void Window::Activate()
200 {
201   mWindowBase->Activate();
202   DALI_LOG_RELEASE_INFO( "Window (%p) Activate() \n", this );
203 }
204
205 uint32_t Window::GetLayerCount() const
206 {
207   return mScene.GetLayerCount();
208 }
209
210 Dali::Layer Window::GetLayer( uint32_t depth ) const
211 {
212   return mScene.GetLayer( depth );
213 }
214
215 Dali::RenderTaskList Window::GetRenderTaskList() const
216 {
217   return mScene.GetRenderTaskList();
218 }
219
220 void Window::AddAvailableOrientation( Dali::Window::WindowOrientation orientation )
221 {
222   bool found = false;
223
224   if( orientation <= Dali::Window::LANDSCAPE_INVERSE )
225   {
226     for( std::size_t i = 0; i < mAvailableOrientations.size(); i++ )
227     {
228       if( mAvailableOrientations[i] == orientation )
229       {
230         found = true;
231         break;
232       }
233     }
234
235     if( !found )
236     {
237       mAvailableOrientations.push_back( orientation );
238       SetAvailableOrientations( mAvailableOrientations );
239     }
240   }
241 }
242
243 void Window::RemoveAvailableOrientation( Dali::Window::WindowOrientation orientation )
244 {
245   for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
246        iter != mAvailableOrientations.end(); ++iter )
247   {
248     if( *iter == orientation )
249     {
250       mAvailableOrientations.erase( iter );
251       break;
252     }
253   }
254   SetAvailableOrientations( mAvailableOrientations );
255 }
256
257 void Window::SetAvailableOrientations( const std::vector< Dali::Window::WindowOrientation >& orientations )
258 {
259   if( orientations.size() > 4 )
260   {
261     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableOrientations: Invalid vector size! [%d]\n", orientations.size() );
262     return;
263   }
264
265   mAvailableOrientations = orientations;
266
267   mWindowBase->SetAvailableOrientations( mAvailableOrientations );
268 }
269
270 const std::vector< Dali::Window::WindowOrientation >& Window::GetAvailableOrientations()
271 {
272   return mAvailableOrientations;
273 }
274
275 void Window::SetPreferredOrientation( Dali::Window::WindowOrientation orientation )
276 {
277   mPreferredOrientation = orientation;
278
279   mWindowBase->SetPreferredOrientation( mPreferredOrientation );
280 }
281
282 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
283 {
284   return mPreferredOrientation;
285 }
286
287 Dali::Any Window::GetNativeHandle() const
288 {
289   return mWindowSurface->GetNativeWindow();
290 }
291
292 void Window::SetAcceptFocus( bool accept )
293 {
294   mIsFocusAcceptable = accept;
295
296   mWindowBase->SetAcceptFocus( accept );
297 }
298
299 bool Window::IsFocusAcceptable() const
300 {
301   return mIsFocusAcceptable;
302 }
303
304 void Window::Show()
305 {
306   mVisible = true;
307
308   mWindowBase->Show();
309
310   if( !mIconified )
311   {
312     WindowVisibilityObserver* observer( mAdaptor );
313     observer->OnWindowShown();
314   }
315
316   DALI_LOG_RELEASE_INFO( "Window (%p) Show(): iconified = %d\n", this, mIconified );
317 }
318
319 void Window::Hide()
320 {
321   mVisible = false;
322
323   mWindowBase->Hide();
324
325   if( !mIconified )
326   {
327     WindowVisibilityObserver* observer( mAdaptor );
328     observer->OnWindowHidden();
329   }
330
331   DALI_LOG_RELEASE_INFO( "Window (%p) Hide(): iconified = %d\n", this, mIconified );
332 }
333
334 bool Window::IsVisible() const
335 {
336   return mVisible && !mIconified;
337 }
338
339 unsigned int Window::GetSupportedAuxiliaryHintCount() const
340 {
341   return mWindowBase->GetSupportedAuxiliaryHintCount();
342 }
343
344 std::string Window::GetSupportedAuxiliaryHint( unsigned int index ) const
345 {
346   return mWindowBase->GetSupportedAuxiliaryHint( index );
347 }
348
349 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
350 {
351   return mWindowBase->AddAuxiliaryHint( hint, value );
352 }
353
354 bool Window::RemoveAuxiliaryHint( unsigned int id )
355 {
356   return mWindowBase->RemoveAuxiliaryHint( id );
357 }
358
359 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
360 {
361   return mWindowBase->SetAuxiliaryHintValue( id, value );
362 }
363
364 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
365 {
366   return mWindowBase->GetAuxiliaryHintValue( id );
367 }
368
369 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
370 {
371   return mWindowBase->GetAuxiliaryHintId( hint );
372 }
373
374 void Window::SetInputRegion( const Rect< int >& inputRegion )
375 {
376   mWindowBase->SetInputRegion( inputRegion );
377
378   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 );
379 }
380
381 void Window::SetType( Dali::Window::Type type )
382 {
383   if( type != mType )
384   {
385     mWindowBase->SetType( type );
386
387     mType = type;
388   }
389 }
390
391 Dali::Window::Type Window::GetType() const
392 {
393   return mType;
394 }
395
396 bool Window::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
397 {
398   if( mType != Dali::Window::NOTIFICATION )
399   {
400     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType );
401     return false;
402   }
403
404   return mWindowBase->SetNotificationLevel( level );
405 }
406
407 Dali::Window::NotificationLevel::Type Window::GetNotificationLevel() const
408 {
409   if( mType != Dali::Window::NOTIFICATION )
410   {
411     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", mType );
412     return Dali::Window::NotificationLevel::NONE;
413   }
414
415   return mWindowBase->GetNotificationLevel();
416 }
417
418 void Window::SetOpaqueState( bool opaque )
419 {
420   mOpaqueState = opaque;
421
422   mWindowBase->SetOpaqueState( opaque );
423
424   DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque );
425 }
426
427 bool Window::IsOpaqueState() const
428 {
429   return mOpaqueState;
430 }
431
432 bool Window::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
433 {
434   return mWindowBase->SetScreenOffMode( screenOffMode );
435 }
436
437 Dali::Window::ScreenOffMode::Type Window::GetScreenOffMode() const
438 {
439   return mWindowBase->GetScreenOffMode();
440 }
441
442 bool Window::SetBrightness( int brightness )
443 {
444   if( brightness < 0 || brightness > 100 )
445   {
446     DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness );
447     return false;
448   }
449
450   return mWindowBase->SetBrightness( brightness );
451 }
452
453 int Window::GetBrightness() const
454 {
455   return mWindowBase->GetBrightness();
456 }
457
458 void Window::SetSize( Dali::Window::WindowSize size )
459 {
460   if( !mResizeEnabled )
461   {
462     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
463     mResizeEnabled = true;
464   }
465
466   PositionSize oldRect = mSurface->GetPositionSize();
467
468   mWindowSurface->MoveResize( PositionSize( oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight() ) );
469
470   PositionSize newRect = mSurface->GetPositionSize();
471
472   // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
473   if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
474   {
475     Uint16Pair newSize( newRect.width, newRect.height );
476
477     bool forceUpdate = false;
478     if( mWindowBase->IsEglWindowRotationSupported() )
479     {
480       forceUpdate = true;
481     }
482
483     SurfaceResized( forceUpdate );
484
485     mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
486
487     Dali::Window handle( this );
488     mResizedSignal.Emit( newSize );
489     mResizeSignal.Emit( handle, newSize );
490
491     mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
492   }
493 }
494
495 Dali::Window::WindowSize Window::GetSize() const
496 {
497   PositionSize positionSize = mSurface->GetPositionSize();
498
499   return Dali::Window::WindowSize( positionSize.width, positionSize.height );
500 }
501
502 void Window::SetPosition( Dali::Window::WindowPosition position )
503 {
504   if( !mResizeEnabled )
505   {
506     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
507     mResizeEnabled = true;
508   }
509
510   PositionSize oldRect = mSurface->GetPositionSize();
511
512   mWindowSurface->MoveResize( PositionSize( position.GetX(), position.GetY(), oldRect.width, oldRect.height ) );
513 }
514
515 Dali::Window::WindowPosition Window::GetPosition() const
516 {
517   PositionSize positionSize = mSurface->GetPositionSize();
518
519   return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
520 }
521
522 void Window::SetPositionSize( PositionSize positionSize )
523 {
524   if( !mResizeEnabled )
525   {
526     AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
527     mResizeEnabled = true;
528   }
529
530   PositionSize oldRect = mSurface->GetPositionSize();
531
532   mWindowSurface->MoveResize( positionSize );
533
534   PositionSize newRect = mSurface->GetPositionSize();
535
536   // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
537   if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
538   {
539     Uint16Pair newSize( newRect.width, newRect.height );
540
541     bool forceUpdate = false;
542     if( mWindowBase->IsEglWindowRotationSupported() )
543     {
544       forceUpdate = true;
545     }
546
547     SurfaceResized( forceUpdate );
548
549     mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
550
551     Dali::Window handle( this );
552     mResizedSignal.Emit( newSize );
553     mResizeSignal.Emit( handle, newSize );
554     mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
555   }
556 }
557
558 Dali::Layer Window::GetRootLayer() const
559 {
560   return mScene.GetRootLayer();
561 }
562
563 void Window::SetTransparency( bool transparent )
564 {
565   mWindowSurface->SetTransparency( transparent );
566 }
567
568 bool Window::GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode )
569 {
570   return mWindowBase->GrabKey( key, grabMode );
571 }
572
573 bool Window::UngrabKey( Dali::KEY key )
574 {
575   return mWindowBase->UngrabKey( key );
576 }
577
578 bool Window::GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result )
579 {
580   return mWindowBase->GrabKeyList( key, grabMode, result );
581 }
582
583 bool Window::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result )
584 {
585   return mWindowBase->UngrabKeyList( key, result );
586 }
587
588 void Window::OnIconifyChanged( bool iconified )
589 {
590   if( iconified )
591   {
592     mIconified = true;
593
594     if( mVisible )
595     {
596       WindowVisibilityObserver* observer( mAdaptor );
597       observer->OnWindowHidden();
598     }
599
600     DALI_LOG_RELEASE_INFO( "Window (%p) Iconified: visible = %d\n", this, mVisible );
601   }
602   else
603   {
604     mIconified = false;
605
606     if( mVisible )
607     {
608       WindowVisibilityObserver* observer( mAdaptor );
609       observer->OnWindowShown();
610     }
611
612     DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified: visible = %d\n", this, mVisible );
613   }
614 }
615
616 void Window::OnFocusChanged( bool focusIn )
617 {
618   Dali::Window handle( this );
619   mFocusChangedSignal.Emit( focusIn );
620   mFocusChangeSignal.Emit( handle, focusIn );
621
622   if (auto b = Dali::Accessibility::Bridge::GetCurrentBridge())
623   {
624     if (focusIn)
625     {
626       b->ApplicationShown();
627     }
628     else
629     {
630       b->ApplicationHidden();
631     }
632   }
633 }
634
635 void Window::OnOutputTransformed()
636 {
637   bool forceUpdate = false;
638   if( mWindowBase->IsEglWindowRotationSupported() )
639   {
640     forceUpdate = true;
641   }
642   PositionSize positionSize = mSurface->GetPositionSize();
643   SurfaceResized( forceUpdate );
644   mAdaptor->SurfaceResizePrepare( mSurface.get(), Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
645   mAdaptor->SurfaceResizeComplete( mSurface.get(), Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
646 }
647
648 void Window::OnDeleteRequest()
649 {
650   mDeleteRequestSignal.Emit();
651 }
652
653 void Window::OnTouchPoint( Dali::Integration::Point& point, int timeStamp )
654 {
655   FeedTouchPoint( point, timeStamp );
656 }
657
658 void Window::OnWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
659 {
660   FeedWheelEvent( wheelEvent );
661 }
662
663 void Window::OnKeyEvent( Dali::Integration::KeyEvent& keyEvent )
664 {
665   FeedKeyEvent( keyEvent );
666 }
667
668 void Window::OnRotation( const RotationEvent& rotation )
669 {
670   mRotationAngle = rotation.angle;
671   mWindowWidth = rotation.width;
672   mWindowHeight = rotation.height;
673
674   // Notify that the orientation is changed
675   mOrientation->OnOrientationChange( rotation );
676
677   mWindowSurface->RequestRotation( mRotationAngle, mWindowWidth, mWindowHeight );
678
679   bool forceUpdate = false;
680   if( mWindowBase->IsEglWindowRotationSupported() )
681   {
682     forceUpdate = true;
683   }
684
685   SurfaceResized( forceUpdate );
686
687   mAdaptor->SurfaceResizePrepare( mSurface.get(), Adaptor::SurfaceSize( mWindowWidth, mWindowHeight ) );
688
689   // Emit signal
690   Dali::Window handle( this );
691   mResizedSignal.Emit( Dali::Window::WindowSize( mWindowWidth, mWindowHeight ) );
692   mResizeSignal.Emit( handle, Dali::Window::WindowSize( mWindowWidth, mWindowHeight ) );
693
694   mAdaptor->SurfaceResizeComplete( mSurface.get(), Adaptor::SurfaceSize( mWindowWidth, mWindowHeight ) );
695 }
696
697 void Window::OnPause()
698 {
699   if( mEventHandler )
700   {
701     mEventHandler->Pause();
702   }
703 }
704
705 void Window::OnResume()
706 {
707   if( mEventHandler )
708   {
709     mEventHandler->Resume();
710   }
711 }
712
713 void Window::RecalculateTouchPosition( Integration::Point& point )
714 {
715   Vector2 position = point.GetScreenPosition();
716   Vector2 convertedPosition;
717
718   switch( mRotationAngle )
719   {
720     case 90:
721     {
722       convertedPosition.x = static_cast<float>( mWindowWidth ) - position.y;
723       convertedPosition.y = position.x;
724       break;
725     }
726     case 180:
727     {
728       convertedPosition.x = static_cast<float>( mWindowWidth ) - position.x;
729       convertedPosition.y = static_cast<float>( mWindowHeight ) - position.y;
730       break;
731     }
732     case 270:
733     {
734       convertedPosition.x = position.y;
735       convertedPosition.y = static_cast<float>( mWindowHeight ) - position.x;
736       break;
737     }
738     default:
739     {
740       convertedPosition = position;
741       break;
742     }
743   }
744
745   point.SetScreenPosition( convertedPosition );
746 }
747
748 Dali::Window Window::Get( Dali::Actor actor )
749 {
750   Internal::Adaptor::Window* windowImpl = nullptr;
751
752   if ( Internal::Adaptor::Adaptor::IsAvailable() )
753   {
754     Dali::Internal::Adaptor::Adaptor& adaptor = Internal::Adaptor::Adaptor::GetImplementation( Internal::Adaptor::Adaptor::Get() );
755     windowImpl = static_cast<Internal::Adaptor::Window*>( adaptor.GetWindow( actor ) );
756   }
757
758   return Dali::Window( windowImpl );
759 }
760
761 void Window::SetParent( Dali::Window& parent )
762 {
763   if ( DALI_UNLIKELY( parent ) )
764   {
765     mParentWindow = parent;
766     Dali::Window grandParent = Dali::DevelWindow::GetParent( parent );
767     // check circular parent window setting
768     if ( DALI_UNLIKELY( grandParent ) && mWindowBase->IsMatchedWindow( grandParent.GetNativeHandle() ) )
769     {
770       Dali::DevelWindow::Unparent( parent );
771     }
772     mWindowBase->SetParent( parent.GetNativeHandle() );
773   }
774 }
775
776 void Window::Unparent()
777 {
778   Any parent;
779   mWindowBase->SetParent( parent );
780 }
781
782 Dali::Window Window::GetParent()
783 {
784   return mParentWindow;
785 }
786
787 } // Adaptor
788
789 } // Internal
790
791 } // Dali