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

« back to all changes in this revision

Viewing changes to plasma/netbook/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-2008 Aaron Seigo <aseigo@kde.org>
 
3
 *   Copyright 2009 Marco Martin <notmart@gmail.com>
 
4
 *
 
5
 *   This program is free software; you can redistribute it and/or modify
 
6
 *   it under the terms of the GNU Library General Public License as
 
7
 *   published by the Free Software Foundation; either version 2, or
 
8
 *   (at your option) any later version.
 
9
 *
 
10
 *   This program is distributed in the hope that it will be useful,
 
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *   GNU General Public License for more details
 
14
 *
 
15
 *   You should have received a copy of the GNU Library General Public
 
16
 *   License along with this program; if not, write to the
 
17
 *   Free Software Foundation, Inc.,
 
18
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
19
 */
 
20
 
 
21
#include "plasmaapp.h"
 
22
 
 
23
#include <unistd.h>
 
24
 
 
25
#include <QApplication>
 
26
#include <QPixmapCache>
 
27
#include <QTimer>
 
28
#include <QtDBus/QtDBus>
 
29
 
 
30
#include <KCrash>
 
31
#include <KDebug>
 
32
#include <KCmdLineArgs>
 
33
#include <KStandardAction>
 
34
#include <KWindowSystem>
 
35
#include <KAction>
 
36
 
 
37
#include <ksmserver_interface.h>
 
38
 
 
39
#include <kephal/screens.h>
 
40
 
 
41
#include <Plasma/Containment>
 
42
#include <Plasma/Dialog>
 
43
#include <Plasma/Theme>
 
44
#include <Plasma/Wallpaper>
 
45
#include <Plasma/WindowEffects>
 
46
 
 
47
#include "netcorona.h"
 
48
#include "netview.h"
 
49
 
 
50
#include "widgetsexplorer/widgetexplorer.h"
 
51
#include "plasmagenericshell/backgrounddialog.h"
 
52
 
 
53
#ifdef Q_WS_X11
 
54
#include <X11/Xlib.h>
 
55
#include <X11/extensions/Xrender.h>
 
56
#include <X11/extensions/shape.h>
 
57
#endif
 
58
 
 
59
PlasmaApp* PlasmaApp::self()
 
60
{
 
61
    if (!kapp) {
 
62
        return new PlasmaApp();
 
63
    }
 
64
 
 
65
    return qobject_cast<PlasmaApp*>(kapp);
 
66
}
 
67
 
 
68
 
 
69
class GlowBar : public QWidget
 
70
{
 
71
public:
 
72
    GlowBar(Plasma::Direction direction, const QRect &triggerZone)
 
73
        : QWidget(0),
 
74
          m_strength(0.3),
 
75
          m_svg(new Plasma::Svg(this)),
 
76
          m_direction(direction)
 
77
    {
 
78
        setAttribute(Qt::WA_TranslucentBackground);
 
79
        KWindowSystem::setOnAllDesktops(winId(), true);
 
80
        unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove;
 
81
        KWindowSystem::setState(winId(), state);
 
82
        KWindowSystem::setType(winId(), NET::Dock);
 
83
        m_svg->setImagePath("widgets/glowbar");
 
84
 
 
85
#ifdef Q_WS_X11
 
86
        QRegion region(QRect(0,0,1,1));
 
87
        XShapeCombineRegion(QX11Info::display(), winId(), ShapeInput, 0, 0,
 
88
                            region.handle(), ShapeSet);
 
89
#endif
 
90
 
 
91
        QPalette pal = palette();
 
92
        pal.setColor(backgroundRole(), Qt::transparent);
 
93
        setPalette(pal);
 
94
 
 
95
        QRect glowGeom = triggerZone;
 
96
        QSize s = sizeHint();
 
97
        switch (m_direction) {
 
98
            case Plasma::Up:
 
99
                glowGeom.setY(glowGeom.y() - s.height() + 1);
 
100
                // fallthrough
 
101
            case Plasma::Down:
 
102
                glowGeom.setHeight(s.height());
 
103
                break;
 
104
            case Plasma::Left:
 
105
                glowGeom.setX(glowGeom.x() - s.width() + 1);
 
106
                // fallthrough
 
107
            case Plasma::Right:
 
108
                glowGeom.setWidth(s.width());
 
109
                break;
 
110
        }
 
111
 
 
112
        //kDebug() << "glow geom is" << glowGeom << "from" << triggerZone;
 
113
        setGeometry(glowGeom);
 
114
        m_buffer = QPixmap(size());
 
115
    }
 
116
 
 
117
    void paintEvent(QPaintEvent* e)
 
118
    {
 
119
        Q_UNUSED(e)
 
120
        QPixmap pixmap;
 
121
        const QSize glowRadius = m_svg->elementSize("hint-glow-radius");
 
122
        QPoint pixmapPosition(0, 0);
 
123
 
 
124
        m_buffer.fill(QColor(0, 0, 0, int(qreal(255)*m_strength)));
 
125
        QPainter p(&m_buffer);
 
126
        p.setCompositionMode(QPainter::CompositionMode_SourceIn);
 
127
 
 
128
        switch (m_direction) {
 
129
            case Plasma::Down:
 
130
                pixmap = m_svg->pixmap("bottom");
 
131
                pixmapPosition = QPoint(0, -glowRadius.height());
 
132
                break;
 
133
            case Plasma::Up:
 
134
                pixmap = m_svg->pixmap("top");
 
135
                break;
 
136
            case Plasma::Right:
 
137
                pixmap = m_svg->pixmap("right");
 
138
                pixmapPosition = QPoint(-glowRadius.width(), 0);
 
139
                break;
 
140
            case Plasma::Left:
 
141
                pixmap = m_svg->pixmap("left");
 
142
                break;
 
143
        }
 
144
 
 
145
        if (m_direction == Plasma::Left || m_direction == Plasma::Right) {
 
146
            p.drawTiledPixmap(QRect(0, pixmapPosition.x(), pixmap.width(), height()), pixmap);
 
147
        } else {
 
148
            p.drawTiledPixmap(QRect(0, pixmapPosition.y(), width(), pixmap.height()), pixmap);
 
149
        }
 
150
 
 
151
        p.end();
 
152
        p.begin(this);
 
153
        p.drawPixmap(QPoint(0, 0), m_buffer);
 
154
    }
 
155
 
 
156
    QSize sizeHint() const
 
157
    {
 
158
        return m_svg->elementSize("bottomright") - m_svg->elementSize("hint-glow-radius");
 
159
    }
 
160
 
 
161
    bool event(QEvent *event)
 
162
    {
 
163
        if (event->type() == QEvent::Paint) {
 
164
            QPainter p(this);
 
165
            p.setCompositionMode(QPainter::CompositionMode_Source);
 
166
            p.fillRect(rect(), Qt::transparent);
 
167
        }
 
168
        return QWidget::event(event);
 
169
    }
 
170
 
 
171
    void updateStrength(QPoint point)
 
172
    {
 
173
        QPoint localPoint = mapFromGlobal(point);
 
174
 
 
175
        qreal newStrength;
 
176
        switch (m_direction) {
 
177
        case Plasma::Up: // when the panel is at the bottom.
 
178
            newStrength = 1 - qreal(-localPoint.y())/m_triggerDistance;
 
179
            break;
 
180
        case Plasma::Right:
 
181
            newStrength = 1 - qreal(localPoint.x())/m_triggerDistance;
 
182
            break;
 
183
        case Plasma::Left: // when the panel is right-aligned
 
184
            newStrength = 1 - qreal(-localPoint.x())/m_triggerDistance;
 
185
            break;
 
186
        case Plasma::Down:
 
187
        default:
 
188
            newStrength = 1- qreal(localPoint.y())/m_triggerDistance;
 
189
            break;
 
190
        }
 
191
        if (qAbs(newStrength - m_strength) > 0.01 && newStrength >= 0 && newStrength <= 1) {
 
192
            m_strength = newStrength;
 
193
            update();
 
194
        }
 
195
    }
 
196
 
 
197
 
 
198
private:
 
199
    static const int m_triggerDistance = 30;
 
200
    qreal m_strength;
 
201
    Plasma::Svg *m_svg;
 
202
    Plasma::Direction m_direction;
 
203
    QPixmap m_buffer;
 
204
};
 
