~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to plasma/screensaver/shell/plasmaapp.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *   Copyright 2006 Aaron Seigo <aseigo@kde.org>
 
3
 *   Copyright 2008 Chani Armitage <chanika@gmail.com>
 
4
 *
 
5
 *
 
6
 *   This program is free software; you can redistribute it and/or modify
 
7
 *   it under the terms of the GNU General Public License as
 
8
 *   published by the Free Software Foundation; either version 2,
 
9
 *   or (at your option) any later version.
 
10
 *
 
11
 *   This program is distributed in the hope that it will be useful,
 
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *   GNU General Public License for more details
 
15
 *
 
16
 *   You should have received a copy of the GNU Library General Public
 
17
 *   License along with this program; if not, write to the
 
18
 *   Free Software Foundation, Inc.,
 
19
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
20
 */
 
21
 
 
22
// plasma.loadEngine("hardware")
 
23
// LineGraph graph
 
24
// plasma.connect(graph, "hardware", "cpu");
 
25
 
 
26
#include "plasmaapp.h"
 
27
 
 
28
#include <unistd.h>
 
29
 
 
30
#ifndef _SC_PHYS_PAGES
 
31
    #ifdef Q_OS_FREEBSD
 
32
    #include <sys/types.h>
 
33
    #include <sys/sysctl.h>
 
34
    #endif
 
35
 
 
36
    #ifdef Q_OS_NETBSD
 
37
    #include <sys/param.h>
 
38
    #include <sys/sysctl.h>
 
39
    #endif
 
40
#endif
 
41
 
 
42
#include <QApplication>
 
43
#include <QDesktopWidget>
 
44
#include <QPixmapCache>
 
45
#include <QtDBus/QtDBus>
 
46
 
 
47
//#include <KCrash>
 
48
#include <KDebug>
 
49
#include <KCmdLineArgs>
 
50
#include <KWindowSystem>
 
51
 
 
52
//#include <ksmserver_interface.h>
 
53
 
 
54
#include <Plasma/Containment>
 
55
#include <Plasma/Theme>
 
56
#include <Plasma/Dialog>
 
57
 
 
58
#include "appadaptor.h"
 
59
#include "savercorona.h"
 
60
#include "saverview.h"
 
61
#include "backgrounddialog.h"
 
62
 
 
63
 
 
64
#include <X11/Xlib.h>
 
65
#include <X11/extensions/Xrender.h>
 
66
#include <fixx11h.h>
 
67
 
 
68
Atom tag; //FIXME should this be a member var or what?
 
69
const unsigned char DIALOG = 1; //FIXME this is really bad code
 
70
const unsigned char VIEW = 2;
 
71
 
 
72
Display* dpy = 0;
 
73
Colormap colormap = 0;
 
74
Visual *visual = 0;
 
75
bool composite = false;
 
76
 
 
77
void checkComposite()
 
78
{
 
79
    dpy = XOpenDisplay(0); // open default display
 
80
    if (!dpy) {
 
81
        kError() << "Cannot connect to the X server" << endl;
 
82
        return;
 
83
    }
 
84
    if( qgetenv( "KDE_SKIP_ARGB_VISUALS" ) == "1" )
 
85
        return;
 
86
 
 
87
    int screen = DefaultScreen(dpy);
 
88
    int eventBase, errorBase;
 
89
 
 
90
    if (XRenderQueryExtension(dpy, &eventBase, &errorBase)) {
 
91
        int nvi;
 
92
        XVisualInfo templ;
 
93
        templ.screen  = screen;
 
94
        templ.depth   = 32;
 
95
        templ.c_class = TrueColor;
 
96
        XVisualInfo *xvi = XGetVisualInfo(dpy,
 
97
                                          VisualScreenMask | VisualDepthMask | VisualClassMask,
 
98
                                          &templ, &nvi);
 
99
        for (int i = 0; i < nvi; ++i) {
 
100
            XRenderPictFormat *format = XRenderFindVisualFormat(dpy, xvi[i].visual);
 
101
            if (format->type == PictTypeDirect && format->direct.alphaMask) {
 
102
                visual = xvi[i].visual;
 
103
                colormap = XCreateColormap(dpy, RootWindow(dpy, screen), visual, AllocNone);
 
104
                break;
 
105
            }
 
106
        }
 
107
        XFree(xvi);
 
108
    }
 
109
 
 
110
    composite = KWindowSystem::compositingActive() && colormap;
 
111
 
 
112
    kDebug() << (colormap ? "Plasma has an argb visual" : "Plasma lacks an argb visual") << visual << colormap;
 
113
    kDebug() << ((KWindowSystem::compositingActive() && colormap) ? "Plasma can use COMPOSITE for effects"
 
114
                                                                    : "Plasma is COMPOSITE-less") << "on" << dpy;
 
115
}
 
