2019-05-11 03:11:50 +03:00
/*
2021-05-27 15:01:00 +00:00
SPDX - FileCopyrightText : 2019 Michail Vourlakos < mvourlakos @ gmail . com >
SPDX - License - Identifier : GPL - 2.0 - or - later
2019-05-11 03:11:50 +03:00
*/
# include "synchronizer.h"
//! local
2021-06-12 15:23:29 +03:00
# include <config-latte.h>
2019-05-11 03:11:50 +03:00
# include "importer.h"
# include "manager.h"
2020-04-24 12:31:03 +03:00
# include "../apptypes.h"
2020-08-25 18:07:24 +03:00
# include "../data/layoutdata.h"
2019-05-11 03:11:50 +03:00
# include "../lattecorona.h"
# include "../layout/centrallayout.h"
# include "../layout/genericlayout.h"
# include "../settings/universalsettings.h"
2020-08-13 20:42:38 +03:00
# include "../templates/templatesmanager.h"
2019-05-11 03:11:50 +03:00
# include "../view/view.h"
// Qt
# include <QDir>
# include <QFile>
2021-05-21 17:54:43 +00:00
# include <QStringList>
2019-05-11 03:11:50 +03:00
2019-06-15 21:38:07 +03:00
// Plasma
# include <Plasma/Containment>
2019-05-11 03:11:50 +03:00
// KDE
# include <KActivities/Consumer>
# include <KActivities/Controller>
2020-08-03 18:13:37 +03:00
# include <KWindowSystem>
2019-05-11 03:11:50 +03:00
2020-08-30 14:34:56 +03:00
# define LAYOUTSINITINTERVAL 350
2019-05-11 03:11:50 +03:00
namespace Latte {
namespace Layouts {
Synchronizer : : Synchronizer ( QObject * parent )
: QObject ( parent ) ,
m_activitiesController ( new KActivities : : Controller )
{
m_manager = qobject_cast < Manager * > ( parent ) ;
2020-08-29 23:37:52 +03:00
connect ( this , & Synchronizer : : layoutsChanged , this , & Synchronizer : : reloadAssignedLayouts ) ;
2020-08-26 20:54:44 +03:00
//! KWin update Disabled Borders
connect ( this , & Synchronizer : : centralLayoutsChanged , this , & Synchronizer : : updateKWinDisabledBorders ) ;
connect ( m_manager - > corona ( ) - > universalSettings ( ) , & UniversalSettings : : canDisableBordersChanged , this , & Synchronizer : : updateKWinDisabledBorders ) ;
2019-05-11 03:11:50 +03:00
//! KActivities tracking
2020-08-31 10:43:37 +03:00
connect ( m_manager - > corona ( ) - > activitiesConsumer ( ) , & KActivities : : Consumer : : activityRemoved ,
this , & Synchronizer : : onActivityRemoved ) ;
2019-05-11 03:11:50 +03:00
connect ( m_manager - > corona ( ) - > activitiesConsumer ( ) , & KActivities : : Consumer : : currentActivityChanged ,
2020-08-26 20:54:44 +03:00
this , & Synchronizer : : onCurrentActivityChanged ) ;
2019-05-11 03:11:50 +03:00
connect ( m_manager - > corona ( ) - > activitiesConsumer ( ) , & KActivities : : Consumer : : runningActivitiesChanged ,
this , [ & ] ( ) {
2020-04-24 12:31:03 +03:00
if ( m_manager - > memoryUsage ( ) = = MemoryUsage : : MultipleLayouts ) {
2019-05-11 03:11:50 +03:00
syncMultipleLayoutsToActivities ( ) ;
}
} ) ;
}
Synchronizer : : ~ Synchronizer ( )
{
m_activitiesController - > deleteLater ( ) ;
}
2020-03-16 18:17:17 +02:00
KActivities : : Controller * Synchronizer : : activitiesController ( ) const
{
return m_activitiesController ;
}
2019-05-11 03:11:50 +03:00
bool Synchronizer : : latteViewExists ( Latte : : View * view ) const
{
for ( const auto layout : m_centralLayouts ) {
for ( const auto & v : layout - > latteViews ( ) ) {
if ( v = = view ) {
return true ;
}
}
}
return false ;
}
bool Synchronizer : : layoutExists ( QString layoutName ) const
{
2020-08-29 20:42:15 +03:00
return m_layouts . containsName ( layoutName ) ;
2019-05-11 03:11:50 +03:00
}
2020-08-25 18:07:24 +03:00
bool Synchronizer : : isAssigned ( QString layoutName ) const
2019-05-11 03:11:50 +03:00
{
2020-08-25 18:07:24 +03:00
for ( auto activityid : m_assignedLayouts . keys ( ) ) {
if ( m_assignedLayouts [ activityid ] . contains ( layoutName ) ) {
return true ;
}
}
return false ;
2019-05-11 03:11:50 +03:00
}
int Synchronizer : : centralLayoutPos ( QString id ) const
{
for ( int i = 0 ; i < m_centralLayouts . size ( ) ; + + i ) {
CentralLayout * layout = m_centralLayouts . at ( i ) ;
if ( layout - > name ( ) = = id ) {
return i ;
}
}
return - 1 ;
}
QString Synchronizer : : layoutPath ( QString layoutName )
{
2020-08-14 09:33:39 +03:00
QString path = Layouts : : Importer : : layoutUserFilePath ( layoutName ) ;
2019-05-11 03:11:50 +03:00
if ( ! QFile ( path ) . exists ( ) ) {
path = " " ;
}
return path ;
}
QStringList Synchronizer : : activities ( )
{
return m_manager - > corona ( ) - > activitiesConsumer ( ) - > activities ( ) ;
}
2020-08-27 16:11:19 +03:00
QStringList Synchronizer : : freeActivities ( )
{
QStringList frees = activities ( ) ;
for ( auto assigned : m_assignedLayouts . keys ( ) ) {
frees . removeAll ( assigned ) ;
}
return frees ;
}
2019-05-11 03:11:50 +03:00
QStringList Synchronizer : : runningActivities ( )
2021-06-12 15:23:29 +03:00
{
2019-05-11 03:11:50 +03:00
return m_manager - > corona ( ) - > activitiesConsumer ( ) - > runningActivities ( ) ;
}
2020-08-27 16:11:19 +03:00
QStringList Synchronizer : : freeRunningActivities ( )
2019-05-11 03:11:50 +03:00
{
2020-03-16 11:02:17 +02:00
QStringList fActivities ;
2019-05-11 03:11:50 +03:00
2020-07-12 15:33:40 +03:00
for ( const auto & activity : runningActivities ( ) ) {
2020-03-16 19:41:18 +02:00
if ( ! m_assignedLayouts . contains ( activity ) ) {
2020-03-16 11:02:17 +02:00
fActivities . append ( activity ) ;
2019-05-11 03:11:50 +03:00
}
}
2020-03-16 11:02:17 +02:00
return fActivities ;
2019-05-11 03:11:50 +03:00
}
2020-08-30 21:28:22 +03:00
QStringList Synchronizer : : validActivities ( const QStringList & layoutActivities )
{
QStringList valids ;
QStringList allactivities = activities ( ) ;
for ( auto activity : layoutActivities ) {
if ( allactivities . contains ( activity ) ) {
valids < < activity ;
}
}
return valids ;
}
2019-05-11 03:11:50 +03:00
QStringList Synchronizer : : centralLayoutsNames ( )
{
QStringList names ;
2020-04-24 12:31:03 +03:00
if ( m_manager - > memoryUsage ( ) = = MemoryUsage : : SingleLayout ) {
2020-08-26 20:54:44 +03:00
names < < m_centralLayouts . at ( 0 ) - > name ( ) ;
2019-05-11 03:11:50 +03:00
} else {
for ( int i = 0 ; i < m_centralLayouts . size ( ) ; + + i ) {
CentralLayout * layout = m_centralLayouts . at ( i ) ;
names < < layout - > name ( ) ;
}
}
return names ;
}
2020-08-27 17:10:13 +03:00
QStringList Synchronizer : : currentLayoutsNames ( ) const
{
QList < CentralLayout * > currents = currentLayouts ( ) ;
QStringList currentNames ;
for ( int i = 0 ; i < currents . size ( ) ; + + i ) {
CentralLayout * layout = currents . at ( i ) ;
currentNames < < layout - > name ( ) ;
}
return currentNames ;
}
2019-05-11 03:11:50 +03:00
QStringList Synchronizer : : layouts ( ) const
{
2020-08-29 20:42:15 +03:00
return m_layouts . names ( ) ;
2019-05-11 03:11:50 +03:00
}
QStringList Synchronizer : : menuLayouts ( ) const
{
2020-08-29 20:42:15 +03:00
QStringList menulayouts ;
for ( int i = 0 ; i < m_layouts . rowCount ( ) ; + + i ) {
if ( ! m_layouts [ i ] . isShownInMenu ) {
continue ;
}
2020-08-30 20:32:13 +03:00
menulayouts < < m_layouts [ i ] . name ;
2020-08-29 20:42:15 +03:00
}
2019-05-11 03:11:50 +03:00
2020-08-27 17:10:13 +03:00
for ( const auto layout : m_centralLayouts ) {
2020-08-29 20:42:15 +03:00
if ( ! menulayouts . contains ( layout - > name ( ) ) ) {
menulayouts . prepend ( layout - > name ( ) ) ;
2019-05-11 03:11:50 +03:00
}
}
2021-05-22 14:10:39 +03:00
menulayouts . sort ( Qt : : CaseInsensitive ) ;
2020-08-29 20:42:15 +03:00
return menulayouts ;
}
2021-02-14 20:11:25 +02:00
void Synchronizer : : setIsSingleLayoutInDeprecatedRenaming ( const bool & enabled )
{
m_isSingleLayoutInDeprecatedRenaming = enabled ;
}
2021-05-15 13:31:56 +03:00
Data : : Layout Synchronizer : : data ( const QString & storedLayoutName ) const
{
Data : : Layout l ;
if ( m_layouts . containsName ( storedLayoutName ) ) {
QString lid = m_layouts . idForName ( storedLayoutName ) ;
return m_layouts [ lid ] ;
}
return l ;
}
2020-08-29 20:42:15 +03:00
Data : : LayoutsTable Synchronizer : : layoutsTable ( ) const
{
return m_layouts ;
2019-05-11 03:11:50 +03:00
}
2020-08-29 20:42:15 +03:00
void Synchronizer : : setLayoutsTable ( const Data : : LayoutsTable & table )
2019-05-11 03:11:50 +03:00
{
2020-08-29 20:42:15 +03:00
if ( m_layouts = = table ) {
2019-05-11 03:11:50 +03:00
return ;
}
2020-08-29 20:42:15 +03:00
m_layouts = table ;
emit layoutsChanged ( ) ;
2019-05-11 03:11:50 +03:00
}
2020-08-29 23:37:52 +03:00
void Synchronizer : : updateLayoutsTable ( )
{
for ( int i = 0 ; i < m_centralLayouts . size ( ) ; + + i ) {
CentralLayout * layout = m_centralLayouts . at ( i ) ;
if ( m_layouts . containsId ( layout - > file ( ) ) ) {
m_layouts [ layout - > file ( ) ] = layout - > data ( ) ;
}
}
for ( int i = 0 ; i < m_layouts . rowCount ( ) ; + + i ) {
2021-04-30 01:01:31 +03:00
if ( ( m_layouts [ i ] . errors > 0 | | m_layouts [ i ] . warnings > 0 ) & & ! m_layouts [ i ] . isActive ) {
2020-08-29 23:37:52 +03:00
CentralLayout central ( this , m_layouts [ i ] . id ) ;
2021-04-30 01:01:31 +03:00
m_layouts [ i ] . errors = central . errors ( ) . count ( ) ;
m_layouts [ i ] . warnings = central . warnings ( ) . count ( ) ;
2020-08-29 23:37:52 +03:00
}
}
}
2020-08-25 22:15:39 +03:00
CentralLayout * Synchronizer : : centralLayout ( QString layoutname ) const
2019-05-11 03:11:50 +03:00
{
for ( int i = 0 ; i < m_centralLayouts . size ( ) ; + + i ) {
CentralLayout * layout = m_centralLayouts . at ( i ) ;
2020-08-25 22:15:39 +03:00
if ( layout - > name ( ) = = layoutname ) {
2019-05-11 03:11:50 +03:00
return layout ;
}
}
return nullptr ;
}
2020-08-25 19:30:33 +03:00
QList < CentralLayout * > Synchronizer : : currentLayouts ( ) const
2019-05-11 03:11:50 +03:00
{
2020-08-25 19:30:33 +03:00
QList < CentralLayout * > layouts ;
2020-08-25 22:15:39 +03:00
2020-04-24 12:31:03 +03:00
if ( m_manager - > memoryUsage ( ) = = MemoryUsage : : SingleLayout ) {
2020-08-25 19:30:33 +03:00
layouts < < m_centralLayouts . at ( 0 ) ;
2019-05-11 03:11:50 +03:00
} else {
for ( auto layout : m_centralLayouts ) {
2020-08-25 19:30:33 +03:00
if ( layout - > isOnAllActivities ( ) | | layout - > appliedActivities ( ) . contains ( m_manager - > corona ( ) - > activitiesConsumer ( ) - > currentActivity ( ) ) ) {
layouts < < layout ;
2019-05-11 03:11:50 +03:00
}
}
2020-08-25 19:30:33 +03:00
}
2019-05-11 03:11:50 +03:00
2020-08-25 19:30:33 +03:00
return layouts ;
}
2020-08-25 22:15:39 +03:00
QList < CentralLayout * > Synchronizer : : centralLayoutsForActivity ( const QString activityid ) const
{
QList < CentralLayout * > layouts ;
2020-10-25 17:00:17 +02:00
if ( m_manager - > memoryUsage ( ) = = MemoryUsage : : SingleLayout & & m_centralLayouts . count ( ) > = 1 ) {
2020-08-25 22:15:39 +03:00
layouts < < m_centralLayouts . at ( 0 ) ;
} else {
for ( auto layout : m_centralLayouts ) {
if ( layout - > isOnAllActivities ( ) | | layout - > appliedActivities ( ) . contains ( activityid ) ) {
layouts < < layout ;
}
}
}
return layouts ;
}
2020-08-25 19:30:33 +03:00
QList < Latte : : View * > Synchronizer : : currentViews ( ) const
{
QList < Latte : : View * > views ;
for ( auto layout : currentLayouts ( ) ) {
views < < layout - > latteViews ( ) ;
2019-05-11 03:11:50 +03:00
}
2020-08-25 19:30:33 +03:00
return views ;
}
QList < Latte : : View * > Synchronizer : : currentViewsWithPlasmaShortcuts ( ) const
{
QList < Latte : : View * > views ;
for ( auto layout : currentLayouts ( ) ) {
views < < layout - > viewsWithPlasmaShortcuts ( ) ;
}
return views ;
}
QList < Latte : : View * > Synchronizer : : sortedCurrentViews ( ) const
{
QList < Latte : : View * > views = currentViews ( ) ;
return Layout : : GenericLayout : : sortedLatteViews ( views ) ;
2019-05-11 03:11:50 +03:00
}
2020-08-25 22:15:39 +03:00
QList < Latte : : View * > Synchronizer : : viewsBasedOnActivityId ( const QString & id ) const
{
QList < Latte : : View * > views ;
for ( auto layout : centralLayoutsForActivity ( id ) ) {
2020-10-25 17:00:17 +02:00
if ( m_centralLayouts . contains ( layout ) ) {
views < < layout - > latteViews ( ) ;
}
2020-08-25 22:15:39 +03:00
}
return views ;
}
Layout : : GenericLayout * Synchronizer : : layout ( QString layoutname ) const
2019-05-11 03:11:50 +03:00
{
2020-08-25 22:15:39 +03:00
Layout : : GenericLayout * l = centralLayout ( layoutname ) ;
2019-05-11 03:11:50 +03:00
return l ;
}
2021-04-13 10:56:15 +03:00
int Synchronizer : : screenForContainment ( Plasma : : Containment * containment )
{
for ( auto layout : m_centralLayouts ) {
if ( layout - > contains ( containment ) ) {
return layout - > screenForContainment ( containment ) ;
}
}
return - 1 ;
}
2020-08-25 19:30:33 +03:00
Latte : : View * Synchronizer : : viewForContainment ( uint id )
{
for ( auto layout : m_centralLayouts ) {
Latte : : View * view = layout - > viewForContainment ( id ) ;
if ( view ) {
return view ;
}
}
return nullptr ;
}
2019-06-15 21:38:07 +03:00
Latte : : View * Synchronizer : : viewForContainment ( Plasma : : Containment * containment )
{
for ( auto layout : m_centralLayouts ) {
Latte : : View * view = layout - > viewForContainment ( containment ) ;
if ( view ) {
return view ;
}
}
return nullptr ;
}
2019-05-11 03:11:50 +03:00
void Synchronizer : : addLayout ( CentralLayout * layout )
{
if ( ! m_centralLayouts . contains ( layout ) ) {
m_centralLayouts . append ( layout ) ;
layout - > initToCorona ( m_manager - > corona ( ) ) ;
}
}
2020-08-31 10:43:37 +03:00
void Synchronizer : : onActivityRemoved ( const QString & activityid )
{
if ( ! m_assignedLayouts . contains ( activityid ) ) {
return ;
}
//! remove any other explicit set layouts for the current activity
QStringList explicits = m_assignedLayouts [ activityid ] ;
for ( auto explicitlayoutname : explicits ) {
QString explicitlayoutid = m_layouts . idForName ( explicitlayoutname ) ;
m_layouts [ explicitlayoutid ] . activities . removeAll ( activityid ) ;
m_manager - > setOnActivities ( explicitlayoutname , m_layouts [ explicitlayoutid ] . activities ) ;
emit layoutActivitiesChanged ( m_layouts [ explicitlayoutid ] ) ;
}
QStringList freelayoutnames ;
if ( m_assignedLayouts . contains ( Data : : Layout : : FREEACTIVITIESID ) ) {
freelayoutnames = m_assignedLayouts [ Data : : Layout : : FREEACTIVITIESID ] ;
}
reloadAssignedLayouts ( ) ;
for ( auto freelayoutname : freelayoutnames ) {
//! inform free activities layouts that their activities probably changed
CentralLayout * central = centralLayout ( freelayoutname ) ;
if ( central ) {
emit central - > activitiesChanged ( ) ;
}
}
}
void Synchronizer : : onCurrentActivityChanged ( const QString & activityid )
2019-05-11 03:11:50 +03:00
{
2020-08-25 18:07:24 +03:00
if ( m_manager - > memoryUsage ( ) = = MemoryUsage : : MultipleLayouts ) {
2020-08-26 20:54:44 +03:00
updateKWinDisabledBorders ( ) ;
2019-05-11 03:11:50 +03:00
}
}
void Synchronizer : : hideAllViews ( )
{
for ( const auto layout : m_centralLayouts ) {
emit currentLayoutIsSwitching ( layout - > name ( ) ) ;
}
}
void Synchronizer : : pauseLayout ( QString layoutName )
{
2021-05-04 09:18:35 +03:00
if ( m_manager - > memoryUsage ( ) = = MemoryUsage : : MultipleLayouts ) {
2019-05-11 03:11:50 +03:00
CentralLayout * layout = centralLayout ( layoutName ) ;
2020-08-31 21:28:07 +03:00
if ( layout - > isOnAllActivities ( ) ) {
return ;
}
QStringList appliedactivities = layout - > appliedActivities ( ) ;
if ( layout & & ! appliedactivities . isEmpty ( ) ) {
2019-05-11 03:11:50 +03:00
int i = 0 ;
2020-08-31 21:28:07 +03:00
for ( const auto & activityid : appliedactivities ) {
2019-05-11 03:11:50 +03:00
//! Stopping the activities must be done asynchronous because otherwise
//! the activity manager cant close multiple activities
2020-08-31 21:28:07 +03:00
QTimer : : singleShot ( i * 1000 , [ this , activityid ] ( ) {
m_activitiesController - > stopActivity ( activityid ) ;
2019-05-11 03:11:50 +03:00
} ) ;
i = i + 1 ;
}
}
}
}
void Synchronizer : : syncActiveLayoutsToOriginalFiles ( )
{
2020-04-24 12:31:03 +03:00
if ( m_manager - > memoryUsage ( ) = = MemoryUsage : : MultipleLayouts ) {
2019-05-11 03:11:50 +03:00
for ( const auto layout : m_centralLayouts ) {
layout - > syncToLayoutFile ( ) ;
}
}
}
void Synchronizer : : syncLatteViewsToScreens ( )
{
for ( const auto layout : m_centralLayouts ) {
layout - > syncLatteViewsToScreens ( ) ;
}
}
void Synchronizer : : unloadCentralLayout ( CentralLayout * layout )
{
int pos = m_centralLayouts . indexOf ( layout ) ;
if ( pos > = 0 ) {
2020-10-25 17:00:17 +02:00
CentralLayout * central = m_centralLayouts . takeAt ( pos ) ;
2019-05-11 03:11:50 +03:00
if ( m_multipleModeInitialized ) {
central - > syncToLayoutFile ( true ) ;
}
central - > unloadLatteViews ( ) ;
2019-11-13 16:21:00 +02:00
central - > unloadContainments ( ) ;
2019-05-11 03:11:50 +03:00
if ( m_multipleModeInitialized ) {
m_manager - > clearUnloadedContainmentsFromLinkedFile ( central - > unloadedContainmentsIds ( ) , true ) ;
}
delete central ;
}
}
2020-08-29 20:42:15 +03:00
void Synchronizer : : initLayouts ( )
2019-05-11 03:11:50 +03:00
{
m_layouts . clear ( ) ;
2020-08-14 09:33:39 +03:00
QDir layoutDir ( Layouts : : Importer : : layoutUserDir ( ) ) ;
2019-05-11 03:11:50 +03:00
QStringList filter ;
filter . append ( QString ( " *.layout.latte " ) ) ;
QStringList files = layoutDir . entryList ( filter , QDir : : Files | QDir : : NoSymLinks ) ;
for ( const auto & layout : files ) {
2020-08-14 09:08:01 +03:00
if ( layout . contains ( Layout : : MULTIPLELAYOUTSHIDDENNAME ) ) {
2019-08-18 19:59:09 +03:00
//! IMPORTANT: DON'T ADD MultipleLayouts hidden file in layouts list
2019-05-11 03:11:50 +03:00
continue ;
}
2020-08-13 21:28:52 +03:00
QString layoutpath = layoutDir . absolutePath ( ) + " / " + layout ;
onLayoutAdded ( layoutpath ) ;
}
2019-05-11 03:11:50 +03:00
2020-08-13 21:28:52 +03:00
emit layoutsChanged ( ) ;
2020-08-13 22:23:59 +03:00
if ( ! m_isLoaded ) {
m_isLoaded = true ;
connect ( m_manager - > corona ( ) - > templatesManager ( ) , & Latte : : Templates : : Manager : : newLayoutAdded , this , & Synchronizer : : onLayoutAdded ) ;
2020-08-29 20:42:15 +03:00
connect ( m_manager - > importer ( ) , & Latte : : Layouts : : Importer : : newLayoutAdded , this , & Synchronizer : : onLayoutAdded ) ;
2020-08-13 22:23:59 +03:00
}
2020-08-13 21:28:52 +03:00
}
2019-05-11 03:11:50 +03:00
2020-08-13 21:28:52 +03:00
void Synchronizer : : onLayoutAdded ( const QString & layout )
{
2020-08-30 21:28:22 +03:00
CentralLayout centrallayout ( this , layout ) ;
m_layouts . insertBasedOnName ( centrallayout . data ( ) ) ;
2019-05-11 03:11:50 +03:00
2020-08-13 22:23:59 +03:00
if ( m_isLoaded ) {
emit layoutsChanged ( ) ;
}
2019-05-11 03:11:50 +03:00
}
2020-08-29 23:37:52 +03:00
void Synchronizer : : reloadAssignedLayouts ( )
{
m_assignedLayouts . clear ( ) ;
for ( int i = 0 ; i < m_layouts . rowCount ( ) ; + + i ) {
for ( const auto & activity : m_layouts [ i ] . activities ) {
if ( m_assignedLayouts . contains ( activity ) ) {
m_assignedLayouts [ activity ] < < m_layouts [ i ] . name ;
} else {
m_assignedLayouts [ activity ] = QStringList ( m_layouts [ i ] . name ) ;
}
}
}
}
2019-05-11 03:11:50 +03:00
void Synchronizer : : unloadLayouts ( )
{
//! Unload all CentralLayouts
while ( ! m_centralLayouts . isEmpty ( ) ) {
CentralLayout * layout = m_centralLayouts . at ( 0 ) ;
unloadCentralLayout ( layout ) ;
}
m_multipleModeInitialized = false ;
}
2020-08-30 14:04:04 +03:00
bool Synchronizer : : memoryInitialized ( ) const
2019-05-11 03:11:50 +03:00
{
2020-08-30 14:04:04 +03:00
return ( ( m_manager - > memoryUsage ( ) = = MemoryUsage : : SingleLayout & & m_centralLayouts . size ( ) > 0 )
| | ( m_manager - > memoryUsage ( ) = = MemoryUsage : : MultipleLayouts & & m_multipleModeInitialized ) ) ;
}
2020-08-27 17:10:13 +03:00
2020-08-30 14:04:04 +03:00
bool Synchronizer : : initSingleMode ( QString layoutName )
{
QString layoutpath = layoutName . isEmpty ( ) ? layoutPath ( m_manager - > corona ( ) - > universalSettings ( ) - > singleModeLayoutName ( ) ) : layoutPath ( layoutName ) ;
2019-05-11 03:11:50 +03:00
2020-08-30 14:04:04 +03:00
if ( layoutpath . isEmpty ( ) ) {
qDebug ( ) < < " Layout : " < < layoutName < < " was not found... " ;
return false ;
}
2020-08-28 19:03:23 +03:00
2020-08-30 14:04:04 +03:00
if ( m_centralLayouts . size ( ) > 0 ) {
emit currentLayoutIsSwitching ( m_centralLayouts [ 0 ] - > name ( ) ) ;
}
2019-05-11 03:11:50 +03:00
2020-08-30 14:04:04 +03:00
//! this code must be called asynchronously because it can create crashes otherwise.
//! Tasks plasmoid case that triggers layouts switching through its context menu
2020-08-30 14:34:56 +03:00
QTimer : : singleShot ( LAYOUTSINITINTERVAL , [ this , layoutName , layoutpath ] ( ) {
2020-08-30 14:04:04 +03:00
qDebug ( ) < < " ... initializing layout in single mode : " < < layoutName < < " - " < < layoutpath ;
unloadLayouts ( ) ;
//! load the main layout/corona file
CentralLayout * newLayout = new CentralLayout ( this , layoutpath , layoutName ) ;
addLayout ( newLayout ) ;
m_manager - > loadLatteLayout ( layoutpath ) ;
emit centralLayoutsChanged ( ) ;
2021-02-14 20:11:25 +02:00
if ( m_isSingleLayoutInDeprecatedRenaming ) {
QString deprecatedlayoutpath = layoutPath ( m_manager - > corona ( ) - > universalSettings ( ) - > singleModeLayoutName ( ) ) ;
if ( ! deprecatedlayoutpath . isEmpty ( ) ) {
qDebug ( ) < < " Removing Deprecated single layout after renaming:: " < < m_manager - > corona ( ) - > universalSettings ( ) - > singleModeLayoutName ( ) ;
QFile ( deprecatedlayoutpath ) . remove ( ) ;
}
m_isSingleLayoutInDeprecatedRenaming = false ;
}
2020-08-30 14:04:04 +03:00
m_manager - > corona ( ) - > universalSettings ( ) - > setSingleModeLayoutName ( layoutName ) ;
} ) ;
return true ;
}
bool Synchronizer : : initMultipleMode ( QString layoutName )
{
if ( m_multipleModeInitialized ) {
return false ;
2019-05-11 03:11:50 +03:00
}
2020-08-30 14:04:04 +03:00
for ( const auto layout : m_centralLayouts ) {
emit currentLayoutIsSwitching ( layout - > name ( ) ) ;
2019-05-11 03:11:50 +03:00
}
2020-08-30 14:04:04 +03:00
//! this code must be called asynchronously because it can create crashes otherwise.
//! Tasks plasmoid case that triggers layouts switching through its context menu
2020-08-30 14:34:56 +03:00
QTimer : : singleShot ( LAYOUTSINITINTERVAL , [ this , layoutName ] ( ) {
2020-08-30 14:04:04 +03:00
qDebug ( ) < < " ... initializing layout in multiple mode : " < < layoutName ;
unloadLayouts ( ) ;
2019-05-11 03:11:50 +03:00
2020-08-30 14:04:04 +03:00
m_manager - > loadLatteLayout ( layoutPath ( QString ( Layout : : MULTIPLELAYOUTSHIDDENNAME ) ) ) ;
2019-05-11 03:11:50 +03:00
2020-08-30 14:04:04 +03:00
m_multipleModeInitialized = true ;
2019-05-11 03:11:50 +03:00
2020-08-30 14:04:04 +03:00
emit centralLayoutsChanged ( ) ;
2020-08-30 20:38:39 +03:00
if ( ! layoutName . isEmpty ( ) ) {
switchToLayoutInMultipleModeBasedOnActivities ( layoutName ) ;
}
2020-08-30 14:04:04 +03:00
syncMultipleLayoutsToActivities ( ) ;
} ) ;
return true ;
}
bool Synchronizer : : switchToLayoutInSingleMode ( QString layoutName )
{
if ( ! memoryInitialized ( ) | | m_manager - > memoryUsage ( ) ! = MemoryUsage : : SingleLayout ) {
return false ;
}
if ( m_centralLayouts . size ( ) > 0 & & m_centralLayouts [ 0 ] - > name ( ) = = layoutName ) {
return true ;
}
return initSingleMode ( layoutName ) ;
}
2020-08-30 20:32:13 +03:00
bool Synchronizer : : switchToLayoutInMultipleModeBasedOnActivities ( const QString & layoutName )
{
Data : : Layout layoutdata ;
CentralLayout * central = centralLayout ( layoutName ) ;
if ( central ) {
layoutdata = central - > data ( ) ;
} else if ( m_layouts . containsName ( layoutName ) ) {
QString layoutid = m_layouts . idForName ( layoutName ) ;
CentralLayout storagedlayout ( this , layoutid ) ;
layoutdata = storagedlayout . data ( ) ;
m_layouts [ layoutid ] = layoutdata ;
}
if ( layoutdata . isEmpty ( ) ) {
return false ;
}
QString switchToActivity ;
2020-08-31 01:31:03 +03:00
//! try to not remove activityids that belong to different machines that are not currently present
QStringList validlayoutactivities = validActivities ( layoutdata . activities ) ;
2020-08-30 20:32:13 +03:00
if ( layoutdata . isOnAllActivities ( ) ) {
//! no reason to switch in any activity;
} else if ( layoutdata . isForFreeActivities ( ) ) {
//! free-activities case
QStringList freerunningactivities = freeRunningActivities ( ) ;
if ( freerunningactivities . count ( ) > 0 ) {
if ( freerunningactivities . contains ( layoutdata . lastUsedActivity ) ) {
switchToActivity = layoutdata . lastUsedActivity ;
} else {
switchToActivity = freerunningactivities [ 0 ] ;
}
} else {
QStringList freepausedactivities = freeActivities ( ) ;
if ( freepausedactivities . count ( ) > 0 ) {
switchToActivity = freepausedactivities [ 0 ] ;
}
}
2020-08-31 01:31:03 +03:00
} else if ( ! validlayoutactivities . isEmpty ( ) ) {
2020-08-30 20:32:13 +03:00
//! set on-explicit activities
QStringList allactivities = activities ( ) ;
2020-08-31 01:31:03 +03:00
if ( validlayoutactivities . contains ( layoutdata . lastUsedActivity ) ) {
2020-08-30 20:32:13 +03:00
switchToActivity = layoutdata . lastUsedActivity ;
} else {
2020-08-31 01:31:03 +03:00
switchToActivity = validlayoutactivities [ 0 ] ;
2020-08-30 20:32:13 +03:00
}
2020-08-31 01:31:03 +03:00
} else if ( validlayoutactivities . isEmpty ( ) & & m_layouts . containsName ( layoutName ) ) {
2020-08-30 20:32:13 +03:00
//! no-activities are set
//! has not been set in any activities but nonetheless it is requested probably by the user
//! requested layout is assigned explicitly in current activity and any remaining explicit layouts
//! are removing current activity from their activities list
QString layoutid = m_layouts . idForName ( layoutName ) ;
QString currentactivityid = m_activitiesController - > currentActivity ( ) ;
QStringList layoutIdsChanged ;
2020-08-31 01:31:03 +03:00
m_layouts [ layoutid ] . activities . append ( currentactivityid ) ;
2020-08-30 20:32:13 +03:00
m_manager - > setOnActivities ( layoutName , m_layouts [ layoutid ] . activities ) ;
emit layoutActivitiesChanged ( m_layouts [ layoutid ] ) ;
layoutIdsChanged < < layoutid ;
if ( m_assignedLayouts . contains ( currentactivityid ) ) {
//! remove any other explicit set layouts for the current activity
QStringList explicits = m_assignedLayouts [ currentactivityid ] ;
for ( auto explicitlayoutname : explicits ) {
QString explicitlayoutid = m_layouts . idForName ( explicitlayoutname ) ;
m_layouts [ explicitlayoutid ] . activities . removeAll ( currentactivityid ) ;
m_manager - > setOnActivities ( explicitlayoutname , m_layouts [ explicitlayoutid ] . activities ) ;
emit layoutActivitiesChanged ( m_layouts [ explicitlayoutid ] ) ;
}
}
QStringList freelayoutnames ;
if ( m_assignedLayouts . contains ( Data : : Layout : : FREEACTIVITIESID ) ) {
freelayoutnames = m_assignedLayouts [ Data : : Layout : : FREEACTIVITIESID ] ;
}
reloadAssignedLayouts ( ) ;
for ( auto freelayoutname : freelayoutnames ) {
//! inform free activities layouts that their activities probably changed
CentralLayout * central = centralLayout ( freelayoutname ) ;
if ( central ) {
emit central - > activitiesChanged ( ) ;
}
}
}
if ( ! switchToActivity . isEmpty ( ) ) {
if ( ! m_manager - > corona ( ) - > activitiesConsumer ( ) - > runningActivities ( ) . contains ( switchToActivity ) ) {
m_activitiesController - > startActivity ( switchToActivity ) ;
}
m_activitiesController - > setCurrentActivity ( switchToActivity ) ;
}
return true ;
}
2020-08-30 14:04:04 +03:00
bool Synchronizer : : switchToLayoutInMultipleMode ( QString layoutName )
{
if ( ! memoryInitialized ( ) | | m_manager - > memoryUsage ( ) ! = MemoryUsage : : MultipleLayouts ) {
return false ;
}
CentralLayout * layout = centralLayout ( layoutName ) ;
if ( layout ) {
QStringList appliedActivities = layout - > appliedActivities ( ) ;
QString nextActivity = ! layout - > lastUsedActivity ( ) . isEmpty ( ) ? layout - > lastUsedActivity ( ) : appliedActivities [ 0 ] ;
if ( ! appliedActivities . contains ( m_manager - > corona ( ) - > activitiesConsumer ( ) - > currentActivity ( ) ) ) {
//! it means we are at a foreign activity and we can switch to correct one
m_activitiesController - > setCurrentActivity ( nextActivity ) ;
return true ;
}
2019-05-11 03:11:50 +03:00
} else {
2020-08-30 20:32:13 +03:00
if ( ! layoutName . isEmpty ( ) ) {
switchToLayoutInMultipleModeBasedOnActivities ( layoutName ) ;
}
2020-08-30 14:04:04 +03:00
syncMultipleLayoutsToActivities ( ) ;
2019-05-11 03:11:50 +03:00
}
return true ;
}
2020-08-30 14:04:04 +03:00
bool Synchronizer : : switchToLayout ( QString layoutName , MemoryUsage : : LayoutsMemory newMemoryUsage )
{
qDebug ( ) < < " >>>>> SWITCHING >> " < < layoutName < < " __ from memory: " < < m_manager - > memoryUsage ( ) < < " to memory: " < < newMemoryUsage ;
2020-08-30 20:32:13 +03:00
if ( newMemoryUsage = = MemoryUsage : : Current ) {
newMemoryUsage = m_manager - > memoryUsage ( ) ;
}
2020-08-30 14:04:04 +03:00
if ( ! memoryInitialized ( ) | | newMemoryUsage ! = m_manager - > memoryUsage ( ) ) {
//! Initiate Layouts memory properly
2020-08-30 20:32:13 +03:00
m_manager - > setMemoryUsage ( newMemoryUsage ) ;
2020-08-30 14:04:04 +03:00
return ( newMemoryUsage = = MemoryUsage : : SingleLayout ? initSingleMode ( layoutName ) : initMultipleMode ( layoutName ) ) ;
}
if ( m_manager - > memoryUsage ( ) = = MemoryUsage : : SingleLayout ) {
return switchToLayoutInSingleMode ( layoutName ) ;
} else {
return switchToLayoutInMultipleMode ( layoutName ) ;
}
}
2020-08-25 18:07:24 +03:00
void Synchronizer : : syncMultipleLayoutsToActivities ( )
2019-05-11 03:11:50 +03:00
{
qDebug ( ) < < " ---- --------- ------ syncMultipleLayoutsToActivities ------- " ;
qDebug ( ) < < " ---- --------- ------ ------------------------------- ------- " ;
2020-08-30 14:34:56 +03:00
QStringList layoutNamesToUnload ;
QStringList layoutNamesToLoad ;
QStringList currentNames = centralLayoutsNames ( ) ;
2019-05-11 03:11:50 +03:00
2020-08-25 18:07:24 +03:00
//! discover OnAllActivities layouts
if ( m_assignedLayouts . contains ( Data : : Layout : : ALLACTIVITIESID ) ) {
2020-08-30 14:34:56 +03:00
layoutNamesToLoad < < m_assignedLayouts [ Data : : Layout : : ALLACTIVITIESID ] ;
2020-08-25 18:07:24 +03:00
}
2019-05-11 03:11:50 +03:00
2020-08-25 18:07:24 +03:00
//! discover ForFreeActivities layouts
2020-08-30 21:31:13 +03:00
if ( m_assignedLayouts . contains ( Data : : Layout : : FREEACTIVITIESID ) & & freeRunningActivities ( ) . count ( ) > 0 ) {
2020-08-30 14:34:56 +03:00
layoutNamesToLoad < < m_assignedLayouts [ Data : : Layout : : FREEACTIVITIESID ] ;
2019-05-11 03:11:50 +03:00
}
2020-08-25 18:07:24 +03:00
//! discover layouts assigned to explicit activities based on running activities
2019-05-11 03:11:50 +03:00
for ( const auto & activity : runningActivities ( ) ) {
2021-06-12 15:23:29 +03:00
# if KF5_VERSION_MINOR < 81
2020-08-03 18:13:37 +03:00
if ( KWindowSystem : : isPlatformWayland ( ) & & ( m_activitiesController - > currentActivity ( ) ! = activity ) ) {
2021-06-12 15:23:29 +03:00
//! Wayland Protection: Plasma wayland does not support Activities for windows before kde frameworks 5.81
//! In that scenario we can load the layouts that belong OnAllActivities + (ForFreeActivities OR SpecificActivity)
2020-08-03 18:13:37 +03:00
continue ;
}
2021-06-12 15:23:29 +03:00
# endif
2020-08-03 18:13:37 +03:00
2020-03-16 21:03:14 +02:00
if ( m_assignedLayouts . contains ( activity ) ) {
2020-08-30 14:34:56 +03:00
layoutNamesToLoad < < m_assignedLayouts [ activity ] ;
2019-05-11 03:11:50 +03:00
}
}
2020-08-03 18:13:37 +03:00
//! discover layouts that must be unloaded because of running activities changes
2019-05-11 03:11:50 +03:00
for ( const auto layout : m_centralLayouts ) {
2020-08-30 14:34:56 +03:00
if ( ! layoutNamesToLoad . contains ( layout - > name ( ) ) ) {
layoutNamesToUnload < < layout - > name ( ) ;
2019-05-11 03:11:50 +03:00
}
2021-06-12 15:51:29 +03:00
}
2019-05-11 03:11:50 +03:00
2020-08-25 18:07:24 +03:00
QString defaultForcedLayout ;
//! Safety
2020-08-30 14:34:56 +03:00
if ( layoutNamesToLoad . isEmpty ( ) ) {
2020-08-25 18:07:24 +03:00
//! If no layout is found then force loading Default Layout
QString layoutPath = m_manager - > corona ( ) - > templatesManager ( ) - > newLayout ( " " , i18n ( Templates : : DEFAULTLAYOUTTEMPLATENAME ) ) ;
2020-08-30 14:34:56 +03:00
layoutNamesToLoad < < Layout : : AbstractLayout : : layoutName ( layoutPath ) ;
m_manager - > setOnAllActivities ( layoutNamesToLoad [ 0 ] ) ;
defaultForcedLayout = layoutNamesToLoad [ 0 ] ;
2019-05-11 03:11:50 +03:00
}
2020-08-25 18:16:20 +03:00
QStringList newlyActivatedLayouts ;
2020-08-25 18:07:24 +03:00
//! Add needed Layouts based on Activities settings
2020-08-30 14:34:56 +03:00
for ( const auto & layoutname : layoutNamesToLoad ) {
if ( ! centralLayout ( layoutname ) ) {
CentralLayout * newLayout = new CentralLayout ( this , QString ( layoutPath ( layoutname ) ) , layoutname ) ;
2019-05-11 03:11:50 +03:00
if ( newLayout ) {
2020-08-30 14:34:56 +03:00
qDebug ( ) < < " ACTIVATING LAYOUT ::::: " < < layoutname ;
2019-05-11 03:11:50 +03:00
addLayout ( newLayout ) ;
newLayout - > importToCorona ( ) ;
2020-08-30 14:34:56 +03:00
if ( ! defaultForcedLayout . isEmpty ( ) & & defaultForcedLayout = = layoutname ) {
2020-08-29 23:37:52 +03:00
emit newLayoutAdded ( newLayout - > data ( ) ) ;
}
2020-08-25 18:16:20 +03:00
newlyActivatedLayouts < < newLayout - > name ( ) ;
2019-05-11 03:11:50 +03:00
}
}
}
2021-05-05 13:50:57 +03:00
if ( newlyActivatedLayouts . count ( ) > 0 & & m_manager - > corona ( ) - > universalSettings ( ) - > showInfoWindow ( ) ) {
2021-05-04 09:18:35 +03:00
m_manager - > showInfoWindow ( i18np ( " Activating layout: <b>%2</b> ... " ,
2021-05-08 19:26:48 +03:00
" Activating layouts: <b>%2</b> ... " ,
2021-05-04 09:18:35 +03:00
newlyActivatedLayouts . count ( ) ,
2021-05-08 19:26:48 +03:00
newlyActivatedLayouts . join ( " , " ) ) ,
2021-05-04 09:18:35 +03:00
4000 , QStringList ( Data : : Layout : : ALLACTIVITIESID ) ) ;
2020-08-25 18:16:20 +03:00
}
2020-08-03 17:28:59 +03:00
//! Unload no needed Layouts
2020-08-30 14:34:56 +03:00
//! hide layouts that will be removed in the end
if ( ! layoutNamesToUnload . isEmpty ( ) ) {
for ( const auto layoutname : layoutNamesToUnload ) {
emit currentLayoutIsSwitching ( layoutname ) ;
}
QTimer : : singleShot ( LAYOUTSINITINTERVAL , [ this , layoutNamesToUnload ] ( ) {
unloadLayouts ( layoutNamesToUnload ) ;
} ) ;
}
2021-05-21 17:54:43 +00:00
currentNames . sort ( ) ;
layoutNamesToLoad . sort ( ) ;
2020-08-30 14:34:56 +03:00
if ( currentNames ! = layoutNamesToLoad ) {
emit centralLayoutsChanged ( ) ;
}
}
void Synchronizer : : unloadLayouts ( const QStringList & layoutNames )
{
if ( layoutNames . isEmpty ( ) ) {
return ;
}
//! Unload no needed Layouts
for ( const auto & layoutname : layoutNames ) {
CentralLayout * layout = centralLayout ( layoutname ) ;
int posLayout = centralLayoutPos ( layoutname ) ;
2020-08-03 17:28:59 +03:00
if ( posLayout > = 0 ) {
2020-08-30 14:34:56 +03:00
qDebug ( ) < < " REMOVING LAYOUT ::::: " < < layoutname ;
2020-08-03 17:28:59 +03:00
m_centralLayouts . removeAt ( posLayout ) ;
layout - > syncToLayoutFile ( true ) ;
layout - > unloadContainments ( ) ;
layout - > unloadLatteViews ( ) ;
m_manager - > clearUnloadedContainmentsFromLinkedFile ( layout - > unloadedContainmentsIds ( ) ) ;
delete layout ;
}
}
2020-08-30 14:34:56 +03:00
emit centralLayoutsChanged ( ) ;
2020-08-26 20:54:44 +03:00
}
void Synchronizer : : updateKWinDisabledBorders ( )
{
2021-04-09 13:52:56 +03:00
if ( KWindowSystem : : isPlatformWayland ( ) ) {
// BUG: https://bugs.kde.org/show_bug.cgi?id=428202
// KWin::reconfigure() function blocks/freezes Latte under wayland
return ;
}
2020-08-26 20:54:44 +03:00
if ( ! m_manager - > corona ( ) - > universalSettings ( ) - > canDisableBorders ( ) ) {
m_manager - > corona ( ) - > universalSettings ( ) - > kwin_setDisabledMaximizedBorders ( false ) ;
} else {
if ( m_manager - > corona ( ) - > layoutsManager ( ) - > memoryUsage ( ) = = MemoryUsage : : SingleLayout ) {
m_manager - > corona ( ) - > universalSettings ( ) - > kwin_setDisabledMaximizedBorders ( m_centralLayouts . at ( 0 ) - > disableBordersForMaximizedWindows ( ) ) ;
} else if ( m_manager - > corona ( ) - > layoutsManager ( ) - > memoryUsage ( ) = = MemoryUsage : : MultipleLayouts ) {
QList < CentralLayout * > centrals = centralLayoutsForActivity ( m_manager - > corona ( ) - > activitiesConsumer ( ) - > currentActivity ( ) ) ;
for ( int i = 0 ; i < centrals . size ( ) ; + + i ) {
CentralLayout * layout = centrals . at ( i ) ;
if ( layout - > disableBordersForMaximizedWindows ( ) ) {
m_manager - > corona ( ) - > universalSettings ( ) - > kwin_setDisabledMaximizedBorders ( true ) ;
return ;
}
}
m_manager - > corona ( ) - > universalSettings ( ) - > kwin_setDisabledMaximizedBorders ( false ) ;
}
}
2019-05-11 03:11:50 +03:00
}
}
} // end of namespace