205
 
 
206
 
 
207
class ShadowWindow : public QWidget
 
208
{
 
209
public:
 
210
    ShadowWindow(NetView *panel)
 
211
       : QWidget(0),
 
212
         m_panel(panel),
 
213
         m_valid(false)
 
214
    {
 
215
        setAttribute(Qt::WA_TranslucentBackground);
 
216
        setAttribute(Qt::WA_NoSystemBackground, false);
 
217
        setAutoFillBackground(false);
 
218
#ifdef Q_WS_X11
 
219
        QRegion region(QRect(0,0,1,1));
 
220
        XShapeCombineRegion(QX11Info::display(), winId(), ShapeInput, 0, 0,
 
221
                            region.handle(), ShapeSet);
 
222
#endif
 
223
 
 
224
        m_shadow = new Plasma::FrameSvg(this);
 
225
    }
 
226
 
 
227
    void setSvg(const QString &path)
 
228
    {
 
229
        m_shadow->setImagePath(path);
 
230
 
 
231
        if (!m_shadow->hasElementPrefix("shadow")) {
 
232
            hide();
 
233
            m_valid = false;
 
234
        } else {
 
235
            m_valid = true;
 
236
        }
 
237
 
 
238
        m_shadow->setElementPrefix("shadow");
 
239
 
 
240
        adjustMargins(geometry());
 
241
    }
 
242
 
 
243
    bool isValid() const
 
244
    {
 
245
        return m_valid;
 
246
    }
 
247
 
 
248
    void adjustMargins(const QRect &geo)
 
249
    {
 
250
        QRect screenRect = Kephal::ScreenUtils::screenGeometry(m_panel->screen());
 
251
 
 
252
        Plasma::FrameSvg::EnabledBorders enabledBorders = Plasma::FrameSvg::AllBorders;
 
253
 
 
254
        if (geo.left() <= screenRect.left()) {
 
255
            enabledBorders ^= Plasma::FrameSvg::LeftBorder;
 
256
        }
 
257
        if (geo.top() <= screenRect.top()) {
 
258
            enabledBorders ^= Plasma::FrameSvg::TopBorder;
 
259
        }
 
260
        if (geo.bottom() >= screenRect.bottom()) {
 
261
            enabledBorders ^= Plasma::FrameSvg::BottomBorder;
 
262
        }
 
263
        if (geo.right() >= screenRect.right()) {
 
264
            enabledBorders ^= Plasma::FrameSvg::RightBorder;
 
265
        }
 
266
 
 
267
        m_shadow->setEnabledBorders(enabledBorders);
 
268
 
 
269
        qreal left, top, right, bottom;
 
270
 
 
271
        m_shadow->getMargins(left, top, right, bottom);
 
272
        setContentsMargins(left, top, right, bottom);
 
273
    }
 
274
 
 
275
protected:
 
276
    bool event(QEvent *event)
 
277
    {
 
278
        Q_UNUSED(event)
 
279
 
 
280
        if (event->type() == QEvent::Paint) {
 
281
            QPainter p(this);
 
282
            p.setCompositionMode(QPainter::CompositionMode_Source);
 
283
            p.fillRect(rect(), Qt::transparent);
 
284
        }
 
285
        return QWidget::event(event);
 
286
    }
 
287
 
 
288
    void resizeEvent(QResizeEvent *event)
 
289
    {
 
290
        m_shadow->resizeFrame(event->size());
 
291
 
 
292
        adjustMargins(geometry());
 
293
    }
 
294
 
 
295
    void paintEvent(QPaintEvent* e)
 
296
    {
 
297
        Q_UNUSED(e)
 
298
 
 
299
        QPainter p(this);
 
300
        //p.setCompositionMode(QPainter::CompositionMode_Source);
 
301
        m_shadow->paintFrame(&p);
 
302
    }
 
303
 
 
304
private:
 
305
    Plasma::FrameSvg *m_shadow;
 
306
    NetView *m_panel;
 
307
    bool m_valid;
 
308
};
 
309
 
 
310
PlasmaApp::PlasmaApp()
 
311
    : KUniqueApplication(),
 
312
      m_corona(0),
 
313
      m_widgetExplorerView(0),
 
314
      m_widgetExplorer(0),
 
315
      m_glowBar(0),
 
316
      m_mousePollTimer(0),
 
317
      m_controlBar(0),
 
318
      m_mainView(0),
 
319
      m_isDesktop(false),
 
320
      m_autoHideControlBar(true),
 
321
      m_unHideTimer(0),
 
322
      m_shadowWindow(0),
 
323
      m_startupSuspendWaitCount(0)
 
324
{
 
325
    PlasmaApp::suspendStartup(true);
 
326
    KGlobal::locale()->insertCatalog("libplasma");
 
327
    KGlobal::locale()->insertCatalog("plasmagenericshell");
 
328
 
 
329
 
 
330
    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
 
331
    bool isDesktop = args->isSet("desktop");
 
332
    if (isDesktop) {
 
333
        KCrash::setFlags(KCrash::AutoRestart);
 
334
    }
 
335
 
 
336
    //TODO: decide how to handle the cache size; possibilities:
 
337
    //      * % of ram, as in desktop
 
338
    //      * fixed size, hardcoded (uck)
 
339
    //      * optional size, specified on command line
 
340
    //      * optional size, in a config file
 
341
    //      * don't do anything special at all
 
342
    //QPixmapCache::setCacheLimit(cacheSize);
 
343
 
 
344
    KConfigGroup cg(KSharedConfig::openConfig("plasmarc"), "Theme-plasma-netbook");
 
345
    const QString themeName = cg.readEntry("name", "air-netbook");
 
346
    Plasma::Theme::defaultTheme()->setUseGlobalSettings(false);
 
347
    Plasma::Theme::defaultTheme()->setThemeName(themeName);
 
348
 
 
349
    cg = KConfigGroup(KGlobal::config(), "General");
 
350
 
 
351
    Plasma::Theme::defaultTheme()->setFont(cg.readEntry("desktopFont", font()));
 
352
 
 
353
    m_mainView = new NetView(0, NetView::mainViewId(), 0);
 
354
    m_mainView->hide();
 
355
 
 
356
    connect(m_mainView, SIGNAL(containmentActivated()), this, SLOT(mainContainmentActivated()));
 
357
    connect(KWindowSystem::self(), SIGNAL(workAreaChanged()), this, SLOT(positionPanel()));
 
358
 
 
359
    bool useGL = args->isSet("opengl");
 
360
    m_mainView->setUseGL(useGL);
 
361
 
 
362
    connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(controlBarVisibilityUpdate()));
 