116
 
 
117
PlasmaApp* PlasmaApp::self()
 
118
{
 
119
    if (!kapp) {
 
120
        checkComposite();
 
121
        return new PlasmaApp(dpy, visual ? Qt::HANDLE(visual) : 0, colormap ? Qt::HANDLE(colormap) : 0);
 
122
    }
 
123
 
 
124
    return qobject_cast<PlasmaApp*>(kapp);
 
125
}
 
126
 
 
127
PlasmaApp::PlasmaApp(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap)
 
128
    : KUniqueApplication(display, visual, colormap),
 
129
      m_corona(0),
 
130
      m_configDialog(0)
 
131
{
 
132
    //load translations for libplasma
 
133
    KGlobal::locale()->insertCatalog("libplasma");
 
134
    KGlobal::locale()->insertCatalog("plasmagenericshell");
 
135
 
 
136
    new AppAdaptor(this);
 
137
    QDBusConnection::sessionBus().registerObject("/App", this);
 
138
 
 
139
    //FIXME this is probably totally invalid
 
140
    // Enlarge application pixmap cache
 
141
    // Calculate the size required to hold background pixmaps for all screens.
 
142
    // Add 10% so that other (smaller) pixmaps can also be cached.
 
143
    int cacheSize = 0;
 
144
    QDesktopWidget *desktop = QApplication::desktop();
 
145
    int numScreens = desktop->numScreens();
 
146
    for (int i = 0; i < numScreens; i++) {
 
147
        QRect geometry = desktop->screenGeometry(i);
 
148
        cacheSize += 4 * geometry.width() * geometry.height() / 1024;
 
149
    }
 
150
    cacheSize += cacheSize / 10;
 
151
 
 
152
    // Calculate the size of physical system memory; _SC_PHYS_PAGES *
 
153
    // _SC_PAGESIZE is documented to be able to overflow 32-bit integers,
 
154
    // so apply a 10-bit shift. FreeBSD 6-STABLE doesn't have _SC_PHYS_PAGES
 
155
    // (it is documented in FreeBSD 7-STABLE as "Solaris and Linux extension")
 
156
    // so use sysctl in those cases.
 
157
#if defined(_SC_PHYS_PAGES)
 
158
    int memorySize = sysconf(_SC_PHYS_PAGES);
 
159
    memorySize *= sysconf(_SC_PAGESIZE) / 1024;
 
160
#else
 
161
#ifdef Q_OS_FREEBSD
 
162
    int sysctlbuf[2];
 
163
    size_t size = sizeof(sysctlbuf);
 
164
    int memorySize;
 
165
    // This could actually use hw.physmem instead, but I can't find
 
166
    // reliable documentation on how to read the value (which may
 
167
    // not fit in a 32 bit integer).
 
168
    if (!sysctlbyname("vm.stats.vm.v_page_size", sysctlbuf, &size, NULL, 0)) {
 
169
        memorySize = sysctlbuf[0] / 1024;
 
170
        size = sizeof(sysctlbuf);
 
171
        if (!sysctlbyname("vm.stats.vm.v_page_count", sysctlbuf, &size, NULL, 0)) {
 
172
            memorySize *= sysctlbuf[0];
 
173
        }
 
174
    }
 
175
#endif
 
176
#ifdef Q_OS_NETBSD
 
177
    size_t memorySize;
 
178
    size_t len;
 
179
    static int mib[] = { CTL_HW, HW_PHYSMEM };
 
180
 
 
181
    len = sizeof(memorySize);
 
182
    sysctl(mib, 2, &memorySize, &len, NULL, 0);
 
183
    memorySize /= 1024;
 
184
#endif
 
185
    // If you have no suitable sysconf() interface and are not FreeBSD,
 
186
    // then you are out of luck and get a compile error.
 
187
#endif
 
188
 
 
189
    // Increase the pixmap cache size to 1% of system memory if it isn't already
 
190
    // larger so as to maximize cache usage. 1% of 1GB ~= 10MB.
 
191
    if (cacheSize < memorySize / 100) {
 
192
        cacheSize = memorySize / 100;
 
193
    }
 
194
 
 
195
    kDebug() << "Setting the pixmap cache size to" << cacheSize << "kilobytes";
 
196
    QPixmapCache::setCacheLimit(cacheSize);
 
197
 
 
198
    KConfigGroup cg(KGlobal::config(), "General");
 
199
    Plasma::Theme::defaultTheme()->setFont(cg.readEntry("desktopFont", font()));
 
200
    m_activeOpacity = cg.readEntry("activeOpacity", 1.0);
 
201
    m_idleOpacity = cg.readEntry("idleOpacity", 1.0);
 
202
 
 
203
    if (cg.readEntry("forceNoComposite", false)) {
 
204
        composite = false;
 
205
    }
 
206
 
 
207
    //we have to keep an eye on created windows
 
208
    tag = XInternAtom(QX11Info::display(), "_KDE_SCREENSAVER_OVERRIDE", False);
 
209
    qApp->installEventFilter(this);
 
210
 
 
211
    // this line initializes the corona.
 
212
    corona();
 
213
 
 
214
    connect(this, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));
 
