2016-12-25 10:25:27 +03:00
/*
2017-03-08 00:26:09 +03:00
* Copyright 2016 Smith AR < audoban @ openmaibox . org >
2017-01-03 01:05:30 +03:00
* Michail Vourlakos < mvourlakos @ gmail . com >
*
* This file is part of Latte - Dock
*
* Latte - Dock is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation ; either version 2 of
* the License , or ( at your option ) any later version .
*
* Latte - Dock is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2016-12-25 10:25:27 +03:00
2016-12-31 00:25:27 +03:00
# include "dockcorona.h"
# include "dockview.h"
# include "packageplugins/shell/dockpackage.h"
2017-02-25 05:40:47 +03:00
# include "abstractwindowinterface.h"
2017-02-15 07:54:41 +03:00
# include "alternativeshelper.h"
2017-02-24 21:58:21 +03:00
# include "screenpool.h"
2017-03-11 11:06:10 +03:00
//dbus adaptor
# include "lattedockadaptor.h"
2016-12-25 10:25:27 +03:00
# include <QAction>
2017-02-26 03:43:41 +03:00
# include <QApplication>
2016-12-25 10:25:27 +03:00
# include <QScreen>
2017-03-11 11:06:10 +03:00
# include <QDBusConnection>
2016-12-25 10:25:27 +03:00
# include <QDebug>
2017-02-26 03:43:41 +03:00
# include <QDesktopWidget>
2017-04-21 16:59:58 +03:00
# include <QFontDatabase>
2017-02-15 07:54:41 +03:00
# include <QQmlContext>
2016-12-25 10:25:27 +03:00
# include <Plasma>
# include <Plasma/Corona>
# include <Plasma/Containment>
2017-04-06 20:00:48 +03:00
2016-12-31 00:25:27 +03:00
# include <KActionCollection>
# include <KPluginMetaData>
2017-04-06 20:00:48 +03:00
# include <KGlobalAccel>
2016-12-25 10:25:27 +03:00
# include <KLocalizedString>
# include <KPackage/Package>
# include <KPackage/PackageLoader>
2017-01-29 08:16:28 +03:00
# include <KAboutData>
2017-02-15 07:54:41 +03:00
# include <KActivities/Consumer>
2017-01-07 16:27:26 +03:00
2017-04-25 19:18:49 +03:00
# include <KWindowSystem>
# include <KWayland/Client/connection_thread.h>
# include <KWayland/Client/registry.h>
# include <KWayland/Client/plasmashell.h>
2016-12-30 10:20:06 +03:00
namespace Latte {
2017-02-26 20:37:46 +03:00
DockCorona : : DockCorona ( QObject * parent )
2017-01-07 16:27:26 +03:00
: Plasma : : Corona ( parent ) ,
2017-04-02 08:25:03 +03:00
m_activityConsumer ( new KActivities : : Consumer ( this ) ) ,
2017-02-24 21:58:21 +03:00
m_screenPool ( new ScreenPool ( KSharedConfig : : openConfig ( ) , this ) ) ,
2017-06-04 01:58:03 +03:00
m_globalSettings ( new GlobalSettings ( this ) ) ,
2017-04-25 19:18:49 +03:00
m_globalShortcuts ( new GlobalShortcuts ( this ) ) ,
m_waylandDockCorona ( nullptr )
2016-12-25 10:25:27 +03:00
{
2017-04-25 19:18:49 +03:00
setupWaylandIntegration ( ) ;
2016-12-31 00:25:27 +03:00
KPackage : : Package package ( new DockPackage ( this ) ) ;
2017-02-26 21:06:31 +03:00
m_screenPool - > load ( ) ;
2017-01-16 22:07:49 +03:00
2016-12-25 10:25:27 +03:00
if ( ! package . isValid ( ) ) {
qWarning ( ) < < staticMetaObject . className ( )
< < " the package " < < package . metadata ( ) . rawData ( ) < < " is invalid! " ;
return ;
} else {
qDebug ( ) < < staticMetaObject . className ( )
< < " the package " < < package . metadata ( ) . rawData ( ) < < " is valid! " ;
}
2017-01-16 22:07:49 +03:00
2016-12-25 10:25:27 +03:00
setKPackage ( package ) ;
2017-04-23 22:34:29 +03:00
//! global settings must be loaded after the package has been set
m_globalSettings - > load ( ) ;
2016-12-25 10:25:27 +03:00
qmlRegisterTypes ( ) ;
2017-04-21 16:59:58 +03:00
QFontDatabase : : addApplicationFont ( kPackage ( ) . filePath ( " tangerineFont " ) ) ;
2017-06-06 12:48:11 +03:00
//connect(this, &Corona::containmentAdded, this, &DockCorona::addDock);
2017-01-24 21:32:22 +03:00
if ( m_activityConsumer & & ( m_activityConsumer - > serviceStatus ( ) = = KActivities : : Consumer : : Running ) ) {
load ( ) ;
}
2017-01-07 16:27:26 +03:00
connect ( m_activityConsumer , & KActivities : : Consumer : : serviceStatusChanged , this , & DockCorona : : load ) ;
2017-03-01 21:49:21 +03:00
m_docksScreenSyncTimer . setSingleShot ( true ) ;
m_docksScreenSyncTimer . setInterval ( 2500 ) ;
connect ( & m_docksScreenSyncTimer , & QTimer : : timeout , this , & DockCorona : : syncDockViews ) ;
2017-03-11 11:06:10 +03:00
//! Dbus adaptor initialization
new LatteDockAdaptor ( this ) ;
QDBusConnection dbus = QDBusConnection : : sessionBus ( ) ;
dbus . registerObject ( QStringLiteral ( " /Latte " ) , this ) ;
2016-12-25 10:25:27 +03:00
}
2016-12-31 00:25:27 +03:00
DockCorona : : ~ DockCorona ( )
2016-12-25 10:25:27 +03:00
{
2017-03-01 21:49:21 +03:00
m_docksScreenSyncTimer . stop ( ) ;
2017-01-21 21:08:47 +03:00
cleanConfig ( ) ;
2017-01-05 01:28:25 +03:00
while ( ! containments ( ) . isEmpty ( ) ) {
//deleting a containment will remove it from the list due to QObject::destroyed connect in Corona
delete containments ( ) . first ( ) ;
}
2017-01-16 22:07:49 +03:00
2017-03-18 14:21:17 +03:00
m_globalSettings - > deleteLater ( ) ;
2017-06-04 01:58:03 +03:00
m_globalShortcuts - > deleteLater ( ) ;
2017-01-05 01:28:25 +03:00
qDeleteAll ( m_dockViews ) ;
2017-01-16 00:59:15 +03:00
qDeleteAll ( m_waitingDockViews ) ;
2017-01-05 01:28:25 +03:00
m_dockViews . clear ( ) ;
2017-01-16 00:59:15 +03:00
m_waitingDockViews . clear ( ) ;
2017-06-04 01:58:03 +03:00
2017-01-07 16:27:26 +03:00
disconnect ( m_activityConsumer , & KActivities : : Consumer : : serviceStatusChanged , this , & DockCorona : : load ) ;
delete m_activityConsumer ;
2016-12-25 10:25:27 +03:00
qDebug ( ) < < " deleted " < < this ;
}
2017-01-07 16:27:26 +03:00
void DockCorona : : load ( )
{
2017-01-24 21:32:22 +03:00
if ( m_activityConsumer & & ( m_activityConsumer - > serviceStatus ( ) = = KActivities : : Consumer : : Running ) & & m_activitiesStarting ) {
2017-02-24 21:58:21 +03:00
disconnect ( m_activityConsumer , & KActivities : : Consumer : : serviceStatusChanged , this , & DockCorona : : load ) ;
2017-01-24 21:32:22 +03:00
m_activitiesStarting = false ;
2017-03-01 17:59:04 +03:00
m_tasksWillBeLoaded = heuresticForLoadingDockWithTasks ( ) ;
qDebug ( ) < < " TASKS WILL BE PRESENT AFTER LOADING ::: " < < m_tasksWillBeLoaded ;
2017-02-26 03:43:41 +03:00
// connect(qGuiApp, &QGuiApplication::screenAdded, this, &DockCorona::addOutput, Qt::UniqueConnection);
2017-02-24 21:58:21 +03:00
connect ( qGuiApp , & QGuiApplication : : primaryScreenChanged , this , & DockCorona : : primaryOutputChanged , Qt : : UniqueConnection ) ;
2017-02-26 03:43:41 +03:00
// connect(qGuiApp, &QGuiApplication::screenRemoved, this, &DockCorona::screenRemoved, Qt::UniqueConnection);
connect ( QApplication : : desktop ( ) , & QDesktopWidget : : screenCountChanged , this , & DockCorona : : screenCountChanged ) ;
connect ( m_screenPool , & ScreenPool : : primaryPoolChanged , this , & DockCorona : : screenCountChanged ) ;
2017-02-24 21:58:21 +03:00
2017-01-24 21:32:22 +03:00
loadLayout ( ) ;
2017-06-06 12:48:11 +03:00
foreach ( auto containment , containments ( ) )
addDock ( containment ) ;
2017-01-24 21:32:22 +03:00
}
2017-01-07 16:27:26 +03:00
}
2017-04-25 19:18:49 +03:00
void DockCorona : : setupWaylandIntegration ( )
{
if ( ! KWindowSystem : : isPlatformWayland ( ) ) {
return ;
}
using namespace KWayland : : Client ;
ConnectionThread * connection = ConnectionThread : : fromApplication ( this ) ;
if ( ! connection ) {
return ;
}
Registry * registry = new Registry ( this ) ;
registry - > create ( connection ) ;
connect ( registry , & Registry : : plasmaShellAnnounced , this ,
[ this , registry ] ( quint32 name , quint32 version ) {
qDebug ( ) < < " wayland registry ::: " < < name < < " - " < < version ;
m_waylandDockCorona = registry - > createPlasmaShell ( name , version , this ) ;
}
) ;
registry - > setup ( ) ;
}
KWayland : : Client : : PlasmaShell * DockCorona : : waylandDockCoronaInterface ( ) const
{
return m_waylandDockCorona ;
}
2017-01-21 21:08:47 +03:00
void DockCorona : : cleanConfig ( )
{
auto containmentsEntries = config ( ) - > group ( " Containments " ) ;
bool changed = false ;
2017-01-22 02:28:39 +03:00
foreach ( auto cId , containmentsEntries . groupList ( ) ) {
2017-02-06 04:55:41 +03:00
if ( ! containmentExists ( cId . toUInt ( ) ) ) {
2017-01-22 02:28:39 +03:00
//cleanup obsolete containments
containmentsEntries . group ( cId ) . deleteGroup ( ) ;
2017-01-21 21:08:47 +03:00
changed = true ;
2017-01-22 02:28:39 +03:00
qDebug ( ) < < " obsolete containment configuration deleted: " < < cId ;
} else {
//cleanup obsolete applets of running containments
auto appletsEntries = containmentsEntries . group ( cId ) . group ( " Applets " ) ;
foreach ( auto appletId , appletsEntries . groupList ( ) ) {
2017-02-06 04:55:41 +03:00
if ( ! appletExists ( cId . toUInt ( ) , appletId . toUInt ( ) ) ) {
2017-01-22 02:28:39 +03:00
appletsEntries . group ( appletId ) . deleteGroup ( ) ;
changed = true ;
qDebug ( ) < < " obsolete applet configuration deleted: " < < appletId ;
}
}
2017-01-21 21:08:47 +03:00
}
}
if ( changed ) {
config ( ) - > sync ( ) ;
qDebug ( ) < < " configuration file cleaned... " ;
}
}
2017-02-06 04:55:41 +03:00
bool DockCorona : : containmentExists ( uint id ) const
2017-01-21 21:08:47 +03:00
{
foreach ( auto containment , containments ( ) ) {
if ( id = = containment - > id ( ) ) {
return true ;
}
}
return false ;
}
2017-02-06 04:55:41 +03:00
bool DockCorona : : appletExists ( uint containmentId , uint appletId ) const
2017-01-22 02:28:39 +03:00
{
Plasma : : Containment * containment = nullptr ;
foreach ( auto cont , containments ( ) ) {
if ( containmentId = = cont - > id ( ) ) {
containment = cont ;
break ;
}
}
if ( ! containment ) {
return false ;
}
foreach ( auto applet , containment - > applets ( ) ) {
if ( applet - > id ( ) = = appletId ) {
return true ;
}
}
return false ;
}
2017-02-24 21:58:21 +03:00
ScreenPool * DockCorona : : screenPool ( ) const
{
return m_screenPool ;
}
2017-03-18 14:21:17 +03:00
GlobalSettings * DockCorona : : globalSettings ( ) const
{
return m_globalSettings ;
}
2016-12-31 00:25:27 +03:00
int DockCorona : : numScreens ( ) const
2016-12-25 10:25:27 +03:00
{
return qGuiApp - > screens ( ) . count ( ) ;
}
2016-12-31 00:25:27 +03:00
QRect DockCorona : : screenGeometry ( int id ) const
2016-12-25 10:25:27 +03:00
{
const auto screens = qGuiApp - > screens ( ) ;
2017-04-04 14:39:17 +03:00
const QScreen * screen { qGuiApp - > primaryScreen ( ) } ;
QString screenName ;
if ( m_screenPool - > knownIds ( ) . contains ( id ) )
screenName = m_screenPool - > connector ( id ) ;
2017-01-16 22:07:49 +03:00
2017-04-04 14:39:17 +03:00
foreach ( auto scr , screens ) {
if ( scr - > name ( ) = = screenName ) {
screen = scr ;
break ;
}
2016-12-25 10:25:27 +03:00
}
2017-01-16 22:07:49 +03:00
2017-04-04 14:39:17 +03:00
return screen - > geometry ( ) ;
2016-12-25 10:25:27 +03:00
}
2016-12-31 00:25:27 +03:00
QRegion DockCorona : : availableScreenRegion ( int id ) const
2016-12-25 10:25:27 +03:00
{
2017-03-02 23:10:26 +03:00
const auto screens = qGuiApp - > screens ( ) ;
const QScreen * screen { qGuiApp - > primaryScreen ( ) } ;
2017-03-20 20:00:28 +03:00
QString screenName ;
if ( m_screenPool - > knownIds ( ) . contains ( id ) )
screenName = m_screenPool - > connector ( id ) ;
2017-03-02 23:10:26 +03:00
foreach ( auto scr , screens ) {
2017-03-20 20:00:28 +03:00
if ( scr - > name ( ) = = screenName ) {
2017-03-02 23:10:26 +03:00
screen = scr ;
break ;
}
}
if ( ! screen )
return QRegion ( ) ;
QRegion available ( screen - > geometry ( ) ) ;
for ( const auto * view : m_dockViews ) {
if ( view & & view - > containment ( ) & & view - > screen ( ) = = screen ) {
int realThickness = view - > normalThickness ( ) - view - > shadow ( ) ;
// Usually availableScreenRect is used by the desktop,
// but Latte dont have desktop, then here just
// need calculate available space for top and bottom location,
// because the left and right are those who dodge others docks
switch ( view - > location ( ) ) {
case Plasma : : Types : : TopEdge :
2017-05-07 15:06:29 +03:00
if ( view - > behaveAsPlasmaPanel ( ) ) {
2017-03-02 23:10:26 +03:00
available - = view - > geometry ( ) ;
} else {
QRect realGeometry ;
int realWidth = view - > maxLength ( ) * view - > width ( ) ;
switch ( view - > alignment ( ) ) {
case Latte : : Dock : : Left :
realGeometry = QRect ( view - > x ( ) , view - > y ( ) ,
realWidth , realThickness ) ;
break ;
case Latte : : Dock : : Center :
case Latte : : Dock : : Justify :
2017-03-04 16:29:56 +03:00
realGeometry = QRect ( qMax ( view - > geometry ( ) . x ( ) , view - > geometry ( ) . center ( ) . x ( ) - realWidth / 2 ) , view - > y ( ) ,
2017-03-02 23:10:26 +03:00
realWidth , realThickness ) ;
break ;
case Latte : : Dock : : Right :
realGeometry = QRect ( view - > geometry ( ) . right ( ) - realWidth + 1 , view - > y ( ) ,
realWidth , realThickness ) ;
break ;
}
available - = realGeometry ;
}
break ;
case Plasma : : Types : : BottomEdge :
2017-05-07 15:06:29 +03:00
if ( view - > behaveAsPlasmaPanel ( ) ) {
2017-03-02 23:10:26 +03:00
available - = view - > geometry ( ) ;
} else {
QRect realGeometry ;
int realWidth = view - > maxLength ( ) * view - > width ( ) ;
int realY = view - > geometry ( ) . bottom ( ) - realThickness + 1 ;
switch ( view - > alignment ( ) ) {
case Latte : : Dock : : Left :
realGeometry = QRect ( view - > x ( ) , realY ,
realWidth , realThickness ) ;
break ;
case Latte : : Dock : : Center :
case Latte : : Dock : : Justify :
realGeometry = QRect ( qMax ( view - > geometry ( ) . x ( ) , view - > geometry ( ) . center ( ) . x ( ) - realWidth / 2 ) ,
realY , realWidth , realThickness ) ;
break ;
case Latte : : Dock : : Right :
realGeometry = QRect ( view - > geometry ( ) . right ( ) - realWidth + 1 , realY ,
realWidth , realThickness ) ;
break ;
}
available - = realGeometry ;
}
break ;
}
}
}
/*qDebug() << "::::: FREE AREAS :::::";
2017-03-04 16:29:56 +03:00
2017-03-02 23:10:26 +03:00
for ( int i = 0 ; i < available . rectCount ( ) ; + + i ) {
qDebug ( ) < < available . rects ( ) . at ( i ) ;
}
2017-03-04 16:29:56 +03:00
2017-03-02 23:10:26 +03:00
qDebug ( ) < < " ::::: END OF FREE AREAS ::::: " ; */
return available ;
2016-12-25 10:25:27 +03:00
}
2016-12-31 00:25:27 +03:00
QRect DockCorona : : availableScreenRect ( int id ) const
2016-12-25 10:25:27 +03:00
{
const auto screens = qGuiApp - > screens ( ) ;
2017-03-01 21:22:23 +03:00
const QScreen * screen { qGuiApp - > primaryScreen ( ) } ;
2017-03-13 22:07:40 +03:00
if ( m_screenPool - > knownIds ( ) . contains ( id ) ) {
QString scrName = m_screenPool - > connector ( id ) ;
foreach ( auto scr , screens ) {
if ( scr - > name ( ) = = scrName ) {
screen = scr ;
break ;
}
2017-03-02 19:07:29 +03:00
}
2017-03-01 21:22:23 +03:00
}
2017-02-10 02:11:34 +03:00
2017-02-11 06:12:17 +03:00
if ( ! screen )
return { } ;
2017-01-16 22:07:49 +03:00
2017-02-11 06:12:17 +03:00
auto available = screen - > geometry ( ) ;
2017-02-10 02:11:34 +03:00
2017-02-11 06:12:17 +03:00
for ( const auto * view : m_dockViews ) {
if ( view & & view - > containment ( ) & & view - > screen ( ) = = screen ) {
auto dockRect = view - > absGeometry ( ) ;
2017-02-10 02:11:34 +03:00
2017-02-12 02:59:09 +03:00
// Usually availableScreenRect is used by the desktop,
// but Latte dont have desktop, then here just
// need calculate available space for top and bottom location,
// because the left and right are those who dodge others docks
2017-02-11 06:12:17 +03:00
switch ( view - > location ( ) ) {
2017-03-02 19:07:29 +03:00
case Plasma : : Types : : TopEdge :
available . setTopLeft ( { available . x ( ) , dockRect . bottom ( ) } ) ;
break ;
2017-02-12 02:59:09 +03:00
2017-03-02 19:07:29 +03:00
case Plasma : : Types : : BottomEdge :
available . setBottomLeft ( { available . x ( ) , dockRect . top ( ) } ) ;
break ;
2017-02-10 02:11:34 +03:00
}
}
}
2017-02-11 06:12:17 +03:00
return available ;
2016-12-25 10:25:27 +03:00
}
2017-03-02 19:07:29 +03:00
//! the number of currently running docks containing
//! tasks plasmoid
2017-03-01 17:59:04 +03:00
int DockCorona : : noDocksWithTasks ( ) const
{
int result = 0 ;
foreach ( auto view , m_dockViews ) {
2017-03-10 23:41:13 +03:00
if ( view - > tasksPresent ( ) & & view - > session ( ) = = m_session ) {
2017-03-01 17:59:04 +03:00
result + + ;
}
}
return result ;
}
2017-02-24 21:58:21 +03:00
void DockCorona : : addOutput ( QScreen * screen )
{
Q_ASSERT ( screen ) ;
2017-02-26 03:43:41 +03:00
2017-02-26 21:06:31 +03:00
int id = m_screenPool - > id ( screen - > name ( ) ) ;
2017-02-27 20:46:10 +03:00
if ( id = = - 1 ) {
2017-02-26 21:06:31 +03:00
int newId = m_screenPool - > firstAvailableId ( ) ;
m_screenPool - > insertScreenMapping ( newId , screen - > name ( ) ) ;
}
2017-02-24 21:58:21 +03:00
}
void DockCorona : : primaryOutputChanged ( )
{
2017-02-27 20:46:10 +03:00
/* qDebug() << "primary changed ### "<< qGuiApp->primaryScreen()->name();
foreach ( auto scr , qGuiApp - > screens ( ) ) {
qDebug ( ) < < " Found screen: " < < scr - > name ( ) ;
} */
2017-02-26 03:43:41 +03:00
2017-02-26 20:15:20 +03:00
//if (m_dockViews.count()==1 && qGuiApp->screens().size()==1) {
2017-02-27 20:46:10 +03:00
// foreach(auto view, m_dockViews) {
// view->setScreenToFollow(qGuiApp->primaryScreen());
// }
// }
2017-02-24 21:58:21 +03:00
}
void DockCorona : : screenRemoved ( QScreen * screen )
{
Q_ASSERT ( screen ) ;
2017-02-26 03:43:41 +03:00
}
void DockCorona : : screenCountChanged ( )
{
2017-03-01 21:49:21 +03:00
m_docksScreenSyncTimer . start ( ) ;
2017-02-26 03:43:41 +03:00
}
2017-03-02 19:07:29 +03:00
//! the central functions that updates loading/unloading dockviews
//! concerning screen changed (for multi-screen setups mainly)
2017-02-27 23:52:22 +03:00
void DockCorona : : syncDockViews ( )
2017-02-26 03:43:41 +03:00
{
2017-02-27 20:46:10 +03:00
qDebug ( ) < < " screen count changed -+-+ " < < qGuiApp - > screens ( ) . size ( ) ;
2017-02-26 03:43:41 +03:00
qDebug ( ) < < " adding consideration.... " ;
2017-02-26 21:06:31 +03:00
qDebug ( ) < < " dock view running : " < < m_dockViews . count ( ) ;
2017-02-26 03:43:41 +03:00
2017-02-27 20:46:10 +03:00
foreach ( auto scr , qGuiApp - > screens ( ) ) {
qDebug ( ) < < " Found screen: " < < scr - > name ( ) ;
foreach ( auto cont , containments ( ) ) {
2017-02-26 03:43:41 +03:00
int id = cont - > screen ( ) ;
2017-02-27 20:46:10 +03:00
if ( id = = - 1 ) {
2017-02-26 03:43:41 +03:00
id = cont - > lastScreen ( ) ;
}
2017-02-27 01:53:27 +03:00
bool onPrimary = cont - > config ( ) . readEntry ( " onPrimary " , true ) ;
2017-03-11 02:45:31 +03:00
Plasma : : Types : : Location location = static_cast < Plasma : : Types : : Location > ( ( int ) cont - > config ( ) . readEntry ( " location " , ( int ) Plasma : : Types : : BottomEdge ) ) ;
Dock : : SessionType session = static_cast < Dock : : SessionType > ( ( int ) cont - > config ( ) . readEntry ( " session " , ( int ) Dock : : DefaultSession ) ) ;
2017-02-27 01:53:27 +03:00
2017-03-02 19:07:29 +03:00
//! two main situations that a dock must be added when it is not already running
//! 1. when a dock is primary, not running and the edge for which is associated is free
//! 2. when a dock in explicit, not running and the associated screen currently exists
//! e.g. the screen has just been added
if ( ( ( onPrimary & & freeEdges ( qGuiApp - > primaryScreen ( ) ) . contains ( location ) ) | | ( ! onPrimary & & ( m_screenPool - > connector ( id ) = = scr - > name ( ) ) ) )
2017-03-10 23:41:13 +03:00
& & ( ! m_dockViews . contains ( cont ) ) & & session = = currentSession ( ) ) {
2017-02-27 20:46:10 +03:00
qDebug ( ) < < " screen Count signal: view must be added... for: " < < scr - > name ( ) ;
2017-02-26 03:43:41 +03:00
addDock ( cont ) ;
}
}
}
2017-02-27 01:53:27 +03:00
qDebug ( ) < < " removing consideration & updating screen for always on primary docks.... " ;
2017-02-27 20:46:10 +03:00
2017-03-02 19:07:29 +03:00
//! this code trys to find a containment that must not be deleted by
//! automatic algorithm. Currently the containment with the minimum id
//! containing tasks plasmoid wins
int preserveContainmentId { - 1 } ;
2017-03-01 17:59:04 +03:00
bool dockWithTasksWillBeShown { false } ;
2017-03-02 19:07:29 +03:00
//! associate correct values for preserveContainmentId and
//! dockWithTasksWillBeShown
2017-03-01 17:59:04 +03:00
foreach ( auto view , m_dockViews ) {
bool found { false } ;
2017-03-02 19:07:29 +03:00
2017-03-01 17:59:04 +03:00
foreach ( auto scr , qGuiApp - > screens ( ) ) {
int id = view - > containment ( ) - > screen ( ) ;
2017-03-02 19:07:29 +03:00
2017-03-01 17:59:04 +03:00
if ( id = = - 1 ) {
id = view - > containment ( ) - > lastScreen ( ) ;
}
2017-03-02 19:07:29 +03:00
2017-03-01 17:59:04 +03:00
if ( scr - > name ( ) = = view - > currentScreen ( ) ) {
found = true ;
break ;
}
}
2017-03-02 19:07:29 +03:00
//!check if a tasks dock will be shown (try to prevent its deletion)
if ( found & & view - > tasksPresent ( ) ) {
dockWithTasksWillBeShown = true ;
2017-03-01 17:59:04 +03:00
}
if ( ! found & & ! view - > onPrimary ( ) & & ( m_dockViews . size ( ) > 1 ) & & m_dockViews . contains ( view - > containment ( ) )
2017-03-02 19:07:29 +03:00
& & ! ( view - > tasksPresent ( ) & & noDocksWithTasks ( ) = = 1 ) ) { //do not delete last dock containing tasks
2017-03-01 17:59:04 +03:00
if ( view - > tasksPresent ( ) ) {
2017-03-02 19:07:29 +03:00
if ( preserveContainmentId = = - 1 )
2017-03-01 17:59:04 +03:00
preserveContainmentId = view - > containment ( ) - > id ( ) ;
2017-03-02 19:07:29 +03:00
else if ( view - > containment ( ) - > id ( ) < preserveContainmentId )
2017-03-01 17:59:04 +03:00
preserveContainmentId = view - > containment ( ) - > id ( ) ;
}
}
}
2017-03-02 19:07:29 +03:00
//! check which docks must be deleted e.g. when the corresponding
//! screen does not exist any more.
//! The code is smart enough in order
//! to never delete the last tasks dock and also it makes sure that
//! the last tasks dock which will exist in the end will be the one
//! with the lowest containment id
2017-02-27 20:46:10 +03:00
foreach ( auto view , m_dockViews ) {
2017-02-26 03:43:41 +03:00
bool found { false } ;
2017-02-27 20:46:10 +03:00
foreach ( auto scr , qGuiApp - > screens ( ) ) {
if ( scr - > name ( ) = = view - > currentScreen ( ) ) {
2017-02-26 03:43:41 +03:00
found = true ;
break ;
}
}
2017-03-10 23:41:13 +03:00
if ( view - > session ( ) ! = currentSession ( ) ) {
qDebug ( ) < < " deleting view that does not belong in this session... " ;
auto viewToDelete = m_dockViews . take ( view - > containment ( ) ) ;
2017-03-20 21:40:27 +03:00
viewToDelete - > deactivateApplets ( ) ;
2017-03-10 23:41:13 +03:00
viewToDelete - > deleteLater ( ) ;
//! which explicit docks can be deleted
} else if ( ! found & & ! view - > onPrimary ( ) & & ( m_dockViews . size ( ) > 1 ) & & m_dockViews . contains ( view - > containment ( ) )
& & ! ( view - > tasksPresent ( ) & & noDocksWithTasks ( ) = = 1 ) ) {
2017-03-01 17:59:04 +03:00
//do not delete last dock containing tasks
if ( dockWithTasksWillBeShown | | preserveContainmentId ! = view - > containment ( ) - > id ( ) ) {
qDebug ( ) < < " screen Count signal: view must be deleted... for: " < < view - > currentScreen ( ) ;
auto viewToDelete = m_dockViews . take ( view - > containment ( ) ) ;
viewToDelete - > deleteLater ( ) ;
}
2017-03-02 19:07:29 +03:00
//!which primary docks can be deleted
2017-03-01 21:16:09 +03:00
} else if ( view - > onPrimary ( ) & & ! found
2017-03-02 19:07:29 +03:00
& & ! freeEdges ( qGuiApp - > primaryScreen ( ) ) . contains ( view - > location ( ) ) ) {
2017-03-01 21:16:09 +03:00
qDebug ( ) < < " screen Count signal: primary view must be deleted... for: " < < view - > currentScreen ( ) ;
auto viewToDelete = m_dockViews . take ( view - > containment ( ) ) ;
viewToDelete - > deleteLater ( ) ;
2017-02-26 03:43:41 +03:00
} else {
2017-03-02 19:07:29 +03:00
//! if the dock will not be deleted its a very good point to reconsider
//! if the screen in which is running is the correct one
2017-02-26 03:43:41 +03:00
view - > reconsiderScreen ( ) ;
}
}
qDebug ( ) < < " end of screens count change.... " ;
2017-02-24 21:58:21 +03:00
}
2016-12-31 00:25:27 +03:00
int DockCorona : : primaryScreenId ( ) const
2016-12-30 17:51:44 +03:00
{
2017-02-13 19:53:54 +03:00
//this is not the proper way because kwin probably uses a different
//index of screens...
//This needs a lot of testing...
2017-02-24 21:58:21 +03:00
return m_screenPool - > id ( qGuiApp - > primaryScreen ( ) - > name ( ) ) ;
2016-12-30 17:51:44 +03:00
}
2017-01-16 00:59:15 +03:00
int DockCorona : : docksCount ( int screen ) const
2017-01-05 01:28:25 +03:00
{
2017-06-11 23:55:34 +03:00
QScreen * scr = m_screenPool - > screenForId ( screen ) ;
2017-01-16 22:07:49 +03:00
2017-01-16 00:59:15 +03:00
int docks { 0 } ;
2017-01-16 22:07:49 +03:00
2017-01-16 00:59:15 +03:00
for ( const auto & view : m_dockViews ) {
2017-06-11 23:55:34 +03:00
if ( view & & view - > screen ( ) = = scr & & ! view - > containment ( ) - > destroyed ( ) ) {
2017-01-16 00:59:15 +03:00
+ + docks ;
}
}
2017-01-16 22:07:49 +03:00
2017-01-28 20:34:03 +03:00
// qDebug() << docks << "docks on screen:" << screen;
2017-01-16 00:59:15 +03:00
return docks ;
2017-01-05 01:28:25 +03:00
}
2017-03-03 18:23:37 +03:00
int DockCorona : : docksCount ( ) const
{
int docks { 0 } ;
for ( const auto & view : m_dockViews ) {
if ( view & & view - > containment ( )
& & ! view - > containment ( ) - > destroyed ( ) ) {
+ + docks ;
}
}
// qDebug() << docks << "docks on screen:" << screen;
return docks ;
}
2017-01-05 01:28:25 +03:00
void DockCorona : : closeApplication ( )
{
qGuiApp - > quit ( ) ;
}
2017-01-29 08:16:28 +03:00
void DockCorona : : aboutApplication ( )
{
if ( aboutDialog ) {
aboutDialog - > hide ( ) ;
aboutDialog - > deleteLater ( ) ;
}
aboutDialog = new KAboutApplicationDialog ( KAboutData : : applicationData ( ) ) ;
connect ( aboutDialog . data ( ) , & QDialog : : finished , aboutDialog . data ( ) , & QObject : : deleteLater ) ;
WindowSystem : : self ( ) . skipTaskBar ( * aboutDialog ) ;
aboutDialog - > show ( ) ;
}
2017-03-10 23:41:13 +03:00
Dock : : SessionType DockCorona : : currentSession ( )
{
return m_session ;
}
void DockCorona : : setCurrentSession ( Dock : : SessionType session )
{
if ( m_session = = session ) {
return ;
}
m_session = session ;
2017-03-18 02:53:44 +03:00
2017-03-18 14:21:17 +03:00
emit currentSessionChanged ( m_session ) ; ;
2017-03-10 23:41:13 +03:00
}
2017-03-18 14:21:17 +03:00
2017-03-10 23:41:13 +03:00
void DockCorona : : switchToSession ( Dock : : SessionType session )
{
if ( currentSession ( ) = = session ) {
return ;
}
setCurrentSession ( session ) ;
if ( noDocksForSession ( session ) = = 0 ) {
m_waitingSessionDocksCreation = true ;
loadDefaultLayout ( ) ;
} else {
m_waitingSessionDocksCreation = false ;
syncDockViews ( ) ;
}
}
int DockCorona : : noDocksForSession ( Dock : : SessionType session )
{
int count { 0 } ;
foreach ( auto cont , containments ( ) ) {
2017-03-11 02:45:31 +03:00
Dock : : SessionType ses = static_cast < Dock : : SessionType > ( cont - > config ( ) . readEntry ( " session " , ( int ) Dock : : DefaultSession ) ) ;
2017-03-10 23:41:13 +03:00
if ( session = = ses )
count + + ;
}
return count ;
}
2017-03-08 00:26:09 +03:00
2017-02-27 20:46:10 +03:00
QList < Plasma : : Types : : Location > DockCorona : : freeEdges ( QScreen * screen ) const
{
using Plasma : : Types ;
QList < Types : : Location > edges { Types : : BottomEdge , Types : : LeftEdge ,
2017-03-02 19:07:29 +03:00
Types : : TopEdge , Types : : RightEdge } ;
2017-02-27 20:46:10 +03:00
for ( auto * view : m_dockViews ) {
2017-03-10 23:41:13 +03:00
if ( view & & view - > currentScreen ( ) = = screen - > name ( ) & & view - > session ( ) = = m_session ) {
2017-02-27 20:46:10 +03:00
edges . removeOne ( view - > location ( ) ) ;
}
}
return edges ;
}
2016-12-31 00:25:27 +03:00
QList < Plasma : : Types : : Location > DockCorona : : freeEdges ( int screen ) const
2016-12-25 10:25:27 +03:00
{
using Plasma : : Types ;
2016-12-29 21:34:21 +03:00
QList < Types : : Location > edges { Types : : BottomEdge , Types : : LeftEdge ,
2017-03-02 19:07:29 +03:00
Types : : TopEdge , Types : : RightEdge } ;
2017-06-11 23:55:34 +03:00
QScreen * scr = m_screenPool - > screenForId ( screen ) ;
2017-01-16 22:07:49 +03:00
2017-01-16 21:24:46 +03:00
for ( auto * view : m_dockViews ) {
2017-06-11 23:55:34 +03:00
if ( view & & view - > screen ( ) = = scr & & view - > session ( ) = = m_session ) {
2017-01-16 00:59:15 +03:00
edges . removeOne ( view - > location ( ) ) ;
}
2016-12-25 10:25:27 +03:00
}
2017-01-16 22:07:49 +03:00
2016-12-25 10:25:27 +03:00
return edges ;
}
2016-12-31 00:25:27 +03:00
int DockCorona : : screenForContainment ( const Plasma : : Containment * containment ) const
2016-12-25 10:25:27 +03:00
{
2017-02-12 16:58:39 +03:00
//FIXME: indexOf is not a proper way to support multi-screen
// as for environment to environment the indexes change
// also there is the following issue triggered
// from dockView adaptToScreen()
//
// in a multi-screen environment that
// primary screen is not set to 0 it was
// created an endless showing loop at
// startup (catch-up race) between
// screen:0 and primaryScreen
2017-02-24 21:58:21 +03:00
//case in which this containment is child of an applet, hello systray :)
if ( Plasma : : Applet * parentApplet = qobject_cast < Plasma : : Applet * > ( containment - > parent ( ) ) ) {
if ( Plasma : : Containment * cont = parentApplet - > containment ( ) ) {
return screenForContainment ( cont ) ;
} else {
return - 1 ;
}
}
//if the panel views already exist, base upon them
DockView * view = m_dockViews . value ( containment ) ;
if ( view & & view - > screen ( ) ) {
return m_screenPool - > id ( view - > screen ( ) - > name ( ) ) ;
}
//Failed? fallback on lastScreen()
//lastScreen() is the correct screen for panels
//It is also correct for desktops *that have the correct activity()*
//a containment with lastScreen() == 0 but another activity,
//won't be associated to a screen
2017-02-26 03:43:41 +03:00
// qDebug() << "ShellCorona screenForContainment: " << containment << " Last screen is " << containment->lastScreen();
2017-02-24 21:58:21 +03:00
for ( auto screen : qGuiApp - > screens ( ) ) {
// containment->lastScreen() == m_screenPool->id(screen->name()) to check if the lastScreen refers to a screen that exists/it's known
if ( containment - > lastScreen ( ) = = m_screenPool - > id ( screen - > name ( ) ) & &
2017-03-02 19:07:29 +03:00
( containment - > activity ( ) = = m_activityConsumer - > currentActivity ( ) | |
containment - > containmentType ( ) = = Plasma : : Types : : PanelContainment | | containment - > containmentType ( ) = = Plasma : : Types : : CustomPanelContainment ) ) {
2017-02-24 21:58:21 +03:00
return containment - > lastScreen ( ) ;
}
}
return - 1 ;
2016-12-25 10:25:27 +03:00
}
2016-12-31 00:25:27 +03:00
void DockCorona : : addDock ( Plasma : : Containment * containment )
2016-12-25 10:25:27 +03:00
{
if ( ! containment | | ! containment - > kPackage ( ) . isValid ( ) ) {
qWarning ( ) < < " the requested containment plugin can not be located or loaded " ;
return ;
}
2017-01-16 22:07:49 +03:00
2017-01-16 21:24:46 +03:00
auto metadata = containment - > kPackage ( ) . metadata ( ) ;
2017-01-16 22:07:49 +03:00
2017-03-01 17:59:04 +03:00
if ( metadata . pluginId ( ) ! = " org.kde.latte.containment " )
return ;
2017-01-21 21:08:47 +03:00
2017-03-10 23:41:13 +03:00
int session = containment - > config ( ) . readEntry ( " session " , ( int ) Dock : : DefaultSession ) ;
//! when this containment does not belong to this session
if ( session ! = currentSession ( ) & & ! m_waitingSessionDocksCreation ) {
return ;
}
2017-01-16 21:24:46 +03:00
for ( auto * dock : m_dockViews ) {
if ( dock - > containment ( ) = = containment )
2016-12-28 16:17:36 +03:00
return ;
}
2017-01-16 22:07:49 +03:00
2017-02-25 16:29:05 +03:00
QScreen * nextScreen { qGuiApp - > primaryScreen ( ) } ;
2017-03-02 19:07:29 +03:00
//! forceDockLoading is used when a latte configuration based on the
//! current running screens does not provide a dock containing tasks.
//! in such case the lowest latte containment containing tasks is loaded
//! and it forcefully becomes primary dock
2017-03-01 17:59:04 +03:00
bool forceDockLoading = false ;
2017-03-12 06:53:01 +03:00
if ( ! m_tasksWillBeLoaded & & m_firstContainmentWithTasks = = static_cast < int > ( containment - > id ( ) ) ) {
2017-03-01 17:59:04 +03:00
m_tasksWillBeLoaded = true ; //this protects by loading more than one dock at startup
forceDockLoading = true ;
}
2017-02-27 01:53:27 +03:00
bool onPrimary = containment - > config ( ) . readEntry ( " onPrimary " , true ) ;
2017-02-26 03:43:41 +03:00
int id = containment - > screen ( ) ;
if ( id = = - 1 ) {
id = containment - > lastScreen ( ) ;
}
2017-02-27 20:46:10 +03:00
qDebug ( ) < < " add dock - containment id : " < < id ;
2017-02-26 21:06:31 +03:00
2017-03-01 17:59:04 +03:00
if ( id > = 0 & & ! onPrimary & & ! forceDockLoading ) {
2017-02-26 03:43:41 +03:00
QString connector = m_screenPool - > connector ( id ) ;
2017-02-27 20:46:10 +03:00
qDebug ( ) < < " add dock - connector : " < < connector ;
2017-02-25 16:29:05 +03:00
bool found { false } ;
2017-02-27 20:46:10 +03:00
foreach ( auto scr , qGuiApp - > screens ( ) ) {
if ( scr & & scr - > name ( ) = = connector ) {
found = true ;
2017-02-25 16:29:05 +03:00
nextScreen = scr ;
break ;
}
}
2017-03-01 21:49:21 +03:00
if ( ! found ) {
qDebug ( ) < < " adding dock rejected, screen not available : " < < connector ;
2017-02-25 16:29:05 +03:00
return ;
2017-03-01 21:49:21 +03:00
}
2017-02-25 16:29:05 +03:00
}
2016-12-31 00:25:27 +03:00
qDebug ( ) < < " Adding dock for container... " ;
2017-03-12 12:02:24 +03:00
qDebug ( ) < < " onPrimary: " < < onPrimary < < " screen!!! : " < < containment - > screen ( ) ;
2017-03-08 22:00:09 +03:00
//! it is used to set the correct flag during the creation
//! of the window... This of course is also used during
//! recreations of the window between different visibility modes
auto mode = static_cast < Dock : : Visibility > ( containment - > config ( ) . readEntry ( " visibility " , static_cast < int > ( Dock : : DodgeActive ) ) ) ;
2017-04-22 12:37:11 +03:00
bool dockWin { true } ;
2017-03-08 22:00:09 +03:00
2017-04-09 21:42:39 +03:00
if ( mode = = Dock : : AlwaysVisible | | mode = = Dock : : WindowsGoBelow ) {
dockWin = true ;
} else {
2017-04-22 12:37:11 +03:00
dockWin = containment - > config ( ) . readEntry ( " dockWindowBehavior " , true ) ;
2017-03-08 22:00:09 +03:00
}
2017-04-09 21:42:39 +03:00
auto dockView = new DockView ( this , nextScreen , dockWin ) ;
2016-12-25 10:25:27 +03:00
dockView - > init ( ) ;
dockView - > setContainment ( containment ) ;
2017-03-01 17:59:04 +03:00
2017-03-02 19:07:29 +03:00
//! force this special dock case to become primary
//! even though it isnt
2017-03-01 17:59:04 +03:00
if ( forceDockLoading ) {
dockView - > setOnPrimary ( true ) ;
}
2017-03-10 23:41:13 +03:00
dockView - > setSession ( currentSession ( ) ) ;
2017-01-05 01:28:25 +03:00
connect ( containment , & QObject : : destroyed , this , & DockCorona : : dockContainmentDestroyed ) ;
2017-01-16 00:59:15 +03:00
connect ( containment , & Plasma : : Applet : : destroyedChanged , this , & DockCorona : : destroyedChanged ) ;
2017-01-22 14:29:40 +03:00
connect ( containment , & Plasma : : Applet : : locationChanged , this , & DockCorona : : dockLocationChanged ) ;
2017-02-15 07:54:41 +03:00
connect ( containment , & Plasma : : Containment : : appletAlternativesRequested
, this , & DockCorona : : showAlternativesForApplet , Qt : : QueuedConnection ) ;
2016-12-25 10:25:27 +03:00
dockView - > show ( ) ;
2017-01-05 01:28:25 +03:00
m_dockViews [ containment ] = dockView ;
2017-03-10 23:41:13 +03:00
if ( m_waitingSessionDocksCreation ) {
m_waitingSessionDocksCreation = false ;
if ( noDocksForSession ( currentSession ( ) ) = = 1 ) {
syncDockViews ( ) ;
}
}
2017-01-16 21:24:46 +03:00
emit docksCountChanged ( ) ;
2017-01-05 01:28:25 +03:00
}
2017-03-08 22:00:09 +03:00
void DockCorona : : recreateDock ( Plasma : : Containment * containment )
{
auto view = m_dockViews . take ( containment ) ;
if ( view ) {
view - > setVisible ( false ) ;
view - > deleteLater ( ) ;
addDock ( view - > containment ( ) ) ;
}
}
2017-01-16 00:59:15 +03:00
void DockCorona : : destroyedChanged ( bool destroyed )
{
2017-02-26 03:43:41 +03:00
qDebug ( ) < < " dock containment destroyed changed!!!! " ;
2017-01-16 00:59:15 +03:00
Plasma : : Containment * sender = qobject_cast < Plasma : : Containment * > ( QObject : : sender ( ) ) ;
2017-01-16 22:07:49 +03:00
2017-01-16 00:59:15 +03:00
if ( ! sender ) {
return ;
}
2017-01-16 22:07:49 +03:00
2017-01-16 00:59:15 +03:00
if ( destroyed ) {
m_waitingDockViews [ sender ] = m_dockViews . take ( static_cast < Plasma : : Containment * > ( sender ) ) ;
} else {
m_dockViews [ sender ] = m_waitingDockViews . take ( static_cast < Plasma : : Containment * > ( sender ) ) ;
}
2017-01-16 22:07:49 +03:00
2017-01-16 21:24:46 +03:00
emit docksCountChanged ( ) ;
2017-01-16 00:59:15 +03:00
}
2017-01-05 01:28:25 +03:00
void DockCorona : : dockContainmentDestroyed ( QObject * cont )
{
2017-02-26 03:43:41 +03:00
qDebug ( ) < < " dock containment destroyed!!!! " ;
2017-01-16 00:59:15 +03:00
auto view = m_waitingDockViews . take ( static_cast < Plasma : : Containment * > ( cont ) ) ;
2017-01-16 22:07:49 +03:00
2017-01-16 21:24:46 +03:00
if ( view )
2017-05-27 19:31:36 +03:00
view - > deleteLater ( ) ;
2017-01-16 22:07:49 +03:00
2017-01-16 21:24:46 +03:00
emit docksCountChanged ( ) ;
2016-12-25 10:25:27 +03:00
}
2017-02-15 07:54:41 +03:00
void DockCorona : : showAlternativesForApplet ( Plasma : : Applet * applet )
{
const QString alternativesQML = kPackage ( ) . filePath ( " appletalternativesui " ) ;
2017-02-24 21:58:21 +03:00
2017-02-15 07:54:41 +03:00
if ( alternativesQML . isEmpty ( ) ) {
return ;
}
KDeclarative : : QmlObject * qmlObj = new KDeclarative : : QmlObject ( this ) ;
qmlObj - > setInitializationDelayed ( true ) ;
qmlObj - > setSource ( QUrl : : fromLocalFile ( alternativesQML ) ) ;
AlternativesHelper * helper = new AlternativesHelper ( applet , qmlObj ) ;
qmlObj - > rootContext ( ) - > setContextProperty ( QStringLiteral ( " alternativesHelper " ) , helper ) ;
m_alternativesObjects < < qmlObj ;
qmlObj - > completeInitialization ( ) ;
connect ( qmlObj - > rootObject ( ) , SIGNAL ( visibleChanged ( bool ) ) ,
this , SLOT ( alternativesVisibilityChanged ( bool ) ) ) ;
2017-02-24 21:58:21 +03:00
connect ( applet , & Plasma : : Applet : : destroyedChanged , this , [ this , qmlObj ] ( bool destroyed ) {
2017-02-15 07:54:41 +03:00
if ( ! destroyed ) {
return ;
}
2017-02-24 21:58:21 +03:00
2017-02-15 07:54:41 +03:00
QMutableListIterator < KDeclarative : : QmlObject * > it ( m_alternativesObjects ) ;
2017-02-24 21:58:21 +03:00
2017-02-15 07:54:41 +03:00
while ( it . hasNext ( ) ) {
KDeclarative : : QmlObject * obj = it . next ( ) ;
2017-02-24 21:58:21 +03:00
2017-02-15 07:54:41 +03:00
if ( obj = = qmlObj ) {
it . remove ( ) ;
obj - > deleteLater ( ) ;
}
}
} ) ;
}
void DockCorona : : alternativesVisibilityChanged ( bool visible )
{
if ( visible ) {
return ;
}
QObject * root = sender ( ) ;
QMutableListIterator < KDeclarative : : QmlObject * > it ( m_alternativesObjects ) ;
2017-02-24 21:58:21 +03:00
2017-02-15 07:54:41 +03:00
while ( it . hasNext ( ) ) {
KDeclarative : : QmlObject * obj = it . next ( ) ;
2017-02-24 21:58:21 +03:00
2017-02-15 07:54:41 +03:00
if ( obj - > rootObject ( ) = = root ) {
it . remove ( ) ;
obj - > deleteLater ( ) ;
}
}
}
2016-12-31 00:25:27 +03:00
void DockCorona : : loadDefaultLayout ( )
2016-12-25 10:25:27 +03:00
{
qDebug ( ) < < " loading default layout " ;
//! Settting mutable for create a containment
setImmutability ( Plasma : : Types : : Mutable ) ;
QVariantList args ;
2016-12-25 16:58:14 +03:00
auto defaultContainment = createContainmentDelayed ( " org.kde.latte.containment " , args ) ;
2016-12-25 10:25:27 +03:00
defaultContainment - > setContainmentType ( Plasma : : Types : : PanelContainment ) ;
defaultContainment - > init ( ) ;
2017-01-16 22:07:49 +03:00
2016-12-25 10:25:27 +03:00
if ( ! defaultContainment | | ! defaultContainment - > kPackage ( ) . isValid ( ) ) {
qWarning ( ) < < " the requested containment plugin can not be located or loaded " ;
return ;
}
2017-01-16 22:07:49 +03:00
2016-12-25 10:25:27 +03:00
auto config = defaultContainment - > config ( ) ;
2016-12-28 16:17:36 +03:00
defaultContainment - > restore ( config ) ;
2016-12-29 21:50:47 +03:00
QList < Plasma : : Types : : Location > edges = freeEdges ( defaultContainment - > screen ( ) ) ;
2017-01-16 22:07:49 +03:00
2017-03-10 23:41:13 +03:00
if ( ( edges . count ( ) > 0 ) & & ! m_waitingSessionDocksCreation ) {
2016-12-29 21:50:47 +03:00
defaultContainment - > setLocation ( edges . at ( 0 ) ) ;
} else {
defaultContainment - > setLocation ( Plasma : : Types : : BottomEdge ) ;
2016-12-25 10:25:27 +03:00
}
2017-01-16 22:07:49 +03:00
2017-03-26 13:05:25 +03:00
if ( currentSession ( ) ! = Dock : : DefaultSession ) {
config . writeEntry ( " session " , ( int ) currentSession ( ) ) ;
}
2016-12-28 16:17:36 +03:00
defaultContainment - > updateConstraints ( Plasma : : Types : : StartupCompletedConstraint ) ;
2017-03-10 23:41:13 +03:00
2016-12-28 16:17:36 +03:00
defaultContainment - > save ( config ) ;
requestConfigSync ( ) ;
2017-03-10 23:41:13 +03:00
2016-12-28 16:17:36 +03:00
defaultContainment - > flushPendingConstraintsEvents ( ) ;
emit containmentAdded ( defaultContainment ) ;
emit containmentCreated ( defaultContainment ) ;
2017-03-10 23:41:13 +03:00
2016-12-25 10:25:27 +03:00
addDock ( defaultContainment ) ;
2016-12-29 00:07:17 +03:00
defaultContainment - > createApplet ( QStringLiteral ( " org.kde.latte.plasmoid " ) ) ;
2016-12-25 10:25:27 +03:00
defaultContainment - > createApplet ( QStringLiteral ( " org.kde.plasma.analogclock " ) ) ;
}
2017-06-05 23:52:49 +03:00
void DockCorona : : copyDock ( Plasma : : Containment * containment )
{
if ( ! containment )
return ;
qDebug ( ) < < " copying containment layout " ;
//! Settting mutable for create a containment
setImmutability ( Plasma : : Types : : Mutable ) ;
2017-06-06 12:48:11 +03:00
//! WE NEED A WAY TO COPY A CONTAINMENT!!!!
QFile copyFile ( QDir : : homePath ( ) + " /.config/lattedock.copy1.bak " ) ;
if ( copyFile . exists ( ) )
copyFile . remove ( ) ;
KSharedConfigPtr newFile = KSharedConfig : : openConfig ( QDir : : homePath ( ) + " /.config/lattedock.copy1.bak " ) ;
KConfigGroup copied_conts = KConfigGroup ( newFile , " Containments " ) ;
KConfigGroup copied_c1 = KConfigGroup ( & copied_conts , QString : : number ( containment - > id ( ) ) ) ;
containment - > config ( ) . copyTo ( & copied_c1 ) ;
//!investigate if there is a systray in the containment to copy also
int systrayId = - 1 ;
auto applets = containment - > config ( ) . group ( " Applets " ) ;
foreach ( auto applet , applets . groupList ( ) ) {
KConfigGroup appletSettings = applets . group ( applet ) . group ( " Configuration " ) ;
int tSysId = appletSettings . readEntry ( " SystrayContainmentId " , " -1 " ) . toInt ( ) ;
if ( tSysId ! = - 1 ) {
systrayId = tSysId ;
qDebug ( ) < < " systray was found in the containment... " ;
break ;
}
}
if ( systrayId ! = - 1 ) {
Plasma : : Containment * systray { nullptr } ;
foreach ( auto containment , containments ( ) ) {
if ( containment - > id ( ) = = systrayId ) {
systray = containment ;
break ;
}
}
if ( systray ) {
KConfigGroup copied_systray = KConfigGroup ( & copied_conts , QString : : number ( systray - > id ( ) ) ) ;
systray - > config ( ) . copyTo ( & copied_systray ) ;
}
}
//! end of systray specific code
//! Finally import the configuration
auto nConts = importLayout ( KConfigGroup ( newFile , " " ) ) ;
///Find latte and systray containments
qDebug ( ) < < " imported containments ::: " < < nConts . length ( ) ;
2017-06-05 23:52:49 +03:00
Plasma : : Containment * newContainment { nullptr } ;
2017-06-06 12:48:11 +03:00
int newSystrayId = - 1 ;
2017-06-05 23:52:49 +03:00
2017-06-06 12:48:11 +03:00
foreach ( auto containment , nConts ) {
KPluginMetaData meta = containment - > kPackage ( ) . metadata ( ) ;
if ( meta . pluginId ( ) = = " org.kde.latte.containment " ) {
qDebug ( ) < < " new latte containment id: " < < containment - > id ( ) ;
newContainment = containment ;
} else if ( meta . pluginId ( ) = = " org.kde.plasma.private.systemtray " ) {
qDebug ( ) < < " new systray containment id: " < < containment - > id ( ) ;
newSystrayId = containment - > id ( ) ;
}
}
2017-06-05 23:52:49 +03:00
if ( ! newContainment )
return ;
2017-06-06 12:48:11 +03:00
///after systray was found we must update in latte the relevant id
if ( newSystrayId ! = - 1 ) {
applets = newContainment - > config ( ) . group ( " Applets " ) ;
qDebug ( ) < < " systray found with id : " < < newSystrayId < < " and applets in the containment : " < < applets . groupList ( ) . count ( ) ;
foreach ( auto applet , applets . groupList ( ) ) {
KConfigGroup appletSettings = applets . group ( applet ) . group ( " Configuration " ) ;
if ( appletSettings . hasKey ( " SystrayContainmentId " ) ) {
qDebug ( ) < < " !!! updating systray id to : " < < newSystrayId ;
appletSettings . writeEntry ( " SystrayContainmentId " , newSystrayId ) ;
}
}
}
2017-06-05 23:52:49 +03:00
newContainment - > setContainmentType ( Plasma : : Types : : PanelContainment ) ;
newContainment - > init ( ) ;
if ( ! newContainment | | ! newContainment - > kPackage ( ) . isValid ( ) ) {
qWarning ( ) < < " the requested containment plugin can not be located or loaded " ;
return ;
}
auto config = newContainment - > config ( ) ;
newContainment - > restore ( config ) ;
2017-06-06 13:39:23 +03:00
//in multi-screen environment the copied dock is moved to alternative screens first
const auto screens = qGuiApp - > screens ( ) ;
auto dock = m_dockViews [ containment ] ;
bool setOnExplicitScreen = false ;
2017-06-11 23:30:55 +03:00
int dockScrId = - 1 ;
2017-06-06 13:39:23 +03:00
2017-06-11 23:30:55 +03:00
if ( dock ) {
dockScrId = m_screenPool - > id ( dock - > currentScreen ( ) ) ;
if ( dockScrId ! = - 1 & & screens . count ( ) > 1 ) {
2017-06-06 13:39:23 +03:00
foreach ( auto scr , screens ) {
int copyScrId = m_screenPool - > id ( scr - > name ( ) ) ;
//the screen must exist and not be the same with the original dock
if ( copyScrId > - 1 & & copyScrId ! = dockScrId ) {
QList < Plasma : : Types : : Location > fEdges = freeEdges ( copyScrId ) ;
if ( fEdges . contains ( ( Plasma : : Types : : Location ) containment - > location ( ) ) ) {
///set this containment to an explicit screen
newContainment - > config ( ) . writeEntry ( " onPrimary " , false ) ;
newContainment - > config ( ) . writeEntry ( " lastScreen " , copyScrId ) ;
setOnExplicitScreen = true ;
}
}
}
}
}
if ( ! setOnExplicitScreen ) {
QList < Plasma : : Types : : Location > edges = freeEdges ( newContainment - > screen ( ) ) ;
if ( edges . count ( ) > 0 ) {
newContainment - > setLocation ( edges . at ( 0 ) ) ;
} else {
newContainment - > setLocation ( Plasma : : Types : : BottomEdge ) ;
}
2017-06-11 23:30:55 +03:00
newContainment - > config ( ) . writeEntry ( " onPrimary " , false ) ;
newContainment - > config ( ) . writeEntry ( " lastScreen " , dockScrId ) ;
2017-06-05 23:52:49 +03:00
}
if ( currentSession ( ) ! = Dock : : DefaultSession ) {
2017-06-11 23:30:55 +03:00
newContainment - > config ( ) . writeEntry ( " session " , ( int ) currentSession ( ) ) ;
2017-06-05 23:52:49 +03:00
}
newContainment - > updateConstraints ( Plasma : : Types : : StartupCompletedConstraint ) ;
newContainment - > save ( config ) ;
requestConfigSync ( ) ;
newContainment - > flushPendingConstraintsEvents ( ) ;
emit containmentAdded ( newContainment ) ;
emit containmentCreated ( newContainment ) ;
addDock ( newContainment ) ;
}
2017-03-01 17:59:04 +03:00
//! This function figures in the beginning if a dock with tasks
2017-03-02 19:07:29 +03:00
//! in it will be loaded taking into account also the screens are present.
2017-03-01 17:59:04 +03:00
bool DockCorona : : heuresticForLoadingDockWithTasks ( )
{
auto containmentsEntries = config ( ) - > group ( " Containments " ) ;
foreach ( auto cId , containmentsEntries . groupList ( ) ) {
QString plugin = containmentsEntries . group ( cId ) . readEntry ( " plugin " ) ;
if ( plugin = = " org.kde.latte.containment " ) {
bool onPrimary = containmentsEntries . group ( cId ) . readEntry ( " onPrimary " , true ) ;
int lastScreen = containmentsEntries . group ( cId ) . readEntry ( " lastScreen " , - 1 ) ;
2017-03-11 02:45:31 +03:00
Dock : : SessionType session = static_cast < Dock : : SessionType > ( containmentsEntries . group ( cId ) . readEntry ( " session " , ( int ) Dock : : DefaultSession ) ) ;
2017-03-01 17:59:04 +03:00
qDebug ( ) < < " containment values: " < < onPrimary < < " - " < < lastScreen ;
auto appletEntries = containmentsEntries . group ( cId ) . group ( " Applets " ) ;
bool containsTasks = false ;
foreach ( auto appId , appletEntries . groupList ( ) ) {
if ( appletEntries . group ( appId ) . readEntry ( " plugin " ) = = " org.kde.latte.plasmoid " ) {
containsTasks = true ;
break ;
}
}
2017-03-10 23:41:13 +03:00
if ( containsTasks & & session = = Dock : : DefaultSession ) {
2017-03-01 17:59:04 +03:00
m_firstContainmentWithTasks = cId . toInt ( ) ;
2017-03-02 19:07:29 +03:00
2017-03-01 17:59:04 +03:00
if ( onPrimary ) {
return true ;
} else {
if ( lastScreen > = 0 ) {
QString connector = m_screenPool - > connector ( lastScreen ) ;
foreach ( auto scr , qGuiApp - > screens ( ) ) {
if ( scr & & scr - > name ( ) = = connector ) {
return true ;
break ;
}
}
}
}
}
}
}
return false ;
}
//! This function figures if a latte containment contains a
//! latte tasks plasmoid
bool DockCorona : : containmentContainsTasks ( Plasma : : Containment * cont )
{
auto containmentsEntries = config ( ) - > group ( " Containments " ) ;
foreach ( auto cId , containmentsEntries . groupList ( ) ) {
QString plugin = containmentsEntries . group ( cId ) . readEntry ( " plugin " ) ;
if ( ( plugin = = " org.kde.latte.containment " ) & & ( cId . toUInt ( ) = = cont - > id ( ) ) ) {
auto appletEntries = containmentsEntries . group ( cId ) . group ( " Applets " ) ;
foreach ( auto appId , appletEntries . groupList ( ) ) {
if ( appletEntries . group ( appId ) . readEntry ( " plugin " ) = = " org.kde.latte.plasmoid " ) {
return true ;
break ;
}
}
}
}
return false ;
}
2017-03-11 11:06:10 +03:00
//! Activate launcher menu through dbus interface
void DockCorona : : activateLauncherMenu ( )
{
2017-06-04 01:58:03 +03:00
m_globalShortcuts - > activateLauncherMenu ( ) ;
2017-03-11 11:06:10 +03:00
}
2017-04-11 20:23:43 +03:00
//! update badge for specific dock item
void DockCorona : : updateDockItemBadge ( QString identifier , QString value )
{
2017-06-04 01:58:03 +03:00
m_globalShortcuts - > updateDockItemBadge ( identifier , value ) ;
2017-04-11 20:23:43 +03:00
}
2016-12-31 00:25:27 +03:00
inline void DockCorona : : qmlRegisterTypes ( ) const
2016-12-25 10:25:27 +03:00
{
qmlRegisterType < QScreen > ( ) ;
}
2016-12-30 10:20:06 +03:00
}