363
 
 
364
    int width = 400;
 
365
    int height = 200;
 
366
    if (isDesktop) {
 
367
        QRect rect = Kephal::ScreenUtils::screenGeometry(m_mainView->screen());
 
368
        width = rect.width();
 
369
        height = rect.height();
 
370
    } else {
 
371
        QAction *action = KStandardAction::quit(qApp, SLOT(quit()), m_mainView);
 
372
        m_mainView->addAction(action);
 
373
 
 
374
        QString geom = args->getOption("screen");
 
375
        int x = geom.indexOf('x');
 
376
 
 
377
        if (x > 0)  {
 
378
            width = qMax(width, geom.left(x).toInt());
 
379
            height = qMax(height, geom.right(geom.length() - x - 1).toInt());
 
380
        }
 
381
    }
 
382
 
 
383
    m_mainView->setFixedSize(width, height);
 
384
    m_mainView->move(0,0);
 
385
    setIsDesktop(isDesktop);
 
386
 
 
387
    // this line initializes the corona.
 
388
    corona();
 
389
    //setIsDesktop(isDesktop);
 
390
    reserveStruts();
 
391
 
 
392
    connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(checkShadow()));
 
393
    connect(this, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));
 
394
}
 
395
 
 
396
PlasmaApp::~PlasmaApp()
 
397
{
 
398
}
 
399
 
 
400
void PlasmaApp::cleanup()
 
401
{
 
402
    if (m_corona) {
 
403
        m_corona->saveLayout();
 
404
    }
 
405
 
 
406
    if (!m_mainView->containment()) {
 
407
        return;
 
408
    }
 
409
 
 
410
    // save the mapping of Views to Containments at the moment
 
411
    // of application exit so we can restore that when we start again.
 
412
    KConfigGroup viewIds(KGlobal::config(), "ViewIds");
 
413
    viewIds.deleteGroup();
 
414
    viewIds.writeEntry(QString::number(m_mainView->containment()->id()), NetView::mainViewId());
 
415
 
 
416
    if (m_controlBar) {
 
417
        viewIds.writeEntry(QString::number(m_controlBar->containment()->id()), NetView::controlBarId());
 
418
    }
 
419
 
 
420
    delete m_mainView;
 
421
    m_mainView = 0;
 
422
 
 
423
    delete m_corona;
 
424
    m_corona = 0;
 
425
 
 
426
    //TODO: This manual sync() should not be necessary?
 
427
    syncConfig();
 
428
}
 
429
 
 
430
void PlasmaApp::syncConfig()
 
431
{
 
432
    KGlobal::config()->sync();
 
433
}
 
434
 
 
435
void PlasmaApp::positionPanel()
 
436
{
 
437
    if (!m_controlBar) {
 
438
        return;
 
439
    }
 
440
 
 
441
    QRect screenRect = Kephal::ScreenUtils::screenGeometry(m_controlBar->screen());
 
442
    if (!m_isDesktop) {
 
443
        screenRect = m_mainView->geometry();
 
444
    }
 
445
 
 
446
    //move
 
447
    controlBarMoved(m_controlBar);
 
448
 
 
449
    if (m_controlBar->formFactor() == Plasma::Horizontal) {
 
450
        m_controlBar->setFixedSize(screenRect.width(), m_controlBar->size().height());
 
451
    } else if (m_controlBar->formFactor() == Plasma::Vertical) {
 
452
        m_controlBar->setFixedSize(m_controlBar->size().width(), screenRect.height());
 
453
    }
 
454
 
 
455
 
 
456
    m_controlBar->containment()->setMaximumSize(m_controlBar->size());
 
457
    m_controlBar->containment()->setMinimumSize(m_controlBar->size());
 
458
 
 
459
    if (m_autoHideControlBar && m_controlBar->isVisible()) {
 
460
        destroyUnHideTrigger();
 
461
        createUnhideTrigger();
 
462
    }
 
463
 
 
464
    checkShadow();
 
465
 
 
466
    emit controlBarChanged();
 
467
}
 
468
 
 
469
void PlasmaApp::checkShadow()
 
470
{
 
471
    if (!m_controlBar) {
 
472
        return;
 
473
    }
 
474
 
 
475
    if (KWindowSystem::compositingActive() && m_controlBar->containment()->property("shadowPath").isValid()) {
 
476
        if (!m_shadowWindow) {
 
477
            m_shadowWindow = new ShadowWindow(m_controlBar);
 
478
            KWindowSystem::setOnAllDesktops(m_controlBar->winId(), true);
 
479
        }
 
480
        KWindowSystem::setType(m_shadowWindow->winId(), NET::Dock);
 
481
        KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepBelow);
 
482
        KWindowSystem::setOnAllDesktops(m_shadowWindow->winId(), true);
 
483
        m_shadowWindow->setSvg(m_controlBar->containment()->property("shadowPath").toString());
 
484
        int left, right, top, bottom;
 
485
        m_shadowWindow->adjustMargins(m_controlBar->geometry());
 
486
        m_shadowWindow->getContentsMargins(&left, &top, &right, &bottom);
 
487
        m_shadowWindow->setMinimumSize(-1, -1);
 
488
        m_shadowWindow->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
 
489
        m_shadowWindow->setGeometry(m_controlBar->geometry().adjusted(-left, -top, right, bottom));
 
490
        m_shadowWindow->setFixedSize(m_shadowWindow->size());
 
491
        if (m_shadowWindow->isValid()) {
 
492
            m_shadowWindow->show();
 
493
        }
 
494
    } else {
 
495
        m_shadowWindow->deleteLater();
 
496
        m_shadowWindow = 0;
 
497
    }
 
498
}
 
499
 
 
500
void PlasmaApp::mainContainmentActivated()
 
501
{
 
502
    if (m_mainView->containment()) {
 
503
        m_mainView->setWindowTitle(m_mainView->containment()->activity());
 
504
    }
 
505
 
 
506
 
 
507
    const WId id = m_mainView->effectiveWinId();
 
508
 
 
509
    QWidget * activeWindow = QApplication::activeWindow();
 
510
    KWindowSystem::raiseWindow(id);
 
511
 
 
512
    if (activeWindow) {
 
513
        KWindowSystem::raiseWindow(activeWindow->effectiveWinId());
 
514
        m_mainView->activateWindow();
 
515
        activeWindow->setFocus();
 
516
        if (m_shadowWindow) {
 
517
            KWindowSystem::clearState(m_shadowWindow->winId(), NET::KeepBelow);
 
518
            KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepAbove);
 
519
        }
 
520
    } else {
 
521
        m_mainView->activateWindow();
 
522
    }
 
523
}
 
524
 
 
525
void PlasmaApp::setIsDesktop(bool isDesktop)
 
526
{
 
527
    m_isDesktop = isDesktop;
 
528
 
 
529
    if (isDesktop) {
 
530
        KWindowSystem::setType(m_mainView->winId(), NET::Normal);
 
531
        m_mainView->setWindowFlags(m_mainView->windowFlags() | Qt::FramelessWindowHint);
 
532
        KWindowSystem::setOnAllDesktops(m_mainView->winId(), true);
 
533
        if (m_controlBar) {
 
534
            KWindowSystem::setOnAllDesktops(m_controlBar->winId(), true);
 
535
        }
 
536
        m_mainView->show();
 
537
    } else {
 
538
        m_mainView->setWindowFlags(m_mainView->windowFlags() & ~Qt::FramelessWindowHint);
 
539
        KWindowSystem::setOnAllDesktops(m_mainView->winId(), false);
 
540
        if (m_controlBar) {
 
541
            KWindowSystem::setOnAllDesktops(m_controlBar->winId(), false);
 
542
        }
 
543
        KWindowSystem::setType(m_mainView->winId(), NET::Normal);
 
544
    }
 
545
}
 