215
 
 
216
    setup(KCmdLineArgs::parsedArgs()->isSet("setup"));
 
217
    
 
218
    m_viewCreationTimer.setSingleShot(true);
 
219
    m_viewCreationTimer.setInterval(0);
 
220
    connect(&m_viewCreationTimer, SIGNAL(timeout()), this, SLOT(createWaitingViews()));
 
221
}
 
222
 
 
223
PlasmaApp::~PlasmaApp()
 
224
{
 
225
}
 
226
 
 
227
void PlasmaApp::cleanup()
 
228
{
 
229
    if (m_corona) {
 
230
        m_corona->saveLayout();
 
231
    }
 
232
 
 
233
    qDeleteAll(m_views);
 
234
    delete m_corona;
 
235
    m_corona = 0;
 
236
 
 
237
    KGlobal::config()->sync();
 
238
}
 
239
 
 
240
void PlasmaApp::setActiveOpacity(qreal opacity)
 
241
{
 
242
    if (qFuzzyCompare(opacity, m_activeOpacity)) {
 
243
        return;
 
244
    }
 
245
    m_activeOpacity = opacity;
 
246
    emit setViewOpacity(opacity);
 
247
    KConfigGroup cg(KGlobal::config(), "General");
 
248
    cg.writeEntry("activeOpacity", opacity);
 
249
    m_corona->requestConfigSync();
 
250
}
 
251
 
 
252
void PlasmaApp::createWaitingViews()
 
