2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/window-system/common/window-impl.h>
22 #include <dali/integration-api/core.h>
23 #include <dali/integration-api/system-overlay.h>
24 #include <dali/integration-api/render-task-list-integ.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/devel-api/adaptor-framework/orientation.h>
31 #include <dali/internal/input/common/drag-and-drop-detector-impl.h>
32 #include <dali/internal/window-system/common/window-visibility-observer.h>
33 #include <dali/internal/window-system/common/orientation-impl.h>
34 #include <dali/internal/window-system/common/render-surface-factory.h>
35 #include <dali/internal/window-system/common/window-factory.h>
36 #include <dali/internal/window-system/common/window-base.h>
37 #include <dali/internal/window-system/common/window-render-surface.h>
49 #if defined(DEBUG_ENABLED)
50 Debug::Filter* gWindowLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW" );
53 } // unnamed namespace
55 Window* Window::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
57 Window* window = new Window();
58 window->mIsTransparent = isTransparent;
59 window->Initialize( positionSize, name, className );
66 mIndicatorVisible( Dali::Window::INVISIBLE ), // TODO: Enable this after indicator implementation based on tizen 5.
67 mIndicatorIsShown( false ),
68 mShowRotatedIndicatorOnClose( false ),
70 mIsTransparent( false ),
71 mIsFocusAcceptable( true ),
74 mOpaqueState( false ),
75 mResizeEnabled( false ),
77 mIndicatorOrientation( Dali::Window::PORTRAIT ),
78 mNextIndicatorOrientation( Dali::Window::PORTRAIT ),
79 mIndicatorOpacityMode( Dali::Window::OPAQUE ),
82 mType( Dali::Window::NORMAL ),
83 mPreferredOrientation( Dali::Window::PORTRAIT ),
84 mIndicatorVisibilityChangedSignal(),
85 mFocusChangedSignal(),
87 mDeleteRequestSignal()
95 mOverlay->Remove( mIndicator->GetActor() );
96 Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
97 Dali::RenderTask indicatorTask = taskList.GetTask(0);
98 mOverlay->GetOverlayRenderTasks().RemoveTask(indicatorTask);
104 mAdaptor->RemoveObserver( *this );
105 mAdaptor->SetDragAndDropDetector( NULL );
112 void Window::Initialize(const PositionSize& positionSize, const std::string& name, const std::string& className)
114 // Create a window render surface
116 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
117 auto windowRenderSurface = renderSurfaceFactory->CreateWindowRenderSurface( positionSize, surface, mIsTransparent );
118 mSurface = windowRenderSurface.release();
121 mWindowBase = mSurface->GetWindowBase();
124 mWindowBase->IconifyChangedSignal().Connect( this, &Window::OnIconifyChanged );
125 mWindowBase->FocusChangedSignal().Connect( this, &Window::OnFocusChanged );
126 mWindowBase->DeleteRequestSignal().Connect( this, &Window::OnDeleteRequest );
127 mWindowBase->IndicatorFlickedSignal().Connect( this, &Window::OnIndicatorFlicked );
129 mSurface->OutputTransformedSignal().Connect( this, &Window::OnOutputTransformed );
131 if( !positionSize.IsEmpty() )
133 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
134 mResizeEnabled = true;
137 SetClass( name, className );
141 mOrientation = Orientation::New( this );
144 void Window::SetAdaptor(Dali::Adaptor& adaptor)
146 DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
149 // Create one overlay for the main window only
150 Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
151 Integration::Core& core = adaptorImpl.GetCore();
152 mOverlay = &core.GetSystemOverlay();
154 // Only create render task list for the overlay once
155 if (!mOverlay->GetOverlayRenderTasks())
157 Dali::RenderTaskList overlayRenderTaskList = Integration::RenderTaskList::New();
159 Dali::Actor overlayRootActor = mOverlay->GetDefaultRootActor();
160 Dali::CameraActor overlayCameraActor = mOverlay->GetDefaultCameraActor();
161 Integration::RenderTaskList::CreateTask( overlayRenderTaskList, overlayRootActor, overlayCameraActor );
163 mOverlay->SetOverlayRenderTasks( overlayRenderTaskList );
166 mAdaptor = &adaptorImpl;
167 mAdaptor->AddObserver( *this );
169 // Can only create the detector when we know the Core has been instantiated.
170 mDragAndDropDetector = DragAndDropDetector::New();
171 mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
175 mOrientation->SetAdaptor(adaptor);
178 if( mIndicator != NULL )
180 mIndicator->SetAdaptor(mAdaptor);
184 WindowRenderSurface* Window::GetSurface()
189 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
191 // TODO: Enable this after indicator implementation based on tizen 5.
192 // mIndicatorVisible = visibleMode;
194 mWindowBase->ShowIndicator( mIndicatorVisible, mIndicatorOpacityMode );
196 DoShowIndicator( mIndicatorOrientation );
199 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
201 mIndicatorOpacityMode = opacityMode;
203 if( mIndicator != NULL )
205 mIndicator->SetOpacityMode( opacityMode );
209 void Window::SetIndicatorVisibleMode( Dali::Window::IndicatorVisibleMode mode )
211 // TODO: Enable this after indicator implementation based on tizen 5.
212 // mIndicatorVisible = mode;
215 void Window::RotateIndicator( Dali::Window::WindowOrientation orientation )
217 DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
219 DoRotateIndicator( orientation );
222 void Window::SetClass( std::string name, std::string className )
224 mWindowBase->SetClass( name, className );
229 mWindowBase->Raise();
234 mWindowBase->Lower();
237 void Window::Activate()
239 mWindowBase->Activate();
242 void Window::AddAvailableOrientation( Dali::Window::WindowOrientation orientation )
246 if( orientation <= Dali::Window::LANDSCAPE_INVERSE )
248 for( std::size_t i = 0; i < mAvailableOrientations.size(); i++ )
250 if( mAvailableOrientations[i] == orientation )
259 mAvailableOrientations.push_back( orientation );
260 SetAvailableOrientations( mAvailableOrientations );
265 void Window::RemoveAvailableOrientation( Dali::Window::WindowOrientation orientation )
267 for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
268 iter != mAvailableOrientations.end(); ++iter )
270 if( *iter == orientation )
272 mAvailableOrientations.erase( iter );
276 SetAvailableOrientations( mAvailableOrientations );
279 void Window::SetAvailableOrientations( const std::vector< Dali::Window::WindowOrientation >& orientations )
281 if( orientations.size() > 4 )
283 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableOrientations: Invalid vector size! [%d]\n", orientations.size() );
287 mAvailableOrientations = orientations;
289 mWindowBase->SetAvailableOrientations( mAvailableOrientations );
292 const std::vector< Dali::Window::WindowOrientation >& Window::GetAvailableOrientations()
294 return mAvailableOrientations;
297 void Window::SetPreferredOrientation( Dali::Window::WindowOrientation orientation )
299 mPreferredOrientation = orientation;
301 mWindowBase->SetPreferredOrientation( mPreferredOrientation );
304 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
306 return mPreferredOrientation;
309 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
311 return mDragAndDropDetector;
314 Dali::Any Window::GetNativeHandle() const
316 return mSurface->GetNativeWindow();
319 void Window::SetAcceptFocus( bool accept )
321 mIsFocusAcceptable = accept;
323 mWindowBase->SetAcceptFocus( accept );
326 bool Window::IsFocusAcceptable() const
328 return mIsFocusAcceptable;
339 WindowVisibilityObserver* observer( mAdaptor );
340 observer->OnWindowShown();
343 DALI_LOG_RELEASE_INFO( "Window (%p) Show(): iconified = %d\n", this, mIconified );
354 WindowVisibilityObserver* observer( mAdaptor );
355 observer->OnWindowHidden();
358 DALI_LOG_RELEASE_INFO( "Window (%p) Hide(): iconified = %d\n", this, mIconified );
361 bool Window::IsVisible() const
366 unsigned int Window::GetSupportedAuxiliaryHintCount() const
368 return mWindowBase->GetSupportedAuxiliaryHintCount();
371 std::string Window::GetSupportedAuxiliaryHint( unsigned int index ) const
373 return mWindowBase->GetSupportedAuxiliaryHint( index );
376 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
378 return mWindowBase->AddAuxiliaryHint( hint, value );
381 bool Window::RemoveAuxiliaryHint( unsigned int id )
383 return mWindowBase->RemoveAuxiliaryHint( id );
386 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
388 return mWindowBase->SetAuxiliaryHintValue( id, value );
391 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
393 return mWindowBase->GetAuxiliaryHintValue( id );
396 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
398 return mWindowBase->GetAuxiliaryHintId( hint );
401 void Window::SetInputRegion( const Rect< int >& inputRegion )
403 mWindowBase->SetInputRegion( inputRegion );
405 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 );
408 void Window::SetType( Dali::Window::Type type )
412 mWindowBase->SetType( type );
418 Dali::Window::Type Window::GetType() const
423 bool Window::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
425 if( mType != Dali::Window::NOTIFICATION )
427 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType );
431 return mWindowBase->SetNotificationLevel( level );
434 Dali::Window::NotificationLevel::Type Window::GetNotificationLevel() const
436 if( mType != Dali::Window::NOTIFICATION )
438 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", mType );
439 return Dali::Window::NotificationLevel::NONE;
442 return mWindowBase->GetNotificationLevel();
445 void Window::SetOpaqueState( bool opaque )
447 mOpaqueState = opaque;
449 mWindowBase->SetOpaqueState( opaque );
451 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque );
454 bool Window::IsOpaqueState() const
459 bool Window::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
461 return mWindowBase->SetScreenOffMode( screenOffMode );
464 Dali::Window::ScreenOffMode::Type Window::GetScreenOffMode() const
466 return mWindowBase->GetScreenOffMode();
469 bool Window::SetBrightness( int brightness )
471 if( brightness < 0 || brightness > 100 )
473 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness );
477 return mWindowBase->SetBrightness( brightness );
480 int Window::GetBrightness() const
482 return mWindowBase->GetBrightness();
485 void Window::SetSize( Dali::Window::WindowSize size )
487 if( !mResizeEnabled )
489 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
490 mResizeEnabled = true;
493 PositionSize oldRect = mSurface->GetPositionSize();
495 mSurface->MoveResize( PositionSize( oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight() ) );
497 PositionSize newRect = mSurface->GetPositionSize();
499 // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
500 if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
502 Uint16Pair newSize( newRect.width, newRect.height );
504 mAdaptor->SurfaceResizePrepare( newSize );
506 mResizedSignal.Emit( newSize );
508 mAdaptor->SurfaceResizeComplete( newSize );
512 Dali::Window::WindowSize Window::GetSize() const
514 PositionSize positionSize = mSurface->GetPositionSize();
516 return Dali::Window::WindowSize( positionSize.width, positionSize.height );
519 void Window::SetPosition( Dali::Window::WindowPosition position )
521 if( !mResizeEnabled )
523 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
524 mResizeEnabled = true;
527 PositionSize oldRect = mSurface->GetPositionSize();
529 mSurface->MoveResize( PositionSize( position.GetX(), position.GetY(), oldRect.width, oldRect.height ) );
532 Dali::Window::WindowPosition Window::GetPosition() const
534 PositionSize positionSize = mSurface->GetPositionSize();
536 return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
539 void Window::SetPositionSize( PositionSize positionSize )
541 if( !mResizeEnabled )
543 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
544 mResizeEnabled = true;
547 PositionSize oldRect = mSurface->GetPositionSize();
549 mSurface->MoveResize( positionSize );
551 PositionSize newRect = mSurface->GetPositionSize();
553 // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
554 if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
556 Uint16Pair newSize( newRect.width, newRect.height );
558 mAdaptor->SurfaceResizePrepare( newSize );
560 mResizedSignal.Emit( newSize );
562 mAdaptor->SurfaceResizeComplete( newSize );
566 void Window::SetTransparency( bool transparent )
568 mSurface->SetTransparency( transparent );
571 bool Window::GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode )
573 return mWindowBase->GrabKey( key, grabMode );
576 bool Window::UngrabKey( Dali::KEY key )
578 return mWindowBase->UngrabKey( key );
581 bool Window::GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result )
583 return mWindowBase->GrabKeyList( key, grabMode, result );
586 bool Window::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result )
588 return mWindowBase->UngrabKeyList( key, result );
591 void Window::RotationDone( int orientation, int width, int height )
593 mSurface->RequestRotation( orientation, width, height );
595 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( width, height ) );
598 mResizedSignal.Emit( Dali::Window::WindowSize( width, height ) );
600 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( width, height ) );
603 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
605 if( mIndicator == NULL )
607 if( mIndicatorVisible != Dali::Window::INVISIBLE )
609 auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
610 mIndicator = windowFactory->CreateIndicator( mAdaptor, mIndicatorOrientation, this );
613 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
614 Dali::Actor actor = mIndicator->GetActor();
615 SetIndicatorActorRotation();
616 mOverlay->Add(actor);
619 // else don't create a hidden indicator
621 else // Already have indicator
623 if( mIndicatorVisible == Dali::Window::VISIBLE )
625 // If we are resuming, and rotation has changed,
626 if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
628 // then close current indicator and open new one
629 mShowRotatedIndicatorOnClose = true;
630 mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
631 // Don't show actor - will contain indicator for old orientation.
636 // set indicator visible mode
637 if( mIndicator != NULL )
639 mIndicator->SetVisible( mIndicatorVisible );
642 bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
643 SetIndicatorProperties( show, lastOrientation );
644 mIndicatorIsShown = show;
647 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
649 if( mIndicatorIsShown )
651 mShowRotatedIndicatorOnClose = true;
652 mNextIndicatorOrientation = orientation;
655 mIndicator->Close(); // May synchronously call IndicatorClosed() callback
660 // Save orientation for when the indicator is next shown
661 mShowRotatedIndicatorOnClose = false;
662 mNextIndicatorOrientation = orientation;
666 void Window::SetIndicatorActorRotation()
668 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
671 Dali::Actor actor = mIndicator->GetActor();
672 switch( mIndicatorOrientation )
674 case Dali::Window::PORTRAIT:
675 actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
676 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
677 actor.SetOrientation( Degree(0), Vector3::ZAXIS );
679 case Dali::Window::PORTRAIT_INVERSE:
680 actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
681 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
682 actor.SetOrientation( Degree(180), Vector3::ZAXIS );
684 case Dali::Window::LANDSCAPE:
685 actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
686 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
687 actor.SetOrientation( Degree(270), Vector3::ZAXIS );
689 case Dali::Window::LANDSCAPE_INVERSE:
690 actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
691 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
692 actor.SetOrientation( Degree(90), Vector3::ZAXIS );
698 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
700 mWindowBase->SetIndicatorProperties( isShow, lastOrientation );
703 void Window::OnIconifyChanged( bool iconified )
711 WindowVisibilityObserver* observer( mAdaptor );
712 observer->OnWindowHidden();
715 DALI_LOG_RELEASE_INFO( "Window (%p) Iconified: visible = %d\n", this, mVisible );
723 WindowVisibilityObserver* observer( mAdaptor );
724 observer->OnWindowShown();
727 DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified: visible = %d\n", this, mVisible );
731 void Window::OnFocusChanged( bool focusIn )
733 mFocusChangedSignal.Emit( focusIn );
736 void Window::OnOutputTransformed()
738 PositionSize positionSize = mSurface->GetPositionSize();
739 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
740 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
743 void Window::OnDeleteRequest()
745 mDeleteRequestSignal.Emit();
748 void Window::OnIndicatorFlicked()
752 mIndicator->Flicked();
756 void Window::IndicatorTypeChanged( IndicatorInterface::Type type )
758 mWindowBase->IndicatorTypeChanged( type );
761 void Window::IndicatorClosed( IndicatorInterface* indicator )
763 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
765 if( mShowRotatedIndicatorOnClose )
767 Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
770 mIndicator->Open( mNextIndicatorOrientation );
772 mIndicatorOrientation = mNextIndicatorOrientation;
773 SetIndicatorActorRotation();
774 DoShowIndicator( currentOrientation );
778 void Window::IndicatorVisibilityChanged( bool isVisible )
780 mIndicatorVisibilityChangedSignal.Emit( isVisible );
783 void Window::OnStart()
785 DoShowIndicator( mIndicatorOrientation );
788 void Window::OnPause()
792 void Window::OnResume()
794 // resume indicator status
795 if( mIndicator != NULL )
797 // Restore own indicator opacity
798 // Send opacity mode to indicator service when app resumed
799 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
803 void Window::OnStop()
810 mIndicator.release();
813 void Window::OnDestroy()