546
 
 
547
bool PlasmaApp::isDesktop() const
 
548
{
 
549
    return m_isDesktop;
 
550
}
 
551
 
 
552
void PlasmaApp::adjustSize(Kephal::Screen *screen)
 
553
{
 
554
    Q_UNUSED(screen)
 
555
 
 
556
    QRect rect = Kephal::ScreenUtils::screenGeometry(m_mainView->screen());
 
557
 
 
558
    int width = rect.width();
 
559
    int height = rect.height();
 
560
    //FIXME: ugly hack there too
 
561
    m_mainView->setFixedSize(width, height);
 
562
    positionPanel();
 
563
    reserveStruts();
 
564
}
 
565
 
 
566
void PlasmaApp::reserveStruts()
 
567
{
 
568
    if (!m_controlBar) {
 
569
        return;
 
570
    }
 
571
 
 
572
    if (m_autoHideControlBar || !isDesktop()) {
 
573
        KWindowSystem::setExtendedStrut(m_controlBar->winId(),
 
574
                                    0, 0, 0,
 
575
                                    0, 0, 0,
 
576
                                    0, 0, 0,
 
577
                                    0, 0, 0);
 
578
        return;
 
579
    }
 
580
 
 
581
    NETExtendedStrut strut;
 
582
 
 
583
    if (!m_autoHideControlBar || hasForegroundWindows()) {
 
584
        switch (m_controlBar->location()) {
 
585
        case Plasma::LeftEdge:
 
586
            strut.left_width = m_controlBar->width();
 
587
            strut.left_start = m_controlBar->y();
 
588
            strut.left_end = m_controlBar->y() + m_controlBar->height() - 1;
 
589
            break;
 
590
        case Plasma::RightEdge:
 
591
            strut.right_width = m_controlBar->width();
 
592
            strut.right_start = m_controlBar->y();
 
593
            strut.right_end = m_controlBar->y() + m_controlBar->height() - 1;
 
594
            break;
 
595
        case Plasma::TopEdge:
 
596
            strut.top_width = m_controlBar->height();
 
597
            strut.top_start = m_controlBar->x();
 
598
            strut.top_end = m_controlBar->x() + m_controlBar->width() - 1;
 
599
            break;
 
600
        case Plasma::BottomEdge:
 
601
        default:
 
602
            strut.bottom_width = m_controlBar->height();
 
603
            strut.bottom_start = m_controlBar->x();
 
604
            strut.bottom_end = m_controlBar->x() + m_controlBar->width() - 1;
 
605
        }
 
606
    }
 
607
 
 
608
    KWindowSystem::setExtendedStrut(m_controlBar->winId(),
 
609
                                    strut.left_width, strut.left_start, strut.left_end,
 
610
                                    strut.right_width, strut.right_start, strut.right_end,
 
611
                                    strut.top_width, strut.top_start, strut.top_end,
 
612
                                    strut.bottom_width, strut.bottom_start, strut.bottom_end);
 
613
 
 
614
    //ensure the main view is at the proper position too
 
615
    QRect screenRect = Kephal::ScreenUtils::screenGeometry(m_controlBar->screen());
 
616
    m_mainView->move(screenRect.topLeft());
 
617
}
 
618
 
 
619
NetView *PlasmaApp::controlBar() const
 
620
{
 
621
    return m_controlBar;
 
622
}
 
623
 
 
624
NetView *PlasmaApp::mainView() const
 
625
{
 
626
    return m_mainView;
 
627
}
 
628
 
 
629
QWidget *PlasmaApp::widgetExplorer() const
 
630
{
 
631
    return m_widgetExplorerView;
 
632
}
 
633
 
 
634
Plasma::Corona* PlasmaApp::corona()
 
635
{
 
636
    if (!m_corona) {
 
637
        m_corona = new NetCorona(this);
 
638
        connect(m_corona, SIGNAL(containmentAdded(Plasma::Containment*)),
 
639
                this, SLOT(createView(Plasma::Containment*)));
 
640
        connect(m_corona, SIGNAL(configSynced()), this, SLOT(syncConfig()));
 
641
 
 
642
        connect(m_corona, SIGNAL(screenOwnerChanged(int,int,Plasma::Containment*)),
 
643
                m_mainView, SLOT(screenOwnerChanged(int,int,Plasma::Containment*)));
 
644
 
 
645
        m_corona->setItemIndexMethod(QGraphicsScene::NoIndex);
 
646
        m_corona->initializeLayout();
 
647
        m_corona->processUpdateScripts();
 
648
 
 
649
        m_mainView->show();
 
650
    }
 
651
 
 
652
    foreach (Plasma::Containment *containment, m_corona->containments()) {
 
653
        if (containment->screen() != -1 && containment->wallpaper()) {
 
654
            ++m_startupSuspendWaitCount;
 
655
            connect(containment->wallpaper(), SIGNAL(update(QRectF)), this, SLOT(wallpaperCheckedIn()));
 
656
        }
 
657
    }
 
658
 
 
659
    QTimer::singleShot(5000, this, SLOT(wallpaperCheckInTimeout()));
 
660
 
 
661
    return m_corona;
 
662
}
 
663
 
 
664
void PlasmaApp::wallpaperCheckInTimeout()
 
665
{
 
666
    if (m_startupSuspendWaitCount > 0) {
 
667
        m_startupSuspendWaitCount = 0;
 
668
        suspendStartup(false);
 
669
    }
 
670
}
 
671
 
 
672
void PlasmaApp::wallpaperCheckedIn()
 
673
{
 
674
    if (m_startupSuspendWaitCount < 1) {
 
675
        return;
 
676
    }
 
677
 
 
678
    --m_startupSuspendWaitCount;
 
679
    if (m_startupSuspendWaitCount < 1) {
 
680
        m_startupSuspendWaitCount = 0;
 
681
        suspendStartup(false);
 
682
    }
 
683
}
 
684
 
 
685
bool PlasmaApp::hasComposite()
 
686
{
 
687
    return KWindowSystem::compositingActive();
 
688
}
 
689
 
 
690
void PlasmaApp::suspendStartup(bool suspend)
 
691
{
 
692
    org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus());
 
693
 
 
694
    const QString startupID("netbook desktop");
 
695
    if (suspend) {
 
696
        ksmserver.suspendStartup(startupID);
 
697
    } else {
 
698
        ksmserver.resumeStartup(startupID);
 
699
    }
 
700
}
 
701
 
 
702
void PlasmaApp::createView(Plasma::Containment *containment)
 