253
{
 
254
    const QList<QWeakPointer<Plasma::Containment> > containments = m_viewsWaiting;
 
255
    m_viewsWaiting.clear();
 
256
    foreach(QWeakPointer<Plasma::Containment> weakContainment, containments) {
 
257
        if (weakContainment) {
 
258
            Plasma::Containment *containment = weakContainment.data();
 
259
            
 
260
            KConfigGroup viewIds(KGlobal::config(), "ViewIds");
 
261
            
 
262
            const int id = viewIds.readEntry(QString::number(containment->id()), 0);
 
263
            // we have a new screen. neat.
 
264
            SaverView *view = viewForScreen(containment->screen());
 
265
            if (view) {
 
266
                return;
 
267
            }
 
268
            
 
269
            view = new SaverView(containment, 0);
 
270
            if (m_corona) {
 
271
                connect(m_corona, SIGNAL(screenOwnerChanged(int,int,Plasma::Containment*)),
 
272
                        view, SLOT(screenOwnerChanged(int,int,Plasma::Containment*)));
 
273
                connect(m_corona, SIGNAL(shortcutsChanged()), view, SLOT(updateShortcuts()));
 
274
            }
 
275
            view->setGeometry(QApplication::desktop()->screenGeometry(containment->screen()));
 
276
 
 
277
            //FIXME why do I get BadWindow?
 
278
            //unsigned char data = VIEW;
 
279
            //XChangeProperty(QX11Info::display(), view->effectiveWinId(), tag, tag, 8, PropModeReplace, &data, 1);
 
280
 
 
281
            connect(containment, SIGNAL(configureRequested(Plasma::Containment*)),
 
282
                    this, SLOT(configureContainment(Plasma::Containment*)));
 
283
 
 
284
            //a hack to make sure the keyboard shortcut works
 
285
            view->addAction(corona()->action("unlock desktop"));
 
286
            view->addAction(corona()->action("unlock widgets"));
 
287
            m_views.append(view);
 
288
            connect(view, SIGNAL(hidden()), SLOT(lock()));
 
289
            connect(view, SIGNAL(hidden()), SIGNAL(hidden()));
 
290
            connect(this, SIGNAL(showViews()), view, SLOT(show()));
 
291
            connect(this, SIGNAL(hideViews()), view, SLOT(hide()));
 
292
            connect(this, SIGNAL(setViewOpacity(qreal)), view, SLOT(setOpacity(qreal)));
 
293
            connect(this, SIGNAL(enableSetupMode()), view, SLOT(disableSetupMode()));
 
294
            connect(this, SIGNAL(disableSetupMode()), view, SLOT(disableSetupMode()));
 
295
            connect(this, SIGNAL(openToolBox()), view, SLOT(openToolBox()));
 
296
            connect(this, SIGNAL(closeToolBox()), view, SLOT(closeToolBox()));
 
297
            connect(QApplication::desktop(), SIGNAL(resized(int)), view, SLOT(adjustSize(int)));
 
298
            emit(openToolBox());
 
299
            kDebug() << "view created";
 
300
        }
 
301
    }
 
302
    //activate the new views (yes, this is a lazy way to do it)
 
303
    setActive(m_active);
 
304
}
 
305
 
 
306
void PlasmaApp::setIdleOpacity(qreal opacity)
 
307
{
 
308
    if (qFuzzyCompare(opacity, m_idleOpacity)) {
 
309
        return;
 
310
    }
 
311
    m_idleOpacity = opacity;
 
312
    KConfigGroup cg(KGlobal::config(), "General");
 
313
    cg.writeEntry("idleOpacity", opacity);
 
314
    m_corona->requestConfigSync();
 
315
}
 
316
 
 
317
qreal PlasmaApp::activeOpacity() const
 
318
{
 
319
    return m_activeOpacity;
 
320
}
 
321
 
 
322
qreal PlasmaApp::idleOpacity() const
 
323
{
 
324
    return m_idleOpacity;
 
325
}
 
326
 
 
327
 
 
328
void PlasmaApp::setActive(bool activate)
 
329
{
 
330
    m_active = activate;
 
331
    //note: allow this to run even if the value isn't changed,
 
332
    //because some views may need updating.
 
333
    if (activate) {
 
334
        emit setViewOpacity(m_activeOpacity);
 
335
        emit showViews();
 
336
        emit openToolBox();
 
337
    } else {
 
338
        if (qFuzzyCompare(m_idleOpacity + qreal(1.0), qreal(1.0))) {
 
339
            //opacity is 0
 
340
            emit hideViews();
 
341
        } else {
 
342
            lock();
 
343
            emit setViewOpacity(m_idleOpacity);
 
344
            emit showViews();
 
345
            emit closeToolBox();
 
346
        }
 
347
    }
 
348
}
 
349
 
 
350
void PlasmaApp::syncConfig()
 
351
{
 
352
    KGlobal::config()->sync();
 
353
}
 
354
 
 
355
Plasma::Corona* PlasmaApp::corona()
 
