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/render-task-list-integ.h>
24 #include <dali/public-api/actors/camera-actor.h>
25 #include <dali/public-api/render-tasks/render-task.h>
26 #include <dali/public-api/render-tasks/render-task-list.h>
27 #include <dali/devel-api/adaptor-framework/orientation.h>
30 #include <dali/internal/input/common/drag-and-drop-detector-impl.h>
31 #include <dali/internal/window-system/common/window-visibility-observer.h>
32 #include <dali/internal/window-system/common/orientation-impl.h>
33 #include <dali/internal/window-system/common/render-surface-factory.h>
34 #include <dali/internal/window-system/common/window-factory.h>
35 #include <dali/internal/window-system/common/window-base.h>
36 #include <dali/internal/window-system/common/window-render-surface.h>
48 #if defined(DEBUG_ENABLED)
49 Debug::Filter* gWindowLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_WINDOW" );
52 } // unnamed namespace
54 Window* Window::New( const PositionSize& positionSize, const std::string& name, const std::string& className, bool isTransparent )
56 Window* window = new Window();
57 window->mIsTransparent = isTransparent;
58 window->Initialize( positionSize, name, className );
65 mIndicatorVisible( Dali::Window::INVISIBLE ), // TODO: Enable this after indicator implementation based on tizen 5.
66 mIndicatorIsShown( false ),
67 mShowRotatedIndicatorOnClose( false ),
69 mIsTransparent( false ),
70 mIsFocusAcceptable( true ),
73 mOpaqueState( false ),
74 mResizeEnabled( false ),
76 mIndicatorOrientation( Dali::Window::PORTRAIT ),
77 mNextIndicatorOrientation( Dali::Window::PORTRAIT ),
78 mIndicatorOpacityMode( Dali::Window::OPAQUE ),
80 mType( Dali::Window::NORMAL ),
81 mPreferredOrientation( Dali::Window::PORTRAIT ),
82 mIndicatorVisibilityChangedSignal(),
83 mFocusChangedSignal(),
85 mDeleteRequestSignal()
98 mAdaptor->RemoveObserver( *this );
99 mAdaptor->SetDragAndDropDetector( NULL );
106 void Window::Initialize(const PositionSize& positionSize, const std::string& name, const std::string& className)
108 // Create a window render surface
110 auto renderSurfaceFactory = Dali::Internal::Adaptor::GetRenderSurfaceFactory();
111 auto windowRenderSurface = renderSurfaceFactory->CreateWindowRenderSurface( positionSize, surface, mIsTransparent );
112 mSurface = windowRenderSurface.release();
115 mWindowBase = mSurface->GetWindowBase();
118 mWindowBase->IconifyChangedSignal().Connect( this, &Window::OnIconifyChanged );
119 mWindowBase->FocusChangedSignal().Connect( this, &Window::OnFocusChanged );
120 mWindowBase->DeleteRequestSignal().Connect( this, &Window::OnDeleteRequest );
121 mWindowBase->IndicatorFlickedSignal().Connect( this, &Window::OnIndicatorFlicked );
123 mSurface->OutputTransformedSignal().Connect( this, &Window::OnOutputTransformed );
125 if( !positionSize.IsEmpty() )
127 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
128 mResizeEnabled = true;
131 SetClass( name, className );
135 mOrientation = Orientation::New( this );
138 void Window::SetAdaptor(Dali::Adaptor& adaptor)
140 DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
143 // Create one overlay for the main window only
144 Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
145 mAdaptor = &adaptorImpl;
146 mAdaptor->AddObserver( *this );
148 // Can only create the detector when we know the Core has been instantiated.
149 mDragAndDropDetector = DragAndDropDetector::New();
150 mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
154 mOrientation->SetAdaptor(adaptor);
157 if( mIndicator != NULL )
159 mIndicator->SetAdaptor(mAdaptor);
163 WindowRenderSurface* Window::GetSurface()
168 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
170 // TODO: Enable this after indicator implementation based on tizen 5.
171 // mIndicatorVisible = visibleMode;
173 mWindowBase->ShowIndicator( mIndicatorVisible, mIndicatorOpacityMode );
175 DoShowIndicator( mIndicatorOrientation );
178 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
180 mIndicatorOpacityMode = opacityMode;
182 if( mIndicator != NULL )
184 mIndicator->SetOpacityMode( opacityMode );
188 void Window::SetIndicatorVisibleMode( Dali::Window::IndicatorVisibleMode mode )
190 // TODO: Enable this after indicator implementation based on tizen 5.
191 // mIndicatorVisible = mode;
194 void Window::RotateIndicator( Dali::Window::WindowOrientation orientation )
196 DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
198 DoRotateIndicator( orientation );
201 void Window::SetClass( std::string name, std::string className )
203 mWindowBase->SetClass( name, className );
208 mWindowBase->Raise();
213 mWindowBase->Lower();
216 void Window::Activate()
218 mWindowBase->Activate();
221 void Window::AddAvailableOrientation( Dali::Window::WindowOrientation orientation )
225 if( orientation <= Dali::Window::LANDSCAPE_INVERSE )
227 for( std::size_t i = 0; i < mAvailableOrientations.size(); i++ )
229 if( mAvailableOrientations[i] == orientation )
238 mAvailableOrientations.push_back( orientation );
239 SetAvailableOrientations( mAvailableOrientations );
244 void Window::RemoveAvailableOrientation( Dali::Window::WindowOrientation orientation )
246 for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
247 iter != mAvailableOrientations.end(); ++iter )
249 if( *iter == orientation )
251 mAvailableOrientations.erase( iter );
255 SetAvailableOrientations( mAvailableOrientations );
258 void Window::SetAvailableOrientations( const std::vector< Dali::Window::WindowOrientation >& orientations )
260 if( orientations.size() > 4 )
262 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableOrientations: Invalid vector size! [%d]\n", orientations.size() );
266 mAvailableOrientations = orientations;
268 mWindowBase->SetAvailableOrientations( mAvailableOrientations );
271 const std::vector< Dali::Window::WindowOrientation >& Window::GetAvailableOrientations()
273 return mAvailableOrientations;
276 void Window::SetPreferredOrientation( Dali::Window::WindowOrientation orientation )
278 mPreferredOrientation = orientation;
280 mWindowBase->SetPreferredOrientation( mPreferredOrientation );
283 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
285 return mPreferredOrientation;
288 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
290 return mDragAndDropDetector;
293 Dali::Any Window::GetNativeHandle() const
295 return mSurface->GetNativeWindow();
298 void Window::SetAcceptFocus( bool accept )
300 mIsFocusAcceptable = accept;
302 mWindowBase->SetAcceptFocus( accept );
305 bool Window::IsFocusAcceptable() const
307 return mIsFocusAcceptable;
318 WindowVisibilityObserver* observer( mAdaptor );
319 observer->OnWindowShown();
320 DALI_LOG_RELEASE_INFO( "Window (%p) ::Show()\n", this );
332 WindowVisibilityObserver* observer( mAdaptor );
333 observer->OnWindowHidden();
334 DALI_LOG_RELEASE_INFO( "Window (%p) ::Hide() \n", this );
338 bool Window::IsVisible() const
343 unsigned int Window::GetSupportedAuxiliaryHintCount() const
345 return mWindowBase->GetSupportedAuxiliaryHintCount();
348 std::string Window::GetSupportedAuxiliaryHint( unsigned int index ) const
350 return mWindowBase->GetSupportedAuxiliaryHint( index );
353 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
355 return mWindowBase->AddAuxiliaryHint( hint, value );
358 bool Window::RemoveAuxiliaryHint( unsigned int id )
360 return mWindowBase->RemoveAuxiliaryHint( id );
363 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
365 return mWindowBase->SetAuxiliaryHintValue( id, value );
368 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
370 return mWindowBase->GetAuxiliaryHintValue( id );
373 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
375 return mWindowBase->GetAuxiliaryHintId( hint );
378 void Window::SetInputRegion( const Rect< int >& inputRegion )
380 mWindowBase->SetInputRegion( inputRegion );
382 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 );
385 void Window::SetType( Dali::Window::Type type )
389 mWindowBase->SetType( type );
395 Dali::Window::Type Window::GetType() const
400 bool Window::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
402 if( mType != Dali::Window::NOTIFICATION )
404 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType );
408 return mWindowBase->SetNotificationLevel( level );
411 Dali::Window::NotificationLevel::Type Window::GetNotificationLevel() const
413 if( mType != Dali::Window::NOTIFICATION )
415 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", mType );
416 return Dali::Window::NotificationLevel::NONE;
419 return mWindowBase->GetNotificationLevel();
422 void Window::SetOpaqueState( bool opaque )
424 mOpaqueState = opaque;
426 mWindowBase->SetOpaqueState( opaque );
428 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque );
431 bool Window::IsOpaqueState() const
436 bool Window::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
438 return mWindowBase->SetScreenOffMode( screenOffMode );
441 Dali::Window::ScreenOffMode::Type Window::GetScreenOffMode() const
443 return mWindowBase->GetScreenOffMode();
446 bool Window::SetBrightness( int brightness )
448 if( brightness < 0 || brightness > 100 )
450 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness );
454 return mWindowBase->SetBrightness( brightness );
457 int Window::GetBrightness() const
459 return mWindowBase->GetBrightness();
462 void Window::SetSize( Dali::Window::WindowSize size )
464 if( !mResizeEnabled )
466 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
467 mResizeEnabled = true;
470 PositionSize oldRect = mSurface->GetPositionSize();
472 mSurface->MoveResize( PositionSize( oldRect.x, oldRect.y, size.GetWidth(), size.GetHeight() ) );
474 PositionSize newRect = mSurface->GetPositionSize();
476 // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
477 if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
479 Uint16Pair newSize( newRect.width, newRect.height );
481 mAdaptor->SurfaceResizePrepare( newSize );
483 mResizedSignal.Emit( newSize );
485 mAdaptor->SurfaceResizeComplete( newSize );
489 Dali::Window::WindowSize Window::GetSize() const
491 PositionSize positionSize = mSurface->GetPositionSize();
493 return Dali::Window::WindowSize( positionSize.width, positionSize.height );
496 void Window::SetPosition( Dali::Window::WindowPosition position )
498 if( !mResizeEnabled )
500 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
501 mResizeEnabled = true;
504 PositionSize oldRect = mSurface->GetPositionSize();
506 mSurface->MoveResize( PositionSize( position.GetX(), position.GetY(), oldRect.width, oldRect.height ) );
509 Dali::Window::WindowPosition Window::GetPosition() const
511 PositionSize positionSize = mSurface->GetPositionSize();
513 return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
516 void Window::SetPositionSize( PositionSize positionSize )
518 if( !mResizeEnabled )
520 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
521 mResizeEnabled = true;
524 PositionSize oldRect = mSurface->GetPositionSize();
526 mSurface->MoveResize( positionSize );
528 PositionSize newRect = mSurface->GetPositionSize();
530 // When surface size is updated, inform adaptor of resizing and emit ResizeSignal
531 if( ( oldRect.width != newRect.width ) || ( oldRect.height != newRect.height ) )
533 Uint16Pair newSize( newRect.width, newRect.height );
535 mAdaptor->SurfaceResizePrepare( newSize );
537 mResizedSignal.Emit( newSize );
539 mAdaptor->SurfaceResizeComplete( newSize );
543 void Window::SetTransparency( bool transparent )
545 mSurface->SetTransparency( transparent );
548 bool Window::GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode )
550 return mWindowBase->GrabKey( key, grabMode );
553 bool Window::UngrabKey( Dali::KEY key )
555 return mWindowBase->UngrabKey( key );
558 bool Window::GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result )
560 return mWindowBase->GrabKeyList( key, grabMode, result );
563 bool Window::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result )
565 return mWindowBase->UngrabKeyList( key, result );
568 void Window::RotationDone( int orientation, int width, int height )
570 mSurface->RequestRotation( orientation, width, height );
572 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( width, height ) );
575 mResizedSignal.Emit( Dali::Window::WindowSize( width, height ) );
577 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( width, height ) );
580 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
582 if( mIndicator == NULL )
584 if( mIndicatorVisible != Dali::Window::INVISIBLE )
586 auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
587 mIndicator = windowFactory->CreateIndicator( mAdaptor, mIndicatorOrientation, this );
590 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
591 Dali::Actor actor = mIndicator->GetActor();
592 SetIndicatorActorRotation();
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()