703
{
 
704
    connect(containment, SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(showWidgetExplorer()));
 
705
    connect(containment, SIGNAL(configureRequested(Plasma::Containment*)),
 
706
            this, SLOT(configureContainment(Plasma::Containment*)));
 
707
    connect(containment, SIGNAL(toolBoxVisibilityChanged(bool)),
 
708
            this, SLOT(updateToolBoxVisibility(bool)));
 
709
 
 
710
 
 
711
    KConfigGroup viewIds(KGlobal::config(), "ViewIds");
 
712
    int defaultId = 0;
 
713
    if (containment->containmentType() == Plasma::Containment::PanelContainment && 
 
714
        (!m_controlBar || m_controlBar->containment() == 0) ) {
 
715
        defaultId = NetView::controlBarId();
 
716
    } else if (containment->containmentType() == Plasma::Containment::PanelContainment && 
 
717
        m_mainView->containment() == 0 ) {
 
718
        defaultId = NetView::mainViewId();
 
719
    }
 
720
 
 
721
    int id = viewIds.readEntry(QString::number(containment->id()), defaultId);
 
722
 
 
723
 
 
724
    kDebug() << "new containment" << (QObject*)containment << containment->id() << "view id" << id;
 
725
 
 
726
    //is it a desktop -and- is it active?
 
727
    if ((m_mainView && id == NetView::mainViewId()) ||
 
728
        (containment->containmentType() != Plasma::Containment::PanelContainment &&
 
729
         containment->containmentType() != Plasma::Containment::CustomPanelContainment &&
 
730
         !viewIds.exists() && containment->screen() == 0)) {
 
731
        m_mainView->setContainment(containment);
 
732
        containment->setScreen(0);
 
733
    //is it a panel?
 
734
    } else if (id == NetView::controlBarId()) {
 
735
        if (!m_controlBar) {
 
736
            m_controlBar = new NetView(0, NetView::controlBarId(), 0);
 
737
 
 
738
            Kephal::Screens *screens = Kephal::Screens::self();
 
739
            connect(screens, SIGNAL(screenResized(Kephal::Screen *, QSize, QSize)),
 
740
                    this, SLOT(adjustSize(Kephal::Screen *)));
 
741
 
 
742
            m_controlBar->setAutoFillBackground(false);
 
743
            m_controlBar->viewport()->setAutoFillBackground(false);
 
744
            m_controlBar->setAttribute(Qt::WA_TranslucentBackground);
 
745
 
 
746
            connect(m_controlBar, SIGNAL(locationChanged(const NetView *)), this, SLOT(positionPanel()));
 
747
            connect(m_controlBar, SIGNAL(geometryChanged()), this, SLOT(positionPanel()));
 
748
            connect(m_controlBar, SIGNAL(containmentActivated()), this, SLOT(showControlBar()));
 
749
            connect(m_controlBar, SIGNAL(autoHideChanged(bool)), this, SLOT(setAutoHideControlBar(bool)));
 
750
        }
 
751
 
 
752
        m_controlBar->setContainment(containment);
 
753
        positionPanel();
 
754
        setControlBarVisible(true);
 
755
        containment->setMaximumSize(m_controlBar->size());
 
756
        containment->setMinimumSize(m_controlBar->size());
 
757
        containment->setImmutability(Plasma::UserImmutable);
 
758
 
 
759
        m_autoHideControlBar = m_controlBar->config().readEntry("panelAutoHide", true);
 
760
 
 
761
        setAutoHideControlBar(m_autoHideControlBar);
 
762
        emit controlBarChanged();
 
763
        setControlBarVisible(true);
 
764
    } else {
 
765
        containment->setScreen(-1);
 
766
    }
 
767
}
 
768
 
 
769
void PlasmaApp::closeWidgetExplorer()
 
770
{
 
771
    if (m_widgetExplorer) {
 
772
        Plasma::WindowEffects::slideWindow(m_widgetExplorerView, m_controlBar->location());
 
773
        m_widgetExplorer->deleteLater();
 
774
        m_widgetExplorerView->deleteLater();
 
775
    }
 
776
}
 
777
 
 
778
void PlasmaApp::updateToolBoxVisibility(bool visible)
 
779
{
 
780
    bool hadToolBoxOpen = false;
 
781
 
 
782
    foreach (Plasma::Containment *cont, m_corona->containments()) {
 
783
        if (cont->isToolBoxOpen()) {
 
784
            hadToolBoxOpen = true;
 
785
        }
 
786
         cont->setToolBoxOpen(visible);
 
787
    }
 
788
 
 
789
    if (!visible && hadToolBoxOpen) {
 
790
        closeWidgetExplorer();
 
791
    }
 
792
}
 
793
 
 
794
void PlasmaApp::controlBarMoved(const NetView *controlBar)
 
795
{
 
796
    if (!m_controlBar || controlBar != m_controlBar) {
 
797
        return;
 
798
    }
 
799
 
 
800
    QRect screenRect = Kephal::ScreenUtils::screenGeometry(m_controlBar->screen());
 
801
 
 
802
    Plasma::Containment *cont = m_controlBar->containment();
 
803
 
 
804
    switch (controlBar->location()) {
 
805
    case Plasma::LeftEdge:
 
806
        m_controlBar->move(screenRect.topLeft());
 
807
        break;
 
808
    case Plasma::RightEdge:
 
809
        m_controlBar->move(screenRect.topRight()-QPoint(m_controlBar->size().width(), 0));
 
810
        break;
 
811
    case Plasma::TopEdge:
 
812
        m_controlBar->move(screenRect.topLeft());
 
813
        break;
 
814
    case Plasma::BottomEdge:
 
815
        m_controlBar->move(screenRect.bottomLeft()-QPoint(0,m_controlBar->size().height()));
 
816
    default:
 
817
        break;
 
818
    }
 
819
 
 
820
    //flip height and width
 
821
    if (controlBar->formFactor() == Plasma::Vertical) {
 
822
        if (cont && m_controlBar->size().width() > m_controlBar->size().height()) {
 
823
            cont->setMinimumSize(cont->size().height(), cont->size().width());
 
824
            cont->setMaximumSize(cont->minimumSize());
 
825
        }
 
826
    } else if (controlBar->formFactor() == Plasma::Horizontal) {
 
827
        if (cont && m_controlBar->size().width() < m_controlBar->size().height()) {
 
828
            cont->setMinimumSize(cont->size().height(), cont->size().width());
 
829
            cont->setMaximumSize(cont->minimumSize());
 
830
        }
 
831
    }
 
832
 
 
833
    reserveStruts();
 
834
}
 
835
 
 
836
void PlasmaApp::setAutoHideControlBar(bool autoHide)
 
837
{
 
838
    if (!m_controlBar) {
 
839
        return;
 
840
    }
 
841
 
 
842
    if (autoHide) {
 
843
        if (!m_unHideTimer) {
 
844
            m_unHideTimer = new QTimer(this);
 
845
            m_unHideTimer->setSingleShot(true);
 
846
            connect(m_unHideTimer, SIGNAL(timeout()), this, SLOT(controlBarVisibilityUpdate()));
 
847
        }
 
848
 
 
849
        m_controlBar->installEventFilter(this);
 
850
        controlBarVisibilityUpdate();
 
851
    } else {
 
852
        m_controlBar->removeEventFilter(this);
 
853
        destroyUnHideTrigger();
 
854
        delete m_unHideTimer;
 
855
        m_unHideTimer = 0;
 
856
        setControlBarVisible(true);
 
857
    }
 
858
 
 
859
    m_autoHideControlBar = autoHide;
 
860
    reserveStruts();
 
861
    m_controlBar->config().writeEntry("panelAutoHide", autoHide);
 
862
}
 
863
 
 
864
void PlasmaApp::showWidgetExplorer()
 
865
{
 
866
    Plasma::Containment *containment = dynamic_cast<Plasma::Containment *>(sender());
 
867
 
 
868
    if (!containment) {
 
869
        return;
 
870
    }
 
871
 
 
872
    showWidgetExplorer(containment);
 
873
}
 
