2 * Copyright 2006 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 "plasmaapp.h"
26 #define _WIN32_WINNT 0x0500
32 #ifndef _SC_PHYS_PAGES
34 #include <sys/types.h>
35 #include <sys/sysctl.h>
39 #include <sys/param.h>
40 #include <sys/sysctl.h>
44 #include <QApplication>
45 #include <QDesktopWidget>
46 #include <QPixmapCache>
48 #include <QtDBus/QtDBus>
53 #include <KCmdLineArgs>
54 #include <KWindowSystem>
56 #include <ksmserver_interface.h>
58 #include <Plasma/Containment>
59 #include <Plasma/Theme>
60 #include <Plasma/Dialog>
62 #include "appletbrowser.h"
63 #include "appadaptor.h"
64 #include "backgrounddialog.h"
65 #include "desktopcorona.h"
66 #include "desktopview.h"
67 #include "panelview.h"
68 #include "plasma-shell-desktop.h"
69 #include "toolbutton.h"
71 #include <kephal/screens.h>
75 #include <X11/extensions/Xrender.h>
78 PlasmaApp
* PlasmaApp::self()
81 return new PlasmaApp();
84 return qobject_cast
<PlasmaApp
*>(kapp
);
87 PlasmaApp::PlasmaApp()
88 : KUniqueApplication(),
92 m_zoomLevel(Plasma::DesktopZoom
),
95 KGlobal::locale()->insertCatalog("libplasma");
96 KGlobal::locale()->insertCatalog("plasma-shells-common");
97 KCrash::setFlags(KCrash::AutoRestart
);
99 new PlasmaAppAdaptor(this);
100 QDBusConnection::sessionBus().registerObject("/App", this);
101 notifyStartup(false);
103 // Enlarge application pixmap cache
104 // Calculate the size required to hold background pixmaps for all screens.
105 // Add 10% so that other (smaller) pixmaps can also be cached.
107 for (int i
= 0; i
< Kephal::ScreenUtils::numScreens(); i
++) {
108 QSize size
= Kephal::ScreenUtils::screenSize(i
);
109 cacheSize
+= 4 * size
.width() * size
.height() / 1024;
111 cacheSize
+= cacheSize
/ 10;
113 // Calculate the size of physical system memory; _SC_PHYS_PAGES *
114 // _SC_PAGESIZE is documented to be able to overflow 32-bit integers,
115 // so apply a 10-bit shift. FreeBSD 6-STABLE doesn't have _SC_PHYS_PAGES
116 // (it is documented in FreeBSD 7-STABLE as "Solaris and Linux extension")
117 // so use sysctl in those cases.
118 #if defined(_SC_PHYS_PAGES)
119 int memorySize
= sysconf(_SC_PHYS_PAGES
);
120 memorySize
*= sysconf(_SC_PAGESIZE
) / 1024;
124 size_t size
= sizeof(sysctlbuf
);
126 // This could actually use hw.physmem instead, but I can't find
127 // reliable documentation on how to read the value (which may
128 // not fit in a 32 bit integer).
129 if (!sysctlbyname("vm.stats.vm.v_page_size", sysctlbuf
, &size
, NULL
, 0)) {
130 memorySize
= sysctlbuf
[0] / 1024;
131 size
= sizeof(sysctlbuf
);
132 if (!sysctlbyname("vm.stats.vm.v_page_count", sysctlbuf
, &size
, NULL
, 0)) {
133 memorySize
*= sysctlbuf
[0];
140 static int mib
[] = { CTL_HW
, HW_PHYSMEM
};
142 len
= sizeof(memorySize
);
143 sysctl(mib
, 2, &memorySize
, &len
, NULL
, 0);
149 MEMORYSTATUSEX statex
;
150 statex
.dwLength
= sizeof (statex
);
151 GlobalMemoryStatusEx (&statex
);
153 memorySize
= (statex
.ullTotalPhys
/1024) + (statex
.ullTotalPageFile
/1024);
155 // If you have no suitable sysconf() interface and are not FreeBSD,
156 // then you are out of luck and get a compile error.
159 // Increase the pixmap cache size to 1% of system memory if it isn't already
160 // larger so as to maximize cache usage. 1% of 1GB ~= 10MB.
161 if (cacheSize
< memorySize
/ 100) {
162 cacheSize
= memorySize
/ 100;
165 kDebug() << "Setting the pixmap cache size to" << cacheSize
<< "kilobytes";
166 QPixmapCache::setCacheLimit(cacheSize
);
168 KAction
*showAction
= new KAction(this);
169 showAction
->setText(i18n("Show Dashboard"));
170 showAction
->setObjectName("Show Dashboard"); // NO I18N
171 showAction
->setGlobalShortcut(KShortcut(Qt::CTRL
+ Qt::Key_F12
));
172 connect(showAction
, SIGNAL(triggered()), this, SLOT(toggleDashboard()));
174 connect(this, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));
175 QTimer::singleShot(0, this, SLOT(setupDesktop()));
178 PlasmaApp::~PlasmaApp()
180 delete m_appletBrowser
;
183 void PlasmaApp::setupDesktop()
187 const char * const atomNames
[] = {"XdndAware", "XdndEnter", "XdndFinished", "XdndPosition", "XdndStatus"};
188 XInternAtoms(QX11Info::display(), const_cast<char **>(atomNames
), 5, False
, atoms
);
189 m_XdndAwareAtom
= atoms
[0];
190 m_XdndEnterAtom
= atoms
[1];
191 m_XdndFinishedAtom
= atoms
[2];
192 m_XdndPositionAtom
= atoms
[3];
193 m_XdndStatusAtom
= atoms
[4];
194 const int xdndversion
= 5;
195 m_XdndVersionAtom
= (Atom
)xdndversion
;
198 // intialize the default theme and set the font
199 Plasma::Theme
*theme
= Plasma::Theme::defaultTheme();
200 theme
->setFont(AppSettings::desktopFont());
201 connect(theme
, SIGNAL(themeChanged()), this, SLOT(compositingChanged()));
203 // this line initializes the corona.
206 Kephal::Screens
*screens
= Kephal::Screens::self();
207 connect(screens
, SIGNAL(screenRemoved(int)), SLOT(screenRemoved(int)));
209 // and now, let everyone know we're ready!
213 void PlasmaApp::cleanup()
216 m_corona
->saveLayout();
219 // save the mapping of Views to Containments at the moment
220 // of application exit so we can restore that when we start again.
221 KConfigGroup
viewIds(KGlobal::config(), "ViewIds");
222 viewIds
.deleteGroup();
224 foreach (PanelView
*v
, m_panels
) {
225 if (v
->containment()) {
226 viewIds
.writeEntry(QString::number(v
->containment()->id()), v
->id());
230 foreach (DesktopView
*v
, m_desktops
) {
231 if (v
->containment()) {
232 viewIds
.writeEntry(QString::number(v
->containment()->id()), v
->id());
236 QList
<DesktopView
*> desktops
= m_desktops
;
238 qDeleteAll(desktops
);
240 QList
<PanelView
*> panels
= m_panels
;
246 //TODO: This manual sync() should not be necessary. Remove it when
248 KGlobal::config()->sync();
251 void PlasmaApp::syncConfig()
253 KGlobal::config()->sync();
256 void PlasmaApp::toggleDashboardIfWindows()
258 const int desktop
= KWindowSystem::currentDesktop();
260 foreach (WId id
, KWindowSystem::stackingOrder()) {
261 const KWindowInfo info
= KWindowSystem::windowInfo(id
, NET::WMDesktop
| NET::WMState
|
262 NET::XAWMState
| NET::WMWindowType
|
264 NET::WindowType type
= info
.windowType(NET::Normal
| NET::Dialog
);
265 if ((type
== NET::Normal
|| type
== NET::Dialog
) &&
266 info
.isOnDesktop(desktop
) && !(info
.state() & NET::Hidden
) /*!info.isMinimized()*/) {
267 kDebug() << info
.visibleName() << info
.state() << info
.windowType(NET::Normal
| NET::Dialog
);
274 void PlasmaApp::toggleDashboard()
276 int currentScreen
= 0;
277 if (Kephal::ScreenUtils::numScreens() > 1) {
278 currentScreen
= Kephal::ScreenUtils::screenId(QCursor::pos());
281 int currentDesktop
= -1;
282 if (AppSettings::perVirtualDesktopViews()) {
283 currentDesktop
= KWindowSystem::currentDesktop();
286 DesktopView
*view
= viewForScreen(currentScreen
, currentDesktop
);
288 kWarning() << "we don't have a DesktopView for the current screen!" << currentScreen
<< currentDesktop
;
292 view
->toggleDashboard();
295 void PlasmaApp::panelHidden(bool hidden
)
299 //kDebug() << "panel hidden" << m_panelHidden;
302 if (m_panelHidden
< 0) {
303 kDebug() << "panelHidden(false) called too many times!";
306 //kDebug() << "panel unhidden" << m_panelHidden;
310 Plasma::ZoomLevel
PlasmaApp::desktopZoomLevel() const
315 QList
<PanelView
*> PlasmaApp::panelViews() const
320 void PlasmaApp::compositingChanged()
323 foreach (PanelView
*panel
, m_panels
) {
324 panel
->recreateUnhideTrigger();
330 PanelView
*PlasmaApp::findPanelForTrigger(WId trigger
) const
332 foreach (PanelView
*panel
, m_panels
) {
333 if (panel
->unhideTrigger() == trigger
) {
341 bool PlasmaApp::x11EventFilter(XEvent
*event
)
344 (event
->type
== ClientMessage
||
345 (event
->xany
.send_event
!= True
&& (event
->type
== EnterNotify
||
346 event
->type
== MotionNotify
)))) {
349 if (event->type == ClientMessage) {
350 kDebug() << "client message with" << event->xclient.message_type << m_XdndEnterAtom << event->xcrossing.window;
354 bool dndEnter
= false;
355 bool dndPosition
= false;
356 if (event
->type
== ClientMessage
) {
357 dndEnter
= event
->xclient
.message_type
== m_XdndEnterAtom
;
359 dndPosition
= event
->xclient
.message_type
== m_XdndPositionAtom
;
361 //kDebug() << "FAIL!";
362 return KUniqueApplication::x11EventFilter(event
);
365 //kDebug() << "on enter" << event->xclient.data.l[0];
369 PanelView
*panel
= findPanelForTrigger(event
->xcrossing
.window
);
370 //kDebug() << "panel?" << panel << ((dndEnter || dndPosition) ? "Drag and drop op" : "Mouse move op");
372 if (dndEnter
|| dndPosition
) {
375 const unsigned long *l
= (const unsigned long *)event
->xclient
.data
.l
;
377 p
= QPoint((l
[2] & 0xffff0000) >> 16, l
[2] & 0x0000ffff);
380 XClientMessageEvent response
;
381 response
.type
= ClientMessage
;
382 response
.window
= l
[0];
383 response
.format
= 32;
384 response
.data
.l
[0] = panel
->winId(); //event->xcrossing.window;
386 if (panel
->hintOrUnhide(p
, true)) {
387 response
.message_type
= m_XdndFinishedAtom
;
388 response
.data
.l
[1] = 0; // flags
389 response
.data
.l
[2] = XNone
;
391 response
.message_type
= m_XdndStatusAtom
;
392 response
.data
.l
[1] = 0; // flags
393 response
.data
.l
[2] = 0; // x, y
394 response
.data
.l
[3] = 0; // w, h
395 response
.data
.l
[4] = 0; // action
398 XSendEvent(QX11Info::display(), l
[0], False
, NoEventMask
, (XEvent
*)&response
);
399 } else if (event
->type
== EnterNotify
) {
400 panel
->hintOrUnhide(QPoint(-1, -1));
401 //kDebug() << "entry";
402 //FIXME: this if it was possible to avoid the polling
403 /*} else if (event->type == LeaveNotify) {
406 } else if (event
->type
== MotionNotify
) {
407 XMotionEvent
*motion
= (XMotionEvent
*)event
;
408 //kDebug() << "motion" << motion->x << motion->y << panel->location();
409 panel
->hintOrUnhide(QPoint(motion
->x_root
, motion
->y_root
));
416 return KUniqueApplication::x11EventFilter(event
);
420 void PlasmaApp::screenRemoved(int id
)
423 QMutableListIterator
<DesktopView
*> it(m_desktops
);
424 while (it
.hasNext()) {
425 DesktopView
*view
= it
.next();
426 if (view
->screen() == id
) {
427 // the screen was removed, so we'll destroy the
428 // corresponding view
429 kDebug() << "removing the view for screen" << id
;
430 view
->setContainment(0);
436 QMutableListIterator
<PanelView
*> pIt(m_panels
);
437 while (pIt
.hasNext()) {
438 PanelView
*panel
= pIt
.next();
439 if (panel
->screen() == id
) {
440 kDebug() << "removing a panel for screen" << id
;
441 panel
->setContainment(0);
448 DesktopView
* PlasmaApp::viewForScreen(int screen
, int desktop
) const
450 foreach (DesktopView
*view
, m_desktops
) {
451 //kDebug() << "comparing" << view->screen() << screen;
452 if (view
->screen() == screen
&& (desktop
< 0 || view
->desktop() == desktop
)) {
460 Plasma::Corona
* PlasmaApp::corona()
465 DesktopCorona
*c
= new DesktopCorona(this);
466 connect(c
, SIGNAL(containmentAdded(Plasma::Containment
*)),
467 this, SLOT(containmentAdded(Plasma::Containment
*)));
468 connect(c
, SIGNAL(configSynced()), this, SLOT(syncConfig()));
469 connect(c
, SIGNAL(immutabilityChanged(Plasma::ImmutabilityType
)),
470 this, SLOT(updateActions(Plasma::ImmutabilityType
)));
472 foreach (DesktopView
*view
, m_desktops
) {
473 connect(c
, SIGNAL(screenOwnerChanged(int,int,Plasma::Containment
*)),
474 view
, SLOT(screenOwnerChanged(int,int,Plasma::Containment
*)));
478 KAction
*activityAction
= new KAction(i18n("Add Activity"), this);
479 activityAction
->setIcon(KIcon("list-add"));
480 activityAction
->setVisible(false);
481 activityAction
->setEnabled(false);
482 connect(activityAction
, SIGNAL(triggered()), this, SLOT(addContainment()));
483 activityAction
->setShortcut(QKeySequence("alt+d,alt+a"));
484 activityAction
->setShortcutContext(Qt::ApplicationShortcut
);
485 c
->addAction("add sibling containment", activityAction
);
488 c
->setItemIndexMethod(QGraphicsScene::NoIndex
);
489 c
->initializeLayout();
491 kDebug() << " ------------------------------------------>" << t
.elapsed();
497 void PlasmaApp::showAppletBrowser()
499 Plasma::Containment
*containment
= dynamic_cast<Plasma::Containment
*>(sender());
505 foreach (DesktopView
*view
, m_desktops
) {
506 if (view
->containment() == containment
&& view
->isDashboardVisible()) {
507 // the dashboard will pick this one up!
512 showAppletBrowser(containment
);
515 void PlasmaApp::showAppletBrowser(Plasma::Containment
*containment
)
521 if (!m_appletBrowser
) {
522 m_appletBrowser
= new Plasma::AppletBrowser();
523 m_appletBrowser
->setContainment(containment
);
524 m_appletBrowser
->setApplication();
525 m_appletBrowser
->setAttribute(Qt::WA_DeleteOnClose
);
526 m_appletBrowser
->setWindowTitle(i18n("Add Widgets"));
527 m_appletBrowser
->setWindowIcon(KIcon("plasmagik"));
528 connect(m_appletBrowser
, SIGNAL(destroyed()), this, SLOT(appletBrowserDestroyed()));
530 m_appletBrowser
->setContainment(containment
);
533 KWindowSystem::setOnDesktop(m_appletBrowser
->winId(), KWindowSystem::currentDesktop());
534 m_appletBrowser
->show();
535 KWindowSystem::activateWindow(m_appletBrowser
->winId());
538 void PlasmaApp::appletBrowserDestroyed()
543 bool PlasmaApp::hasComposite()
547 return KWindowSystem::compositingActive();
553 void PlasmaApp::notifyStartup(bool completed
)
555 org::kde::KSMServerInterface
ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus());
557 const QString
startupID("workspace desktop");
559 ksmserver
.resumeStartup(startupID
);
561 ksmserver
.suspendStartup(startupID
);
565 bool PlasmaApp::isPanelContainment(Plasma::Containment
*containment
)
567 Plasma::Containment::Type t
= containment
->containmentType();
569 return t
== Plasma::Containment::PanelContainment
||
570 t
== Plasma::Containment::CustomPanelContainment
;
574 void PlasmaApp::createView(Plasma::Containment
*containment
)
576 kDebug() << "Containment name:" << containment
->name()
577 << "| type" << containment
->containmentType()
578 << "| screen:" << containment
->screen()
579 << "| desktop:" << containment
->desktop()
580 << "| geometry:" << containment
->geometry()
581 << "| zValue:" << containment
->zValue();
583 // find the mapping of View to Containment, if any,
584 // so we can restore things on start.
585 KConfigGroup
viewIds(KGlobal::config(), "ViewIds");
586 int id
= viewIds
.readEntry(QString::number(containment
->id()), 0);
590 if (isPanelContainment(containment
)) {
591 if (containment
->screen() < Kephal::ScreenUtils::numScreens()) {
592 PanelView
*panelView
= new PanelView(containment
, id
);
593 viewWindow
= panelView
->winId();
594 connect(panelView
, SIGNAL(destroyed(QObject
*)), this, SLOT(panelRemoved(QObject
*)));
595 m_panels
<< panelView
;
598 } else if (containment
->screen() > -1 &&
599 containment
->screen() < Kephal::ScreenUtils::numScreens()) {
600 DesktopView
*view
= viewForScreen(containment
->screen(), containment
->desktop());
602 kDebug() << "had a view for" << containment
->screen() << containment
->desktop();
603 // we already have a view for this screen
607 kDebug() << "creating a new view for" << containment
->screen() << containment
->desktop()
608 << "and we have" << Kephal::ScreenUtils::numScreens() << "screens";
610 // we have a new screen. neat.
611 view
= new DesktopView(containment
, id
, 0);
612 viewWindow
= view
->winId();
614 connect(m_corona
, SIGNAL(screenOwnerChanged(int,int,Plasma::Containment
*)),
615 view
, SLOT(screenOwnerChanged(int,int,Plasma::Containment
*)));
618 m_desktops
.append(view
);
623 //FIXME: if argb visuals enabled Qt will always set WM_CLASS as "qt-subapplication" no matter what
624 //the application name is we set the proper XClassHint here, hopefully won't be necessary anymore when
625 //qapplication will manage apps with argvisuals in a better way
627 XClassHint classHint
;
628 classHint
.res_name
= const_cast<char*>("Plasma");
629 classHint
.res_class
= const_cast<char*>("Plasma");
630 XSetClassHint(QX11Info::display(), viewWindow
, &classHint
);
635 void PlasmaApp::containmentAdded(Plasma::Containment
*containment
)
637 if (isPanelContainment(containment
)) {
638 foreach (PanelView
* panel
, m_panels
) {
639 if (panel
->containment() == containment
) {
640 kDebug() << "not creating second PanelView with existing Containment!!";
646 createView(containment
);
647 disconnect(containment
, 0, this, 0);
648 connect(containment
, SIGNAL(zoomRequested(Plasma::Containment
*,Plasma::ZoomDirection
)),
649 this, SLOT(zoom(Plasma::Containment
*,Plasma::ZoomDirection
)));
650 connect(containment
, SIGNAL(showAddWidgetsInterface(QPointF
)), this, SLOT(showAppletBrowser()));
651 connect(containment
, SIGNAL(configureRequested(Plasma::Containment
*)),
652 this, SLOT(configureContainment(Plasma::Containment
*)));
654 if (containment
->containmentType() == Plasma::Containment::DesktopContainment
655 && m_zoomLevel
== Plasma::DesktopZoom
) {
656 foreach (QAction
*action
, m_corona
->actions()) {
657 containment
->addToolBoxAction(action
);
662 void PlasmaApp::configureContainment(Plasma::Containment
*containment
)
664 const QString id
= "plasma_containment_settings_" + QString::number(containment
->id());
665 BackgroundDialog
*configDialog
= qobject_cast
<BackgroundDialog
*>(KConfigDialog::exists(id
));
666 kDebug() << configDialog
;
669 configDialog
->reloadConfig();
671 const QSize resolution
= QApplication::desktop()->screenGeometry(containment
->screen()).size();
672 Plasma::View
*view
= viewForScreen(containment
->screen(), containment
->desktop());
675 view
= viewForScreen(desktop()->screenNumber(QCursor::pos()), containment
->desktop());
678 if (m_desktops
.count() < 1) {
682 view
= m_desktops
.at(0);
687 KConfigSkeleton
*nullManager
= new KConfigSkeleton(0);
688 configDialog
= new BackgroundDialog(resolution
, containment
, view
, 0, id
, nullManager
);
689 configDialog
->setAttribute(Qt::WA_DeleteOnClose
);
691 connect(configDialog
, SIGNAL(destroyed(QObject
*)), nullManager
, SLOT(deleteLater()));
694 configDialog
->show();
695 KWindowSystem::setOnDesktop(configDialog
->winId(), KWindowSystem::currentDesktop());
696 KWindowSystem::activateWindow(configDialog
->winId());
699 void PlasmaApp::addContainment()
701 //try to find the "active" containment to get a plugin name
702 int currentScreen
= Kephal::ScreenUtils::screenId(QCursor::pos());
703 int currentDesktop
= -1;
704 if (AppSettings::perVirtualDesktopViews()) {
705 currentDesktop
= KWindowSystem::currentDesktop();
707 Plasma::Containment
*fromContainment
=m_corona
->containmentForScreen(currentScreen
, currentDesktop
);
709 QString plugin
= fromContainment
? fromContainment
->pluginName() : QString();
710 Plasma::Containment
*c
= m_corona
->addContainment(plugin
);
712 if (c
&& fromContainment
) {
713 foreach (DesktopView
*view
, m_desktops
) {
714 if (view
->containment() == fromContainment
){
715 view
->setContainment(c
);
720 // if we reach here, the containment isn't going to be taken over by the view,
721 // so we're going to resize it ourselves!
722 c
->resize(fromContainment
->size());
726 void PlasmaApp::zoom(Plasma::Containment
*containment
, Plasma::ZoomDirection direction
)
728 if (direction
== Plasma::ZoomIn
) {
730 foreach (DesktopView
*view
, m_desktops
) {
731 view
->zoomIn(m_zoomLevel
);
734 if (m_zoomLevel
== Plasma::DesktopZoom
) {
735 int currentDesktop
= -1;
736 if (AppSettings::perVirtualDesktopViews()) {
737 currentDesktop
= KWindowSystem::currentDesktop();
740 DesktopView
*view
= viewForScreen(desktop()->screenNumber(QCursor::pos()), currentDesktop
);
742 if (view
&& view
->containment() != containment
) {
743 // zooming in all the way, so lets swap containments about if need be
744 view
->setContainment(containment
);
747 } else if (direction
== Plasma::ZoomOut
) {
748 zoomOut(containment
);
749 foreach (DesktopView
*view
, m_desktops
) {
750 view
->zoomOut(m_zoomLevel
);
755 void PlasmaApp::zoomIn(Plasma::Containment
*containment
)
757 bool isMutable
= m_corona
->immutability() == Plasma::Mutable
;
760 bool addSibling
= isMutable
;
763 if (m_zoomLevel
== Plasma::GroupZoom
) {
764 setControllerVisible(false);
765 m_zoomLevel
= Plasma::DesktopZoom
;
766 containment
->closeToolBox();
769 } else if (m_zoomLevel
== Plasma::OverviewZoom
) {
770 m_zoomLevel
= Plasma::GroupZoom
;
771 remove
= isMutable
&& true;
774 //make sure everybody can zoom out again
775 foreach (Plasma::Containment
*c
, m_corona
->containments()) {
776 if (isPanelContainment(c
)) {
780 if (m_zoomLevel
== Plasma::DesktopZoom
) {
781 foreach (QAction
*action
, m_corona
->actions()) {
782 c
->addToolBoxAction(action
);
786 c
->enableAction("zoom in", zoomIn
);
787 c
->enableAction("zoom out", zoomOut
);
788 c
->enableAction("remove", remove
&& (c
->screen() == -1));
789 c
->enableAction("add widgets", isMutable
);
791 m_corona
->enableAction("add sibling containment", addSibling
);
794 void PlasmaApp::zoomOut(Plasma::Containment
*)
796 bool isMutable
= m_corona
->immutability() == Plasma::Mutable
;
799 bool addSibling
= isMutable
&& true; //FIXME wtf?
800 bool addWidgets
= isMutable
&& true;
802 if (m_zoomLevel
== Plasma::DesktopZoom
) {
803 setControllerVisible(true);
804 m_zoomLevel
= Plasma::GroupZoom
;
805 } else if (m_zoomLevel
== Plasma::GroupZoom
) {
806 m_zoomLevel
= Plasma::OverviewZoom
;
811 //make sure everybody can zoom out again
812 foreach (Plasma::Containment
*c
, m_corona
->containments()) {
813 if (isPanelContainment(c
)) {
817 if (m_zoomLevel
== Plasma::GroupZoom
) {
818 foreach (QAction
*action
, m_corona
->actions()) {
819 c
->removeToolBoxAction(action
);
823 c
->enableAction("zoom in", zoomIn
);
824 c
->enableAction("zoom out", zoomOut
);
825 c
->enableAction("remove", isMutable
&& c
->screen() == -1);
826 c
->enableAction("add widgets", addWidgets
);
828 m_corona
->enableAction("add sibling containment", addSibling
);
831 void PlasmaApp::setControllerVisible(bool show
)
833 if (show
&& !m_controllerDialog
) {
834 m_controllerDialog
= new Plasma::Dialog
;
835 QVBoxLayout
*layout
= new QVBoxLayout(m_controllerDialog
);
837 foreach (QAction
*action
, m_corona
->actions()) {
838 ToolButton
*actionButton
= new ToolButton(m_controllerDialog
);
839 actionButton
->setToolButtonStyle(Qt::ToolButtonTextBesideIcon
);
840 actionButton
->setDefaultAction(action
);
841 layout
->addWidget(actionButton
);
844 m_controllerDialog
->show();
846 delete m_controllerDialog
;
847 m_controllerDialog
= 0;
851 void PlasmaApp::panelRemoved(QObject
* panel
)
853 m_panels
.removeAll((PanelView
*)panel
);
856 void PlasmaApp::updateActions(Plasma::ImmutabilityType immutability
)
858 bool enable
= immutability
== Plasma::Mutable
&& m_zoomLevel
!= Plasma::DesktopZoom
;
860 m_corona
->enableAction("add sibling containment", enable
);
864 #include "plasmaapp.moc"