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 positionSize = mSurface->GetPositionSize();
493 if( positionSize.width != size.GetWidth() || positionSize.height != size.GetHeight() )
495 positionSize.width = size.GetWidth();
496 positionSize.height = size.GetHeight();
498 mSurface->MoveResize( positionSize );
500 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
503 mResizedSignal.Emit( Dali::Window::WindowSize( positionSize.width, positionSize.height ) );
505 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
509 Dali::Window::WindowSize Window::GetSize() const
511 PositionSize positionSize = mSurface->GetPositionSize();
513 return Dali::Window::WindowSize( positionSize.width, positionSize.height );
516 void Window::SetPosition( Dali::Window::WindowPosition position )
518 if( !mResizeEnabled )
520 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
521 mResizeEnabled = true;
524 PositionSize positionSize = mSurface->GetPositionSize();
526 if( positionSize.x != position.GetX() || positionSize.y != position.GetY() )
528 positionSize.x = position.GetX();
529 positionSize.y = position.GetY();
531 mSurface->MoveResize( positionSize );
535 Dali::Window::WindowPosition Window::GetPosition() const
537 PositionSize positionSize = mSurface->GetPositionSize();
539 return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
542 void Window::SetTransparency( bool transparent )
544 mSurface->SetTransparency( transparent );
547 bool Window::GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode )
549 return mWindowBase->GrabKey( key, grabMode );
552 bool Window::UngrabKey( Dali::KEY key )
554 return mWindowBase->UngrabKey( key );
557 bool Window::GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result )
559 return mWindowBase->GrabKeyList( key, grabMode, result );
562 bool Window::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result )
564 return mWindowBase->UngrabKeyList( key, result );
567 void Window::RotationDone( int orientation, int width, int height )
569 mSurface->RequestRotation( orientation, width, height );
571 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( width, height ) );
574 mResizedSignal.Emit( Dali::Window::WindowSize( width, height ) );
576 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( width, height ) );
579 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
581 if( mIndicator == NULL )
583 if( mIndicatorVisible != Dali::Window::INVISIBLE )
585 auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
586 mIndicator = windowFactory->CreateIndicator( mAdaptor, mIndicatorOrientation, this );
589 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
590 Dali::Actor actor = mIndicator->GetActor();
591 SetIndicatorActorRotation();
592 mOverlay->Add(actor);
595 // else don't create a hidden indicator
597 else // Already have indicator
599 if( mIndicatorVisible == Dali::Window::VISIBLE )
601 // If we are resuming, and rotation has changed,
602 if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
604 // then close current indicator and open new one
605 mShowRotatedIndicatorOnClose = true;
606 mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
607 // Don't show actor - will contain indicator for old orientation.
612 // set indicator visible mode
613 if( mIndicator != NULL )
615 mIndicator->SetVisible( mIndicatorVisible );
618 bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
619 SetIndicatorProperties( show, lastOrientation );
620 mIndicatorIsShown = show;
623 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
625 if( mIndicatorIsShown )
627 mShowRotatedIndicatorOnClose = true;
628 mNextIndicatorOrientation = orientation;
631 mIndicator->Close(); // May synchronously call IndicatorClosed() callback
636 // Save orientation for when the indicator is next shown
637 mShowRotatedIndicatorOnClose = false;
638 mNextIndicatorOrientation = orientation;
642 void Window::SetIndicatorActorRotation()
644 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
647 Dali::Actor actor = mIndicator->GetActor();
648 switch( mIndicatorOrientation )
650 case Dali::Window::PORTRAIT:
651 actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
652 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
653 actor.SetOrientation( Degree(0), Vector3::ZAXIS );
655 case Dali::Window::PORTRAIT_INVERSE:
656 actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
657 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
658 actor.SetOrientation( Degree(180), Vector3::ZAXIS );
660 case Dali::Window::LANDSCAPE:
661 actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
662 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
663 actor.SetOrientation( Degree(270), Vector3::ZAXIS );
665 case Dali::Window::LANDSCAPE_INVERSE:
666 actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
667 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
668 actor.SetOrientation( Degree(90), Vector3::ZAXIS );
674 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
676 mWindowBase->SetIndicatorProperties( isShow, lastOrientation );
679 void Window::OnIconifyChanged( bool iconified )
687 WindowVisibilityObserver* observer( mAdaptor );
688 observer->OnWindowHidden();
689 DALI_LOG_RELEASE_INFO( "Window (%p) Iconified\n", this );
698 WindowVisibilityObserver* observer( mAdaptor );
699 observer->OnWindowShown();
700 DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified\n", this );
705 void Window::OnFocusChanged( bool focusIn )
707 mFocusChangedSignal.Emit( focusIn );
710 void Window::OnOutputTransformed()
712 PositionSize positionSize = mSurface->GetPositionSize();
713 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
714 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
717 void Window::OnDeleteRequest()
719 mDeleteRequestSignal.Emit();
722 void Window::OnIndicatorFlicked()
726 mIndicator->Flicked();
730 void Window::IndicatorTypeChanged( IndicatorInterface::Type type )
732 mWindowBase->IndicatorTypeChanged( type );
735 void Window::IndicatorClosed( IndicatorInterface* indicator )
737 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
739 if( mShowRotatedIndicatorOnClose )
741 Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
744 mIndicator->Open( mNextIndicatorOrientation );
746 mIndicatorOrientation = mNextIndicatorOrientation;
747 SetIndicatorActorRotation();
748 DoShowIndicator( currentOrientation );
752 void Window::IndicatorVisibilityChanged( bool isVisible )
754 mIndicatorVisibilityChangedSignal.Emit( isVisible );
757 void Window::OnStart()
759 DoShowIndicator( mIndicatorOrientation );
762 void Window::OnPause()
766 void Window::OnResume()
768 // resume indicator status
769 if( mIndicator != NULL )
771 // Restore own indicator opacity
772 // Send opacity mode to indicator service when app resumed
773 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
777 void Window::OnStop()
784 mIndicator.release();
787 void Window::OnDestroy()