874
 
 
875
void PlasmaApp::showWidgetExplorer(Plasma::Containment *containment)
 
876
{
 
877
    if (!containment) {
 
878
        return;
 
879
    }
 
880
 
 
881
    containment->setToolBoxOpen(true);
 
882
 
 
883
    if (!m_widgetExplorerView) {
 
884
 
 
885
        m_widgetExplorerView = new Plasma::Dialog();
 
886
 
 
887
        KWindowSystem::setOnAllDesktops(m_widgetExplorerView->winId(), true);
 
888
        m_widgetExplorerView->show();
 
889
        KWindowSystem::activateWindow(m_widgetExplorerView->winId());
 
890
        m_widgetExplorerView->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
 
891
        m_widgetExplorerView->setAttribute(Qt::WA_TranslucentBackground);
 
892
        m_widgetExplorerView->setAttribute(Qt::WA_DeleteOnClose);
 
893
        KWindowSystem::setState(m_widgetExplorerView->winId(), NET::StaysOnTop|NET::KeepAbove);
 
894
        connect(m_widgetExplorerView, SIGNAL(destroyed()), this, SLOT(widgetExplorerDestroyed()));
 
895
 
 
896
        if (m_controlBar) {
 
897
            switch (m_controlBar->location()) {
 
898
            case Plasma::TopEdge:
 
899
                m_widgetExplorerView->resize(m_mainView->size().width(), KIconLoader::SizeEnormous);
 
900
                m_widgetExplorerView->move(m_controlBar->geometry().bottomLeft());
 
901
                break;
 
902
            case Plasma::LeftEdge:
 
903
                m_widgetExplorerView->resize(KIconLoader::SizeEnormous, m_mainView->size().height());
 
904
                m_widgetExplorerView->move(m_controlBar->geometry().topRight());
 
905
                break;
 
906
            case Plasma::RightEdge:
 
907
                m_widgetExplorerView->resize(KIconLoader::SizeEnormous, m_mainView->size().height());
 
908
                m_widgetExplorerView->move(m_controlBar->geometry().topLeft() - QPoint(m_widgetExplorerView->size().width(), 0));
 
909
                break;
 
910
            case Plasma::BottomEdge:
 
911
            default:
 
912
                m_widgetExplorerView->resize(m_mainView->size().width(), KIconLoader::SizeEnormous);
 
913
                m_widgetExplorerView->move(m_controlBar->geometry().topLeft() - QPoint(0, m_widgetExplorerView->size().height()));
 
914
                break;
 
915
            }
 
916
        } else {
 
917
            m_widgetExplorerView->resize(m_mainView->size().width(), KIconLoader::SizeEnormous);
 
918
            m_widgetExplorerView->move(0,0);
 
919
        }
 
920
 
 
921
    }
 
922
 
 
923
    if (!m_widgetExplorer) {
 
924
        m_widgetExplorer = new Plasma::WidgetExplorer(m_controlBar->containment());
 
925
        connect(m_widgetExplorer, SIGNAL(closeClicked()), this, SLOT(closeWidgetExplorer()));
 
926
        m_widgetExplorer->setContainment(m_mainView->containment());
 
927
        m_widgetExplorer->populateWidgetList();
 
928
 
 
929
        m_corona->addOffscreenWidget(m_widgetExplorer);
 
930
 
 
931
        QSize viewSize = m_widgetExplorerView->size();
 
932
        m_widgetExplorerView->setGraphicsWidget(m_widgetExplorer);
 
933
 
 
934
        m_widgetExplorer->setIconSize(KIconLoader::SizeLarge);
 
935
        m_widgetExplorerView->installEventFilter(this);
 
936
    }
 
937
 
 
938
    m_widgetExplorer->setLocation(m_controlBar->location());
 
939
 
 
940
    if (m_widgetExplorer->location() == Plasma::LeftEdge || m_widgetExplorer->location() == Plasma::RightEdge) {
 
941
        m_widgetExplorer->setMinimumWidth(-1);
 
942
        m_widgetExplorer->setMinimumHeight(m_mainView->size().height());
 
943
    } else {
 
944
        m_widgetExplorer->setMinimumWidth(m_mainView->size().width());
 
945
        m_widgetExplorer->setMinimumHeight(-1);
 
946
    }
 
947
 
 
948
    positionPanel();
 
949
 
 
950
    m_widgetExplorer->show();
 
951
    Plasma::WindowEffects::slideWindow(m_widgetExplorerView, m_controlBar->location());
 
952
    m_widgetExplorerView->show();
 
953
    emit controlBarChanged();
 
954
}
 
955
 
 
956
void PlasmaApp::widgetExplorerDestroyed()
 
957
{
 
958
    m_widgetExplorer = 0;
 
959
    m_widgetExplorerView = 0;
 
960
    positionPanel();
 
961
    if (m_mainView->containment()) {
 
962
        m_mainView->containment()->setToolBoxOpen(false);
 
963
    }
 
964
}
 
965
 
 
966
 
 
967
void PlasmaApp::configureContainment(Plasma::Containment *containment)
 
968
{
 
969
    const QString id = "plasma_containment_settings_" + QString::number(containment->id());
 
970
    BackgroundDialog *configDialog = qobject_cast<BackgroundDialog*>(KConfigDialog::exists(id));
 
971
    kDebug() << configDialog;
 
972
 
 
973
    if (configDialog) {
 
974
        configDialog->reloadConfig();
 
975
    } else {
 
976
        const QSize resolution = Kephal::ScreenUtils::screenGeometry(m_mainView->screen()).size();
 
977
 
 
978
 
 
979
        KConfigSkeleton *nullManager = new KConfigSkeleton(0);
 
980
        configDialog = new BackgroundDialog(resolution, containment, m_mainView, 0, id, nullManager);
 
981
        configDialog->setAttribute(Qt::WA_DeleteOnClose);
 
982
 
 
983
        connect(configDialog, SIGNAL(destroyed(QObject*)), nullManager, SLOT(deleteLater()));
 
984
    }
 
985
 
 
986
    configDialog->show();
 
987
    KWindowSystem::setOnDesktop(configDialog->winId(), KWindowSystem::currentDesktop());
 
988
    KWindowSystem::activateWindow(configDialog->winId());
 
989
}
 
990
 
 
991
bool PlasmaApp::mainViewOnTop() const
 
992
{
 
993
    bool onTop = false;
 
994
 
 
995
    QSet<WId> ownWindows;
 
996
    foreach (QWidget *widget, QApplication::topLevelWidgets()) {
 
997
        ownWindows.insert(widget->winId());
 
998
    }
 
999
 
 
1000
    //search if the main view is actually one of the widgets on top, show the panel only in this case
 
1001
    QList<WId> windows = KWindowSystem::stackingOrder();
 
1002
    for (int i = windows.size() - 1; i >= 0; --i) {
 
1003
        WId window = windows.at(i);
 
1004
 
 
1005
        if (window == m_mainView->winId()) {
 
1006
            onTop = true;
 
1007
            break;
 
1008
        } else if (!ownWindows.contains(window)) {
 
1009
            break;
 
1010
        }
 
1011
    }
 
1012
 
 
1013
    return onTop;
 
1014
}
 
1015
 
 
1016
bool PlasmaApp::eventFilter(QObject * watched, QEvent *event)
 
