2017-01-02 17:05:30 -05:00
/*
2021-05-27 15:01:00 +00:00
SPDX - FileCopyrightText : 2016 Smith AR < audoban @ openmailbox . org >
SPDX - FileCopyrightText : 2016 Michail Vourlakos < mvourlakos @ gmail . com >
SPDX - License - Identifier : GPL - 2.0 - or - later
2017-01-02 17:05:30 -05:00
*/
2016-12-25 09:25:27 +02:00
# include "visibilitymanager.h"
2018-02-03 11:34:13 +02:00
2018-12-02 02:05:52 +02:00
// local
2018-11-29 21:30:00 +02:00
# include "positioner.h"
2018-12-06 12:15:58 +02:00
# include "view.h"
2020-01-22 19:45:13 +02:00
# include "helpers/floatinggapwindow.h"
# include "helpers/screenedgeghostwindow.h"
2019-06-08 17:36:14 +03:00
# include "windowstracker/currentscreentracker.h"
2020-04-24 12:31:03 +03:00
# include "../apptypes.h"
2018-12-06 14:35:34 +02:00
# include "../lattecorona.h"
2018-08-02 14:23:01 +03:00
# include "../screenpool.h"
2019-05-09 17:12:57 +03:00
# include "../layouts/manager.h"
2019-05-11 15:43:10 +03:00
# include "../wm/abstractwindowinterface.h"
2016-12-25 09:25:27 +02:00
2018-12-02 02:05:52 +02:00
// Qt
# include <QDebug>
// KDE
2019-04-12 19:08:00 +03:00
# include <KWindowSystem>
2018-03-28 20:39:52 +03:00
# include <KWayland/Client/plasmashell.h>
# include <KWayland/Client/surface.h>
2019-07-30 18:00:33 +03:00
//! Hide Timer can create cases that when it is low it does not allow the
//! view to be show. For example !compositing+kwin_edges+hide inteval<50ms
2020-08-02 03:23:00 +03:00
//! FIXED: As it appears because we dont hide any view anymore before its sliding in
//! animation has ended that probably allows to set the hide minimum interval to zero
//! without any further issues, such as to not show the view even though the
//! user is touching the screen edge
const int HIDEMINIMUMINTERVAL = 0 ;
2020-07-29 00:20:58 +03:00
//! After calling SidebarAutoHide panel to show for example through Sidebar button
//! or global shortcuts we make sure bar will be shown enough time
//! in order for the user to observe its contents
const int SIDEBARAUTOHIDEMINIMUMSHOW = 1000 ;
2019-07-30 18:00:33 +03:00
2020-07-28 15:49:55 +00:00
2016-12-29 00:40:35 -05:00
namespace Latte {
2018-12-09 00:29:35 +02:00
namespace ViewPart {
2016-12-25 09:25:27 +02:00
2018-12-20 18:59:38 +02:00
//! BEGIN: VisiblityManager implementation
2020-10-27 19:12:48 +02:00
const QRect VisibilityManager : : ISHIDDENMASK = QRect ( - 1 , - 1 , 1 , 1 ) ;
2018-12-20 18:59:38 +02:00
VisibilityManager : : VisibilityManager ( PlasmaQuick : : ContainmentView * view )
: QObject ( view )
2016-12-29 00:40:35 -05:00
{
2018-12-20 18:59:38 +02:00
qDebug ( ) < < " VisibilityManager creating... " ;
2018-12-06 12:51:15 +02:00
m_latteView = qobject_cast < Latte : : View * > ( view ) ;
2018-12-06 14:35:34 +02:00
m_corona = qobject_cast < Latte : : Corona * > ( view - > corona ( ) ) ;
2019-04-23 10:54:53 +03:00
m_wm = m_corona - > wm ( ) ;
2017-01-16 14:07:49 -05:00
2020-08-20 19:58:45 +03:00
connect ( this , & VisibilityManager : : hidingIsBlockedChanged , this , & VisibilityManager : : onHidingIsBlockedChanged ) ;
2020-04-05 14:40:32 +03:00
2019-05-11 09:08:18 +03:00
connect ( this , & VisibilityManager : : slideOutFinished , this , & VisibilityManager : : updateHiddenState ) ;
2020-01-22 00:11:37 +02:00
connect ( this , & VisibilityManager : : slideInFinished , this , & VisibilityManager : : updateHiddenState ) ;
2019-05-02 00:10:29 +03:00
2019-07-16 14:06:26 +03:00
connect ( this , & VisibilityManager : : enableKWinEdgesChanged , this , & VisibilityManager : : updateKWinEdgesSupport ) ;
connect ( this , & VisibilityManager : : modeChanged , this , & VisibilityManager : : updateKWinEdgesSupport ) ;
2021-05-21 17:08:19 +03:00
connect ( this , & VisibilityManager : : modeChanged , this , & VisibilityManager : : updateSidebarState ) ;
2021-03-04 19:18:42 +02:00
connect ( this , & VisibilityManager : : isFloatingGapWindowEnabledChanged , this , & VisibilityManager : : onIsFloatingGapWindowEnabledChanged ) ;
2019-07-16 14:06:26 +03:00
2020-07-18 19:40:31 +03:00
connect ( this , & VisibilityManager : : mustBeShown , this , [ & ] ( ) {
if ( m_latteView & & ! m_latteView - > isVisible ( ) ) {
m_latteView - > setVisible ( true ) ;
}
} ) ;
2018-12-06 12:51:15 +02:00
if ( m_latteView ) {
2018-12-20 18:59:38 +02:00
connect ( m_latteView , & Latte : : View : : eventTriggered , this , & VisibilityManager : : viewEventManager ) ;
2020-03-19 13:35:31 +02:00
connect ( m_latteView , & Latte : : View : : behaveAsPlasmaPanelChanged , this , & VisibilityManager : : updateKWinEdgesSupport ) ;
2019-06-20 10:25:18 +03:00
connect ( m_latteView , & Latte : : View : : byPassWMChanged , this , & VisibilityManager : : updateKWinEdgesSupport ) ;
2020-07-29 00:58:21 +03:00
2020-01-22 14:06:53 +02:00
connect ( m_latteView , & Latte : : View : : inEditModeChanged , this , & VisibilityManager : : initViewFlags ) ;
2019-04-23 10:41:35 +03:00
2020-05-11 17:31:03 +03:00
//! Frame Extents
2020-08-20 19:58:45 +03:00
connect ( m_latteView , & Latte : : View : : headThicknessGapChanged , this , & VisibilityManager : : onHeadThicknessChanged ) ;
2020-05-16 21:51:16 +03:00
connect ( m_latteView , & Latte : : View : : locationChanged , this , [ & ] ( ) {
2020-07-16 09:44:44 +03:00
if ( ! m_latteView - > behaveAsPlasmaPanel ( ) ) {
//! Resend frame extents because their geometry has changed
const bool forceUpdate { true } ;
publishFrameExtents ( forceUpdate ) ;
}
2020-05-16 21:51:16 +03:00
} ) ;
2020-05-26 16:41:53 +03:00
connect ( m_latteView , & Latte : : View : : typeChanged , this , [ & ] ( ) {
if ( m_latteView - > inEditMode ( ) ) {
//! Resend frame extents because type has changed
const bool forceUpdate { true } ;
publishFrameExtents ( forceUpdate ) ;
}
} ) ;
2020-05-12 10:30:05 +03:00
connect ( m_latteView , & Latte : : View : : forcedShown , this , [ & ] ( ) {
2020-05-12 14:45:31 +03:00
//! Resend frame extents to compositor otherwise because compositor cleared
//! them with no reason when the user is closing an activity
2020-05-12 10:30:05 +03:00
const bool forceUpdate { true } ;
publishFrameExtents ( forceUpdate ) ;
} ) ;
2020-05-11 17:31:03 +03:00
2019-04-12 18:55:45 +03:00
connect ( this , & VisibilityManager : : modeChanged , this , [ & ] ( ) {
2019-12-28 13:59:36 +02:00
emit m_latteView - > availableScreenRectChangedFrom ( m_latteView ) ;
2019-04-12 18:55:45 +03:00
} ) ;
2021-10-22 21:31:21 +03:00
//! Send frame extents on startup, this is really necessary when recreating a view.
//! Such a case is when toggling byPassWM and a view is recreated after disabling editing mode
const bool forceUpdate { true } ;
publishFrameExtents ( forceUpdate ) ;
2018-12-20 18:59:38 +02:00
}
2020-05-12 14:45:31 +03:00
m_timerStartUp . setInterval ( 4000 ) ;
2018-12-20 18:59:38 +02:00
m_timerStartUp . setSingleShot ( true ) ;
m_timerShow . setSingleShot ( true ) ;
m_timerHide . setSingleShot ( true ) ;
2019-02-07 20:24:52 +02:00
2018-12-20 18:59:38 +02:00
connect ( & m_timerShow , & QTimer : : timeout , this , [ & ] ( ) {
2019-12-27 13:38:22 +02:00
if ( m_isHidden | | m_isBelowLayer ) {
2017-01-28 19:34:03 +02:00
// qDebug() << "must be shown";
2018-12-20 18:59:38 +02:00
emit mustBeShown ( ) ;
2017-01-02 01:04:10 -05:00
}
} ) ;
2018-12-20 18:59:38 +02:00
connect ( & m_timerHide , & QTimer : : timeout , this , [ & ] ( ) {
2020-04-05 14:40:32 +03:00
if ( ! hidingIsBlocked ( ) & & ! m_isHidden & & ! m_isBelowLayer & & ! m_dragEnter ) {
2021-03-04 19:18:42 +02:00
if ( m_isFloatingGapWindowEnabled ) {
2020-01-22 00:11:37 +02:00
//! first check if mouse is inside the floating gap
checkMouseInFloatingArea ( ) ;
} else {
//! immediate call
emit mustBeHide ( ) ;
}
2017-01-02 01:04:10 -05:00
}
} ) ;
2019-04-23 10:20:08 +03:00
2020-05-12 14:45:31 +03:00
m_timerPublishFrameExtents . setInterval ( 1500 ) ;
2020-05-11 17:31:03 +03:00
m_timerPublishFrameExtents . setSingleShot ( true ) ;
2020-05-12 10:30:05 +03:00
connect ( & m_timerPublishFrameExtents , & QTimer : : timeout , this , [ & ] ( ) { publishFrameExtents ( ) ; } ) ;
2020-05-11 17:31:03 +03:00
2021-12-10 17:04:34 +02:00
m_timerBlockStrutsUpdate . setInterval ( 1000 ) ;
m_timerBlockStrutsUpdate . setSingleShot ( true ) ;
connect ( & m_timerBlockStrutsUpdate , & QTimer : : timeout , this , [ & ] ( ) { updateStrutsBasedOnLayoutsAndActivities ( ) ; } ) ;
2017-02-26 18:43:48 -05:00
restoreConfig ( ) ;
2016-12-29 00:40:35 -05:00
}
2016-12-25 09:25:27 +02:00
2018-12-20 18:59:38 +02:00
VisibilityManager : : ~ VisibilityManager ( )
2016-12-25 09:25:27 +02:00
{
2018-12-20 18:59:38 +02:00
qDebug ( ) < < " VisibilityManager deleting... " ;
2019-04-23 10:54:53 +03:00
m_wm - > removeViewStruts ( * m_latteView ) ;
2018-03-28 20:39:52 +03:00
2019-04-23 10:54:53 +03:00
if ( m_edgeGhostWindow ) {
m_edgeGhostWindow - > deleteLater ( ) ;
2018-03-28 20:39:52 +03:00
}
2020-01-22 00:11:37 +02:00
if ( m_floatingGapWindow ) {
m_floatingGapWindow - > deleteLater ( ) ;
}
2016-12-25 09:25:27 +02:00
}
2021-01-07 15:02:16 +02:00
//! Struts
int VisibilityManager : : strutsThickness ( ) const
{
return m_strutsThickness ;
}
void VisibilityManager : : setStrutsThickness ( int thickness )
{
if ( m_strutsThickness = = thickness ) {
return ;
}
m_strutsThickness = thickness ;
emit strutsThicknessChanged ( ) ;
}
2018-12-20 18:59:38 +02:00
Types : : Visibility VisibilityManager : : mode ( ) const
2016-12-25 09:25:27 +02:00
{
2018-12-20 18:59:38 +02:00
return m_mode ;
}
2019-12-26 21:58:21 +02:00
void VisibilityManager : : initViewFlags ( )
{
2019-12-27 13:38:22 +02:00
if ( ( m_mode = = Types : : WindowsCanCover | | m_mode = = Types : : WindowsAlwaysCover ) & & ( ! m_latteView - > inEditMode ( ) ) ) {
setViewOnBackLayer ( ) ;
2019-12-26 21:58:21 +02:00
} else {
2019-12-27 13:38:22 +02:00
setViewOnFrontLayer ( ) ;
2019-12-26 21:58:21 +02:00
}
}
2019-12-27 13:38:22 +02:00
void VisibilityManager : : setViewOnBackLayer ( )
{
m_wm - > setViewExtraFlags ( m_latteView , false , Types : : WindowsAlwaysCover ) ;
setIsBelowLayer ( true ) ;
}
void VisibilityManager : : setViewOnFrontLayer ( )
{
m_wm - > setViewExtraFlags ( m_latteView , true ) ;
setIsBelowLayer ( false ) ;
2021-01-16 20:57:07 +02:00
if ( KWindowSystem : : isPlatformX11 ( ) ) {
m_latteView - > raise ( ) ;
}
2019-12-27 13:38:22 +02:00
}
2018-12-20 18:59:38 +02:00
void VisibilityManager : : setMode ( Latte : : Types : : Visibility mode )
{
if ( m_mode = = mode )
2016-12-30 02:17:38 -05:00
return ;
2017-01-16 14:07:49 -05:00
2019-05-01 20:19:39 +03:00
Q_ASSERT_X ( mode ! = Types : : None , staticMetaObject . className ( ) , " set visibility to Types::None " ) ;
2017-02-26 18:43:48 -05:00
2016-12-30 02:17:38 -05:00
// clear mode
2019-04-23 10:54:53 +03:00
for ( auto & c : m_connections ) {
2016-12-30 02:17:38 -05:00
disconnect ( c ) ;
}
2017-01-16 14:07:49 -05:00
2019-04-23 10:20:08 +03:00
int base { 0 } ;
2019-05-01 23:26:56 +03:00
m_publishedStruts = QRect ( ) ;
2018-12-20 18:59:38 +02:00
if ( m_mode = = Types : : AlwaysVisible ) {
2019-04-23 10:20:08 +03:00
//! remove struts for old always visible mode
2019-04-23 10:54:53 +03:00
m_wm - > removeViewStruts ( * m_latteView ) ;
2019-04-23 10:20:08 +03:00
}
m_timerShow . stop ( ) ;
m_timerHide . stop ( ) ;
m_mode = mode ;
2019-12-26 21:58:21 +02:00
initViewFlags ( ) ;
2019-12-26 21:10:11 +02:00
2019-04-23 10:20:08 +03:00
if ( mode ! = Types : : AlwaysVisible & & mode ! = Types : : WindowsGoBelow ) {
2019-05-11 15:43:10 +03:00
m_connections [ 0 ] = connect ( m_wm , & WindowSystem : : AbstractWindowInterface : : currentDesktopChanged , this , [ & ] {
2019-04-23 10:54:53 +03:00
if ( m_raiseOnDesktopChange ) {
2018-12-06 16:17:35 +02:00
raiseViewTemporarily ( ) ;
2019-04-23 10:54:53 +03:00
}
2017-03-12 04:01:27 -05:00
} ) ;
2019-05-11 15:43:10 +03:00
m_connections [ 1 ] = connect ( m_wm , & WindowSystem : : AbstractWindowInterface : : currentActivityChanged , this , [ & ] ( ) {
2019-04-23 10:54:53 +03:00
if ( m_raiseOnActivityChange ) {
2018-12-06 16:17:35 +02:00
raiseViewTemporarily ( ) ;
2019-04-23 10:54:53 +03:00
} else {
2017-03-12 15:14:30 -05:00
updateHiddenState ( ) ;
2019-04-23 10:54:53 +03:00
}
2017-03-12 04:01:27 -05:00
} ) ;
2019-04-23 10:20:08 +03:00
base = 2 ;
}
2017-01-16 14:07:49 -05:00
2018-12-20 18:59:38 +02:00
switch ( m_mode ) {
2019-05-01 21:31:33 +03:00
case Types : : AlwaysVisible : {
if ( m_latteView - > containment ( ) & & m_latteView - > screen ( ) ) {
updateStrutsBasedOnLayoutsAndActivities ( ) ;
}
2021-12-12 03:13:35 +02:00
m_connections [ base ] = connect ( this , & VisibilityManager : : strutsThicknessChanged , & VisibilityManager : : updateStrutsAfterTimer ) ;
2021-12-10 17:04:34 +02:00
2021-12-12 03:13:35 +02:00
// disabling this call because it was creating too many struts calls and ???
// could create reduced responsiveness for DynamicStruts Scenario(for example ??
// when dragging active window from a floating dock/panel) ???
m_connections [ base + 1 ] = connect ( m_latteView , & Latte : : View : : absoluteGeometryChanged , this , & VisibilityManager : : updateStrutsAfterTimer ) ;
2019-05-01 21:31:33 +03:00
2021-12-12 03:13:35 +02:00
m_connections [ base + 2 ] = connect ( m_corona - > activitiesConsumer ( ) , & KActivities : : Consumer : : currentActivityChanged , this , [ & ] ( ) {
2020-04-24 12:31:03 +03:00
if ( m_corona & & m_corona - > layoutsManager ( ) - > memoryUsage ( ) = = MemoryUsage : : MultipleLayouts ) {
2019-05-14 17:56:22 +03:00
updateStrutsBasedOnLayoutsAndActivities ( true ) ;
2017-03-23 00:03:45 -05:00
}
2019-05-01 21:31:33 +03:00
} ) ;
2017-01-16 14:07:49 -05:00
2021-12-12 14:34:28 +02:00
//! respect canSetStrut that must be disabled under x11 when an alwaysvisible screen edge is common between two or more screens
m_connections [ base + 3 ] = connect ( m_corona - > screenPool ( ) , & Latte : : ScreenPool : : screenGeometryChanged , this , & VisibilityManager : : updateStrutsAfterTimer ) ;
m_connections [ base + 4 ] = connect ( m_latteView , & Latte : : View : : activitiesChanged , this , [ & ] ( ) {
2020-05-23 20:04:37 +03:00
updateStrutsBasedOnLayoutsAndActivities ( true ) ;
2019-05-01 21:31:33 +03:00
} ) ;
2018-01-13 19:27:32 +02:00
2019-05-01 21:31:33 +03:00
raiseView ( true ) ;
2016-12-30 02:17:38 -05:00
break ;
2019-05-01 21:31:33 +03:00
}
2017-01-16 14:07:49 -05:00
2019-05-01 21:31:33 +03:00
case Types : : AutoHide : {
m_connections [ base ] = connect ( this , & VisibilityManager : : containsMouseChanged , this , [ & ] ( ) {
2018-12-20 18:59:38 +02:00
raiseView ( m_containsMouse ) ;
2019-05-01 21:31:33 +03:00
} ) ;
raiseView ( m_containsMouse ) ;
2016-12-30 02:17:38 -05:00
break ;
2019-05-01 21:31:33 +03:00
}
2017-01-16 14:07:49 -05:00
2019-05-01 21:31:33 +03:00
case Types : : DodgeActive : {
m_connections [ base ] = connect ( this , & VisibilityManager : : containsMouseChanged
, this , & VisibilityManager : : dodgeActive ) ;
2019-06-08 17:36:14 +03:00
m_connections [ base + 1 ] = connect ( m_latteView - > windowsTracker ( ) - > currentScreen ( ) , & TrackerPart : : CurrentScreenTracker : : activeWindowTouchingChanged
2019-05-01 21:31:33 +03:00
, this , & VisibilityManager : : dodgeActive ) ;
2019-04-23 09:58:06 +03:00
2019-05-01 21:31:33 +03:00
dodgeActive ( ) ;
2016-12-30 02:24:04 -05:00
break ;
2019-05-01 21:31:33 +03:00
}
2017-01-16 14:07:49 -05:00
2019-05-01 21:31:33 +03:00
case Types : : DodgeMaximized : {
m_connections [ base ] = connect ( this , & VisibilityManager : : containsMouseChanged
, this , & VisibilityManager : : dodgeMaximized ) ;
2019-06-08 17:36:14 +03:00
m_connections [ base + 1 ] = connect ( m_latteView - > windowsTracker ( ) - > currentScreen ( ) , & TrackerPart : : CurrentScreenTracker : : activeWindowMaximizedChanged
2019-06-03 19:20:06 +03:00
, this , & VisibilityManager : : dodgeMaximized ) ;
2019-04-23 09:58:06 +03:00
2019-05-01 21:31:33 +03:00
dodgeMaximized ( ) ;
2016-12-30 02:24:04 -05:00
break ;
2019-05-01 21:31:33 +03:00
}
2017-01-16 14:07:49 -05:00
2019-05-01 21:31:33 +03:00
case Types : : DodgeAllWindows : {
m_connections [ base ] = connect ( this , & VisibilityManager : : containsMouseChanged
, this , & VisibilityManager : : dodgeAllWindows ) ;
2017-01-16 14:07:49 -05:00
2019-06-08 17:36:14 +03:00
m_connections [ base + 1 ] = connect ( m_latteView - > windowsTracker ( ) - > currentScreen ( ) , & TrackerPart : : CurrentScreenTracker : : existsWindowTouchingChanged
2019-05-01 21:31:33 +03:00
, this , & VisibilityManager : : dodgeAllWindows ) ;
2019-06-03 19:16:48 +03:00
dodgeAllWindows ( ) ;
2017-02-12 03:01:12 -05:00
break ;
2019-05-01 21:31:33 +03:00
}
2017-06-04 02:43:52 +03:00
2019-05-01 21:31:33 +03:00
case Types : : WindowsGoBelow :
2019-04-23 10:20:08 +03:00
break ;
2017-06-08 17:10:49 -05:00
2019-12-26 21:10:11 +02:00
case Types : : WindowsCanCover :
2019-12-27 13:38:22 +02:00
m_connections [ base ] = connect ( this , & VisibilityManager : : containsMouseChanged , this , [ & ] ( ) {
2021-05-29 20:16:04 +03:00
raiseView ( m_containsMouse ) ;
2019-12-27 13:38:22 +02:00
} ) ;
raiseView ( m_containsMouse ) ;
2019-12-26 21:10:11 +02:00
break ;
2019-12-26 17:21:03 +02:00
case Types : : WindowsAlwaysCover :
break ;
2020-07-29 00:02:50 +03:00
case Types : : SidebarOnDemand :
2020-03-01 17:19:24 +02:00
m_connections [ base ] = connect ( m_latteView , & Latte : : View : : inEditModeChanged , this , [ & ] ( ) {
if ( ! m_latteView - > inEditMode ( ) ) {
2021-05-03 23:24:23 +03:00
m_isRequestedShownSidebarOnDemand = false ;
updateHiddenState ( ) ;
2020-03-01 17:19:24 +02:00
}
} ) ;
2021-05-03 23:24:23 +03:00
m_isRequestedShownSidebarOnDemand = false ;
updateHiddenState ( ) ;
2020-07-28 15:49:55 +00:00
break ;
2020-03-01 17:19:24 +02:00
2020-07-28 15:49:55 +00:00
case Types : : SidebarAutoHide :
2020-08-02 02:31:09 +03:00
m_connections [ base ] = connect ( this , & VisibilityManager : : containsMouseChanged , this , [ & ] ( ) {
if ( ! m_latteView - > inEditMode ( ) ) {
updateHiddenState ( ) ;
}
} ) ;
2020-07-28 15:49:55 +00:00
2020-07-29 00:58:21 +03:00
m_connections [ base + 1 ] = connect ( m_latteView , & Latte : : View : : inEditModeChanged , this , [ & ] ( ) {
2020-08-02 02:31:09 +03:00
if ( m_latteView - > inEditMode ( ) & & ! m_isHidden ) {
updateHiddenState ( ) ;
2020-07-28 15:49:55 +00:00
}
} ) ;
2020-07-29 00:58:21 +03:00
2020-07-28 15:49:55 +00:00
toggleHiddenState ( ) ;
break ;
2020-07-29 00:58:21 +03:00
2019-05-01 21:31:33 +03:00
default :
2019-04-23 10:20:08 +03:00
break ;
2016-12-30 02:17:38 -05:00
}
2017-01-16 14:07:49 -05:00
2018-12-20 18:59:38 +02:00
m_latteView - > containment ( ) - > config ( ) . writeEntry ( " visibility " , static_cast < int > ( m_mode ) ) ;
2017-03-12 04:01:27 -05:00
2018-12-20 18:59:38 +02:00
emit modeChanged ( ) ;
2017-03-12 04:01:27 -05:00
}
2021-12-12 03:13:35 +02:00
void VisibilityManager : : updateStrutsAfterTimer ( )
{
bool execute = ! m_timerBlockStrutsUpdate . isActive ( ) ;
m_timerBlockStrutsUpdate . start ( ) ;
if ( execute ) {
updateStrutsBasedOnLayoutsAndActivities ( ) ;
}
}
2021-05-21 17:08:19 +03:00
void VisibilityManager : : updateSidebarState ( )
{
bool cursidebarstate = ( ( m_mode = = Types : : SidebarOnDemand )
| | ( m_mode = = Types : : SidebarAutoHide ) ) ;
if ( m_isSidebar = = cursidebarstate ) {
return ;
}
m_isSidebar = = cursidebarstate ;
emit isSidebarChanged ( ) ;
}
2019-05-14 17:56:22 +03:00
void VisibilityManager : : updateStrutsBasedOnLayoutsAndActivities ( bool forceUpdate )
2018-01-13 20:00:03 +02:00
{
2021-01-10 13:14:07 +02:00
bool inMultipleLayoutsAndCurrent = ( m_corona - > layoutsManager ( ) - > memoryUsage ( ) = = MemoryUsage : : MultipleLayouts
2021-12-12 14:34:28 +02:00
& & m_latteView - > layout ( ) & & ! m_latteView - > positioner ( ) - > inRelocationAnimation ( )
& & m_latteView - > layout ( ) - > isCurrent ( ) ) ;
2018-01-13 20:00:03 +02:00
2021-12-12 14:34:28 +02:00
if ( m_strutsThickness > 0 & & canSetStrut ( ) & & ( m_corona - > layoutsManager ( ) - > memoryUsage ( ) = = MemoryUsage : : SingleLayout | | inMultipleLayoutsAndCurrent ) ) {
2019-05-01 23:04:39 +03:00
QRect computedStruts = acceptableStruts ( ) ;
2019-05-14 17:56:22 +03:00
if ( m_publishedStruts ! = computedStruts | | forceUpdate ) {
//! Force update is needed when very important events happen in DE and there is a chance
//! that previously even though struts where sent the DE did not accept them.
//! Such a case is when STOPPING an Activity and windows faulty become invisible even
//! though they should not. In such case setting struts when the windows are hidden
//! the struts do not take any effect
2019-05-01 23:04:39 +03:00
m_publishedStruts = computedStruts ;
m_wm - > setViewStruts ( * m_latteView , m_publishedStruts , m_latteView - > location ( ) ) ;
}
2018-01-13 20:00:03 +02:00
} else {
2019-05-03 02:39:21 +03:00
m_publishedStruts = QRect ( ) ;
2019-04-23 10:54:53 +03:00
m_wm - > removeViewStruts ( * m_latteView ) ;
2018-01-13 20:00:03 +02:00
}
}
2021-12-12 14:34:28 +02:00
bool VisibilityManager : : canSetStrut ( ) const
{
2021-12-13 23:01:21 +02:00
if ( m_latteView - > positioner ( ) - > isOffScreen ( ) ) {
return false ;
}
2021-12-14 17:03:24 +02:00
if ( ! KWindowSystem : : isPlatformX11 ( ) | | ! m_wm - > isKWinRunning ( ) /*alternative de*/ ) {
2021-12-12 14:34:28 +02:00
return true ;
}
// read the wm name, need to do this every time which means a roundtrip unfortunately
// but WM might have changed
//NETRootInfo rootInfo(QX11Info::connection(), NET::Supported | NET::SupportingWMCheck);
//if (qstricmp(rootInfo.wmName(), "KWin") == 0) {
// KWin since 5.7 can handle this fine, so only exclude for other window managers
//return true;
//}
if ( qGuiApp - > screens ( ) . count ( ) < 2 ) {
return true ;
}
const QRect thisScreen = m_latteView - > screen ( ) - > geometry ( ) ;
// Extended struts against a screen edge near to another screen are really harmful, so windows maximized under the panel is a lesser pain
// TODO: force "windows can cover" in those cases?
for ( QScreen * screen : qGuiApp - > screens ( ) ) {
if ( ! screen | | m_latteView - > screen ( ) = = screen ) {
continue ;
}
const QRect otherScreen = screen - > geometry ( ) ;
switch ( m_latteView - > location ( ) ) {
case Plasma : : Types : : TopEdge :
if ( otherScreen . bottom ( ) < = thisScreen . top ( ) ) {
return false ;
}
break ;
case Plasma : : Types : : BottomEdge :
if ( otherScreen . top ( ) > = thisScreen . bottom ( ) ) {
return false ;
}
break ;
case Plasma : : Types : : RightEdge :
if ( otherScreen . left ( ) > = thisScreen . right ( ) ) {
return false ;
}
break ;
case Plasma : : Types : : LeftEdge :
if ( otherScreen . right ( ) < = thisScreen . left ( ) ) {
return false ;
}
break ;
default :
return false ;
}
}
return true ;
}
2019-05-01 23:04:39 +03:00
QRect VisibilityManager : : acceptableStruts ( )
{
QRect calcs ;
switch ( m_latteView - > location ( ) ) {
2019-07-30 18:00:33 +03:00
case Plasma : : Types : : TopEdge : {
2021-01-07 15:02:16 +02:00
calcs = QRect ( m_latteView - > x ( ) , m_latteView - > screenGeometry ( ) . top ( ) , m_latteView - > width ( ) , m_strutsThickness ) ;
2019-07-30 18:00:33 +03:00
break ;
}
2019-05-01 23:04:39 +03:00
2019-07-30 18:00:33 +03:00
case Plasma : : Types : : BottomEdge : {
2021-01-07 15:02:16 +02:00
int y = m_latteView - > screenGeometry ( ) . bottom ( ) - m_strutsThickness + 1 /* +1, is needed in order to not leave a gap at screen_edge*/ ;
calcs = QRect ( m_latteView - > x ( ) , y , m_latteView - > width ( ) , m_strutsThickness ) ;
2019-07-30 18:00:33 +03:00
break ;
}
2019-05-01 23:04:39 +03:00
2019-07-30 18:00:33 +03:00
case Plasma : : Types : : LeftEdge : {
2021-01-07 15:02:16 +02:00
calcs = QRect ( m_latteView - > screenGeometry ( ) . left ( ) , m_latteView - > y ( ) , m_strutsThickness , m_latteView - > height ( ) ) ;
2019-07-30 18:00:33 +03:00
break ;
}
2019-05-01 23:04:39 +03:00
2019-07-30 18:00:33 +03:00
case Plasma : : Types : : RightEdge : {
2021-01-07 15:02:16 +02:00
int x = m_latteView - > screenGeometry ( ) . right ( ) - m_strutsThickness + 1 /* +1, is needed in order to not leave a gap at screen_edge*/ ;
calcs = QRect ( x , m_latteView - > y ( ) , m_strutsThickness , m_latteView - > height ( ) ) ;
2019-07-30 18:00:33 +03:00
break ;
}
2019-05-01 23:04:39 +03:00
}
return calcs ;
}
2018-12-20 18:59:38 +02:00
bool VisibilityManager : : raiseOnDesktop ( ) const
{
2019-04-23 10:54:53 +03:00
return m_raiseOnDesktopChange ;
2018-12-20 18:59:38 +02:00
}
void VisibilityManager : : setRaiseOnDesktop ( bool enable )
2017-03-12 04:01:27 -05:00
{
2019-04-23 10:54:53 +03:00
if ( enable = = m_raiseOnDesktopChange )
2017-03-12 04:01:27 -05:00
return ;
2019-04-23 10:54:53 +03:00
m_raiseOnDesktopChange = enable ;
2018-12-20 18:59:38 +02:00
emit raiseOnDesktopChanged ( ) ;
2017-03-12 04:01:27 -05:00
}
2018-12-20 18:59:38 +02:00
bool VisibilityManager : : raiseOnActivity ( ) const
{
2019-04-23 10:54:53 +03:00
return m_raiseOnActivityChange ;
2018-12-20 18:59:38 +02:00
}
void VisibilityManager : : setRaiseOnActivity ( bool enable )
2017-03-12 04:01:27 -05:00
{
2019-04-23 10:54:53 +03:00
if ( enable = = m_raiseOnActivityChange )
2017-03-12 04:01:27 -05:00
return ;
2019-04-23 10:54:53 +03:00
m_raiseOnActivityChange = enable ;
2018-12-20 18:59:38 +02:00
emit raiseOnActivityChanged ( ) ;
}
2019-12-27 13:38:22 +02:00
bool VisibilityManager : : isBelowLayer ( ) const
{
return m_isBelowLayer ;
}
void VisibilityManager : : setIsBelowLayer ( bool below )
{
if ( m_isBelowLayer = = below ) {
return ;
}
m_isBelowLayer = below ;
2020-01-02 17:06:50 +02:00
updateGhostWindowState ( ) ;
2019-12-27 13:38:22 +02:00
emit isBelowLayerChanged ( ) ;
}
2018-12-20 18:59:38 +02:00
bool VisibilityManager : : isHidden ( ) const
{
return m_isHidden ;
2016-12-25 09:25:27 +02:00
}
2018-12-20 18:59:38 +02:00
void VisibilityManager : : setIsHidden ( bool isHidden )
2016-12-25 09:25:27 +02:00
{
2018-12-20 18:59:38 +02:00
if ( m_isHidden = = isHidden )
2016-12-30 02:17:38 -05:00
return ;
2017-01-16 14:07:49 -05:00
2018-12-20 18:59:38 +02:00
m_isHidden = isHidden ;
2020-01-02 18:40:44 +02:00
updateGhostWindowState ( ) ;
2018-03-28 20:39:52 +03:00
2018-12-20 18:59:38 +02:00
emit isHiddenChanged ( ) ;
2016-12-29 00:40:35 -05:00
}
2016-12-25 09:25:27 +02:00
2021-05-13 19:14:33 +03:00
bool VisibilityManager : : isShownFully ( ) const
{
return m_isShownFully ;
}
void VisibilityManager : : setIsShownFully ( bool fully )
{
if ( m_isShownFully = = fully ) {
return ;
}
m_isShownFully = fully ;
emit isShownFullyChanged ( ) ;
}
2020-04-05 14:40:32 +03:00
bool VisibilityManager : : hidingIsBlocked ( ) const
{
return ( m_blockHidingEvents . count ( ) > 0 ) ;
}
2021-03-04 19:18:42 +02:00
bool VisibilityManager : : isFloatingGapWindowEnabled ( ) const
{
return m_isFloatingGapWindowEnabled ;
}
void VisibilityManager : : setIsFloatingGapWindowEnabled ( bool enabled )
{
if ( m_isFloatingGapWindowEnabled = = enabled ) {
return ;
}
m_isFloatingGapWindowEnabled = enabled ;
emit isFloatingGapWindowEnabledChanged ( ) ;
}
2020-04-05 14:40:32 +03:00
2021-05-13 20:09:05 +03:00
bool VisibilityManager : : hasBlockHidingEvent ( const QString & type )
{
return ( ! type . isEmpty ( ) & & m_blockHidingEvents . contains ( type ) ) ;
}
2020-04-05 14:40:32 +03:00
void VisibilityManager : : addBlockHidingEvent ( const QString & type )
2017-01-02 03:06:47 -05:00
{
2020-04-05 14:40:32 +03:00
if ( m_blockHidingEvents . contains ( type ) | | type . isEmpty ( ) ) {
return ;
}
2021-01-31 23:05:54 +02:00
//qDebug() << " org.kde.late {{ ++++ adding block hiding event :: " << type;
2020-04-05 14:40:32 +03:00
bool prevHidingIsBlocked = hidingIsBlocked ( ) ;
m_blockHidingEvents < < type ;
if ( prevHidingIsBlocked ! = hidingIsBlocked ( ) ) {
emit hidingIsBlockedChanged ( ) ;
}
2018-12-20 18:59:38 +02:00
}
2020-04-05 14:40:32 +03:00
void VisibilityManager : : removeBlockHidingEvent ( const QString & type )
2018-12-20 18:59:38 +02:00
{
2020-04-05 14:40:32 +03:00
if ( ! m_blockHidingEvents . contains ( type ) | | type . isEmpty ( ) ) {
2017-01-02 03:06:47 -05:00
return ;
2018-12-20 18:59:38 +02:00
}
2021-01-31 23:05:54 +02:00
//qDebug() << " org.kde.latte {{ ---- remove block hiding event :: " << type;
2020-04-05 14:40:32 +03:00
bool prevHidingIsBlocked = hidingIsBlocked ( ) ;
2017-01-16 14:07:49 -05:00
2020-04-05 14:40:32 +03:00
m_blockHidingEvents . removeAll ( type ) ;
if ( prevHidingIsBlocked ! = hidingIsBlocked ( ) ) {
emit hidingIsBlockedChanged ( ) ;
}
}
2017-01-16 14:07:49 -05:00
2020-08-20 19:58:45 +03:00
void VisibilityManager : : onHidingIsBlockedChanged ( )
2020-04-05 14:40:32 +03:00
{
if ( hidingIsBlocked ( ) ) {
2018-12-20 18:59:38 +02:00
m_timerHide . stop ( ) ;
2020-08-02 02:31:09 +03:00
emit mustBeShown ( ) ;
2017-01-02 03:06:47 -05:00
} else {
updateHiddenState ( ) ;
}
2018-12-20 18:59:38 +02:00
}
2020-08-20 19:58:45 +03:00
void VisibilityManager : : onHeadThicknessChanged ( )
2020-05-11 17:31:03 +03:00
{
if ( ! m_timerPublishFrameExtents . isActive ( ) ) {
m_timerPublishFrameExtents . start ( ) ;
}
}
2020-05-12 10:30:05 +03:00
void VisibilityManager : : publishFrameExtents ( bool forceUpdate )
2021-01-06 21:29:34 +02:00
{
2020-05-11 17:31:03 +03:00
if ( m_frameExtentsHeadThicknessGap ! = m_latteView - > headThicknessGap ( )
2020-05-12 10:30:05 +03:00
| | m_frameExtentsLocation ! = m_latteView - > location ( )
| | forceUpdate ) {
2020-05-11 17:31:03 +03:00
m_frameExtentsLocation = m_latteView - > location ( ) ;
2020-07-18 19:27:47 +03:00
m_frameExtentsHeadThicknessGap = m_latteView - > headThicknessGap ( ) ;
2020-05-11 17:31:03 +03:00
2021-10-24 16:28:00 +03:00
if ( KWindowSystem : : isPlatformX11 ( ) & & m_latteView - > devicePixelRatio ( ) ! = 1.0 ) {
//!Fix for X11 Global Scale
m_frameExtentsHeadThicknessGap = qRound ( m_frameExtentsHeadThicknessGap * m_latteView - > devicePixelRatio ( ) ) ;
}
2020-07-18 19:27:47 +03:00
QMargins frameExtents ( 0 , 0 , 0 , 0 ) ;
2020-05-11 17:31:03 +03:00
if ( m_latteView - > location ( ) = = Plasma : : Types : : LeftEdge ) {
frameExtents . setRight ( m_frameExtentsHeadThicknessGap ) ;
} else if ( m_latteView - > location ( ) = = Plasma : : Types : : TopEdge ) {
frameExtents . setBottom ( m_frameExtentsHeadThicknessGap ) ;
} else if ( m_latteView - > location ( ) = = Plasma : : Types : : RightEdge ) {
frameExtents . setLeft ( m_frameExtentsHeadThicknessGap ) ;
} else {
frameExtents . setTop ( m_frameExtentsHeadThicknessGap ) ;
}
2021-10-22 20:41:50 +03:00
bool bypasswm { m_latteView - > byPassWM ( ) & & KWindowSystem : : isPlatformX11 ( ) } ;
2021-10-22 21:31:21 +03:00
qDebug ( ) < < " -> Frame Extents :: " < < m_frameExtentsLocation < < " __ " < < " extents :: " < < frameExtents < < " bypasswm :: " < < bypasswm ;
2021-10-22 20:41:50 +03:00
if ( ! frameExtents . isNull ( ) & & ! m_latteView - > behaveAsPlasmaPanel ( ) & & ! bypasswm ) {
2020-05-12 14:45:31 +03:00
//! When a view returns its frame extents to zero then that triggers a compositor
//! strange behavior that moves/hides the view totally and freezes entire Latte
//! this is why we have blocked that setting
m_wm - > setFrameExtents ( m_latteView , frameExtents ) ;
2021-10-22 20:41:50 +03:00
} else if ( m_latteView - > behaveAsPlasmaPanel ( ) | | bypasswm ) {
2020-07-18 19:27:47 +03:00
QMargins panelExtents ( 0 , 0 , 0 , 0 ) ;
m_wm - > setFrameExtents ( m_latteView , panelExtents ) ;
2020-05-12 14:45:31 +03:00
emit frameExtentsCleared ( ) ;
}
2020-05-11 17:31:03 +03:00
}
}
2018-12-20 18:59:38 +02:00
int VisibilityManager : : timerShow ( ) const
{
return m_timerShow . interval ( ) ;
}
void VisibilityManager : : setTimerShow ( int msec )
{
2019-07-30 18:00:33 +03:00
if ( m_timerShow . interval ( ) = = msec ) {
return ;
}
2018-12-20 18:59:38 +02:00
m_timerShow . setInterval ( msec ) ;
emit timerShowChanged ( ) ;
}
int VisibilityManager : : timerHide ( ) const
{
2020-07-29 00:13:16 +03:00
return m_timerHideInterval ;
2017-01-02 03:06:47 -05:00
}
2018-12-20 18:59:38 +02:00
void VisibilityManager : : setTimerHide ( int msec )
2016-12-25 09:25:27 +02:00
{
2020-01-19 20:52:14 +02:00
int interval = qMax ( HIDEMINIMUMINTERVAL , msec ) ;
2019-07-30 18:00:33 +03:00
2020-07-29 00:13:16 +03:00
if ( m_timerHideInterval = = interval ) {
2019-07-30 18:00:33 +03:00
return ;
}
2020-07-29 00:13:16 +03:00
m_timerHideInterval = interval ;
2020-01-19 20:52:14 +02:00
m_timerHide . setInterval ( interval ) ;
emit timerHideChanged ( ) ;
2016-12-25 09:25:27 +02:00
}
2020-07-28 15:49:55 +00:00
bool VisibilityManager : : isSidebar ( ) const
{
2020-07-29 00:02:50 +03:00
return m_mode = = Latte : : Types : : SidebarOnDemand | | m_mode = = Latte : : Types : : SidebarAutoHide ;
2020-07-28 15:49:55 +00:00
}
2018-12-20 18:59:38 +02:00
bool VisibilityManager : : supportsKWinEdges ( ) const
2016-12-25 09:25:27 +02:00
{
2019-04-23 10:54:53 +03:00
return ( m_edgeGhostWindow ! = nullptr ) ;
2016-12-25 09:25:27 +02:00
}
2019-02-24 19:09:48 +02:00
void VisibilityManager : : updateGhostWindowState ( )
{
if ( supportsKWinEdges ( ) ) {
2020-04-24 12:31:03 +03:00
bool inCurrentLayout = ( m_corona - > layoutsManager ( ) - > memoryUsage ( ) = = MemoryUsage : : SingleLayout | |
( m_corona - > layoutsManager ( ) - > memoryUsage ( ) = = MemoryUsage : : MultipleLayouts
2021-01-19 21:14:09 +02:00
& & m_latteView - > layout ( ) & & ! m_latteView - > positioner ( ) - > inRelocationAnimation ( )
2019-07-16 14:06:26 +03:00
& & m_latteView - > layout ( ) - > isCurrent ( ) ) ) ;
2019-02-24 19:09:48 +02:00
if ( inCurrentLayout ) {
2019-12-27 13:38:22 +02:00
if ( m_mode = = Latte : : Types : : WindowsCanCover ) {
2020-01-03 13:32:08 +02:00
m_wm - > setActiveEdge ( m_edgeGhostWindow , m_isBelowLayer & & ! m_containsMouse ) ;
2019-12-27 13:38:22 +02:00
} else {
2020-01-22 00:11:37 +02:00
bool activated = ( m_isHidden & & ! windowContainsMouse ( ) ) ;
2020-01-03 14:10:04 +02:00
m_wm - > setActiveEdge ( m_edgeGhostWindow , activated ) ;
2019-12-27 13:38:22 +02:00
}
2019-02-24 19:09:48 +02:00
} else {
2020-01-03 13:32:08 +02:00
m_wm - > setActiveEdge ( m_edgeGhostWindow , false ) ;
2019-02-24 19:09:48 +02:00
}
}
}
2019-04-12 19:08:00 +03:00
void VisibilityManager : : hide ( )
{
2020-12-27 13:47:01 +02:00
if ( KWindowSystem : : isPlatformX11 ( ) ) {
m_latteView - > setVisible ( false ) ;
2020-11-30 21:06:24 +02:00
}
2019-04-12 19:08:00 +03:00
}
void VisibilityManager : : show ( )
{
2020-12-27 13:47:01 +02:00
if ( KWindowSystem : : isPlatformX11 ( ) ) {
m_latteView - > setVisible ( true ) ;
2019-04-12 19:08:00 +03:00
}
}
2020-03-01 17:19:24 +02:00
void VisibilityManager : : toggleHiddenState ( )
{
if ( ! m_latteView - > inEditMode ( ) ) {
2020-07-28 15:49:55 +00:00
if ( isSidebar ( ) ) {
2021-12-12 14:34:28 +02:00
// if (m_blockHidingEvents.contains(Q_FUNC_INFO)) {
2021-05-03 23:24:23 +03:00
// removeBlockHidingEvent(Q_FUNC_INFO);
2021-12-12 14:34:28 +02:00
// }
2020-04-15 16:47:15 +03:00
2021-05-03 23:24:23 +03:00
if ( m_mode = = Latte : : Types : : SidebarOnDemand ) {
m_isRequestedShownSidebarOnDemand = ! m_isRequestedShownSidebarOnDemand ;
updateHiddenState ( ) ;
} else if ( m_mode = = Latte : : Types : : SidebarAutoHide ) {
if ( m_isHidden ) {
emit mustBeShown ( ) ;
2020-07-29 00:20:58 +03:00
startTimerHide ( SIDEBARAUTOHIDEMINIMUMSHOW + m_timerHideInterval ) ;
2021-05-03 23:24:23 +03:00
} else {
emit mustBeHide ( ) ;
2020-07-28 15:49:55 +00:00
}
2020-03-01 17:19:24 +02:00
}
} else {
2021-12-12 14:34:28 +02:00
/* if (!m_isHidden && !m_blockHidingEvents.contains(Q_FUNC_INFO)) {
2020-04-05 14:40:32 +03:00
addBlockHidingEvent ( Q_FUNC_INFO ) ;
2021-04-12 12:48:22 +03:00
} else if ( m_isHidden ) {
2020-04-05 14:40:32 +03:00
removeBlockHidingEvent ( Q_FUNC_INFO ) ;
2021-04-12 12:48:22 +03:00
} */
2020-03-01 17:19:24 +02:00
}
}
}
2018-12-20 18:59:38 +02:00
void VisibilityManager : : updateHiddenState ( )
2017-01-02 03:06:47 -05:00
{
2019-04-23 10:54:53 +03:00
if ( m_dragEnter )
2017-01-03 12:36:40 -05:00
return ;
2017-01-16 14:07:49 -05:00
2018-12-20 18:59:38 +02:00
switch ( m_mode ) {
2019-05-01 21:31:33 +03:00
case Types : : AutoHide :
2019-12-27 13:38:22 +02:00
case Types : : WindowsCanCover :
2020-01-22 00:11:37 +02:00
raiseView ( m_containsMouse ) ;
2019-05-01 21:31:33 +03:00
break ;
2017-01-16 14:07:49 -05:00
2019-05-01 21:31:33 +03:00
case Types : : DodgeActive :
dodgeActive ( ) ;
break ;
2017-01-16 14:07:49 -05:00
2019-05-01 21:31:33 +03:00
case Types : : DodgeMaximized :
dodgeMaximized ( ) ;
break ;
2017-01-16 14:07:49 -05:00
2019-05-01 21:31:33 +03:00
case Types : : DodgeAllWindows :
dodgeAllWindows ( ) ;
break ;
2017-08-13 13:00:46 +03:00
2021-05-03 23:24:23 +03:00
case Types : : SidebarOnDemand :
raiseView ( m_isRequestedShownSidebarOnDemand ) ;
break ;
2020-07-29 00:58:21 +03:00
case Types : : SidebarAutoHide :
raiseView ( m_latteView - > inEditMode ( ) | | ( m_containsMouse & & ! m_isHidden ) ) ;
2020-08-02 02:31:09 +03:00
break ;
2020-07-29 00:58:21 +03:00
2019-05-01 21:31:33 +03:00
default :
break ;
2017-01-02 03:06:47 -05:00
}
}
2021-05-03 23:24:23 +03:00
void VisibilityManager : : raiseView ( bool raise )
{
if ( m_mode = = Latte : : Types : : SidebarOnDemand ) {
if ( raise & & m_isHidden ) {
emit mustBeShown ( ) ;
} else if ( ! raise & & ! m_isHidden & & ! m_dragEnter & & ! hidingIsBlocked ( ) ) {
emit mustBeHide ( ) ;
}
return ;
}
if ( raise ) {
m_timerHide . stop ( ) ;
if ( ! m_timerShow . isActive ( ) ) {
m_timerShow . start ( ) ;
}
} else if ( ! m_dragEnter & & ! hidingIsBlocked ( ) ) {
m_timerShow . stop ( ) ;
if ( m_hideNow ) {
m_hideNow = false ;
emit mustBeHide ( ) ;
} else if ( ! m_timerHide . isActive ( ) ) {
startTimerHide ( ) ;
}
}
}
void VisibilityManager : : raiseViewTemporarily ( )
{
if ( m_raiseTemporarily )
return ;
m_raiseTemporarily = true ;
m_timerHide . stop ( ) ;
m_timerShow . stop ( ) ;
if ( m_isHidden )
emit mustBeShown ( ) ;
QTimer : : singleShot ( qBound ( 1800 , 2 * m_timerHide . interval ( ) , 3000 ) , this , [ & ] ( ) {
m_raiseTemporarily = false ;
m_hideNow = true ;
updateHiddenState ( ) ;
} ) ;
}
bool VisibilityManager : : isValidMode ( ) const
{
return ( m_mode ! = Types : : None & & m_mode ! = Types : : NormalWindow ) ;
}
2018-12-20 18:59:38 +02:00
void VisibilityManager : : applyActivitiesToHiddenWindows ( const QStringList & activities )
2018-03-28 20:39:52 +03:00
{
2019-04-23 10:54:53 +03:00
if ( m_edgeGhostWindow ) {
2021-06-12 14:18:03 +03:00
m_wm - > setWindowOnActivities ( m_edgeGhostWindow - > trackedWindowId ( ) , activities ) ;
2018-03-28 20:39:52 +03:00
}
2020-01-22 00:11:37 +02:00
if ( m_floatingGapWindow ) {
2021-06-12 14:18:03 +03:00
m_wm - > setWindowOnActivities ( m_floatingGapWindow - > trackedWindowId ( ) , activities ) ;
2020-01-22 00:11:37 +02:00
}
2018-03-28 20:39:52 +03:00
}
2020-07-29 00:13:16 +03:00
void VisibilityManager : : startTimerHide ( const int & msec )
{
if ( msec = = 0 ) {
2020-12-27 13:47:01 +02:00
int secs = m_timerHideInterval ;
if ( ! KWindowSystem : : compositingActive ( ) ) {
//! this is needed in order to give view time to show and
//! for floating case to give time to user to reach the view with its mouse
secs = qMax ( m_timerHideInterval , m_latteView - > screenEdgeMargin ( ) > 0 ? 700 : 200 ) ;
}
m_timerHide . start ( secs ) ;
2020-07-29 00:13:16 +03:00
} else {
m_timerHide . start ( msec ) ;
}
}
2019-04-23 09:58:06 +03:00
void VisibilityManager : : dodgeActive ( )
2016-12-25 09:25:27 +02:00
{
2019-04-23 10:54:53 +03:00
if ( m_raiseTemporarily )
2017-02-12 03:01:12 -05:00
return ;
2018-12-06 16:17:35 +02:00
//!don't send false raiseView signal when containing mouse
2018-12-20 18:59:38 +02:00
if ( m_containsMouse ) {
2018-12-06 16:17:35 +02:00
raiseView ( true ) ;
2017-08-13 13:24:32 +03:00
return ;
}
2019-06-08 17:36:14 +03:00
raiseView ( ! m_latteView - > windowsTracker ( ) - > currentScreen ( ) - > activeWindowTouching ( ) ) ;
2016-12-25 09:25:27 +02:00
}
2019-04-23 09:58:06 +03:00
void VisibilityManager : : dodgeMaximized ( )
2016-12-25 09:25:27 +02:00
{
2019-04-23 10:54:53 +03:00
if ( m_raiseTemporarily )
2017-02-12 03:01:12 -05:00
return ;
2018-12-06 16:17:35 +02:00
//!don't send false raiseView signal when containing mouse
2018-12-20 18:59:38 +02:00
if ( m_containsMouse ) {
2018-12-06 16:17:35 +02:00
raiseView ( true ) ;
2017-08-13 13:24:32 +03:00
return ;
}
2019-06-08 17:36:14 +03:00
raiseView ( ! m_latteView - > windowsTracker ( ) - > currentScreen ( ) - > activeWindowMaximized ( ) ) ;
2016-12-25 09:25:27 +02:00
}
2019-02-07 20:24:52 +02:00
void VisibilityManager : : dodgeAllWindows ( )
2016-12-25 09:25:27 +02:00
{
2019-04-23 10:54:53 +03:00
if ( m_raiseTemporarily )
2017-02-12 03:01:12 -05:00
return ;
2018-12-20 18:59:38 +02:00
if ( m_containsMouse ) {
2018-12-06 16:17:35 +02:00
raiseView ( true ) ;
2020-01-22 00:11:37 +02:00
return ;
2017-08-13 13:24:32 +03:00
}
2019-06-08 17:36:14 +03:00
bool windowIntersects { m_latteView - > windowsTracker ( ) - > currentScreen ( ) - > activeWindowTouching ( ) | | m_latteView - > windowsTracker ( ) - > currentScreen ( ) - > existsWindowTouching ( ) } ;
2017-01-16 14:07:49 -05:00
2019-02-07 20:24:52 +02:00
raiseView ( ! windowIntersects ) ;
2016-12-25 09:25:27 +02:00
}
2018-12-20 18:59:38 +02:00
void VisibilityManager : : saveConfig ( )
2016-12-25 09:25:27 +02:00
{
2018-12-20 18:59:38 +02:00
if ( ! m_latteView - > containment ( ) )
2016-12-30 02:17:38 -05:00
return ;
2017-01-16 14:07:49 -05:00
2018-12-20 18:59:38 +02:00
auto config = m_latteView - > containment ( ) - > config ( ) ;
2017-04-02 00:23:47 -05:00
2019-04-23 10:54:53 +03:00
config . writeEntry ( " enableKWinEdges " , m_enableKWinEdgesFromUser ) ;
2018-12-20 18:59:38 +02:00
config . writeEntry ( " timerShow " , m_timerShow . interval ( ) ) ;
2020-07-29 00:13:16 +03:00
config . writeEntry ( " timerHide " , m_timerHideInterval ) ;
2019-04-23 10:54:53 +03:00
config . writeEntry ( " raiseOnDesktopChange " , m_raiseOnDesktopChange ) ;
config . writeEntry ( " raiseOnActivityChange " , m_raiseOnActivityChange ) ;
2018-03-28 20:39:52 +03:00
2018-12-20 18:59:38 +02:00
m_latteView - > containment ( ) - > configNeedsSaving ( ) ;
2016-12-25 09:25:27 +02:00
}
2018-12-20 18:59:38 +02:00
void VisibilityManager : : restoreConfig ( )
2016-12-25 09:25:27 +02:00
{
2018-12-20 18:59:38 +02:00
if ( ! m_latteView | | ! m_latteView - > containment ( ) ) {
2016-12-30 02:24:04 -05:00
return ;
2018-12-20 18:59:38 +02:00
}
2017-01-16 14:07:49 -05:00
2018-12-20 18:59:38 +02:00
auto config = m_latteView - > containment ( ) - > config ( ) ;
m_timerShow . setInterval ( config . readEntry ( " timerShow " , 0 ) ) ;
2020-07-29 00:13:16 +03:00
m_timerHideInterval = qMax ( HIDEMINIMUMINTERVAL , config . readEntry ( " timerHide " , 700 ) ) ;
2018-12-20 18:59:38 +02:00
emit timerShowChanged ( ) ;
2020-01-19 20:52:14 +02:00
emit timerHideChanged ( ) ;
2017-02-11 00:55:22 -05:00
2019-04-23 10:54:53 +03:00
m_enableKWinEdgesFromUser = config . readEntry ( " enableKWinEdges " , true ) ;
2018-12-20 18:59:38 +02:00
emit enableKWinEdgesChanged ( ) ;
2018-03-28 20:39:52 +03:00
2017-03-25 16:17:41 -05:00
setRaiseOnDesktop ( config . readEntry ( " raiseOnDesktopChange " , false ) ) ;
setRaiseOnActivity ( config . readEntry ( " raiseOnActivityChange " , false ) ) ;
2020-04-22 21:10:17 +03:00
auto storedMode = ( Types : : Visibility ) ( m_latteView - > containment ( ) - > config ( ) . readEntry ( " visibility " , ( int ) ( Types : : DodgeActive ) ) ) ;
2017-04-02 00:23:47 -05:00
2018-12-20 18:59:38 +02:00
if ( storedMode = = Types : : AlwaysVisible ) {
qDebug ( ) < < " Loading visibility mode: Always Visible , on startup... " ;
2018-12-07 18:55:35 +02:00
setMode ( Types : : AlwaysVisible ) ;
2017-02-12 03:01:12 -05:00
} else {
2018-12-20 18:59:38 +02:00
connect ( & m_timerStartUp , & QTimer : : timeout , this , [ & ] ( ) {
2019-05-27 10:57:16 +03:00
if ( ! m_latteView | | ! m_latteView - > containment ( ) ) {
return ;
}
2020-04-22 21:10:17 +03:00
Types : : Visibility fMode = ( Types : : Visibility ) ( m_latteView - > containment ( ) - > config ( ) . readEntry ( " visibility " , ( int ) ( Types : : DodgeActive ) ) ) ;
2018-12-20 18:59:38 +02:00
qDebug ( ) < < " Loading visibility mode: " < < fMode < < " on startup... " ;
setMode ( fMode ) ;
2017-02-11 00:55:22 -05:00
} ) ;
2018-12-20 18:59:38 +02:00
connect ( m_latteView - > containment ( ) , & Plasma : : Containment : : userConfiguringChanged
2019-05-01 21:31:33 +03:00
, this , [ & ] ( bool configuring ) {
2018-12-20 18:59:38 +02:00
if ( configuring & & m_timerStartUp . isActive ( ) )
m_timerStartUp . start ( 100 ) ;
2017-04-02 04:24:49 -05:00
} ) ;
2018-12-20 18:59:38 +02:00
m_timerStartUp . start ( ) ;
2017-02-11 00:55:22 -05:00
}
2017-03-12 04:01:27 -05:00
2018-12-20 18:59:38 +02:00
connect ( m_latteView - > containment ( ) , & Plasma : : Containment : : userConfiguringChanged
2019-05-01 21:31:33 +03:00
, this , [ & ] ( bool configuring ) {
2018-12-20 18:59:38 +02:00
if ( ! configuring ) {
2017-03-12 13:30:54 -05:00
saveConfig ( ) ;
2018-12-20 18:59:38 +02:00
}
2017-03-12 04:01:27 -05:00
} ) ;
2016-12-25 09:25:27 +02:00
}
2018-12-20 18:59:38 +02:00
bool VisibilityManager : : containsMouse ( ) const
2016-12-25 09:25:27 +02:00
{
2018-12-20 18:59:38 +02:00
return m_containsMouse ;
}
void VisibilityManager : : setContainsMouse ( bool contains )
{
if ( m_containsMouse = = contains ) {
2018-11-13 19:06:33 +02:00
return ;
}
2017-01-16 14:07:49 -05:00
2018-12-20 18:59:38 +02:00
m_containsMouse = contains ;
emit containsMouseChanged ( ) ;
2020-01-22 00:11:37 +02:00
}
2017-01-16 14:07:49 -05:00
2020-01-22 00:11:37 +02:00
bool VisibilityManager : : windowContainsMouse ( )
{
return m_containsMouse | | ( m_edgeGhostWindow & & m_edgeGhostWindow - > containsMouse ( ) ) ;
}
void VisibilityManager : : checkMouseInFloatingArea ( )
{
2021-03-04 19:18:42 +02:00
if ( m_isFloatingGapWindowEnabled ) {
2020-01-22 14:06:53 +02:00
if ( ! m_floatingGapWindow ) {
createFloatingGapWindow ( ) ;
}
2020-01-22 00:11:37 +02:00
m_floatingGapWindow - > callAsyncContainsMouse ( ) ;
2018-11-13 19:06:33 +02:00
}
}
2017-01-16 14:07:49 -05:00
2018-12-20 18:59:38 +02:00
void VisibilityManager : : viewEventManager ( QEvent * ev )
2018-11-13 19:06:33 +02:00
{
switch ( ev - > type ( ) ) {
2019-05-01 21:31:33 +03:00
case QEvent : : Enter :
setContainsMouse ( true ) ;
break ;
2017-01-16 14:07:49 -05:00
2019-05-01 21:31:33 +03:00
case QEvent : : Leave :
2019-07-10 16:23:06 +03:00
m_dragEnter = false ;
2019-05-01 21:31:33 +03:00
setContainsMouse ( false ) ;
break ;
2017-01-16 14:07:49 -05:00
2019-05-01 21:31:33 +03:00
case QEvent : : DragEnter :
m_dragEnter = true ;
2017-03-12 15:14:30 -05:00
2020-07-28 15:49:55 +00:00
if ( m_isHidden & & ! isSidebar ( ) ) {
2019-05-01 21:31:33 +03:00
emit mustBeShown ( ) ;
2019-07-10 16:23:06 +03:00
}
2017-03-12 13:09:38 -05:00
2019-05-01 21:31:33 +03:00
break ;
2017-01-16 14:07:49 -05:00
2019-05-01 21:31:33 +03:00
case QEvent : : DragLeave :
case QEvent : : Drop :
m_dragEnter = false ;
updateHiddenState ( ) ;
break ;
2017-01-16 14:07:49 -05:00
2019-05-01 21:31:33 +03:00
default :
break ;
2016-12-25 09:25:27 +02:00
}
}
2017-12-24 20:54:45 +02:00
2018-03-28 20:39:52 +03:00
//! KWin Edges Support functions
2018-12-20 18:59:38 +02:00
bool VisibilityManager : : enableKWinEdges ( ) const
{
2019-04-23 10:54:53 +03:00
return m_enableKWinEdgesFromUser ;
2018-12-20 18:59:38 +02:00
}
void VisibilityManager : : setEnableKWinEdges ( bool enable )
2018-03-28 20:39:52 +03:00
{
2019-04-23 10:54:53 +03:00
if ( m_enableKWinEdgesFromUser = = enable ) {
2018-03-28 20:39:52 +03:00
return ;
}
2019-04-23 10:54:53 +03:00
m_enableKWinEdgesFromUser = enable ;
2018-03-28 20:39:52 +03:00
2018-12-20 18:59:38 +02:00
emit enableKWinEdgesChanged ( ) ;
2018-03-28 20:39:52 +03:00
}
2018-12-20 18:59:38 +02:00
void VisibilityManager : : updateKWinEdgesSupport ( )
2018-03-28 20:39:52 +03:00
{
2019-06-20 10:25:18 +03:00
if ( ( m_mode = = Types : : AutoHide
2019-07-30 18:00:33 +03:00
| | m_mode = = Types : : DodgeActive
| | m_mode = = Types : : DodgeAllWindows
2019-12-27 14:20:31 +02:00
| | m_mode = = Types : : DodgeMaximized )
& & ! m_latteView - > byPassWM ( ) ) {
2020-03-19 13:35:31 +02:00
if ( m_enableKWinEdgesFromUser | | m_latteView - > behaveAsPlasmaPanel ( ) ) {
2018-03-28 20:39:52 +03:00
createEdgeGhostWindow ( ) ;
2019-04-23 10:54:53 +03:00
} else if ( ! m_enableKWinEdgesFromUser ) {
2018-03-28 20:39:52 +03:00
deleteEdgeGhostWindow ( ) ;
}
2019-12-27 14:20:31 +02:00
} else if ( m_mode = = Types : : WindowsCanCover ) {
createEdgeGhostWindow ( ) ;
2019-12-27 13:38:22 +02:00
} else {
2018-03-28 20:39:52 +03:00
deleteEdgeGhostWindow ( ) ;
}
}
2021-03-04 19:18:42 +02:00
void VisibilityManager : : onIsFloatingGapWindowEnabledChanged ( )
2020-07-29 00:58:21 +03:00
{
2021-03-04 19:18:42 +02:00
if ( m_isFloatingGapWindowEnabled ) {
createFloatingGapWindow ( ) ;
2020-07-29 00:58:21 +03:00
} else {
deleteFloatingGapWindow ( ) ;
}
}
2018-12-20 18:59:38 +02:00
void VisibilityManager : : createEdgeGhostWindow ( )
2018-03-28 20:39:52 +03:00
{
2019-04-23 10:54:53 +03:00
if ( ! m_edgeGhostWindow ) {
m_edgeGhostWindow = new ScreenEdgeGhostWindow ( m_latteView ) ;
2018-03-28 20:39:52 +03:00
2020-05-12 14:45:31 +03:00
connect ( m_edgeGhostWindow , & ScreenEdgeGhostWindow : : containsMouseChanged , this , [ = ] ( bool contains ) {
2018-11-13 19:06:33 +02:00
if ( contains ) {
2020-01-22 00:11:37 +02:00
raiseView ( true ) ;
2019-02-24 19:09:48 +02:00
} else {
2020-05-12 14:45:31 +03:00
m_timerShow . stop ( ) ;
updateGhostWindowState ( ) ;
2018-11-13 19:06:33 +02:00
}
2018-03-28 20:39:52 +03:00
} ) ;
2019-07-10 16:23:06 +03:00
connect ( m_edgeGhostWindow , & ScreenEdgeGhostWindow : : dragEntered , this , [ & ] ( ) {
if ( m_isHidden ) {
emit mustBeShown ( ) ;
}
} ) ;
2019-05-11 15:43:10 +03:00
m_connectionsKWinEdges [ 0 ] = connect ( m_wm , & WindowSystem : : AbstractWindowInterface : : currentActivityChanged ,
2019-05-01 21:31:33 +03:00
this , [ & ] ( ) {
2020-04-24 12:31:03 +03:00
bool inCurrentLayout = ( m_corona - > layoutsManager ( ) - > memoryUsage ( ) = = MemoryUsage : : SingleLayout | |
( m_corona - > layoutsManager ( ) - > memoryUsage ( ) = = MemoryUsage : : MultipleLayouts
2021-01-19 21:14:09 +02:00
& & m_latteView - > layout ( ) & & ! m_latteView - > positioner ( ) - > inRelocationAnimation ( )
2019-07-16 14:06:26 +03:00
& & m_latteView - > layout ( ) - > isCurrent ( ) ) ) ;
2018-03-28 20:39:52 +03:00
2019-04-23 10:54:53 +03:00
if ( m_edgeGhostWindow ) {
2018-03-28 20:39:52 +03:00
if ( inCurrentLayout ) {
2020-01-03 13:32:08 +02:00
m_wm - > setActiveEdge ( m_edgeGhostWindow , m_isHidden ) ;
2018-03-28 20:39:52 +03:00
} else {
2020-01-03 13:32:08 +02:00
m_wm - > setActiveEdge ( m_edgeGhostWindow , false ) ;
2018-03-28 20:39:52 +03:00
}
}
} ) ;
2018-12-20 18:59:38 +02:00
emit supportsKWinEdgesChanged ( ) ;
2018-03-28 20:39:52 +03:00
}
}
2018-12-20 18:59:38 +02:00
void VisibilityManager : : deleteEdgeGhostWindow ( )
2018-03-28 20:39:52 +03:00
{
2019-04-23 10:54:53 +03:00
if ( m_edgeGhostWindow ) {
m_edgeGhostWindow - > deleteLater ( ) ;
m_edgeGhostWindow = nullptr ;
2018-03-28 20:39:52 +03:00
2019-04-23 10:54:53 +03:00
for ( auto & c : m_connectionsKWinEdges ) {
2018-03-28 20:39:52 +03:00
disconnect ( c ) ;
}
2018-12-20 18:59:38 +02:00
emit supportsKWinEdgesChanged ( ) ;
2018-03-28 20:39:52 +03:00
}
}
2018-10-28 10:03:22 +02:00
2020-01-22 00:11:37 +02:00
void VisibilityManager : : createFloatingGapWindow ( )
{
if ( ! m_floatingGapWindow ) {
m_floatingGapWindow = new FloatingGapWindow ( m_latteView ) ;
connect ( m_floatingGapWindow , & FloatingGapWindow : : asyncContainsMouseChanged , this , [ = ] ( bool contains ) {
if ( contains ) {
2021-03-04 19:18:42 +02:00
if ( m_isFloatingGapWindowEnabled & & ! m_isHidden ) {
2020-01-22 00:11:37 +02:00
//! immediate call after contains mouse checks for mouse in sensitive floating areas
updateHiddenState ( ) ;
}
} else {
2021-03-04 19:18:42 +02:00
if ( m_isFloatingGapWindowEnabled & & ! m_isHidden ) {
2020-01-22 00:11:37 +02:00
//! immediate call after contains mouse checks for mouse in sensitive floating areas
emit mustBeHide ( ) ;
}
}
} ) ;
}
}
void VisibilityManager : : deleteFloatingGapWindow ( )
{
if ( m_floatingGapWindow ) {
m_floatingGapWindow - > deleteLater ( ) ;
m_floatingGapWindow = nullptr ;
}
}
bool VisibilityManager : : supportsFloatingGap ( ) const
{
return ( m_floatingGapWindow ! = nullptr ) ;
}
2016-12-29 00:40:35 -05:00
//! END: VisibilityManager implementation
2018-10-28 10:03:22 +02:00
2016-12-25 09:25:27 +02:00
}
2018-12-09 00:29:35 +02:00
}