2 * Copyright 2008 Aaron Seigo <aseigo@kde.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "desktopcorona.h"
22 #include <QApplication>
24 #include <QGraphicsLayout>
29 #include <KGlobalSettings>
30 #include <KStandardDirs>
31 #include <KWindowSystem>
33 #include <Plasma/Containment>
34 #include <Plasma/DataEngineManager>
36 #include <kephal/screens.h>
38 #include "panelview.h"
39 #include "plasmaapp.h"
40 #include "plasma-shell-desktop.h"
42 DesktopCorona::DesktopCorona(QObject
*parent
)
43 : Plasma::Corona(parent
)
48 void DesktopCorona::init()
50 Kephal::Screens
*screens
= Kephal::Screens::self();
51 connect(screens
, SIGNAL(screenAdded(Kephal::Screen
*)), SLOT(screenAdded(Kephal::Screen
*)));
52 connect(KWindowSystem::self(), SIGNAL(workAreaChanged()), this, SIGNAL(availableScreenRegionChanged()));
55 void DesktopCorona::checkScreens()
57 // quick sanity check to ensure we have containments for each screen
58 int numScreens
= Kephal::ScreenUtils::numScreens();
59 for (int i
= 0; i
< numScreens
; ++i
) {
64 void DesktopCorona::checkScreen(int screen
, bool signalWhenExists
)
66 if (AppSettings::perVirtualDesktopViews()) {
67 int numDesktops
= KWindowSystem::numberOfDesktops();
69 for (int j
= 0; j
< numDesktops
; ++j
) {
70 Plasma::Containment
*c
= containmentForScreen(screen
, j
);
73 addDesktopContainment(screen
, j
);
74 } else if (signalWhenExists
) {
75 emit
containmentAdded(c
);
79 Plasma::Containment
*c
= containmentForScreen(screen
);
80 if (!containmentForScreen(screen
)) {
81 addDesktopContainment(screen
);
82 } else if (signalWhenExists
) {
83 emit
containmentAdded(c
);
88 void DesktopCorona::addDesktopContainment(int screen
, int desktop
)
90 kDebug() << screen
<< desktop
;
91 Plasma::Containment
* c
= addContainment("desktop");
92 c
->setScreen(screen
, desktop
);
93 c
->setFormFactor(Plasma::Planar
);
94 c
->flushPendingConstraintsEvents();
95 c
->setActivity(i18n("Desktop"));
96 emit
containmentAdded(c
);
99 int DesktopCorona::numScreens() const
101 return Kephal::ScreenUtils::numScreens();
104 QRect
DesktopCorona::screenGeometry(int id
) const
106 return Kephal::ScreenUtils::screenGeometry(id
);
109 QRegion
DesktopCorona::availableScreenRegion(int id
) const
111 QRegion
r(screenGeometry(id
));
112 foreach (PanelView
*view
, PlasmaApp::self()->panelViews()) {
113 if (view
->screen() == id
&& view
->visibilityMode() == PanelView::NormalPanel
) {
114 r
= r
.subtracted(view
->geometry());
121 void DesktopCorona::loadDefaultLayout()
123 QString defaultConfig
= KStandardDirs::locate("appdata", "plasma-default-layoutrc");
124 if (!defaultConfig
.isEmpty()) {
125 kDebug() << "attempting to load the default layout from:" << defaultConfig
;
126 loadLayout(defaultConfig
);
130 kDebug() << "number of screens is" << Kephal::ScreenUtils::numScreens();
131 int topLeftScreen
= 0;
132 QPoint topLeftCorner
= Kephal::ScreenUtils::screenGeometry(0).topLeft();
134 // find our "top left" screen, use it as the primary
135 for (int i
= 0; i
< Kephal::ScreenUtils::numScreens(); ++i
) {
136 QRect g
= Kephal::ScreenUtils::screenGeometry(i
);
137 kDebug() << " screen " << i
<< "geometry is" << g
;
139 if (g
.x() <= topLeftCorner
.x() && g
.y() >= topLeftCorner
.y()) {
140 topLeftCorner
= g
.topLeft();
145 // create a containment for each screen
146 for (int i
= 0; i
< Kephal::ScreenUtils::numScreens(); ++i
) {
147 // passing in an empty string will get us whatever the default
148 // containment type is!
149 Plasma::Containment
* c
= addContainmentDelayed(QString());
157 c
->setWallpaper("image", "SingleImage");
158 c
->setFormFactor(Plasma::Planar
);
159 c
->updateConstraints(Plasma::StartupCompletedConstraint
);
160 c
->flushPendingConstraintsEvents();
162 // put a folder view on the first screen
163 if (i
== topLeftScreen
) {
164 QString desktopPath
= KGlobalSettings::desktopPath();
165 QDir
desktopFolder(desktopPath
);
166 if (desktopPath
!= QDir::homePath() && desktopFolder
.exists()) {
167 Plasma::Applet
*folderView
= Plasma::Applet::load("folderview", c
->id() + 1);
169 c
->addApplet(folderView
, QPointF(KDialog::spacingHint(), KDialog::spacingHint()), true);
170 KConfigGroup config
= folderView
->config();
171 config
.writeEntry("url", "desktop:/");
176 emit
containmentAdded(c
);
179 // make a panel at the bottom
180 Plasma::Containment
*panel
= addContainmentDelayed("panel");
187 panel
->setScreen(topLeftScreen
);
188 panel
->setLocation(Plasma::BottomEdge
);
189 panel
->updateConstraints(Plasma::StartupCompletedConstraint
);
190 panel
->flushPendingConstraintsEvents();
192 // some default applets to get a usable UI
193 Plasma::Applet
*applet
= loadDefaultApplet("launcher", panel
);
195 applet
->setGlobalShortcut(KShortcut("Alt+F1"));
198 loadDefaultApplet("notifier", panel
);
199 loadDefaultApplet("pager", panel
);
200 loadDefaultApplet("tasks", panel
);
201 loadDefaultApplet("systemtray", panel
);
203 Plasma::DataEngineManager
*engines
= Plasma::DataEngineManager::self();
204 Plasma::DataEngine
*power
= engines
->loadEngine("powermanagement");
206 const QStringList
&batteries
= power
->query("Battery")["sources"].toStringList();
207 if (!batteries
.isEmpty()) {
208 loadDefaultApplet("battery", panel
);
211 engines
->unloadEngine("powermanagement");
213 loadDefaultApplet("digital-clock", panel
);
214 emit
containmentAdded(panel
);
216 QTimer::singleShot(1000, this, SLOT(saveDefaultSetup()));
219 void DesktopCorona::saveDefaultSetup()
221 // a "null" KConfigGroup is used to force a save into the config file
222 KConfigGroup invalidConfig
;
224 foreach (Plasma::Containment
*containment
, containments()) {
225 containment
->save(invalidConfig
);
227 foreach (Plasma::Applet
* applet
, containment
->applets()) {
229 applet
->flushPendingConstraintsEvents();
230 applet
->save(invalidConfig
);
237 Plasma::Applet
*DesktopCorona::loadDefaultApplet(const QString
&pluginName
, Plasma::Containment
*c
)
240 Plasma::Applet
*applet
= Plasma::Applet::load(pluginName
, 0, args
);
243 c
->addApplet(applet
);
249 void DesktopCorona::screenAdded(Kephal::Screen
*s
)
252 checkScreen(s
->id(), true);
255 #include "desktopcorona.moc"