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->OutputTransformedSignal().Connect( this, &Window::OnOutputTransformed );
125 mWindowBase->DeleteRequestSignal().Connect( this, &Window::OnDeleteRequest );
126 mWindowBase->IndicatorFlickedSignal().Connect( this, &Window::OnIndicatorFlicked );
128 if( !positionSize.IsEmpty() )
130 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
131 mResizeEnabled = true;
134 SetClass( name, className );
138 mOrientation = Orientation::New( this );
141 void Window::SetAdaptor(Dali::Adaptor& adaptor)
143 DALI_ASSERT_ALWAYS( !mStarted && "Adaptor already started" );
146 // Only create one overlay per window
147 Internal::Adaptor::Adaptor& adaptorImpl = Internal::Adaptor::Adaptor::GetImplementation(adaptor);
148 Integration::Core& core = adaptorImpl.GetCore();
149 mOverlay = &core.GetSystemOverlay();
151 Dali::RenderTaskList taskList = mOverlay->GetOverlayRenderTasks();
152 taskList.CreateTask();
154 mAdaptor = &adaptorImpl;
155 mAdaptor->AddObserver( *this );
157 // Can only create the detector when we know the Core has been instantiated.
158 mDragAndDropDetector = DragAndDropDetector::New();
159 mAdaptor->SetDragAndDropDetector( &GetImplementation( mDragAndDropDetector ) );
163 mOrientation->SetAdaptor(adaptor);
166 if( mIndicator != NULL )
168 mIndicator->SetAdaptor(mAdaptor);
172 WindowRenderSurface* Window::GetSurface()
177 void Window::ShowIndicator( Dali::Window::IndicatorVisibleMode visibleMode )
179 // TODO: Enable this after indicator implementation based on tizen 5.
180 // mIndicatorVisible = visibleMode;
182 mWindowBase->ShowIndicator( mIndicatorVisible, mIndicatorOpacityMode );
184 DoShowIndicator( mIndicatorOrientation );
187 void Window::SetIndicatorBgOpacity( Dali::Window::IndicatorBgOpacity opacityMode )
189 mIndicatorOpacityMode = opacityMode;
191 if( mIndicator != NULL )
193 mIndicator->SetOpacityMode( opacityMode );
197 void Window::SetIndicatorVisibleMode( Dali::Window::IndicatorVisibleMode mode )
199 // TODO: Enable this after indicator implementation based on tizen 5.
200 // mIndicatorVisible = mode;
203 void Window::RotateIndicator( Dali::Window::WindowOrientation orientation )
205 DALI_LOG_TRACE_METHOD_FMT( gWindowLogFilter, "Orientation: %d\n", orientation );
207 DoRotateIndicator( orientation );
210 void Window::SetClass( std::string name, std::string className )
212 mWindowBase->SetClass( name, className );
217 mWindowBase->Raise();
222 mWindowBase->Lower();
225 void Window::Activate()
227 mWindowBase->Activate();
230 void Window::AddAvailableOrientation( Dali::Window::WindowOrientation orientation )
234 if( orientation <= Dali::Window::LANDSCAPE_INVERSE )
236 for( std::size_t i = 0; i < mAvailableOrientations.size(); i++ )
238 if( mAvailableOrientations[i] == orientation )
247 mAvailableOrientations.push_back( orientation );
248 SetAvailableOrientations( mAvailableOrientations );
253 void Window::RemoveAvailableOrientation( Dali::Window::WindowOrientation orientation )
255 for( std::vector<Dali::Window::WindowOrientation>::iterator iter = mAvailableOrientations.begin();
256 iter != mAvailableOrientations.end(); ++iter )
258 if( *iter == orientation )
260 mAvailableOrientations.erase( iter );
264 SetAvailableOrientations( mAvailableOrientations );
267 void Window::SetAvailableOrientations( const std::vector< Dali::Window::WindowOrientation >& orientations )
269 if( orientations.size() > 4 )
271 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetAvailableOrientations: Invalid vector size! [%d]\n", orientations.size() );
275 mAvailableOrientations = orientations;
277 mWindowBase->SetAvailableOrientations( mAvailableOrientations );
280 const std::vector< Dali::Window::WindowOrientation >& Window::GetAvailableOrientations()
282 return mAvailableOrientations;
285 void Window::SetPreferredOrientation( Dali::Window::WindowOrientation orientation )
287 mPreferredOrientation = orientation;
289 mWindowBase->SetPreferredOrientation( mPreferredOrientation );
292 Dali::Window::WindowOrientation Window::GetPreferredOrientation()
294 return mPreferredOrientation;
297 Dali::DragAndDropDetector Window::GetDragAndDropDetector() const
299 return mDragAndDropDetector;
302 Dali::Any Window::GetNativeHandle() const
304 return mSurface->GetNativeWindow();
307 void Window::SetAcceptFocus( bool accept )
309 mIsFocusAcceptable = accept;
311 mWindowBase->SetAcceptFocus( accept );
314 bool Window::IsFocusAcceptable() const
316 return mIsFocusAcceptable;
327 WindowVisibilityObserver* observer( mAdaptor );
328 observer->OnWindowShown();
329 DALI_LOG_RELEASE_INFO( "Window (%p) ::Show()\n", this );
341 WindowVisibilityObserver* observer( mAdaptor );
342 observer->OnWindowHidden();
343 DALI_LOG_RELEASE_INFO( "Window (%p) ::Hide() \n", this );
347 bool Window::IsVisible() const
352 unsigned int Window::GetSupportedAuxiliaryHintCount() const
354 return mWindowBase->GetSupportedAuxiliaryHintCount();
357 std::string Window::GetSupportedAuxiliaryHint( unsigned int index ) const
359 return mWindowBase->GetSupportedAuxiliaryHint( index );
362 unsigned int Window::AddAuxiliaryHint( const std::string& hint, const std::string& value )
364 return mWindowBase->AddAuxiliaryHint( hint, value );
367 bool Window::RemoveAuxiliaryHint( unsigned int id )
369 return mWindowBase->RemoveAuxiliaryHint( id );
372 bool Window::SetAuxiliaryHintValue( unsigned int id, const std::string& value )
374 return mWindowBase->SetAuxiliaryHintValue( id, value );
377 std::string Window::GetAuxiliaryHintValue( unsigned int id ) const
379 return mWindowBase->GetAuxiliaryHintValue( id );
382 unsigned int Window::GetAuxiliaryHintId( const std::string& hint ) const
384 return mWindowBase->GetAuxiliaryHintId( hint );
387 void Window::SetInputRegion( const Rect< int >& inputRegion )
389 mWindowBase->SetInputRegion( inputRegion );
391 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 );
394 void Window::SetType( Dali::Window::Type type )
398 mWindowBase->SetType( type );
404 Dali::Window::Type Window::GetType() const
409 bool Window::SetNotificationLevel( Dali::Window::NotificationLevel::Type level )
411 if( mType != Dali::Window::NOTIFICATION )
413 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetNotificationLevel: Not supported window type [%d]\n", mType );
417 return mWindowBase->SetNotificationLevel( level );
420 Dali::Window::NotificationLevel::Type Window::GetNotificationLevel() const
422 if( mType != Dali::Window::NOTIFICATION )
424 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::GetNotificationLevel: Not supported window type [%d]\n", mType );
425 return Dali::Window::NotificationLevel::NONE;
428 return mWindowBase->GetNotificationLevel();
431 void Window::SetOpaqueState( bool opaque )
433 mOpaqueState = opaque;
435 mWindowBase->SetOpaqueState( opaque );
437 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetOpaqueState: opaque = %d\n", opaque );
440 bool Window::IsOpaqueState() const
445 bool Window::SetScreenOffMode(Dali::Window::ScreenOffMode::Type screenOffMode)
447 return mWindowBase->SetScreenOffMode( screenOffMode );
450 Dali::Window::ScreenOffMode::Type Window::GetScreenOffMode() const
452 return mWindowBase->GetScreenOffMode();
455 bool Window::SetBrightness( int brightness )
457 if( brightness < 0 || brightness > 100 )
459 DALI_LOG_INFO( gWindowLogFilter, Debug::Verbose, "Window::SetBrightness: Invalid brightness value [%d]\n", brightness );
463 return mWindowBase->SetBrightness( brightness );
466 int Window::GetBrightness() const
468 return mWindowBase->GetBrightness();
471 void Window::SetSize( Dali::Window::WindowSize size )
473 if( !mResizeEnabled )
475 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
476 mResizeEnabled = true;
479 PositionSize positionSize = mSurface->GetPositionSize();
481 if( positionSize.width != size.GetWidth() || positionSize.height != size.GetHeight() )
483 positionSize.width = size.GetWidth();
484 positionSize.height = size.GetHeight();
486 mSurface->MoveResize( positionSize );
488 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
491 mResizedSignal.Emit( Dali::Window::WindowSize( positionSize.width, positionSize.height ) );
493 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
497 Dali::Window::WindowSize Window::GetSize() const
499 PositionSize positionSize = mSurface->GetPositionSize();
501 return Dali::Window::WindowSize( positionSize.width, positionSize.height );
504 void Window::SetPosition( Dali::Window::WindowPosition position )
506 if( !mResizeEnabled )
508 AddAuxiliaryHint( "wm.policy.win.user.geometry", "1" );
509 mResizeEnabled = true;
512 PositionSize positionSize = mSurface->GetPositionSize();
514 if( positionSize.x != position.GetX() || positionSize.y != position.GetY() )
516 positionSize.x = position.GetX();
517 positionSize.y = position.GetY();
519 mSurface->MoveResize( positionSize );
523 Dali::Window::WindowPosition Window::GetPosition() const
525 PositionSize positionSize = mSurface->GetPositionSize();
527 return Dali::Window::WindowPosition( positionSize.x, positionSize.y );
530 void Window::SetTransparency( bool transparent )
532 mSurface->SetTransparency( transparent );
535 bool Window::GrabKey( Dali::KEY key, KeyGrab::KeyGrabMode grabMode )
537 return mWindowBase->GrabKey( key, grabMode );
540 bool Window::UngrabKey( Dali::KEY key )
542 return mWindowBase->UngrabKey( key );
545 bool Window::GrabKeyList( const Dali::Vector< Dali::KEY >& key, const Dali::Vector< KeyGrab::KeyGrabMode >& grabMode, Dali::Vector< bool >& result )
547 return mWindowBase->GrabKeyList( key, grabMode, result );
550 bool Window::UngrabKeyList( const Dali::Vector< Dali::KEY >& key, Dali::Vector< bool >& result )
552 return mWindowBase->UngrabKeyList( key, result );
555 void Window::RotationDone( int orientation, int width, int height )
557 mSurface->RequestRotation( orientation, width, height );
559 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( width, height ) );
562 mResizedSignal.Emit( Dali::Window::WindowSize( width, height ) );
564 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( width, height ) );
567 void Window::DoShowIndicator( Dali::Window::WindowOrientation lastOrientation )
569 if( mIndicator == NULL )
571 if( mIndicatorVisible != Dali::Window::INVISIBLE )
573 auto windowFactory = Dali::Internal::Adaptor::GetWindowFactory();
574 mIndicator = windowFactory->CreateIndicator( mAdaptor, mIndicatorOrientation, this );
577 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
578 Dali::Actor actor = mIndicator->GetActor();
579 SetIndicatorActorRotation();
580 mOverlay->Add(actor);
583 // else don't create a hidden indicator
585 else // Already have indicator
587 if( mIndicatorVisible == Dali::Window::VISIBLE )
589 // If we are resuming, and rotation has changed,
590 if( mIndicatorIsShown == false && mIndicatorOrientation != mNextIndicatorOrientation )
592 // then close current indicator and open new one
593 mShowRotatedIndicatorOnClose = true;
594 mIndicator->Close(); // May synchronously call IndicatorClosed() callback & 1 level of recursion
595 // Don't show actor - will contain indicator for old orientation.
600 // set indicator visible mode
601 if( mIndicator != NULL )
603 mIndicator->SetVisible( mIndicatorVisible );
606 bool show = (mIndicatorVisible != Dali::Window::INVISIBLE );
607 SetIndicatorProperties( show, lastOrientation );
608 mIndicatorIsShown = show;
611 void Window::DoRotateIndicator( Dali::Window::WindowOrientation orientation )
613 if( mIndicatorIsShown )
615 mShowRotatedIndicatorOnClose = true;
616 mNextIndicatorOrientation = orientation;
619 mIndicator->Close(); // May synchronously call IndicatorClosed() callback
624 // Save orientation for when the indicator is next shown
625 mShowRotatedIndicatorOnClose = false;
626 mNextIndicatorOrientation = orientation;
630 void Window::SetIndicatorActorRotation()
632 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
635 Dali::Actor actor = mIndicator->GetActor();
636 switch( mIndicatorOrientation )
638 case Dali::Window::PORTRAIT:
639 actor.SetParentOrigin( ParentOrigin::TOP_CENTER );
640 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
641 actor.SetOrientation( Degree(0), Vector3::ZAXIS );
643 case Dali::Window::PORTRAIT_INVERSE:
644 actor.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
645 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
646 actor.SetOrientation( Degree(180), Vector3::ZAXIS );
648 case Dali::Window::LANDSCAPE:
649 actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
650 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
651 actor.SetOrientation( Degree(270), Vector3::ZAXIS );
653 case Dali::Window::LANDSCAPE_INVERSE:
654 actor.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
655 actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
656 actor.SetOrientation( Degree(90), Vector3::ZAXIS );
662 void Window::SetIndicatorProperties( bool isShow, Dali::Window::WindowOrientation lastOrientation )
664 mWindowBase->SetIndicatorProperties( isShow, lastOrientation );
667 void Window::OnIconifyChanged( bool iconified )
675 WindowVisibilityObserver* observer( mAdaptor );
676 observer->OnWindowHidden();
677 DALI_LOG_RELEASE_INFO( "Window (%p) Iconified\n", this );
686 WindowVisibilityObserver* observer( mAdaptor );
687 observer->OnWindowShown();
688 DALI_LOG_RELEASE_INFO( "Window (%p) Deiconified\n", this );
693 void Window::OnFocusChanged( bool focusIn )
695 mFocusChangedSignal.Emit( focusIn );
698 void Window::OnOutputTransformed()
700 PositionSize positionSize = mSurface->GetPositionSize();
701 mAdaptor->SurfaceResizePrepare( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
702 mAdaptor->SurfaceResizeComplete( Adaptor::SurfaceSize( positionSize.width, positionSize.height ) );
705 void Window::OnDeleteRequest()
707 mDeleteRequestSignal.Emit();
710 void Window::OnIndicatorFlicked()
714 mIndicator->Flicked();
718 void Window::IndicatorTypeChanged( IndicatorInterface::Type type )
720 mWindowBase->IndicatorTypeChanged( type );
723 void Window::IndicatorClosed( IndicatorInterface* indicator )
725 DALI_LOG_TRACE_METHOD( gWindowLogFilter );
727 if( mShowRotatedIndicatorOnClose )
729 Dali::Window::WindowOrientation currentOrientation = mIndicatorOrientation;
732 mIndicator->Open( mNextIndicatorOrientation );
734 mIndicatorOrientation = mNextIndicatorOrientation;
735 SetIndicatorActorRotation();
736 DoShowIndicator( currentOrientation );
740 void Window::IndicatorVisibilityChanged( bool isVisible )
742 mIndicatorVisibilityChangedSignal.Emit( isVisible );
745 void Window::OnStart()
747 DoShowIndicator( mIndicatorOrientation );
750 void Window::OnPause()
754 void Window::OnResume()
756 // resume indicator status
757 if( mIndicator != NULL )
759 // Restore own indicator opacity
760 // Send opacity mode to indicator service when app resumed
761 mIndicator->SetOpacityMode( mIndicatorOpacityMode );
765 void Window::OnStop()
772 mIndicator.release();
775 void Window::OnDestroy()