356
{
 
357
    if (!m_corona) {
 
358
        m_corona = new SaverCorona(this);
 
359
        connect(m_corona, SIGNAL(screenOwnerChanged(int, int, Plasma::Containment*)),
 
360
                this, SLOT(containmentScreenOwnerChanged(int, int, Plasma::Containment*)));
 
361
        connect(m_corona, SIGNAL(configSynced()), SLOT(syncConfig()));
 
362
        //kDebug() << "connected to containmentAdded";
 
363
        /*
 
364
        foreach (DesktopView *view, m_desktops) {
 
365
            connect(c, SIGNAL(screenOwnerChanged(int,int,Plasma::Containment*)),
 
366
                            view, SLOT(screenOwnerChanged(int,int,Plasma::Containment*)));
 
367
        }*/
 
368
 
 
369
        m_corona->setItemIndexMethod(QGraphicsScene::NoIndex);
 
370
        m_corona->initializeLayout();
 
371
 
 
372
        //we want this *after* init so that we ignore any lock/unlock spasms that might happen then
 
373
        connect(m_corona, SIGNAL(immutabilityChanged(Plasma::ImmutabilityType)), this, SLOT(immutabilityChanged(Plasma::ImmutabilityType)));
 
374
 
 
375
        //kDebug() << "layout should exist";
 
376
        //c->checkScreens();
 
377
    }
 
378
 
 
379
    return m_corona;
 
380
}
 
381
 
 
382
bool PlasmaApp::hasComposite()
 
383
{
 
384
    return composite;
 
385
}
 
386
 
 
387
void PlasmaApp::containmentScreenOwnerChanged(int wasScreen, int isScreen, Plasma::Containment *containment)
 
388
{
 
389
    Q_UNUSED(wasScreen);
 
390
    if (isScreen < 0)
 
391
        return;
 
392
    m_viewsWaiting.append(containment);
 
393
    m_viewCreationTimer.start();
 
394
}
 
395
 
 
396
void PlasmaApp::setup(bool setupMode)
 
397
{
 
398
    kDebug() << "setup mode:" << setupMode;
 
399
 
 
400
    if (setupMode) {
 
401
        emit enableSetupMode();
 
402
        if (m_corona->immutability() == Plasma::UserImmutable) {
 
403
            m_corona->setImmutability(Plasma::Mutable);
 
404
        }
 
405
        setActive(true);
 
406
    } else {
 
407
        kDebug() << "checking lockprocess is still around";
 
408
        QDBusInterface lockprocess("org.kde.screenlocker", "/LockProcess",
 
409
                "org.kde.screenlocker.LockProcess", QDBusConnection::sessionBus(), this);
 
410
        if (lockprocess.isValid()) {
 
411
            kDebug() << "success!";
 
412
            setActive(false);
 
413
        } else {
 
414
            kDebug() << "bailing out";
 
415
            qApp->quit(); //this failed once. why?
 
416
        }
 
417
    }
 
418
}
 
419
 
 
420
bool PlasmaApp::eventFilter(QObject *obj, QEvent *event)
 
421
{
 
422
    if (event->type() == QEvent::Show) {
 
423
        //apparently this means we created a new window
 
424
        //so, add a tag to prove it's our window
 
425
        //FIXME using the show event means we tag on every show, not just the first.
 
426
        //harmless but kinda wasteful.
 
427
        QWidget *widget = qobject_cast<QWidget*>(obj);
 
428
        if (widget && widget->isWindow() && !(qobject_cast<QDesktopWidget*>(widget) ||
 
429
                    widget->testAttribute(Qt::WA_DontShowOnScreen))) {
 
430
            unsigned char data = 0;
 
431
            if (qobject_cast<SaverView*>(widget)) {
 
432
                data = VIEW;
 
433
            } else if (m_dialogs.contains(widget)) {
 
434
                data = DIALOG;
 
435
            } else {
 
436
                Qt::WindowFlags oldFlags = widget->windowFlags();
 
437
                Qt::WindowFlags newFlags = oldFlags | Qt::X11BypassWindowManagerHint;
 
438
                if (oldFlags != newFlags) {
 
439
                    //now we're *really* fucking with things
 
440
                    //we force-disable window management and frames to cut off access to wm-y stuff
 
441
                    //and to make it easy to check the tag (frames are a pain)
 
442
                    kDebug() << "!!!!!!!setting flags on!!!!!" << widget;
 
443
                    QDesktopWidget *desktop = QApplication::desktop();
 
444
                    if (qobject_cast<Plasma::Dialog*>(widget)) {
 
445
                        //this is a terrible horrible hack that breaks extenders but it mostly works
 
446
                        //weird thing is, it sometimes makes the calendar popup too small.
 
447
                        newFlags = Qt::Popup;
 
448
                    } else {
 
449
                        //plasmadialogs can't handle direct input
 
450
                        //but configdialogs need it
 
451
                        m_dialogs.append(widget);
 
452
                        connect(widget, SIGNAL(destroyed(QObject*)), SLOT(dialogDestroyed(QObject*)));
 
453
                        connect(this, SIGNAL(showDialogs()), widget, SLOT(show()));
 
454
                        connect(this, SIGNAL(hideDialogs()), widget, SLOT(hide()));
 
455
                    }
 
456
                    widget->setWindowFlags(newFlags);
 
457
                    //we do not know the screen this widget should appear on
 
458
                    QRect availableGeometry = desktop->availableGeometry();
 
459
                    //move to the default screen
 
460
                    widget->move(availableGeometry.x(), availableGeometry.y());
 
461
                    widget->show(); //setting the flags hid it :(
 
462
                    //qApp->setActiveWindow(widget); //gives kbd but not mouse events
 
463
                    //kDebug() << "parent" << widget->parentWidget();
 
464
                    //FIXME why can I only activate these dialogs from this exact line?
 
465
                    widget->activateWindow(); //gives keyboard focus
 
466
                    return false; //we'll be back when we get the new show event
 
467
                } else {
 
468
                    widget->activateWindow(); //gives keyboard focus
 
469
                }
 
470
            }
 
471
 
 
472
            XChangeProperty(QX11Info::display(), widget->effectiveWinId(), tag, tag, 8, PropModeReplace, &data, 1);
 
473
            kDebug() << "tagged" << widget << widget->effectiveWinId() << "as" << data;
 
474
        }
 
475
    }
 
476
    return false;
 
477
}
 