1017
{
 
1018
    if (watched == m_widgetExplorerView && event->type() == QEvent::KeyPress) {
 
1019
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
 
1020
        if (keyEvent->key() == Qt::Key_Escape) {
 
1021
            closeWidgetExplorer();
 
1022
        }
 
1023
    } else if (watched == m_widgetExplorerView && event->type() == QEvent::Resize) {
 
1024
         m_widgetExplorer->resize(m_widgetExplorerView->contentsRect().size());
 
1025
    } else if (!m_isDesktop && watched == m_mainView && event->type() == QEvent::Close) {
 
1026
        exit();
 
1027
    }
 
1028
    return false;
 
1029
}
 
1030
 
 
1031
bool PlasmaApp::x11EventFilter(XEvent *event)
 
1032
{
 
1033
 
 
1034
    if (m_controlBar && m_autoHideControlBar && !m_controlBar->isVisible() && event->xcrossing.window == m_unhideTrigger &&
 
1035
        (event->xany.send_event != True && event->type == EnterNotify)) {
 
1036
        //delayed show
 
1037
        if (!m_glowBar && KWindowSystem::compositingActive() && !m_triggerZone.contains(QCursor::pos())) {
 
1038
            Plasma::Direction direction = Plasma::locationToDirection(m_controlBar->location());
 
1039
            m_glowBar = new GlowBar(direction, m_triggerZone);
 
1040
            m_glowBar->show();
 
1041
            XMoveResizeWindow(QX11Info::display(), m_unhideTrigger, m_triggerZone.x(), m_triggerZone.y(), m_triggerZone.width(), m_triggerZone.height());
 
1042
 
 
1043
            //FIXME: This is ugly as hell but well, yeah
 
1044
            if (!m_mousePollTimer) {
 
1045
                m_mousePollTimer = new QTimer(this);
 
1046
            }
 
1047
 
 
1048
            disconnect(m_mousePollTimer, SIGNAL(timeout()), this, SLOT(unhideHintMousePoll()));
 
1049
            connect(m_mousePollTimer, SIGNAL(timeout()), this, SLOT(unhideHintMousePoll()));
 
1050
            m_mousePollTimer->start(200);
 
1051
        } else {
 
1052
            m_unHideTimer->start(400);
 
1053
        }
 
1054
    } else if ((event->xany.send_event != True && event->type == FocusOut)) {
 
1055
        QTimer::singleShot(100, this, SLOT(lowerMainView()));
 
1056
    } else if (m_controlBar && m_autoHideControlBar && m_controlBar->isVisible() &&
 
1057
        (event->xany.send_event != True && event->type == LeaveNotify)) {
 
1058
        if (m_unHideTimer) {
 
1059
            m_unHideTimer->start(200);
 
1060
        }
 
1061
    }
 
1062
 
 
1063
    return KUniqueApplication::x11EventFilter(event);
 
1064
}
 
1065
 
 
1066
bool PlasmaApp::hasForegroundWindows() const
 
1067
{
 
1068
    return QApplication::activeWindow();
 
1069
}
 
1070
 
 
1071
void PlasmaApp::lowerMainView()
 
1072
{
 
1073
    if (m_isDesktop && !hasForegroundWindows()) {
 
1074
        KWindowSystem::lowerWindow(m_mainView->winId());
 
1075
    }
 
1076
    if (m_shadowWindow) {
 
1077
        KWindowSystem::clearState(m_shadowWindow->winId(), NET::KeepAbove);
 
1078
        KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepBelow);
 
1079
    }
 
1080
}
 
1081
 
 
1082
void PlasmaApp::controlBarVisibilityUpdate()
 
1083
{
 
1084
    if (!m_controlBar) {
 
1085
        return;
 
1086
    }
 
1087
 
 
1088
    if (!m_autoHideControlBar) {
 
1089
        setControlBarVisible(true);
 
1090
 
 
1091
        if (m_shadowWindow && m_shadowWindow->isValid()) {
 
1092
            Plasma::WindowEffects::slideWindow(m_shadowWindow, m_controlBar->location());
 
1093
            m_shadowWindow->show();
 
1094
            if (hasForegroundWindows()) {
 
1095
                KWindowSystem::clearState(m_shadowWindow->winId(), NET::KeepBelow);
 
1096
                KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepAbove);
 
1097
            } else {
 
1098
                KWindowSystem::clearState(m_shadowWindow->winId(), NET::KeepAbove);
 
1099
                KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepBelow);
 
1100
            }
 
1101
            KWindowSystem::setOnAllDesktops(m_shadowWindow->winId(), true);
 
1102
        }
 
1103
 
 
1104
        return;
 
1105
    } else if (m_autoHideControlBar && hasForegroundWindows() && m_controlBar->isVisible()) {
 
1106
        return;
 
1107
    }
 
1108
 
 
1109
    if (sender() != m_unHideTimer) {
 
1110
        m_unHideTimer->start(200);
 
1111
        return;
 
1112
    }
 
1113
 
 
1114
    //would be nice to avoid this
 
1115
    QPoint cursorPos = QCursor::pos();
 
1116
 
 
1117
    if (m_triggerZone.adjusted(-1, -1, 1, 1).contains(cursorPos) || hasForegroundWindows()) {
 
1118
        if (!m_controlBar->isVisible()) {
 
1119
            destroyUnHideTrigger();
 
1120
            Plasma::WindowEffects::slideWindow(m_controlBar, m_controlBar->location());
 
1121
            setControlBarVisible(true);
 
1122
        }
 
1123
 
 
1124
        if (m_shadowWindow && m_shadowWindow->isValid()) {
 
1125
            Plasma::WindowEffects::slideWindow(m_shadowWindow, m_controlBar->location());
 
1126
            if (hasForegroundWindows()) {
 
1127
                KWindowSystem::clearState(m_shadowWindow->winId(), NET::KeepBelow);
 
1128
                KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepAbove);
 
1129
            }
 
1130
            m_shadowWindow->show();
 
1131
            KWindowSystem::setOnAllDesktops(m_shadowWindow->winId(), true);
 
1132
        }
 
1133
    } else if (!m_controlBar->geometry().contains(cursorPos) && !mainViewOnTop() && !hasForegroundWindows()) {
 
1134
        Plasma::WindowEffects::slideWindow(m_controlBar, m_controlBar->location());
 
1135
        m_controlBar->hide();
 
1136
 
 
1137
        if (m_shadowWindow) {
 
1138
            Plasma::WindowEffects::slideWindow(m_shadowWindow, m_controlBar->location());
 
1139
            m_shadowWindow->hide();
 
1140
        }
 
1141
 
 
1142
        createUnhideTrigger();
 
1143
    }
 
1144
}
 
1145
 
 
1146
void PlasmaApp::showControlBar()
 
1147
{
 
1148
    setControlBarVisible(true);
 
1149
}
 
1150
 
 
1151
void PlasmaApp::hideControlBar()
 
1152
{
 
1153
    setControlBarVisible(false);
 
1154
}
 
1155
 
 
1156
void PlasmaApp::setControlBarVisible(bool visible)
 
