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();
341 DALI_LOG_RELEASE_INFO( "Window (%p) ::Show()\n", this );
353 WindowVisibilityObserver* observer( mAdaptor );
354 observer->OnWindowHidden();
355 DALI_LOG_RELEASE_INFO( "Window (%p) ::Hide() \n", this );
359 bool Window::IsVisible() const
364 unsigned int Window::GetSupportedAuxiliaryHintCount() const
366 return mWindowBase->GetSupportedAuxiliaryHintCount();
369 std::string Window::GetSupportedAuxiliaryHint( unsigned int index ) const
371 return mWindowBase->GetSupportedAuxiliaryHint( index );
374 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
376 return mWindowBase->AddAuxiliaryHint( hint, value );
379 bool Window::RemoveAuxiliaryHint( unsigned int id )
381 return mWindowBase->RemoveAuxiliaryHint( id );
384 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
386 return mWindowBase->SetAuxiliaryHintValue( id, value );
389 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
391 return mWindowBase->GetAuxiliaryHintValue( id );
394 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
396 return mWindowBase->GetAuxiliaryHintId( hint );
399 void Window::SetInputRegion( const Rect< int >& inputRegion )
401 mWindowBase->SetInputRegion( inputRegion );
403 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 );
406 void Window::SetType( Dali::Window::Type type )
410 mWindowBase->SetType( type );
416 Dali::Window::Type Window::GetType() const
421 bool Window::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
423 if( mType != Dali::Window::NOTIFICATION )
425 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType );
429 return mWindowBase->SetNotificationLevel( level );
432 Dali::Window::NotificationLevel::Type Window::GetNotificationLevel() const
434 if( mType != Dali::Window::NOTIFICATION )
436 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", mType );
437 return Dali::Window::NotificationLevel::NONE;
440 return mWindowBase->GetNotificationLevel();
443 void Window::SetOpaqueState( bool opaque )
445 mOpaqueState = opaque;
447 mWindowBase->SetOpaqueState( opaque );
449 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque );
452 bool Window::IsOpaqueState() const
457 bool Window::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
459 return mWindowBase->SetScreenOffMode( screenOffMode );
462 Dali::Window::ScreenOffMode::Type Window::GetScreenOffMode() const
464 return mWindowBase->GetScreenOffMode();
467 bool Window::SetBrightness( int brightness )
469 if( brightness < 0 || brightness > 100 )
471 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness );
475 return mWindowBase->SetBrightness( brightness );
478 int Window::GetBrightness() const
480 return mWindowBase->GetBrightness();
483 void Window::SetSize( Dali::Window::WindowSize size )
485 if( !mResizeEnabled )
487 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
488 mResizeEnabled = true;
491 PositionSize oldRect = mSurface->GetPositionSize();
493 mSurface->MoveResize( PositionSize( oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight() ) );
495 PositionSize newRect = mSurface->GetPositionSize();
497 // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
498 if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
500 Uint16Pair newSize( newRect.width, newRect.height );
502 mAdaptor->SurfaceResizePrepare( newSize );
504 mResizedSignal.Emit( newSize );
506 mAdaptor->SurfaceResizeComplete( newSize );
510 Dali::Window::WindowSize Window::GetSize() const
512 PositionSize positionSize = mSurface->GetPositionSize();
514 return Dali::Window::WindowSize( positionSize.width, positionSize.height );
517 void Window::SetPosition( Dali::Window::WindowPosition position )
519 if( !mResizeEnabled )
521 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
522 mResizeEnabled = true;
525 PositionSize oldRect = mSurface->GetPositionSize();
527 mSurface->MoveResize( PositionSize( position.GetX(), position.GetY(), oldRect.width, oldRect.height ) );
530 Dali::Window::WindowPosition Window::GetPosition() const
532 PositionSize positionSize = mSurface->GetPositionSize();
534 return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
537 void Window::SetPositionSize( PositionSize positionSize )
539 if( !mResizeEnabled )
541 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
542 mResizeEnabled = true;
545 PositionSize oldRect = mSurface->GetPositionSize();
547 mSurface->MoveResize( positionSize );
549 PositionSize newRect = mSurface->GetPositionSize();
551 // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
552 if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
554 Uint16Pair newSize( newRect.width, newRect.height );
556 mAdaptor->SurfaceResizePrepare( newSize );
558 mResizedSignal.Emit( newSize );
560 mAdaptor->SurfaceResizeComplete( newSize );
564 void Window::SetTransparency( bool transparent )
566 mSurface->SetTransparency( transparent );
569 bool Window::GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode )
571 return mWindowBase->GrabKey( key, grabMode );
574 bool Window::UngrabKey( Dali::KEY key )
576 return mWindowBase->UngrabKey( key );
579 bool Window::GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result )
581 return mWindowBase->GrabKeyList( key, grabMode, result );
584 bool Window::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result )
586 return mWindowBase->UngrabKeyList( key, result );
589 void Window::RotationDone( int orientation, int width, int height )
591 mSurface->RequestRotation( orientation, width, height );
593 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( width, height ) );
596 mResizedSignal.Emit( Dali::Window::WindowSize( width, height ) );
598 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( width, height ) );
601 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
603 if( mIndicator == NULL )
605 if( mIndicatorVisible != Dali::Window::INVISIBLE )
607 auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
608 mIndicator = windowFactory->CreateIndicator( mAdaptor, mIndicatorOrientation, this );
611 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
612 Dali::Actor actor = mIndicator->GetActor();
613 SetIndicatorActorRotation();
614 mOverlay->Add(actor);
617 // else don't create a hidden indicator
619 else // Already have indicator
621 if( mIndicatorVisible == Dali::Window::VISIBLE )
623 // If we are resuming, and rotation has changed,
624 if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
626 // then close current indicator and open new one
627 mShowRotatedIndicatorOnClose = true;
628 mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
629 // Don't show actor - will contain indicator for old orientation.
634 // set indicator visible mode
635 if( mIndicator != NULL )
637 mIndicator->SetVisible( mIndicatorVisible );
640 bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
641 SetIndicatorProperties( show, lastOrientation );
642 mIndicatorIsShown = show;
645 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
647 if( mIndicatorIsShown )
649 mShowRotatedIndicatorOnClose = true;
650 mNextIndicatorOrientation = orientation;
653 mIndicator->Close(); // May synchronously call IndicatorClosed() callback
658 // Save orientation for when the indicator is next shown
659 mShowRotatedIndicatorOnClose = false;
660 mNextIndicatorOrientation = orientation;
664 void Window::SetIndicatorActorRotation()
666 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
669 Dali::Actor actor = mIndicator->GetActor();
670 switch( mIndicatorOrientation )
672 case Dali::Window::PORTRAIT:
673 actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
674 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
675 actor.SetOrientation( Degree(0), Vector3::ZAXIS );
677 case Dali::Window::PORTRAIT_INVERSE:
678 actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
679 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
680 actor.SetOrientation( Degree(180), Vector3::ZAXIS );
682 case Dali::Window::LANDSCAPE:
683 actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
684 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
685 actor.SetOrientation( Degree(270), Vector3::ZAXIS );
687 case Dali::Window::LANDSCAPE_INVERSE:
688 actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
689 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
690 actor.SetOrientation( Degree(90), Vector3::ZAXIS );
696 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
698 mWindowBase->SetIndicatorProperties( isShow, lastOrientation );
701 void Window::OnIconifyChanged( bool iconified )
709 WindowVisibilityObserver* observer( mAdaptor );
710 observer->OnWindowHidden();
711 DALI_LOG_RELEASE_INFO( "Window (%p) Iconified\n", this );
720 WindowVisibilityObserver* observer( mAdaptor );
721 observer->OnWindowShown();
722 DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified\n", this );
727 void Window::OnFocusChanged( bool focusIn )
729 mFocusChangedSignal.Emit( focusIn );
732 void Window::OnOutputTransformed()
734 PositionSize positionSize = mSurface->GetPositionSize();
735 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
736 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
739 void Window::OnDeleteRequest()
741 mDeleteRequestSignal.Emit();
744 void Window::OnIndicatorFlicked()
748 mIndicator->Flicked();
752 void Window::IndicatorTypeChanged( IndicatorInterface::Type type )
754 mWindowBase->IndicatorTypeChanged( type );
757 void Window::IndicatorClosed( IndicatorInterface* indicator )
759 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
761 if( mShowRotatedIndicatorOnClose )
763 Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
766 mIndicator->Open( mNextIndicatorOrientation );
768 mIndicatorOrientation = mNextIndicatorOrientation;
769 SetIndicatorActorRotation();
770 DoShowIndicator( currentOrientation );
774 void Window::IndicatorVisibilityChanged( bool isVisible )
776 mIndicatorVisibilityChangedSignal.Emit( isVisible );
779 void Window::OnStart()
781 DoShowIndicator( mIndicatorOrientation );
784 void Window::OnPause()
788 void Window::OnResume()
790 // resume indicator status
791 if( mIndicator != NULL )
793 // Restore own indicator opacity
794 // Send opacity mode to indicator service when app resumed
795 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
799 void Window::OnStop()
806 mIndicator.release();
809 void Window::OnDestroy()