2 * Copyright (c) 2019 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/render-task-list-integ.h>
24 #include <dali/public-api/actors/actor.h>
25 #include <dali/public-api/actors/layer.h>
26 #include <dali/public-api/actors/camera-actor.h>
27 #include <dali/public-api/render-tasks/render-task.h>
28 #include <dali/public-api/render-tasks/render-task-list.h>
29 #include <dali/public-api/rendering/frame-buffer.h>
30 #include <dali/devel-api/adaptor-framework/orientation.h>
33 #include <dali/internal/input/common/drag-and-drop-detector-impl.h>
34 #include <dali/internal/window-system/common/window-visibility-observer.h>
35 #include <dali/internal/window-system/common/orientation-impl.h>
36 #include <dali/internal/window-system/common/render-surface-factory.h>
37 #include <dali/internal/window-system/common/window-factory.h>
38 #include <dali/internal/window-system/common/window-base.h>
39 #include <dali/internal/window-system/common/window-render-surface.h>
48 uint32_t Window::mWindowCounter = 0;
53 #if defined(DEBUG_ENABLED)
54 Debug::Filter* gWindowLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW" );
57 } // unnamed namespace
59 Window* Window::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
61 Window* window = new Window();
62 window->mIsTransparent = isTransparent;
63 window->Initialize( positionSize, name, className );
68 : mId( mWindowCounter++ ),
71 mIndicatorVisible( Dali::Window::INVISIBLE ), // TODO: Enable this after indicator implementation based on tizen 5.
72 mIndicatorIsShown( false ),
73 mShowRotatedIndicatorOnClose( false ),
75 mIsFocusAcceptable( true ),
78 mOpaqueState( false ),
79 mResizeEnabled( false ),
81 mIndicatorOrientation( Dali::Window::PORTRAIT ),
82 mNextIndicatorOrientation( Dali::Window::PORTRAIT ),
83 mIndicatorOpacityMode( Dali::Window::OPAQUE ),
85 mType( Dali::Window::NORMAL ),
86 mPreferredOrientation( Dali::Window::PORTRAIT ),
87 mIndicatorVisibilityChangedSignal(),
88 mFocusChangedSignal(),
90 mDeleteRequestSignal()
103 mAdaptor->RemoveObserver( *this );
104 mAdaptor->SetDragAndDropDetector( NULL );
105 mAdaptor->RemoveWindow( this );
109 mSurface.reset( nullptr );
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 mSurface = renderSurfaceFactory->CreateWindowRenderSurface( positionSize, surface, mIsTransparent );
120 mWindowBase = mSurface->GetWindowBase();
123 mWindowBase->IconifyChangedSignal().Connect( this, &Window::OnIconifyChanged );
124 mWindowBase->FocusChangedSignal().Connect( this, &Window::OnFocusChanged );
125 mWindowBase->DeleteRequestSignal().Connect( this, &Window::OnDeleteRequest );
126 mWindowBase->IndicatorFlickedSignal().Connect( this, &Window::OnIndicatorFlicked );
128 mSurface->OutputTransformedSignal().Connect( this, &Window::OnOutputTransformed );
130 if( !positionSize.IsEmpty() )
132 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
133 mResizeEnabled = true;
136 SetClass( name, className );
140 mOrientation = Orientation::New( this );
143 void Window::SetAdaptor(Dali::Adaptor& adaptor)
145 DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
148 PositionSize positionSize = mSurface->GetPositionSize();
149 mScene = Dali::Integration::Scene::New( Vector2(positionSize.width, positionSize.height) );
150 mScene.SetSurface( *mSurface.get() );
152 unsigned int dpiHorizontal, dpiVertical;
153 dpiHorizontal = dpiVertical = 0;
155 mSurface->GetDpi( dpiHorizontal, dpiVertical );
156 mScene.SetDpi( Vector2( static_cast<float>( dpiHorizontal ), static_cast<float>( dpiVertical ) ) );
158 // Create one overlay for the main window only
159 Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
160 mAdaptor = &adaptorImpl;
161 mAdaptor->AddObserver( *this );
163 // Can only create the detector when we know the Core has been instantiated.
164 mDragAndDropDetector = DragAndDropDetector::New();
165 mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
169 mOrientation->SetAdaptor(adaptor);
172 if( mIndicator != NULL )
174 mIndicator->SetAdaptor(mAdaptor);
177 mSurface->SetAdaptor( *mAdaptor );
180 WindowRenderSurface* Window::GetSurface()
182 return mSurface.get();
185 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
187 // TODO: Enable this after indicator implementation based on tizen 5.
188 // mIndicatorVisible = visibleMode;
190 mWindowBase->ShowIndicator( mIndicatorVisible, mIndicatorOpacityMode );
192 DoShowIndicator( mIndicatorOrientation );
195 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
197 mIndicatorOpacityMode = opacityMode;
199 if( mIndicator != NULL )
201 mIndicator->SetOpacityMode( opacityMode );
205 void Window::SetIndicatorVisibleMode( Dali::Window::IndicatorVisibleMode mode )
207 // TODO: Enable this after indicator implementation based on tizen 5.
208 // mIndicatorVisible = mode;
211 void Window::RotateIndicator( Dali::Window::WindowOrientation orientation )
213 DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
215 DoRotateIndicator( orientation );
218 void Window::SetClass( std::string name, std::string className )
220 mWindowBase->SetClass( name, className );
225 mWindowBase->Raise();
230 mWindowBase->Lower();
233 void Window::Activate()
235 mWindowBase->Activate();
238 void Window::Add( Dali::Actor actor )
243 void Window::Remove( Dali::Actor actor )
245 mScene.Remove( actor );
248 Dali::Layer Window::GetRootLayer() const
250 return mScene.GetRootLayer();
253 uint32_t Window::GetLayerCount() const
255 return mScene.GetLayerCount();
258 Dali::Layer Window::GetLayer( uint32_t depth ) const
260 return mScene.GetLayer( depth );
263 void Window::SetBackgroundColor( Vector4 color )
267 mSurface->SetBackgroundColor( color );
271 Vector4 Window::GetBackgroundColor() const
273 return mSurface ? mSurface->GetBackgroundColor() : Vector4();
276 void Window::AddAvailableOrientation( Dali::Window::WindowOrientation orientation )
280 if( orientation <= Dali::Window::LANDSCAPE_INVERSE )
282 for( std::size_t i = 0; i < mAvailableOrientations.size(); i++ )
284 if( mAvailableOrientations[i] == orientation )
293 mAvailableOrientations.push_back( orientation );
294 SetAvailableOrientations( mAvailableOrientations );
299 void Window::RemoveAvailableOrientation( Dali::Window::WindowOrientation orientation )
301 for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
302 iter != mAvailableOrientations.end(); ++iter )
304 if( *iter == orientation )
306 mAvailableOrientations.erase( iter );
310 SetAvailableOrientations( mAvailableOrientations );
313 void Window::SetAvailableOrientations( const std::vector< Dali::Window::WindowOrientation >& orientations )
315 if( orientations.size() > 4 )
317 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableOrientations: Invalid vector size! [%d]\n", orientations.size() );
321 mAvailableOrientations = orientations;
323 mWindowBase->SetAvailableOrientations( mAvailableOrientations );
326 const std::vector< Dali::Window::WindowOrientation >& Window::GetAvailableOrientations()
328 return mAvailableOrientations;
331 void Window::SetPreferredOrientation( Dali::Window::WindowOrientation orientation )
333 mPreferredOrientation = orientation;
335 mWindowBase->SetPreferredOrientation( mPreferredOrientation );
338 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
340 return mPreferredOrientation;
343 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
345 return mDragAndDropDetector;
348 Dali::Any Window::GetNativeHandle() const
350 return mSurface->GetNativeWindow();
353 void Window::SetAcceptFocus( bool accept )
355 mIsFocusAcceptable = accept;
357 mWindowBase->SetAcceptFocus( accept );
360 bool Window::IsFocusAcceptable() const
362 return mIsFocusAcceptable;
373 WindowVisibilityObserver* observer( mAdaptor );
374 observer->OnWindowShown();
375 DALI_LOG_RELEASE_INFO( "Window (%p) ::Show()\n", this );
387 WindowVisibilityObserver* observer( mAdaptor );
388 observer->OnWindowHidden();
389 DALI_LOG_RELEASE_INFO( "Window (%p) ::Hide() \n", this );
393 bool Window::IsVisible() const
398 unsigned int Window::GetSupportedAuxiliaryHintCount() const
400 return mWindowBase->GetSupportedAuxiliaryHintCount();
403 std::string Window::GetSupportedAuxiliaryHint( unsigned int index ) const
405 return mWindowBase->GetSupportedAuxiliaryHint( index );
408 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
410 return mWindowBase->AddAuxiliaryHint( hint, value );
413 bool Window::RemoveAuxiliaryHint( unsigned int id )
415 return mWindowBase->RemoveAuxiliaryHint( id );
418 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
420 return mWindowBase->SetAuxiliaryHintValue( id, value );
423 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
425 return mWindowBase->GetAuxiliaryHintValue( id );
428 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
430 return mWindowBase->GetAuxiliaryHintId( hint );
433 void Window::SetInputRegion( const Rect< int >& inputRegion )
435 mWindowBase->SetInputRegion( inputRegion );
437 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 );
440 void Window::SetType( Dali::Window::Type type )
444 mWindowBase->SetType( type );
450 Dali::Window::Type Window::GetType() const
455 bool Window::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
457 if( mType != Dali::Window::NOTIFICATION )
459 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType );
463 return mWindowBase->SetNotificationLevel( level );
466 Dali::Window::NotificationLevel::Type Window::GetNotificationLevel() const
468 if( mType != Dali::Window::NOTIFICATION )
470 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", mType );
471 return Dali::Window::NotificationLevel::NONE;
474 return mWindowBase->GetNotificationLevel();
477 void Window::SetOpaqueState( bool opaque )
479 mOpaqueState = opaque;
481 mWindowBase->SetOpaqueState( opaque );
483 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque );
486 bool Window::IsOpaqueState() const
491 bool Window::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
493 return mWindowBase->SetScreenOffMode( screenOffMode );
496 Dali::Window::ScreenOffMode::Type Window::GetScreenOffMode() const
498 return mWindowBase->GetScreenOffMode();
501 bool Window::SetBrightness( int brightness )
503 if( brightness < 0 || brightness > 100 )
505 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness );
509 return mWindowBase->SetBrightness( brightness );
512 int Window::GetBrightness() const
514 return mWindowBase->GetBrightness();
517 void Window::SetSize( Dali::Window::WindowSize size )
519 if( !mResizeEnabled )
521 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
522 mResizeEnabled = true;
525 PositionSize oldRect = mSurface->GetPositionSize();
527 mSurface->MoveResize( PositionSize( oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight() ) );
529 PositionSize newRect = mSurface->GetPositionSize();
531 // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
532 if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
534 Uint16Pair newSize( newRect.width, newRect.height );
536 mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
538 mResizedSignal.Emit( newSize );
540 mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
544 Dali::Window::WindowSize Window::GetSize() const
546 PositionSize positionSize = mSurface->GetPositionSize();
548 return Dali::Window::WindowSize( positionSize.width, positionSize.height );
551 void Window::SetPosition( Dali::Window::WindowPosition position )
553 if( !mResizeEnabled )
555 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
556 mResizeEnabled = true;
559 PositionSize oldRect = mSurface->GetPositionSize();
561 mSurface->MoveResize( PositionSize( position.GetX(), position.GetY(), oldRect.width, oldRect.height ) );
564 Dali::Window::WindowPosition Window::GetPosition() const
566 PositionSize positionSize = mSurface->GetPositionSize();
568 return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
571 void Window::SetPositionSize( PositionSize positionSize )
573 if( !mResizeEnabled )
575 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
576 mResizeEnabled = true;
579 PositionSize oldRect = mSurface->GetPositionSize();
581 mSurface->MoveResize( positionSize );
583 PositionSize newRect = mSurface->GetPositionSize();
585 // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
586 if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
588 Uint16Pair newSize( newRect.width, newRect.height );
590 mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
592 mResizedSignal.Emit( newSize );
594 mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
598 void Window::SetTransparency( bool transparent )
600 mSurface->SetTransparency( transparent );
603 bool Window::GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode )
605 return mWindowBase->GrabKey( key, grabMode );
608 bool Window::UngrabKey( Dali::KEY key )
610 return mWindowBase->UngrabKey( key );
613 bool Window::GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result )
615 return mWindowBase->GrabKeyList( key, grabMode, result );
618 bool Window::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result )
620 return mWindowBase->UngrabKeyList( key, result );
623 void Window::RotationDone( int orientation, int width, int height )
625 mSurface->RequestRotation( orientation, width, height );
627 mAdaptor->SurfaceResizePrepare( mSurface.get(), Adaptor::SurfaceSize( width, height ) );
630 mResizedSignal.Emit( Dali::Window::WindowSize( width, height ) );
632 mAdaptor->SurfaceResizeComplete( mSurface.get(), Adaptor::SurfaceSize( width, height ) );
635 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
637 if( mIndicator == NULL )
639 if( mIndicatorVisible != Dali::Window::INVISIBLE )
641 auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
642 mIndicator = windowFactory->CreateIndicator( mAdaptor, mIndicatorOrientation, this );
645 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
646 Dali::Actor actor = mIndicator->GetActor();
647 SetIndicatorActorRotation();
650 // else don't create a hidden indicator
652 else // Already have indicator
654 if( mIndicatorVisible == Dali::Window::VISIBLE )
656 // If we are resuming, and rotation has changed,
657 if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
659 // then close current indicator and open new one
660 mShowRotatedIndicatorOnClose = true;
661 mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
662 // Don't show actor - will contain indicator for old orientation.
667 // set indicator visible mode
668 if( mIndicator != NULL )
670 mIndicator->SetVisible( mIndicatorVisible );
673 bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
674 SetIndicatorProperties( show, lastOrientation );
675 mIndicatorIsShown = show;
678 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
680 if( mIndicatorIsShown )
682 mShowRotatedIndicatorOnClose = true;
683 mNextIndicatorOrientation = orientation;
686 mIndicator->Close(); // May synchronously call IndicatorClosed() callback
691 // Save orientation for when the indicator is next shown
692 mShowRotatedIndicatorOnClose = false;
693 mNextIndicatorOrientation = orientation;
697 void Window::SetIndicatorActorRotation()
699 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
702 Dali::Actor actor = mIndicator->GetActor();
703 switch( mIndicatorOrientation )
705 case Dali::Window::PORTRAIT:
706 actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
707 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
708 actor.SetOrientation( Degree(0), Vector3::ZAXIS );
710 case Dali::Window::PORTRAIT_INVERSE:
711 actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
712 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
713 actor.SetOrientation( Degree(180), Vector3::ZAXIS );
715 case Dali::Window::LANDSCAPE:
716 actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
717 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
718 actor.SetOrientation( Degree(270), Vector3::ZAXIS );
720 case Dali::Window::LANDSCAPE_INVERSE:
721 actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
722 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
723 actor.SetOrientation( Degree(90), Vector3::ZAXIS );
729 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
731 mWindowBase->SetIndicatorProperties( isShow, lastOrientation );
734 void Window::OnIconifyChanged( bool iconified )
742 WindowVisibilityObserver* observer( mAdaptor );
743 observer->OnWindowHidden();
744 DALI_LOG_RELEASE_INFO( "Window (%p) Iconified\n", this );
753 WindowVisibilityObserver* observer( mAdaptor );
754 observer->OnWindowShown();
755 DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified\n", this );
760 void Window::OnFocusChanged( bool focusIn )
762 mFocusChangedSignal.Emit( focusIn );
765 void Window::OnOutputTransformed()
767 PositionSize positionSize = mSurface->GetPositionSize();
768 mAdaptor->SurfaceResizePrepare( mSurface.get(), Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
769 mAdaptor->SurfaceResizeComplete( mSurface.get(), Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
772 void Window::OnDeleteRequest()
774 mDeleteRequestSignal.Emit();
777 void Window::OnIndicatorFlicked()
781 mIndicator->Flicked();
785 void Window::IndicatorTypeChanged( IndicatorInterface::Type type )
787 mWindowBase->IndicatorTypeChanged( type );
790 void Window::IndicatorClosed( IndicatorInterface* indicator )
792 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
794 if( mShowRotatedIndicatorOnClose )
796 Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
799 mIndicator->Open( mNextIndicatorOrientation );
801 mIndicatorOrientation = mNextIndicatorOrientation;
802 SetIndicatorActorRotation();
803 DoShowIndicator( currentOrientation );
807 void Window::IndicatorVisibilityChanged( bool isVisible )
809 mIndicatorVisibilityChangedSignal.Emit( isVisible );
812 void Window::OnStart()
814 DoShowIndicator( mIndicatorOrientation );
817 void Window::OnPause()
821 void Window::OnResume()
823 // resume indicator status
824 if( mIndicator != NULL )
826 // Restore own indicator opacity
827 // Send opacity mode to indicator service when app resumed
828 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
832 void Window::OnStop()
839 mIndicator.release();
842 void Window::OnDestroy()
847 uint32_t Window::GetId() const