1157
{
 
1158
    if (!m_controlBar || m_controlBar->isVisible() == visible) {
 
1159
        return;
 
1160
    }
 
1161
 
 
1162
    if (visible) {
 
1163
        destroyUnHideTrigger();
 
1164
        Plasma::WindowEffects::slideWindow(m_controlBar, m_controlBar->location());
 
1165
        m_controlBar->setWindowFlags(m_mainView->windowFlags() | Qt::FramelessWindowHint);
 
1166
        m_controlBar->setFrameShape(QFrame::NoFrame);
 
1167
        m_controlBar->show();
 
1168
        KWindowSystem::setOnAllDesktops(m_controlBar->winId(), m_isDesktop);
 
1169
        unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove;
 
1170
        KWindowSystem::setState(m_controlBar->effectiveWinId(), state);
 
1171
        KWindowSystem::setType(m_controlBar->effectiveWinId(), NET::Dock);
 
1172
 
 
1173
        if (m_shadowWindow && m_shadowWindow->isValid()) {
 
1174
            Plasma::WindowEffects::slideWindow(m_shadowWindow, m_controlBar->location());
 
1175
            m_shadowWindow->show();
 
1176
            if (!m_autoHideControlBar) {
 
1177
                KWindowSystem::setState(m_shadowWindow->winId(), NET::KeepBelow);
 
1178
            }
 
1179
            KWindowSystem::setOnAllDesktops(m_shadowWindow->winId(), true);
 
1180
        }
 
1181
    } else if (!m_autoHideControlBar) {
 
1182
        Plasma::WindowEffects::slideWindow(m_controlBar, m_controlBar->location());
 
1183
        m_controlBar->hide();
 
1184
        createUnhideTrigger();
 
1185
 
 
1186
        if (m_shadowWindow) {
 
1187
            Plasma::WindowEffects::slideWindow(m_shadowWindow, m_controlBar->location());
 
1188
            m_shadowWindow->hide();
 
1189
        }
 
1190
    }
 
1191
}
 
1192
 
 
1193
void PlasmaApp::toggleControlBarVisibility()
 
1194
{
 
1195
    setControlBarVisible(!m_controlBar->isVisible());
 
1196
}
 
1197
 
 
1198
void PlasmaApp::unhideHintMousePoll()
 
1199
{
 
1200
#ifdef Q_WS_X11
 
1201
    QPoint mousePos = QCursor::pos();
 
1202
    m_glowBar->updateStrength(mousePos);
 
1203
 
 
1204
    if (!m_unhideTriggerGeom.contains(mousePos)) {
 
1205
        //kDebug() << "hide the glow";
 
1206
        if (m_mousePollTimer) {
 
1207
            m_mousePollTimer->stop();
 
1208
            disconnect(m_mousePollTimer, SIGNAL(timeout()), this, SLOT(unhideHintMousePoll()));
 
1209
        }
 
1210
 
 
1211
        delete m_glowBar;
 
1212
        m_glowBar = 0;
 
1213
        XMoveResizeWindow(QX11Info::display(), m_unhideTrigger, m_unhideTriggerGeom.x(), m_unhideTriggerGeom.y(), m_unhideTriggerGeom.width(), m_unhideTriggerGeom.height());
 
1214
    } else {
 
1215
        m_unHideTimer->start(0);
 
1216
    }
 
1217
#endif
 
1218
}
 
1219
 
 
1220
void PlasmaApp::createUnhideTrigger()
 
1221
{
 
1222
#ifdef Q_WS_X11
 
1223
    //kDebug() << m_unhideTrigger << None;
 
1224
    if (!m_autoHideControlBar || m_unhideTrigger != None || !m_controlBar || m_controlBar->isVisible()) {
 
1225
        return;
 
1226
    }
 
1227
 
 
1228
    int actualWidth = 1;
 
1229
    int actualHeight = 1;
 
1230
    int triggerWidth = 1;
 
1231
    int triggerHeight = 1;
 
1232
 
 
1233
    if (KWindowSystem::compositingActive()) {
 
1234
        triggerWidth = 30;
 
1235
        triggerHeight = 30;
 
1236
    }
 
1237
 
 
1238
    QPoint actualTriggerPoint;
 
1239
    QPoint triggerPoint = actualTriggerPoint = QPoint(qMax(0, m_controlBar->pos().x()), qMax(0, m_controlBar->pos().y()));
 
1240
 
 
1241
    switch (m_controlBar->location()) {
 
1242
        case Plasma::TopEdge:
 
1243
            actualWidth = triggerWidth = m_controlBar->width() - 1;
 
1244
            actualHeight = 1;
 
1245
            triggerPoint += QPoint(1, 0);
 
1246
 
 
1247
            break;
 
1248
        case Plasma::BottomEdge:
 
1249
            actualWidth = triggerWidth = m_controlBar->width() - 1;
 
1250
            actualTriggerPoint = triggerPoint = m_controlBar->geometry().bottomLeft() + QPoint(1, 0);
 
1251
 
 
1252
            break;
 
1253
        case Plasma::RightEdge:
 
1254
            actualHeight = triggerHeight = m_controlBar->height() - 1;
 
1255
            actualTriggerPoint = triggerPoint = m_controlBar->geometry().topRight() + QPoint(0, 1);
 
1256
 
 
1257
            break;
 
1258
        case Plasma::LeftEdge:
 
1259
            actualHeight = triggerHeight = m_controlBar->height() - 1;
 
1260
            triggerPoint += QPoint(0, -1);
 
1261
 
 
1262
            break;
 
1263
        default:
 
1264
            // no hiding unless we're on an edge.
 
1265
            return;
 
1266
            break;
 
1267
    }
 
1268
 
 
1269
 
 
1270
    XSetWindowAttributes attributes;
 
1271
    attributes.override_redirect = True;
 
1272
    attributes.event_mask = EnterWindowMask;
 
1273
 
 
1274
 
 
1275
    attributes.event_mask = EnterWindowMask | LeaveWindowMask | PointerMotionMask |
 
1276
                            KeyPressMask | KeyPressMask | ButtonPressMask |
 
1277
                            ButtonReleaseMask | ButtonMotionMask |
 
1278
                            KeymapStateMask | VisibilityChangeMask |
 
1279
                            StructureNotifyMask | ResizeRedirectMask |
 
1280
                            SubstructureNotifyMask |
 
1281
                            SubstructureRedirectMask | FocusChangeMask |
 
1282
                            PropertyChangeMask | ColormapChangeMask | OwnerGrabButtonMask;
 
1283
 
 
1284
    unsigned long valuemask = CWOverrideRedirect | CWEventMask;
 
1285
    m_unhideTrigger = XCreateWindow(QX11Info::display(), QX11Info::appRootWindow(),
 
1286
                                    triggerPoint.x(), triggerPoint.y(), triggerWidth, triggerHeight,
 
1287
                                    0, CopyFromParent, InputOnly, CopyFromParent,
 
1288
                                    valuemask, &attributes);
 
1289
 
 
1290
    XMapWindow(QX11Info::display(), m_unhideTrigger);
 
1291
    m_unhideTriggerGeom = QRect(triggerPoint, QSize(triggerWidth, triggerHeight));
 
1292
    m_triggerZone = QRect(actualTriggerPoint, QSize(actualWidth, actualHeight));
 
1293
#endif
 
1294
}
 
1295
 
 
1296
void PlasmaApp::destroyUnHideTrigger()
 
1297
{
 
1298
#ifdef Q_WS_X11
 
1299
    if (m_unhideTrigger != None) {
 
1300
        XDestroyWindow(QX11Info::display(), m_unhideTrigger);
 
1301
        m_unhideTrigger = None;
 
1302
        m_triggerZone = m_unhideTriggerGeom = QRect();
 
1303
    }
 
1304
#endif
 
1305
}
 
1306
 
 
1307
#include "plasmaapp.moc"