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/public-api/render-tasks/render-task.h>
25 #include <dali/public-api/render-tasks/render-task-list.h>
26 #include <dali/devel-api/adaptor-framework/orientation.h>
29 #include <dali/internal/input/common/drag-and-drop-detector-impl.h>
30 #include <dali/internal/window-system/common/window-visibility-observer.h>
31 #include <dali/internal/window-system/common/orientation-impl.h>
32 #include <dali/internal/window-system/common/render-surface-factory.h>
33 #include <dali/internal/window-system/common/window-factory.h>
34 #include <dali/internal/window-system/common/window-base.h>
35 #include <dali/internal/window-system/common/window-render-surface.h>
47 #if defined(DEBUG_ENABLED)
48 Debug::Filter* gWindowLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW" );
51 } // unnamed namespace
53 Window* Window::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
55 Window* window = new Window();
56 window->mIsTransparent = isTransparent;
57 window->Initialize( positionSize, name, className );
64 mIndicatorVisible( Dali::Window::INVISIBLE ), // TODO: Enable this after indicator implementation based on tizen 5.
65 mIndicatorIsShown( false ),
66 mShowRotatedIndicatorOnClose( false ),
68 mIsTransparent( false ),
69 mIsFocusAcceptable( true ),
72 mOpaqueState( false ),
73 mResizeEnabled( false ),
75 mIndicatorOrientation( Dali::Window::PORTRAIT ),
76 mNextIndicatorOrientation( Dali::Window::PORTRAIT ),
77 mIndicatorOpacityMode( Dali::Window::OPAQUE ),
80 mType( Dali::Window::NORMAL ),
81 mPreferredOrientation( Dali::Window::PORTRAIT ),
82 mIndicatorVisibilityChangedSignal(),
83 mFocusChangedSignal(),
85 mDeleteRequestSignal()
93 mOverlay->Remove( mIndicator->GetActor() );
94 Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
95 Dali::RenderTask indicatorTask = taskList.GetTask(0);
96 mOverlay->GetOverlayRenderTasks().RemoveTask(indicatorTask);
102 mAdaptor->RemoveObserver( *this );
103 mAdaptor->SetDragAndDropDetector( NULL );
110 void Window::Initialize(const PositionSize& positionSize, const std::string& name, const std::string& className)
112 // Create a window render surface
114 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
115 auto windowRenderSurface = renderSurfaceFactory->CreateWindowRenderSurface( positionSize, surface, mIsTransparent );
116 mSurface = windowRenderSurface.release();
119 mWindowBase = mSurface->GetWindowBase();
122 mWindowBase->IconifyChangedSignal().Connect( this, &Window::OnIconifyChanged );
123 mWindowBase->FocusChangedSignal().Connect( this, &Window::OnFocusChanged );
124 mWindowBase->DeleteRequestSignal().Connect( this, &Window::OnDeleteRequest );
125 mWindowBase->IndicatorFlickedSignal().Connect( this, &Window::OnIndicatorFlicked );
127 mSurface->OutputTransformedSignal().Connect( this, &Window::OnOutputTransformed );
129 if( !positionSize.IsEmpty() )
131 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
132 mResizeEnabled = true;
135 SetClass( name, className );
139 mOrientation = Orientation::New( this );
142 void Window::SetAdaptor(Dali::Adaptor& adaptor)
144 DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
147 // Only create one overlay per window
148 Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
149 Integration::Core& core = adaptorImpl.GetCore();
150 mOverlay = &core.GetSystemOverlay();
152 Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
153 taskList.CreateTask();
155 mAdaptor = &adaptorImpl;
156 mAdaptor->AddObserver( *this );
158 // Can only create the detector when we know the Core has been instantiated.
159 mDragAndDropDetector = DragAndDropDetector::New();
160 mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
164 mOrientation->SetAdaptor(adaptor);
167 if( mIndicator != NULL )
169 mIndicator->SetAdaptor(mAdaptor);
173 WindowRenderSurface* Window::GetSurface()
178 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
180 // TODO: Enable this after indicator implementation based on tizen 5.
181 // mIndicatorVisible = visibleMode;
183 mWindowBase->ShowIndicator( mIndicatorVisible, mIndicatorOpacityMode );
185 DoShowIndicator( mIndicatorOrientation );
188 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
190 mIndicatorOpacityMode = opacityMode;
192 if( mIndicator != NULL )
194 mIndicator->SetOpacityMode( opacityMode );
198 void Window::SetIndicatorVisibleMode( Dali::Window::IndicatorVisibleMode mode )
200 // TODO: Enable this after indicator implementation based on tizen 5.
201 // mIndicatorVisible = mode;
204 void Window::RotateIndicator( Dali::Window::WindowOrientation orientation )
206 DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
208 DoRotateIndicator( orientation );
211 void Window::SetClass( std::string name, std::string className )
213 mWindowBase->SetClass( name, className );
218 mWindowBase->Raise();
223 mWindowBase->Lower();
226 void Window::Activate()
228 mWindowBase->Activate();
231 void Window::AddAvailableOrientation( Dali::Window::WindowOrientation orientation )
235 if( orientation <= Dali::Window::LANDSCAPE_INVERSE )
237 for( std::size_t i = 0; i < mAvailableOrientations.size(); i++ )
239 if( mAvailableOrientations[i] == orientation )
248 mAvailableOrientations.push_back( orientation );
249 SetAvailableOrientations( mAvailableOrientations );
254 void Window::RemoveAvailableOrientation( Dali::Window::WindowOrientation orientation )
256 for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
257 iter != mAvailableOrientations.end(); ++iter )
259 if( *iter == orientation )
261 mAvailableOrientations.erase( iter );
265 SetAvailableOrientations( mAvailableOrientations );
268 void Window::SetAvailableOrientations( const std::vector< Dali::Window::WindowOrientation >& orientations )
270 if( orientations.size() > 4 )
272 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableOrientations: Invalid vector size! [%d]\n", orientations.size() );
276 mAvailableOrientations = orientations;
278 mWindowBase->SetAvailableOrientations( mAvailableOrientations );
281 const std::vector< Dali::Window::WindowOrientation >& Window::GetAvailableOrientations()
283 return mAvailableOrientations;
286 void Window::SetPreferredOrientation( Dali::Window::WindowOrientation orientation )
288 mPreferredOrientation = orientation;
290 mWindowBase->SetPreferredOrientation( mPreferredOrientation );
293 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
295 return mPreferredOrientation;
298 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
300 return mDragAndDropDetector;
303 Dali::Any Window::GetNativeHandle() const
305 return mSurface->GetNativeWindow();
308 void Window::SetAcceptFocus( bool accept )
310 mIsFocusAcceptable = accept;
312 mWindowBase->SetAcceptFocus( accept );
315 bool Window::IsFocusAcceptable() const
317 return mIsFocusAcceptable;
328 WindowVisibilityObserver* observer( mAdaptor );
329 observer->OnWindowShown();
330 DALI_LOG_RELEASE_INFO( "Window (%p) ::Show()\n", this );
342 WindowVisibilityObserver* observer( mAdaptor );
343 observer->OnWindowHidden();
344 DALI_LOG_RELEASE_INFO( "Window (%p) ::Hide() \n", this );
348 bool Window::IsVisible() const
353 unsigned int Window::GetSupportedAuxiliaryHintCount() const
355 return mWindowBase->GetSupportedAuxiliaryHintCount();
358 std::string Window::GetSupportedAuxiliaryHint( unsigned int index ) const
360 return mWindowBase->GetSupportedAuxiliaryHint( index );
363 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
365 return mWindowBase->AddAuxiliaryHint( hint, value );
368 bool Window::RemoveAuxiliaryHint( unsigned int id )
370 return mWindowBase->RemoveAuxiliaryHint( id );
373 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
375 return mWindowBase->SetAuxiliaryHintValue( id, value );
378 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
380 return mWindowBase->GetAuxiliaryHintValue( id );
383 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
385 return mWindowBase->GetAuxiliaryHintId( hint );
388 void Window::SetInputRegion( const Rect< int >& inputRegion )
390 mWindowBase->SetInputRegion( inputRegion );
392 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 );
395 void Window::SetType( Dali::Window::Type type )
399 mWindowBase->SetType( type );
405 Dali::Window::Type Window::GetType() const
410 bool Window::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
412 if( mType != Dali::Window::NOTIFICATION )
414 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType );
418 return mWindowBase->SetNotificationLevel( level );
421 Dali::Window::NotificationLevel::Type Window::GetNotificationLevel() const
423 if( mType != Dali::Window::NOTIFICATION )
425 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", mType );
426 return Dali::Window::NotificationLevel::NONE;
429 return mWindowBase->GetNotificationLevel();
432 void Window::SetOpaqueState( bool opaque )
434 mOpaqueState = opaque;
436 mWindowBase->SetOpaqueState( opaque );
438 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque );
441 bool Window::IsOpaqueState() const
446 bool Window::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
448 return mWindowBase->SetScreenOffMode( screenOffMode );
451 Dali::Window::ScreenOffMode::Type Window::GetScreenOffMode() const
453 return mWindowBase->GetScreenOffMode();
456 bool Window::SetBrightness( int brightness )
458 if( brightness < 0 || brightness > 100 )
460 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness );
464 return mWindowBase->SetBrightness( brightness );
467 int Window::GetBrightness() const
469 return mWindowBase->GetBrightness();
472 void Window::SetSize( Dali::Window::WindowSize size )
474 if( !mResizeEnabled )
476 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
477 mResizeEnabled = true;
480 PositionSize positionSize = mSurface->GetPositionSize();
482 if( positionSize.width != size.GetWidth() || positionSize.height != size.GetHeight() )
484 positionSize.width = size.GetWidth();
485 positionSize.height = size.GetHeight();
487 mSurface->MoveResize( positionSize );
489 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
492 mResizedSignal.Emit( Dali::Window::WindowSize( positionSize.width, positionSize.height ) );
494 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
498 Dali::Window::WindowSize Window::GetSize() const
500 PositionSize positionSize = mSurface->GetPositionSize();
502 return Dali::Window::WindowSize( positionSize.width, positionSize.height );
505 void Window::SetPosition( Dali::Window::WindowPosition position )
507 if( !mResizeEnabled )
509 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
510 mResizeEnabled = true;
513 PositionSize positionSize = mSurface->GetPositionSize();
515 if( positionSize.x != position.GetX() || positionSize.y != position.GetY() )
517 positionSize.x = position.GetX();
518 positionSize.y = position.GetY();
520 mSurface->MoveResize( positionSize );
524 Dali::Window::WindowPosition Window::GetPosition() const
526 PositionSize positionSize = mSurface->GetPositionSize();
528 return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
531 void Window::SetTransparency( bool transparent )
533 mSurface->SetTransparency( transparent );
536 bool Window::GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode )
538 return mWindowBase->GrabKey( key, grabMode );
541 bool Window::UngrabKey( Dali::KEY key )
543 return mWindowBase->UngrabKey( key );
546 bool Window::GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result )
548 return mWindowBase->GrabKeyList( key, grabMode, result );
551 bool Window::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result )
553 return mWindowBase->UngrabKeyList( key, result );
556 void Window::RotationDone( int orientation, int width, int height )
558 mSurface->RequestRotation( orientation, width, height );
560 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( width, height ) );
563 mResizedSignal.Emit( Dali::Window::WindowSize( width, height ) );
565 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( width, height ) );
568 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
570 if( mIndicator == NULL )
572 if( mIndicatorVisible != Dali::Window::INVISIBLE )
574 auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
575 mIndicator = windowFactory->CreateIndicator( mAdaptor, mIndicatorOrientation, this );
578 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
579 Dali::Actor actor = mIndicator->GetActor();
580 SetIndicatorActorRotation();
581 mOverlay->Add(actor);
584 // else don't create a hidden indicator
586 else // Already have indicator
588 if( mIndicatorVisible == Dali::Window::VISIBLE )
590 // If we are resuming, and rotation has changed,
591 if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
593 // then close current indicator and open new one
594 mShowRotatedIndicatorOnClose = true;
595 mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
596 // Don't show actor - will contain indicator for old orientation.
601 // set indicator visible mode
602 if( mIndicator != NULL )
604 mIndicator->SetVisible( mIndicatorVisible );
607 bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
608 SetIndicatorProperties( show, lastOrientation );
609 mIndicatorIsShown = show;
612 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
614 if( mIndicatorIsShown )
616 mShowRotatedIndicatorOnClose = true;
617 mNextIndicatorOrientation = orientation;
620 mIndicator->Close(); // May synchronously call IndicatorClosed() callback
625 // Save orientation for when the indicator is next shown
626 mShowRotatedIndicatorOnClose = false;
627 mNextIndicatorOrientation = orientation;
631 void Window::SetIndicatorActorRotation()
633 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
636 Dali::Actor actor = mIndicator->GetActor();
637 switch( mIndicatorOrientation )
639 case Dali::Window::PORTRAIT:
640 actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
641 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
642 actor.SetOrientation( Degree(0), Vector3::ZAXIS );
644 case Dali::Window::PORTRAIT_INVERSE:
645 actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
646 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
647 actor.SetOrientation( Degree(180), Vector3::ZAXIS );
649 case Dali::Window::LANDSCAPE:
650 actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
651 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
652 actor.SetOrientation( Degree(270), Vector3::ZAXIS );
654 case Dali::Window::LANDSCAPE_INVERSE:
655 actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
656 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
657 actor.SetOrientation( Degree(90), Vector3::ZAXIS );
663 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
665 mWindowBase->SetIndicatorProperties( isShow, lastOrientation );
668 void Window::OnIconifyChanged( bool iconified )
676 WindowVisibilityObserver* observer( mAdaptor );
677 observer->OnWindowHidden();
678 DALI_LOG_RELEASE_INFO( "Window (%p) Iconified\n", this );
687 WindowVisibilityObserver* observer( mAdaptor );
688 observer->OnWindowShown();
689 DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified\n", this );
694 void Window::OnFocusChanged( bool focusIn )
696 mFocusChangedSignal.Emit( focusIn );
699 void Window::OnOutputTransformed()
701 PositionSize positionSize = mSurface->GetPositionSize();
702 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
703 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
706 void Window::OnDeleteRequest()
708 mDeleteRequestSignal.Emit();
711 void Window::OnIndicatorFlicked()
715 mIndicator->Flicked();
719 void Window::IndicatorTypeChanged( IndicatorInterface::Type type )
721 mWindowBase->IndicatorTypeChanged( type );
724 void Window::IndicatorClosed( IndicatorInterface* indicator )
726 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
728 if( mShowRotatedIndicatorOnClose )
730 Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
733 mIndicator->Open( mNextIndicatorOrientation );
735 mIndicatorOrientation = mNextIndicatorOrientation;
736 SetIndicatorActorRotation();
737 DoShowIndicator( currentOrientation );
741 void Window::IndicatorVisibilityChanged( bool isVisible )
743 mIndicatorVisibilityChangedSignal.Emit( isVisible );
746 void Window::OnStart()
748 DoShowIndicator( mIndicatorOrientation );
751 void Window::OnPause()
755 void Window::OnResume()
757 // resume indicator status
758 if( mIndicator != NULL )
760 // Restore own indicator opacity
761 // Send opacity mode to indicator service when app resumed
762 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
766 void Window::OnStop()
773 mIndicator.release();
776 void Window::OnDestroy()