478
 
 
479
void PlasmaApp::dialogDestroyed(QObject *obj)
 
480
{
 
481
    m_dialogs.removeAll(qobject_cast<QWidget*>(obj));
 
482
    //if (m_dialogs.isEmpty()) {
 
483
        //FIXME multiview
 
484
        //if (m_view) {
 
485
            //this makes qactions work again
 
486
            //m_view->activateWindow();
 
487
        //}
 
488
    /*} else { failed attempt to fix kbd input after a subdialog closes
 
489
        QWidget *top = m_dialogs.last();
 
490
        top->activateWindow();
 
491
        kDebug() << top;*/
 
492
    //}
 
493
}
 
494
 
 
495
void PlasmaApp::configureContainment(Plasma::Containment *containment)
 
496
{
 
497
//     SaverView *view = viewForScreen(containment->screen());
 
498
//     if (!view) {
 
499
//         return;
 
500
//     }
 
501
 
 
502
    if (m_configDialog) {
 
503
        m_configDialog->reloadConfig();
 
504
    } else {
 
505
        const QSize resolution = QApplication::desktop()->screenGeometry(containment->screen()).size();
 
506
 
 
507
        m_configDialog = new BackgroundDialog(resolution, containment);
 
508
        m_configDialog->setAttribute(Qt::WA_DeleteOnClose);
 
509
    }
 
510
 
 
511
    m_configDialog->show();
 
512
}
 
513
 
 
514
void PlasmaApp::lock()
 
515
{
 
516
    kDebug() << "lock";
 
517
    if (corona() && corona()->immutability() == Plasma::Mutable) {
 
518
        corona()->setImmutability(Plasma::UserImmutable);
 
519
    }
 
520
}
 
521
 
 
522
void PlasmaApp::quit()
 
523
{
 
524
    qApp->quit();
 
525
}
 
526
 
 
527
void PlasmaApp::immutabilityChanged(Plasma::ImmutabilityType immutability)
 
528
{
 
529
    if (immutability == Plasma::Mutable) {
 
530
        emit showDialogs();
 
531
    } else {
 
532
        emit hideDialogs();
 
533
        emit hideWidgetExplorer();
 
534
        emit disableSetupMode();
 
535
    }
 
536
}
 
537
 
 
538
SaverView *PlasmaApp::viewForScreen(int screen)
 
539
{
 
540
    foreach(SaverView *view, m_views) {
 
541
        if (view->screen() == screen)
 
542
            return view;
 
543
    }
 
544
    return 0;
 
545
}
 
546
 
 
547
#include "plasmaapp.moc"