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

« back to all changes in this revision

Viewing changes to kwin/effects/desktopgrid/desktopgrid.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
 KWin - the KDE window manager
 
3
 This file is part of the KDE project.
 
4
 
 
5
Copyright (C) 2007 Lubos Lunak <l.lunak@kde.org>
 
6
Copyright (C) 2008 Lucas Murray <lmurray@undefinedfire.com>
 
7
Copyright (C) 2009 Martin Gräßlin <kde@martin-graesslin.com>
 
8
 
 
9
This program is free software; you can redistribute it and/or modify
 
10
it under the terms of the GNU General Public License as published by
 
11
the Free Software Foundation; either version 2 of the License, or
 
12
(at your option) any later version.
 
13
 
 
14
This program is distributed in the hope that it will be useful,
 
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
GNU General Public License for more details.
 
18
 
 
19
You should have received a copy of the GNU General Public License
 
20
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
*********************************************************************/
 
22
 
 
23
#include "desktopgrid.h"
 
24
 
 
25
#include "../presentwindows/presentwindows_proxy.h"
 
26
 
 
27
#include <math.h>
 
28
 
 
29
#include <kaction.h>
 
30
#include <kactioncollection.h>
 
31
#include <kdebug.h>
 
32
#include <klocale.h>
 
33
#include <kconfiggroup.h>
 
34
#include <netwm_def.h>
 
35
#include <QEvent>
 
36
#include <QMouseEvent>
 
37
#include <kglobalsettings.h>
 
38
#include <QtGui/QPainter>
 
39
#include <QtGui/QGraphicsLinearLayout>
 
40
#include <Plasma/FrameSvg>
 
41
#include <Plasma/PushButton>
 
42
#include <Plasma/WindowEffects>
 
43
 
 
44
namespace KWin
 
45
{
 
46
 
 
47
// WARNING, TODO: This effect relies on the desktop layout being EWMH-compliant.
 
48
 
 
49
KWIN_EFFECT(desktopgrid, DesktopGridEffect)
 
50
 
 
51
DesktopGridEffect::DesktopGridEffect()
 
52
    : activated(false)
 
53
    , timeline()
 
54
    , keyboardGrab(false)
 
55
    , wasWindowMove(false)
 
56
    , wasDesktopMove(false)
 
57
    , isValidMove(false)
 
58
    , windowMove(NULL)
 
59
    , windowMoveDiff()
 
60
    , gridSize()
 
61
    , orientation(Qt::Horizontal)
 
62
    , activeCell(1, 1)
 
63
    , scale()
 
64
    , unscaledBorder()
 
65
    , scaledSize()
 
66
    , scaledOffset()
 
67
    , m_proxy(0)
 
68
{
 
69
    // Load shortcuts
 
70
    KActionCollection* actionCollection = new KActionCollection(this);
 
71
    KAction* a = (KAction*) actionCollection->addAction("ShowDesktopGrid");
 
72
    a->setText(i18n("Show Desktop Grid"));
 
73
    a->setGlobalShortcut(KShortcut(Qt::CTRL + Qt::Key_F8));
 
74
    shortcut = a->globalShortcut();
 
75
    connect(a, SIGNAL(triggered(bool)), this, SLOT(toggle()));
 
76
    connect(a, SIGNAL(globalShortcutChanged(QKeySequence)), this, SLOT(globalShortcutChanged(QKeySequence)));
 
77
    connect(effects, SIGNAL(windowAdded(EffectWindow*)), this, SLOT(slotWindowAdded(EffectWindow*)));
 
78
    connect(effects, SIGNAL(windowClosed(EffectWindow*)), this, SLOT(slotWindowClosed(EffectWindow*)));
 
79
    connect(effects, SIGNAL(windowDeleted(EffectWindow*)), this, SLOT(slotWindowDeleted(EffectWindow*)));
 
80
    connect(effects, SIGNAL(numberDesktopsChanged(int)), this, SLOT(slotNumberDesktopsChanged(int)));
 
81
    connect(effects, SIGNAL(windowGeometryShapeChanged(EffectWindow*,QRect)), this, SLOT(slotWindowGeometryShapeChanged(EffectWindow*,QRect)));
 
82
 
 
83
    // Load all other configuration details
 
84
    reconfigure(ReconfigureAll);
 
85
}
 
86
 
 
87
DesktopGridEffect::~DesktopGridEffect()
 
88
{
 
89
    foreach (ElectricBorder border, borderActivate) {
 
90
        effects->unreserveElectricBorder(border);
 
91
    }
 
92
    QHash< DesktopButtonsView*, EffectWindow* >::iterator i = m_desktopButtonsViews.begin();
 
93
    while (i != m_desktopButtonsViews.end()) {
 
94
        DesktopButtonsView *view = i.key();
 
95
        i = m_desktopButtonsViews.erase(i);
 
96
        view->deleteLater();
 
97
    }
 
98
}
 
99
 
 
100
void DesktopGridEffect::reconfigure(ReconfigureFlags)
 
101
{
 
102
    KConfigGroup conf = effects->effectConfig("DesktopGrid");
 
103
 
 
104
    foreach (ElectricBorder border, borderActivate) {
 
105
        effects->unreserveElectricBorder(border);
 
106
    }
 
107
    borderActivate.clear();
 
108
    QList<int> borderList = QList<int>();
 
109
    borderList.append(int(ElectricNone));
 
110
    borderList = conf.readEntry("BorderActivate", borderList);
 
111
    foreach (int i, borderList) {
 
112
        borderActivate.append(ElectricBorder(i));
 
113
        effects->reserveElectricBorder(ElectricBorder(i));
 
114
    }
 
115
 
 
116
    zoomDuration = animationTime(conf, "ZoomDuration", 300);
 
117
    timeline.setCurveShape(QTimeLine::EaseInOutCurve);
 
118
    timeline.setDuration(zoomDuration);
 
119
 
 
120
    border = conf.readEntry("BorderWidth", 10);
 
121
    desktopNameAlignment = Qt::Alignment(conf.readEntry("DesktopNameAlignment", 0));
 
122
    layoutMode = conf.readEntry("LayoutMode", int(LayoutPager));
 
123
    customLayoutRows = conf.readEntry("CustomLayoutRows", 2);
 
124
    m_usePresentWindows = conf.readEntry("PresentWindows", true);
 
125
}
 
126
 
 
127
//-----------------------------------------------------------------------------
 
128
// Screen painting
 
129
 
 
130
void DesktopGridEffect::prePaintScreen(ScreenPrePaintData& data, int time)
 
131
{
 
132
    if (timeline.currentValue() != 0 || activated || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
 
133
        if (activated)
 
134
            timeline.setCurrentTime(timeline.currentTime() + time);
 
135
        else
 
136
            timeline.setCurrentTime(timeline.currentTime() - time);
 
137
        for (int i = 0; i < effects->numberOfDesktops(); i++) {
 
138
            if (i == highlightedDesktop - 1)
 
139
                hoverTimeline[i]->setCurrentTime(hoverTimeline[i]->currentTime() + time);
 
140
            else
 
141
                hoverTimeline[i]->setCurrentTime(hoverTimeline[i]->currentTime() - time);
 
142
        }
 
143
        if (isUsingPresentWindows()) {
 
144
            QList<WindowMotionManager>::iterator i;
 
145
            for (i = m_managers.begin(); i != m_managers.end(); ++i)
 
146
                (*i).calculate(time);
 
147
        }
 
148
        // PAINT_SCREEN_BACKGROUND_FIRST is needed because screen will be actually painted more than once,
 
149
        // so with normal screen painting second screen paint would erase parts of the first paint
 
150
        if (timeline.currentValue() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows()))
 
151
            data.mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_BACKGROUND_FIRST;
 
152
        if (!activated && timeline.currentValue() == 0 && !(isUsingPresentWindows() && isMotionManagerMovingWindows()))
 
153
            finish();
 
154
    }
 
155
    effects->prePaintScreen(data, time);
 
156
}
 
157
 
 
158
void DesktopGridEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
 
159
{
 
160
    if (timeline.currentValue() == 0 && !isUsingPresentWindows()) {
 
161
        effects->paintScreen(mask, region, data);
 
162
        return;
 
163
    }
 
164
    for (int desktop = 1; desktop <= effects->numberOfDesktops(); desktop++) {
 
165
        ScreenPaintData d = data;
 
166
        paintingDesktop = desktop;
 
167
        effects->paintScreen(mask, region, d);
 
168
    }
 
169
 
 
170
    // paint the add desktop button
 
171
    for (QHash< DesktopButtonsView*, EffectWindow*>::iterator it = m_desktopButtonsViews.begin();
 
172
            it != m_desktopButtonsViews.end(); ++it) {
 
173
        if (!it.value()) {
 
174
            EffectWindow *view = effects->findWindow(it.key()->winId());
 
175
            if (view) {
 
176
                view->setData(WindowForceBlurRole, QVariant(true));
 
177
                it.value() = view;
 
178
            }
 
179
        }
 
180
        if (it.value()) {
 
181
            WindowPaintData d(it.value());
 
182
            d.opacity *= timeline.currentValue();
 
183
            effects->drawWindow(it.value(), PAINT_WINDOW_TRANSLUCENT,
 
184
                                infiniteRegion(), d);
 
185
        }
 
186
    }
 
187
 
 
188
    if (isUsingPresentWindows() && windowMove && wasWindowMove) {
 
189
        // the moving window has to be painted on top of all desktops
 
190
        QPoint diff = cursorPos() - m_windowMoveStartPoint;
 
191
        QRect geo = m_windowMoveGeometry.translated(diff);
 
192
        WindowPaintData d(windowMove);
 
193
        d.xScale *= (float)geo.width() / (float)windowMove->width();
 
194
        d.yScale *= (float)geo.height() / (float)windowMove->height();
 
195
        d.xTranslate += qRound(geo.left() - windowMove->x());
 
196
        d.yTranslate += qRound(geo.top() - windowMove->y());
 
197
        effects->drawWindow(windowMove, PAINT_WINDOW_TRANSFORMED | PAINT_WINDOW_LANCZOS, infiniteRegion(), d);
 
198
    }
 
199
 
 
200
    if (desktopNameAlignment) {
 
201
        for (int screen = 0; screen < effects->numScreens(); screen++) {
 
202
            QRect screenGeom = effects->clientArea(ScreenArea, screen, 0);
 
203
            PaintClipper pc(screenGeom);   // TODO: Doesn't work in XRender for some reason?
 
204
            int desktop = 1;
 
205
            foreach (EffectFrame * frame, desktopNames) {
 
206
                QPointF posTL(scalePos(screenGeom.topLeft(), desktop, screen));
 
207
                QPointF posBR(scalePos(screenGeom.bottomRight(), desktop, screen));
 
208
                QRect textArea(posTL.x(), posTL.y(), posBR.x() - posTL.x(), posBR.y() - posTL.y());
 
209
                textArea.adjust(textArea.width() / 10, textArea.height() / 10,
 
210
                                -textArea.width() / 10, -textArea.height() / 10);
 
211
                int x, y;
 
212
                if (desktopNameAlignment & Qt::AlignLeft)
 
213
                    x = textArea.x();
 
214
                else if (desktopNameAlignment & Qt::AlignRight)
 
215
                    x = textArea.right();
 
216
                else
 
217
                    x = textArea.center().x();
 
218
                if (desktopNameAlignment & Qt::AlignTop)
 
219
                    y = textArea.y();
 
220
                else if (desktopNameAlignment & Qt::AlignBottom)
 
221
                    y = textArea.bottom();
 
222
                else
 
223
                    y = textArea.center().y();
 
224
                frame->setPosition(QPoint(x, y));
 
225
                frame->render(region, timeline.currentValue(), 0.7);
 
226
                ++desktop;
 
227
            }
 
228
        }
 
229
    }
 
230
}
 
231
 
 
232
void DesktopGridEffect::postPaintScreen()
 
233
{
 
234
    if (activated ? timeline.currentValue() != 1 : timeline.currentValue() != 0)
 
235
        effects->addRepaintFull(); // Repaint during zoom
 
236
    if (isUsingPresentWindows() && isMotionManagerMovingWindows())
 
237
        effects->addRepaintFull();
 
238
    if (activated) {
 
239
        for (int i = 0; i < effects->numberOfDesktops(); i++) {
 
240
            if (hoverTimeline[i]->currentValue() != 0.0 && hoverTimeline[i]->currentValue() != 1.0) {
 
241
                // Repaint during soft highlighting
 
242
                effects->addRepaintFull();
 
243
                break;
 
244
            }
 
245
        }
 
246
    }
 
247
    effects->postPaintScreen();
 
248
}
 
249
 
 
250
//-----------------------------------------------------------------------------
 
251
// Window painting
 
252
 
 
253
void DesktopGridEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
 
254
{
 
255
    if (timeline.currentValue() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
 
256
        if (w->isOnDesktop(paintingDesktop)) {
 
257
            w->enablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
 
258
            if (w->isMinimized() && isUsingPresentWindows())
 
259
                w->enablePainting(EffectWindow::PAINT_DISABLED_BY_MINIMIZE);
 
260
            data.mask |= PAINT_WINDOW_TRANSFORMED;
 
261
 
 
262
            // Split windows at screen edges
 
263
            for (int screen = 0; screen < effects->numScreens(); screen++) {
 
264
                QRect screenGeom = effects->clientArea(ScreenArea, screen, 0);
 
265
                if (w->x() < screenGeom.x())
 
266
                    data.quads = data.quads.splitAtX(screenGeom.x() - w->x());
 
267
                if (w->x() + w->width() > screenGeom.x() + screenGeom.width())
 
268
                    data.quads = data.quads.splitAtX(screenGeom.x() + screenGeom.width() - w->x());
 
269
                if (w->y() < screenGeom.y())
 
270
                    data.quads = data.quads.splitAtY(screenGeom.y() - w->y());
 
271
                if (w->y() + w->height() > screenGeom.y() + screenGeom.height())
 
272
                    data.quads = data.quads.splitAtY(screenGeom.y() + screenGeom.height() - w->y());
 
273
            }
 
274
            if (windowMove && wasWindowMove && windowMove->findModal() == w)
 
275
                w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
 
276
        } else
 
277
            w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
 
278
    }
 
279
    effects->prePaintWindow(w, data, time);
 
280
}
 
281
 
 
282
void DesktopGridEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
 
283
{
 
284
    if (timeline.currentValue() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
 
285
        if (isUsingPresentWindows() && w == windowMove && wasWindowMove) {
 
286
            return; // will be painted on top of all other windows
 
287
        }
 
288
        if (m_desktopButtonsViews.values().contains(w))
 
289
            return; // will be painted on top of all other windows
 
290
 
 
291
        double xScale = data.xScale;
 
292
        double yScale = data.yScale;
 
293
 
 
294
        // Don't change brightness of windows on all desktops as this causes flickering
 
295
        if (!w->isOnAllDesktops() || w->isDesktop())
 
296
            data.brightness *= 1.0 - (0.3 * (1.0 - hoverTimeline[paintingDesktop - 1]->currentValue()));
 
297
 
 
298
        for (int screen = 0; screen < effects->numScreens(); screen++) {
 
299
            // Assume desktop windows can never be on two screens at once (Plasma makes one window per screen)
 
300
            if (w->isDesktop())
 
301
                screen = w->screen();
 
302
            QRect screenGeom = effects->clientArea(ScreenArea, screen, 0);
 
303
 
 
304
            QRectF transformedGeo = w->geometry();
 
305
            // Display all quads on the same screen on the same pass
 
306
            WindowQuadList screenQuads;
 
307
            bool quadsAdded = false;
 
308
            if (isUsingPresentWindows()) {
 
309
                WindowMotionManager& manager = m_managers[(paintingDesktop-1)*(effects->numScreens())+screen ];
 
310
                if (manager.isManaging(w)) {
 
311
                    foreach (const WindowQuad & quad, data.quads)
 
312
                    screenQuads.append(quad);
 
313
                    transformedGeo = manager.transformedGeometry(w);
 
314
                    quadsAdded = true;
 
315
                    if (!manager.areWindowsMoving() && timeline.currentValue() == 1.0)
 
316
                        mask |= PAINT_WINDOW_LANCZOS;
 
317
                } else if (w->screen() != screen)
 
318
                    quadsAdded = true; // we don't want parts of overlapping windows on the other screen
 
319
            }
 
320
            if (!quadsAdded) {
 
321
                foreach (const WindowQuad & quad, data.quads) {
 
322
                    QRect quadRect(
 
323
                        w->x() + quad.left(), w->y() + quad.top(),
 
324
                        quad.right() - quad.left(), quad.bottom() - quad.top()
 
325
                    );
 
326
                    if (quadRect.intersects(screenGeom))
 
327
                        screenQuads.append(quad);
 
328
                }
 
329
            }
 
330
            if (screenQuads.isEmpty())
 
331
                continue; // Nothing is being displayed, don't bother
 
332
            WindowPaintData d = data;
 
333
            d.quads = screenQuads;
 
334
 
 
335
            QPointF newPos = scalePos(transformedGeo.topLeft().toPoint(), paintingDesktop, screen);
 
336
            double progress = timeline.currentValue();
 
337
            d.xScale = interpolate(1, xScale * scale[screen] * (float)transformedGeo.width() / (float)w->geometry().width(), progress);
 
338
            d.yScale = interpolate(1, yScale * scale[screen] * (float)transformedGeo.height() / (float)w->geometry().height(), progress);
 
339
            d.xTranslate += qRound(newPos.x() - w->x());
 
340
            d.yTranslate += qRound(newPos.y() - w->y());
 
341
 
 
342
            if (isUsingPresentWindows() && (w->isDock() || w->isSkipSwitcher())) {
 
343
                // fade out panels if present windows is used
 
344
                d.opacity *= (1.0 - timeline.currentValue());
 
345
            }
 
346
            if (isUsingPresentWindows() && w->isMinimized()) {
 
347
                d.opacity *= timeline.currentValue();
 
348
            }
 
349
 
 
350
            if (effects->compositingType() == XRenderCompositing) {
 
351
                // More exact clipping as XRender displays the entire window instead of just the quad
 
352
                QPointF screenPosF = scalePos(screenGeom.topLeft(), paintingDesktop).toPoint();
 
353
                QPoint screenPos(
 
354
                    qRound(screenPosF.x()),
 
355
                    qRound(screenPosF.y())
 
356
                );
 
357
                QSize screenSize(
 
358
                    qRound(interpolate(screenGeom.width(), scaledSize[screen].width(), progress)),
 
359
                    qRound(interpolate(screenGeom.height(), scaledSize[screen].height(), progress))
 
360
                );
 
361
                PaintClipper pc(effects->clientArea(ScreenArea, screen, 0) & QRect(screenPos, screenSize));
 
362
                effects->paintWindow(w, mask, region, d);
 
363
            } else {
 
364
                PaintClipper pc(effects->clientArea(ScreenArea, screen, 0));
 
365
                if (w->isDesktop() && timeline.currentValue() == 1.0) {
 
366
                    // desktop windows are not in a motion manager and can always be rendered with
 
367
                    // lanczos sampling except for animations
 
368
                    mask |= PAINT_WINDOW_LANCZOS;
 
369
                }
 
370
                effects->paintWindow(w, mask, region, d);
 
371
            }
 
372
            // Assume desktop windows can never be on two screens at once (Plasma makes one window per screen)
 
373
            if (w->isDesktop())
 
374
                break;
 
375
        }
 
376
    } else
 
377
        effects->paintWindow(w, mask, region, data);
 
378
}
 
379
 
 
380
//-----------------------------------------------------------------------------
 
381
// User interaction
 
382
 
 
383
void DesktopGridEffect::slotWindowAdded(EffectWindow* w)
 
384
{
 
385
    if (!activated)
 
386
        return;
 
387
    if (isUsingPresentWindows()) {
 
388
        if (w->isDesktop() || w->isDock() || !w->visibleInClientGroup())
 
389
            return; // don't add
 
390
        if (w->isOnAllDesktops()) {
 
391
            for (int i = 0; i < effects->numberOfDesktops(); i++) {
 
392
                WindowMotionManager& manager = m_managers[ i*effects->numScreens()+w->screen()];
 
393
                manager.manage(w);
 
394
                m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
 
395
            }
 
396
        } else {
 
397
            WindowMotionManager& manager = m_managers[(w->desktop()-1)*effects->numScreens()+w->screen()];
 
398
            manager.manage(w);
 
399
            m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
 
400
        }
 
401
    }
 
402
    effects->addRepaintFull();
 
403
}
 
404
 
 
405
void DesktopGridEffect::slotWindowClosed(EffectWindow* w)
 
406
{
 
407
    if (!activated && timeline.currentValue() == 0)
 
408
        return;
 
409
    if (w == windowMove) {
 
410
        effects->setElevatedWindow(windowMove, false);
 
411
        windowMove = NULL;
 
412
    }
 
413
    if (isUsingPresentWindows()) {
 
414
        if (w->isOnAllDesktops()) {
 
415
            for (int i = 0; i < effects->numberOfDesktops(); i++) {
 
416
                WindowMotionManager& manager = m_managers[i*effects->numScreens()+w->screen()];
 
417
                manager.unmanage(w);
 
418
                m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
 
419
            }
 
420
        } else {
 
421
            if (w->desktop() <= effects->numberOfDesktops()) {
 
422
                WindowMotionManager& manager = m_managers[(w->desktop()-1)*effects->numScreens()+w->screen()];
 
423
                manager.unmanage(w);
 
424
                m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
 
425
            }
 
426
        }
 
427
    }
 
428
    for (QHash< DesktopButtonsView*, EffectWindow*>::iterator it = m_desktopButtonsViews.begin();
 
429
            it != m_desktopButtonsViews.end(); ++it) {
 
430
        if (it.value() && it.value() == w) {
 
431
            w->refWindow();
 
432
            break;
 
433
        }
 
434
    }
 
435
    effects->addRepaintFull();
 
436
}
 
437
 
 
438
void DesktopGridEffect::slotWindowDeleted(EffectWindow* w)
 
439
{
 
440
    if (w == windowMove)
 
441
        windowMove = 0;
 
442
    for (QHash< DesktopButtonsView*, EffectWindow*>::iterator it = m_desktopButtonsViews.begin();
 
443
            it != m_desktopButtonsViews.end(); ++it) {
 
444
        if (it.value() && it.value() == w) {
 
445
            it.key()->deleteLater();
 
446
            m_desktopButtonsViews.erase(it);
 
447
            break;
 
448
        }
 
449
    }
 
450
}
 
451
 
 
452
void DesktopGridEffect::slotWindowGeometryShapeChanged(EffectWindow* w, const QRect& old)
 
453
{
 
454
    Q_UNUSED(old)
 
455
    if (!activated)
 
456
        return;
 
457
    if (w == windowMove && wasWindowMove)
 
458
        return;
 
459
    if (isUsingPresentWindows()) {
 
460
        if (w->isOnAllDesktops()) {
 
461
            for (int i = 0; i < effects->numberOfDesktops(); i++) {
 
462
                WindowMotionManager& manager = m_managers[i*effects->numScreens()+w->screen()];
 
463
                m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
 
464
            }
 
465
        } else {
 
466
            WindowMotionManager& manager = m_managers[(w->desktop()-1)*effects->numScreens()+w->screen()];
 
467
            m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
 
468
        }
 
469
    }
 
470
}
 
471
 
 
472
void DesktopGridEffect::windowInputMouseEvent(Window, QEvent* e)
 
473
{
 
474
    if ((e->type() != QEvent::MouseMove
 
475
            && e->type() != QEvent::MouseButtonPress
 
476
            && e->type() != QEvent::MouseButtonRelease)
 
477
            || timeline.currentValue() != 1)  // Block user input during animations
 
478
        return;
 
479
    QMouseEvent* me = static_cast< QMouseEvent* >(e);
 
480
    for (QHash< DesktopButtonsView*, EffectWindow*>::iterator it = m_desktopButtonsViews.begin();
 
481
            it != m_desktopButtonsViews.end(); ++it) {
 
482
        DesktopButtonsView* view = it.key();
 
483
        if (!wasWindowMove && !wasDesktopMove && view->geometry().contains(me->pos())) {
 
484
            const QPoint widgetPos = view->mapFromGlobal(me->pos());
 
485
            const QPointF scenePos = view->mapToScene(widgetPos);
 
486
            QMouseEvent event(me->type(), widgetPos, me->pos(), me->button(), me->buttons(), me->modifiers());
 
487
            view->windowInputMouseEvent(&event);
 
488
            return;
 
489
        }
 
490
    }
 
491
 
 
492
    if (e->type() == QEvent::MouseMove) {
 
493
        int d = posToDesktop(me->pos());
 
494
        if (windowMove != NULL &&
 
495
                (me->pos() - dragStartPos).manhattanLength() > KGlobalSettings::dndEventDelay()) {
 
496
            // Handle window moving
 
497
            if (!wasWindowMove) { // Activate on move
 
498
                if (isUsingPresentWindows() && windowMove->isOnAllDesktops()) {
 
499
                    for (int i = 0; i < effects->numberOfDesktops(); ++i) {
 
500
                        WindowMotionManager& manager = m_managers[(i)*(effects->numScreens()) + windowMove->screen()];
 
501
                        if ((i + 1) == d) {
 
502
                            const QRectF transformedGeo = manager.transformedGeometry(windowMove);
 
503
                            const QPointF pos = scalePos(transformedGeo.topLeft().toPoint(), d, windowMove->screen());
 
504
                            const QSize size(scale[windowMove->screen()] *(float)transformedGeo.width(),
 
505
                                             scale[windowMove->screen()] *(float)transformedGeo.height());
 
506
                            m_windowMoveGeometry = QRect(pos.toPoint(), size);
 
507
                            m_windowMoveStartPoint = me->pos();
 
508
                        }
 
509
                        manager.unmanage(windowMove);
 
510
                        if (EffectWindow* modal = windowMove->findModal()) {
 
511
                            if (manager.isManaging(modal))
 
512
                                manager.unmanage(modal);
 
513
                        }
 
514
                        m_proxy->calculateWindowTransformations(manager.managedWindows(), windowMove->screen(), manager);
 
515
                    }
 
516
                } else if (isUsingPresentWindows()) {
 
517
                    WindowMotionManager& manager = m_managers[(windowMove->desktop()-1)*(effects->numScreens()) + windowMove->screen()];
 
518
                    const QRectF transformedGeo = manager.transformedGeometry(windowMove);
 
519
                    const QPointF pos = scalePos(transformedGeo.topLeft().toPoint(), windowMove->desktop(), windowMove->screen());
 
520
                    const QSize size(scale[windowMove->screen()] *(float)transformedGeo.width(),
 
521
                                     scale[windowMove->screen()] *(float)transformedGeo.height());
 
522
                    m_windowMoveGeometry = QRect(pos.toPoint(), size);
 
523
                    m_windowMoveStartPoint = me->pos();
 
524
 
 
525
                    manager.unmanage(windowMove);
 
526
                    if (EffectWindow* modal = windowMove->findModal()) {
 
527
                        if (manager.isManaging(modal))
 
528
                            manager.unmanage(modal);
 
529
                    }
 
530
                    m_proxy->calculateWindowTransformations(manager.managedWindows(), windowMove->screen(), manager);
 
531
                }
 
532
                XDefineCursor(display(), input, QCursor(Qt::ClosedHandCursor).handle());
 
533
            }
 
534
            wasWindowMove = true;
 
535
            if (windowMove->isMovable() && !isUsingPresentWindows()) {
 
536
                int screen = effects->screenNumber(me->pos());
 
537
                effects->moveWindow(windowMove, unscalePos(me->pos(), NULL) + windowMoveDiff, true, 1.0 / scale[screen]);
 
538
            }
 
539
            if (d != highlightedDesktop) {
 
540
                if (!windowMove->isOnAllDesktops())
 
541
                    effects->windowToDesktop(windowMove, d);   // Not true all desktop move
 
542
                const int screen = effects->screenNumber(me->pos());
 
543
                if (screen != windowMove->screen())
 
544
                    effects->windowToScreen(windowMove, screen);
 
545
            }
 
546
            effects->addRepaintFull();
 
547
        } else if ((me->buttons() & Qt::LeftButton) && !wasDesktopMove &&
 
548
                  (me->pos() - dragStartPos).manhattanLength() > KGlobalSettings::dndEventDelay()) {
 
549
            wasDesktopMove = true;
 
550
            XDefineCursor(display(), input, QCursor(Qt::ClosedHandCursor).handle());
 
551
        }
 
552
        if (d != highlightedDesktop) { // Highlight desktop
 
553
            if ((me->buttons() & Qt::LeftButton) && isValidMove && !wasWindowMove && d <= effects->numberOfDesktops()) {
 
554
                EffectWindowList windows = effects->stackingOrder();
 
555
                EffectWindowList stack;
 
556
                foreach (EffectWindow * w, windows) {
 
557
                    if (w->isOnAllDesktops())
 
558
                        continue;
 
559
                    if (w->isOnDesktop(highlightedDesktop)) {
 
560
                        effects->windowToDesktop(w, d);
 
561
                        if (isUsingPresentWindows()) {
 
562
                            m_managers[(d-1)*(effects->numScreens()) + w->screen()].manage(w);
 
563
                            m_managers[(highlightedDesktop-1)*(effects->numScreens()) + w->screen()].unmanage(w);
 
564
                        }
 
565
                    } else if (w->isOnDesktop(d))
 
566
                        stack << w;
 
567
                }
 
568
                foreach (EffectWindow * w, stack) {
 
569
                    effects->windowToDesktop(w, highlightedDesktop);
 
570
                    if (isUsingPresentWindows()) {
 
571
                        m_managers[(d-1)*(effects->numScreens()) + w->screen()].unmanage(w);
 
572
                        m_managers[(highlightedDesktop-1)*(effects->numScreens()) + w->screen()].manage(w);
 
573
                    }
 
574
                }
 
575
                if (isUsingPresentWindows()) {
 
576
                    for (int i = 0; i < effects->numScreens(); i++) {
 
577
                        WindowMotionManager& manager = m_managers[(d-1)*(effects->numScreens()) + i ];
 
578
                        WindowMotionManager& manager2 = m_managers[(highlightedDesktop-1)*(effects->numScreens()) + i ];
 
579
                        m_proxy->calculateWindowTransformations(manager.managedWindows(), i, manager);
 
580
                        m_proxy->calculateWindowTransformations(manager2.managedWindows(), i, manager2);
 
581
                    }
 
582
                    effects->addRepaintFull();
 
583
                }
 
584
            }
 
585
            setHighlightedDesktop(d);
 
586
        }
 
587
    }
 
588
    if (e->type() == QEvent::MouseButtonPress) {
 
589
        if (me->buttons() == Qt::LeftButton) {
 
590
            isValidMove = true;
 
591
//             QRect rect;
 
592
            dragStartPos = me->pos();
 
593
            bool isDesktop = (me->modifiers() & Qt::ControlModifier);
 
594
            EffectWindow* w = isDesktop ? NULL : windowAt(me->pos());
 
595
            if (w != NULL)
 
596
                isDesktop = w->isDesktop();
 
597
            if (w != NULL && !w->isDesktop() && (w->isMovable() || w->isMovableAcrossScreens() || isUsingPresentWindows())) {
 
598
                // Prepare it for moving
 
599
                windowMoveDiff = w->pos() - unscalePos(me->pos(), NULL);
 
600
                windowMove = w;
 
601
                effects->setElevatedWindow(windowMove, true);
 
602
            }
 
603
        } else if ((me->buttons() == Qt::MidButton || me->buttons() == Qt::RightButton) && windowMove == NULL) {
 
604
            EffectWindow* w = windowAt(me->pos());
 
605
            if (w != NULL) {
 
606
                if (w->isOnAllDesktops()) {
 
607
                    const int desktop = posToDesktop(me->pos());
 
608
                    effects->windowToDesktop(w, desktop);
 
609
                    if (isUsingPresentWindows()) {
 
610
                        for (int i = 0; i < effects->numberOfDesktops(); i++) {
 
611
                            if (i != desktop - 1) {
 
612
                                WindowMotionManager& manager = m_managers[ i*effects->numScreens() + w->screen()];
 
613
                                manager.unmanage(w);
 
614
                                m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
 
615
                            }
 
616
                        }
 
617
                    }
 
618
                } else {
 
619
                    if (isUsingPresentWindows()) {
 
620
                        const int desktop = w->desktop();
 
621
                        for (int i = 0; i < effects->numberOfDesktops(); i++) {
 
622
                            if (i != desktop - 1) {
 
623
                                WindowMotionManager& manager = m_managers[ i*effects->numScreens() + w->screen()];
 
624
                                manager.manage(w);
 
625
                                m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
 
626
                            }
 
627
                        }
 
628
                    }
 
629
                    effects->windowToDesktop(w, NET::OnAllDesktops);
 
630
                }
 
631
                effects->addRepaintFull();
 
632
            }
 
633
        }
 
634
    }
 
635
    if (e->type() == QEvent::MouseButtonRelease && me->button() == Qt::LeftButton) {
 
636
        isValidMove = false;
 
637
        if (!wasWindowMove && !wasDesktopMove) {
 
638
            setCurrentDesktop(posToDesktop(me->pos()));
 
639
            if (windowMove)
 
640
                effects->activateWindow(windowMove);
 
641
            setActive(false);
 
642
        }
 
643
        if (windowMove) {
 
644
            if (wasWindowMove) {
 
645
                if (isUsingPresentWindows()) {
 
646
                    if (windowMove->isOnAllDesktops()) {
 
647
                        const int targetDesktop = posToDesktop(cursorPos());
 
648
                        for (int i = 0; i < effects->numberOfDesktops(); ++i) {
 
649
                            WindowMotionManager& manager = m_managers[(i)*(effects->numScreens()) + windowMove->screen()];
 
650
                            manager.manage(windowMove);
 
651
                            if (EffectWindow* modal = windowMove->findModal())
 
652
                                manager.manage(modal);
 
653
                            if (i + 1 == targetDesktop) {
 
654
                                // for the desktop the window is dropped on, we use the current geometry
 
655
                                manager.setTransformedGeometry(windowMove, moveGeometryToDesktop(targetDesktop));
 
656
                            }
 
657
                            m_proxy->calculateWindowTransformations(manager.managedWindows(), windowMove->screen(), manager);
 
658
                        }
 
659
                    } else {
 
660
                        WindowMotionManager& manager = m_managers[(windowMove->desktop()-1)*(effects->numScreens()) + windowMove->screen()];
 
661
                        manager.manage(windowMove);
 
662
                        if (EffectWindow* modal = windowMove->findModal())
 
663
                            manager.manage(modal);
 
664
                        manager.setTransformedGeometry(windowMove, moveGeometryToDesktop(windowMove->desktop()));
 
665
                        m_proxy->calculateWindowTransformations(manager.managedWindows(), windowMove->screen(), manager);
 
666
                    }
 
667
                    effects->addRepaintFull();
 
668
                }
 
669
            }
 
670
            effects->setElevatedWindow(windowMove, false);
 
671
            windowMove = NULL;
 
672
            XDefineCursor(display(), input, QCursor(Qt::PointingHandCursor).handle());
 
673
        } else if (wasDesktopMove)
 
674
            XDefineCursor(display(), input, QCursor(Qt::PointingHandCursor).handle());
 
675
        wasWindowMove = false;
 
676
        wasDesktopMove = false;
 
677
    }
 
678
}
 
679
 
 
680
void DesktopGridEffect::grabbedKeyboardEvent(QKeyEvent* e)
 
681
{
 
682
    if (timeline.currentValue() != 1)   // Block user input during animations
 
683
        return;
 
684
    if (windowMove != NULL)
 
685
        return;
 
686
    if (e->type() == QEvent::KeyPress) {
 
687
        // check for global shortcuts
 
688
        // HACK: keyboard grab disables the global shortcuts so we have to check for global shortcut (bug 156155)
 
689
        if (shortcut.contains(e->key() + e->modifiers())) {
 
690
            toggle();
 
691
            return;
 
692
        }
 
693
 
 
694
        int desktop = -1;
 
695
        // switch by F<number> or just <number>
 
696
        if (e->key() >= Qt::Key_F1 && e->key() <= Qt::Key_F35)
 
697
            desktop = e->key() - Qt::Key_F1 + 1;
 
698
        else if (e->key() >= Qt::Key_0 && e->key() <= Qt::Key_9)
 
699
            desktop = e->key() == Qt::Key_0 ? 10 : e->key() - Qt::Key_0;
 
700
        if (desktop != -1) {
 
701
            if (desktop <= effects->numberOfDesktops()) {
 
702
                setHighlightedDesktop(desktop);
 
703
                setCurrentDesktop(desktop);
 
704
                setActive(false);
 
705
            }
 
706
            return;
 
707
        }
 
708
        switch(e->key()) {
 
709
            // Wrap only on autorepeat
 
710
        case Qt::Key_Left:
 
711
            setHighlightedDesktop(desktopToLeft(highlightedDesktop, !e->isAutoRepeat()));
 
712
            break;
 
713
        case Qt::Key_Right:
 
714
            setHighlightedDesktop(desktopToRight(highlightedDesktop, !e->isAutoRepeat()));
 
715
            break;
 
716
        case Qt::Key_Up:
 
717
            setHighlightedDesktop(desktopUp(highlightedDesktop, !e->isAutoRepeat()));
 
718
            break;
 
719
        case Qt::Key_Down:
 
720
            setHighlightedDesktop(desktopDown(highlightedDesktop, !e->isAutoRepeat()));
 
721
            break;
 
722
        case Qt::Key_Escape:
 
723
            setActive(false);
 
724
            return;
 
725
        case Qt::Key_Enter:
 
726
        case Qt::Key_Return:
 
727
        case Qt::Key_Space:
 
728
            setCurrentDesktop(highlightedDesktop);
 
729
            setActive(false);
 
730
            return;
 
731
        case Qt::Key_Plus:
 
732
            slotAddDesktop();
 
733
            break;
 
734
        case Qt::Key_Minus:
 
735
            slotRemoveDesktop();
 
736
            break;
 
737
        default:
 
738
            break;
 
739
        }
 
740
    }
 
741
}
 
742
 
 
743
bool DesktopGridEffect::borderActivated(ElectricBorder border)
 
744
{
 
745
    if (!borderActivate.contains(border))
 
746
        return false;
 
747
    if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this)
 
748
        return true;
 
749
    toggle();
 
750
    return true;
 
751
}
 
752
 
 
753
//-----------------------------------------------------------------------------
 
754
// Helper functions
 
755
 
 
756
// Transform a point to its position on the scaled grid
 
757
QPointF DesktopGridEffect::scalePos(const QPoint& pos, int desktop, int screen) const
 
758
{
 
759
    if (screen == -1)
 
760
        screen = effects->screenNumber(pos);
 
761
    QRect screenGeom = effects->clientArea(ScreenArea, screen, 0);
 
762
    QPoint desktopCell;
 
763
    if (orientation == Qt::Horizontal) {
 
764
        desktopCell.setX((desktop - 1) % gridSize.width() + 1);
 
765
        desktopCell.setY((desktop - 1) / gridSize.width() + 1);
 
766
    } else {
 
767
        desktopCell.setX((desktop - 1) / gridSize.height() + 1);
 
768
        desktopCell.setY((desktop - 1) % gridSize.height() + 1);
 
769
    }
 
770
 
 
771
    double progress = timeline.currentValue();
 
772
    QPointF point(
 
773
        interpolate(
 
774
            (
 
775
                (screenGeom.width() + unscaledBorder[screen]) *(desktopCell.x() - 1)
 
776
                - (screenGeom.width() + unscaledBorder[screen]) *(activeCell.x() - 1)
 
777
            ) + pos.x(),
 
778
            (
 
779
                (scaledSize[screen].width() + border) *(desktopCell.x() - 1)
 
780
                + scaledOffset[screen].x()
 
781
                + (pos.x() - screenGeom.x()) * scale[screen]
 
782
            ),
 
783
            progress),
 
784
        interpolate(
 
785
            (
 
786
                (screenGeom.height() + unscaledBorder[screen]) *(desktopCell.y() - 1)
 
787
                - (screenGeom.height() + unscaledBorder[screen]) *(activeCell.y() - 1)
 
788
            ) + pos.y(),
 
789
            (
 
790
                (scaledSize[screen].height() + border) *(desktopCell.y() - 1)
 
791
                + scaledOffset[screen].y()
 
792
                + (pos.y() - screenGeom.y()) * scale[screen]
 
793
            ),
 
794
            progress)
 
795
    );
 
796
 
 
797
    return point;
 
798
}
 
799
 
 
800
// Detransform a point to its position on the full grid
 
801
// TODO: Doesn't correctly interpolate (Final position is correct though), don't forget to copy to posToDesktop()
 
802
QPoint DesktopGridEffect::unscalePos(const QPoint& pos, int* desktop) const
 
803
{
 
804
    int screen = effects->screenNumber(pos);
 
805
    QRect screenGeom = effects->clientArea(ScreenArea, screen, 0);
 
806
 
 
807
    //double progress = timeline.currentValue();
 
808
    double scaledX = /*interpolate(
 
809
        ( pos.x() - screenGeom.x() + unscaledBorder[screen] / 2.0 ) / ( screenGeom.width() + unscaledBorder[screen] ) + activeCell.x() - 1,*/
 
810
        (pos.x() - scaledOffset[screen].x() + double(border) / 2.0) / (scaledSize[screen].width() + border)/*,
 
811
        progress )*/;
 
812
    double scaledY = /*interpolate(
 
813
        ( pos.y() - screenGeom.y() + unscaledBorder[screen] / 2.0 ) / ( screenGeom.height() + unscaledBorder[screen] ) + activeCell.y() - 1,*/
 
814
        (pos.y() - scaledOffset[screen].y() + double(border) / 2.0) / (scaledSize[screen].height() + border)/*,
 
815
        progress )*/;
 
816
    int gx = qBound(0, int(scaledX), gridSize.width() - 1);     // Zero-based
 
817
    int gy = qBound(0, int(scaledY), gridSize.height() - 1);
 
818
    scaledX -= gx;
 
819
    scaledY -= gy;
 
820
    if (desktop != NULL) {
 
821
        if (orientation == Qt::Horizontal)
 
822
            *desktop = gy * gridSize.width() + gx + 1;
 
823
        else
 
824
            *desktop = gx * gridSize.height() + gy + 1;
 
825
    }
 
826
 
 
827
    return QPoint(
 
828
               qBound(
 
829
                   screenGeom.x(),
 
830
                   qRound(
 
831
                       scaledX * (screenGeom.width() + unscaledBorder[screen])
 
832
                       - unscaledBorder[screen] / 2.0
 
833
                       + screenGeom.x()
 
834
                   ),
 
835
                   screenGeom.right()
 
836
               ),
 
837
               qBound(
 
838
                   screenGeom.y(),
 
839
                   qRound(
 
840
                       scaledY * (screenGeom.height() + unscaledBorder[screen])
 
841
                       - unscaledBorder[screen] / 2.0
 
842
                       + screenGeom.y()
 
843
                   ),
 
844
                   screenGeom.bottom()
 
845
               )
 
846
           );
 
847
}
 
848
 
 
849
int DesktopGridEffect::posToDesktop(const QPoint& pos) const
 
850
{
 
851
    // Copied from unscalePos()
 
852
    int screen = effects->screenNumber(pos);
 
853
    QRect screenGeom = effects->clientArea(ScreenArea, screen, 0);
 
854
 
 
855
    //double progress = timeline.currentValue();
 
856
    double scaledX = /*interpolate(
 
857
        ( pos.x() - screenGeom.x() + unscaledBorder[screen] / 2.0 ) / ( screenGeom.width() + unscaledBorder[screen] ) + activeCell.x() - 1,*/
 
858
        (pos.x() - scaledOffset[screen].x() + double(border) / 2.0) / (scaledSize[screen].width() + border)/*,
 
859
        progress )*/;
 
860
    double scaledY = /*interpolate(
 
861
        ( pos.y() - screenGeom.y() + unscaledBorder[screen] / 2.0 ) / ( screenGeom.height() + unscaledBorder[screen] ) + activeCell.y() - 1,*/
 
862
        (pos.y() - scaledOffset[screen].y() + double(border) / 2.0) / (scaledSize[screen].height() + border)/*,
 
863
        progress )*/;
 
864
    int gx = qBound(0, int(scaledX), gridSize.width() - 1);     // Zero-based
 
865
    int gy = qBound(0, int(scaledY), gridSize.height() - 1);
 
866
    scaledX -= gx;
 
867
    scaledY -= gy;
 
868
    if (orientation == Qt::Horizontal)
 
869
        return gy * gridSize.width() + gx + 1;
 
870
    return gx * gridSize.height() + gy + 1;
 
871
}
 
872
 
 
873
EffectWindow* DesktopGridEffect::windowAt(QPoint pos) const
 
874
{
 
875
    // Get stacking order top first
 
876
    EffectWindowList windows = effects->stackingOrder();
 
877
    EffectWindowList::Iterator begin = windows.begin();
 
878
    EffectWindowList::Iterator end = windows.end();
 
879
    --end;
 
880
    while (begin < end)
 
881
        qSwap(*begin++, *end--);
 
882
 
 
883
    int desktop;
 
884
    pos = unscalePos(pos, &desktop);
 
885
    if (desktop > effects->numberOfDesktops())
 
886
        return NULL;
 
887
    if (isUsingPresentWindows()) {
 
888
        const int screen = effects->screenNumber(pos);
 
889
        EffectWindow *w =
 
890
            m_managers.at((desktop - 1) * (effects->numScreens()) + screen).windowAtPoint(pos, false);
 
891
        if (w)
 
892
            return w;
 
893
        foreach (EffectWindow * w, windows) {
 
894
            if (w->isOnDesktop(desktop) && w->isDesktop() && w->geometry().contains(pos))
 
895
                return w;
 
896
        }
 
897
    } else {
 
898
        foreach (EffectWindow * w, windows) {
 
899
            if (w->isOnDesktop(desktop) && !w->isMinimized() && w->geometry().contains(pos))
 
900
                return w;
 
901
        }
 
902
    }
 
903
    return NULL;
 
904
}
 
905
 
 
906
void DesktopGridEffect::setCurrentDesktop(int desktop)
 
907
{
 
908
    if (orientation == Qt::Horizontal) {
 
909
        activeCell.setX((desktop - 1) % gridSize.width() + 1);
 
910
        activeCell.setY((desktop - 1) / gridSize.width() + 1);
 
911
    } else {
 
912
        activeCell.setX((desktop - 1) / gridSize.height() + 1);
 
913
        activeCell.setY((desktop - 1) % gridSize.height() + 1);
 
914
    }
 
915
    if (effects->currentDesktop() != desktop)
 
916
        effects->setCurrentDesktop(desktop);
 
917
}
 
918
 
 
919
void DesktopGridEffect::setHighlightedDesktop(int d)
 
920
{
 
921
    if (d == highlightedDesktop || d <= 0 || d > effects->numberOfDesktops())
 
922
        return;
 
923
    highlightedDesktop = d;
 
924
    effects->addRepaintFull();
 
925
}
 
926
 
 
927
int DesktopGridEffect::desktopToRight(int desktop, bool wrap) const
 
928
{
 
929
    // Copied from Workspace::desktopToRight()
 
930
    int dt = desktop - 1;
 
931
    if (orientation == Qt::Vertical) {
 
932
        dt += gridSize.height();
 
933
        if (dt >= effects->numberOfDesktops()) {
 
934
            if (wrap)
 
935
                dt -= effects->numberOfDesktops();
 
936
            else
 
937
                return desktop;
 
938
        }
 
939
    } else {
 
940
        int d = (dt % gridSize.width()) + 1;
 
941
        if (d >= gridSize.width()) {
 
942
            if (wrap)
 
943
                d -= gridSize.width();
 
944
            else
 
945
                return desktop;
 
946
        }
 
947
        dt = dt - (dt % gridSize.width()) + d;
 
948
    }
 
949
    return dt + 1;
 
950
}
 
951
 
 
952
int DesktopGridEffect::desktopToLeft(int desktop, bool wrap) const
 
953
{
 
954
    // Copied from Workspace::desktopToLeft()
 
955
    int dt = desktop - 1;
 
956
    if (orientation == Qt::Vertical) {
 
957
        dt -= gridSize.height();
 
958
        if (dt < 0) {
 
959
            if (wrap)
 
960
                dt += effects->numberOfDesktops();
 
961
            else
 
962
                return desktop;
 
963
        }
 
964
    } else {
 
965
        int d = (dt % gridSize.width()) - 1;
 
966
        if (d < 0) {
 
967
            if (wrap)
 
968
                d += gridSize.width();
 
969
            else
 
970
                return desktop;
 
971
        }
 
972
        dt = dt - (dt % gridSize.width()) + d;
 
973
    }
 
974
    return dt + 1;
 
975
}
 
976
 
 
977
int DesktopGridEffect::desktopUp(int desktop, bool wrap) const
 
978
{
 
979
    // Copied from Workspace::desktopUp()
 
980
    int dt = desktop - 1;
 
981
    if (orientation == Qt::Horizontal) {
 
982
        dt -= gridSize.width();
 
983
        if (dt < 0) {
 
984
            if (wrap)
 
985
                dt += effects->numberOfDesktops();
 
986
            else
 
987
                return desktop;
 
988
        }
 
989
    } else {
 
990
        int d = (dt % gridSize.height()) - 1;
 
991
        if (d < 0) {
 
992
            if (wrap)
 
993
                d += gridSize.height();
 
994
            else
 
995
                return desktop;
 
996
        }
 
997
        dt = dt - (dt % gridSize.height()) + d;
 
998
    }
 
999
    return dt + 1;
 
1000
}
 
1001
 
 
1002
int DesktopGridEffect::desktopDown(int desktop, bool wrap) const
 
1003
{
 
1004
    // Copied from Workspace::desktopDown()
 
1005
    int dt = desktop - 1;
 
1006
    if (orientation == Qt::Horizontal) {
 
1007
        dt += gridSize.width();
 
1008
        if (dt >= effects->numberOfDesktops()) {
 
1009
            if (wrap)
 
1010
                dt -= effects->numberOfDesktops();
 
1011
            else
 
1012
                return desktop;
 
1013
        }
 
1014
    } else {
 
1015
        int d = (dt % gridSize.height()) + 1;
 
1016
        if (d >= gridSize.height()) {
 
1017
            if (wrap)
 
1018
                d -= gridSize.height();
 
1019
            else
 
1020
                return desktop;
 
1021
        }
 
1022
        dt = dt - (dt % gridSize.height()) + d;
 
1023
    }
 
1024
    return dt + 1;
 
1025
}
 
1026
 
 
1027
//-----------------------------------------------------------------------------
 
1028
// Activation
 
1029
 
 
1030
void DesktopGridEffect::toggle()
 
1031
{
 
1032
    setActive(!activated);
 
1033
}
 
1034
 
 
1035
void DesktopGridEffect::setActive(bool active)
 
1036
{
 
1037
    if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this)
 
1038
        return; // Only one fullscreen effect at a time thanks
 
1039
    if (active && isMotionManagerMovingWindows())
 
1040
        return; // Still moving windows from last usage - don't activate
 
1041
    if (activated == active)
 
1042
        return; // Already in that state
 
1043
 
 
1044
    activated = active;
 
1045
    if (activated && timeline.currentValue() == 0)
 
1046
        setup();
 
1047
    if (!activated) {
 
1048
        if (isUsingPresentWindows()) {
 
1049
            QList<WindowMotionManager>::iterator it;
 
1050
            for (it = m_managers.begin(); it != m_managers.end(); ++it) {
 
1051
                foreach (EffectWindow * w, (*it).managedWindows()) {
 
1052
                    (*it).moveWindow(w, w->geometry());
 
1053
                }
 
1054
            }
 
1055
        }
 
1056
        setHighlightedDesktop(effects->currentDesktop());   // Ensure selected desktop is highlighted
 
1057
        for (QHash< DesktopButtonsView*, EffectWindow*>::iterator it = m_desktopButtonsViews.begin();
 
1058
                it != m_desktopButtonsViews.end(); ++it) {
 
1059
            it.key()->hide();
 
1060
        }
 
1061
    }
 
1062
    effects->addRepaintFull();
 
1063
}
 
1064
 
 
1065
void DesktopGridEffect::setup()
 
1066
{
 
1067
    keyboardGrab = effects->grabKeyboard(this);
 
1068
    input = effects->createInputWindow(this, 0, 0, displayWidth(), displayHeight(),
 
1069
                                       Qt::PointingHandCursor);
 
1070
    effects->setActiveFullScreenEffect(this);
 
1071
    setHighlightedDesktop(effects->currentDesktop());
 
1072
 
 
1073
    // Soft highlighting
 
1074
    qDeleteAll(hoverTimeline);
 
1075
    hoverTimeline.clear();
 
1076
    for (int i = 0; i < effects->numberOfDesktops(); i++) {
 
1077
        QTimeLine *newTimeline = new QTimeLine(animationTime(zoomDuration), this);
 
1078
        newTimeline->setCurveShape(QTimeLine::EaseInOutCurve);
 
1079
        hoverTimeline.append(newTimeline);
 
1080
    }
 
1081
    hoverTimeline[effects->currentDesktop() - 1]->setCurrentTime(hoverTimeline[effects->currentDesktop() - 1]->duration());
 
1082
 
 
1083
    // Create desktop name textures if enabled
 
1084
    if (desktopNameAlignment) {
 
1085
        QFont font;
 
1086
        font.setBold(true);
 
1087
        font.setPointSize(12);
 
1088
        for (int i = 0; i < effects->numberOfDesktops(); i++) {
 
1089
            EffectFrame* frame = effects->effectFrame(EffectFrameUnstyled, false);
 
1090
            frame->setFont(font);
 
1091
            frame->setText(effects->desktopName(i + 1));
 
1092
            frame->setAlignment(desktopNameAlignment);
 
1093
            desktopNames.append(frame);
 
1094
        }
 
1095
    }
 
1096
    setupGrid();
 
1097
    setCurrentDesktop(effects->currentDesktop());
 
1098
 
 
1099
    // setup the motion managers
 
1100
    if (m_usePresentWindows)
 
1101
        m_proxy = static_cast<PresentWindowsEffectProxy*>(effects->getProxy("presentwindows"));
 
1102
    if (isUsingPresentWindows()) {
 
1103
        for (int i = 1; i <= effects->numberOfDesktops(); i++) {
 
1104
            for (int j = 0; j < effects->numScreens(); j++) {
 
1105
                WindowMotionManager manager;
 
1106
                foreach (EffectWindow * w, effects->stackingOrder()) {
 
1107
                    if (w->isOnDesktop(i) && w->screen() == j && !w->isDesktop() && !w->isDock() &&
 
1108
                            w->visibleInClientGroup() && !w->isSkipSwitcher() && w->isOnCurrentActivity()) {
 
1109
                        manager.manage(w);
 
1110
                    }
 
1111
                }
 
1112
                m_proxy->calculateWindowTransformations(manager.managedWindows(), j, manager);
 
1113
                m_managers.append(manager);
 
1114
            }
 
1115
        }
 
1116
    }
 
1117
    bool enableAdd = effects->numberOfDesktops() < 20;
 
1118
    bool enableRemove = effects->numberOfDesktops() > 1;
 
1119
    for (int i = 0; i < effects->numScreens(); ++i) {
 
1120
        DesktopButtonsView* view = new DesktopButtonsView();
 
1121
        view->setAddDesktopEnabled(enableAdd);
 
1122
        view->setRemoveDesktopEnabled(enableRemove);
 
1123
        connect(view, SIGNAL(addDesktop()), SLOT(slotAddDesktop()));
 
1124
        connect(view, SIGNAL(removeDesktop()), SLOT(slotRemoveDesktop()));
 
1125
        const QRect screenRect = effects->clientArea(FullScreenArea, i, 1);
 
1126
        view->setGeometry(screenRect.right() + 1 - view->sceneRect().width(),
 
1127
                          screenRect.bottom() + 1 - view->sceneRect().height(),
 
1128
                          view->sceneRect().width(), view->sceneRect().height());
 
1129
        view->show();
 
1130
        m_desktopButtonsViews.insert(view, NULL);
 
1131
    }
 
1132
}
 
1133
 
 
1134
void DesktopGridEffect::setupGrid()
 
1135
{
 
1136
    // We need these variables for every paint so lets cache them
 
1137
    int x, y;
 
1138
    int numDesktops = effects->numberOfDesktops();
 
1139
    switch(layoutMode) {
 
1140
    default:
 
1141
    case LayoutPager:
 
1142
        orientation = Qt::Horizontal;
 
1143
        gridSize = effects->desktopGridSize();
 
1144
        // sanity check: pager may report incorrect size in case of one desktop
 
1145
        if (numDesktops == 1) {
 
1146
            gridSize = QSize(1, 1);
 
1147
        }
 
1148
        break;
 
1149
    case LayoutAutomatic:
 
1150
        y = sqrt(float(numDesktops)) + 0.5;
 
1151
        x = float(numDesktops) / float(y) + 0.5;
 
1152
        if (x * y < numDesktops)
 
1153
            x++;
 
1154
        orientation = Qt::Horizontal;
 
1155
        gridSize.setWidth(x);
 
1156
        gridSize.setHeight(y);
 
1157
        break;
 
1158
    case LayoutCustom:
 
1159
        orientation = Qt::Horizontal;
 
1160
        gridSize.setWidth(ceil(effects->numberOfDesktops() / double(customLayoutRows)));
 
1161
        gridSize.setHeight(customLayoutRows);
 
1162
        break;
 
1163
    }
 
1164
    scale.clear();
 
1165
    unscaledBorder.clear();
 
1166
    scaledSize.clear();
 
1167
    scaledOffset.clear();
 
1168
    for (int i = 0; i < effects->numScreens(); i++) {
 
1169
        QRect geom = effects->clientArea(ScreenArea, i, 0);
 
1170
        double sScale;
 
1171
        if (gridSize.width() > gridSize.height())
 
1172
            sScale = (geom.width() - border * (gridSize.width() + 1)) / double(geom.width() * gridSize.width());
 
1173
        else
 
1174
            sScale = (geom.height() - border * (gridSize.height() + 1)) / double(geom.height() * gridSize.height());
 
1175
        double sBorder = border / sScale;
 
1176
        QSizeF size(
 
1177
            double(geom.width()) * sScale,
 
1178
            double(geom.height()) * sScale
 
1179
        );
 
1180
        QPointF offset(
 
1181
            geom.x() + (geom.width() - size.width() * gridSize.width() - border *(gridSize.width() - 1)) / 2.0,
 
1182
            geom.y() + (geom.height() - size.height() * gridSize.height() - border *(gridSize.height() - 1)) / 2.0
 
1183
        );
 
1184
        scale.append(sScale);
 
1185
        unscaledBorder.append(sBorder);
 
1186
        scaledSize.append(size);
 
1187
        scaledOffset.append(offset);
 
1188
    }
 
1189
}
 
1190
 
 
1191
void DesktopGridEffect::finish()
 
1192
{
 
1193
    if (desktopNameAlignment) {
 
1194
        qDeleteAll(desktopNames);
 
1195
        desktopNames.clear();
 
1196
    }
 
1197
 
 
1198
    if (keyboardGrab)
 
1199
        effects->ungrabKeyboard();
 
1200
    keyboardGrab = false;
 
1201
    effects->destroyInputWindow(input);
 
1202
    effects->setActiveFullScreenEffect(0);
 
1203
    if (isUsingPresentWindows()) {
 
1204
        while (!m_managers.isEmpty()) {
 
1205
            m_managers.first().unmanageAll();
 
1206
            m_managers.removeFirst();
 
1207
        }
 
1208
        m_proxy = 0;
 
1209
    }
 
1210
 
 
1211
    QHash< DesktopButtonsView*, EffectWindow* >::iterator i = m_desktopButtonsViews.begin();
 
1212
    while (i != m_desktopButtonsViews.end()) {
 
1213
        if (*i && (*i)->isDeleted())
 
1214
            (*i)->unrefWindow();
 
1215
        DesktopButtonsView *view = i.key();
 
1216
        i = m_desktopButtonsViews.erase(i);
 
1217
        view->deleteLater();
 
1218
    }
 
1219
}
 
1220
 
 
1221
void DesktopGridEffect::globalShortcutChanged(const QKeySequence& seq)
 
1222
{
 
1223
    shortcut = KShortcut(seq);
 
1224
}
 
1225
 
 
1226
bool DesktopGridEffect::isMotionManagerMovingWindows()
 
1227
{
 
1228
    if (isUsingPresentWindows()) {
 
1229
        QList<WindowMotionManager>::iterator it;
 
1230
        for (it = m_managers.begin(); it != m_managers.end(); ++it) {
 
1231
            if ((*it).areWindowsMoving())
 
1232
                return true;
 
1233
        }
 
1234
    }
 
1235
    return false;
 
1236
}
 
1237
 
 
1238
bool DesktopGridEffect::isUsingPresentWindows() const
 
1239
{
 
1240
    return (m_proxy != NULL);
 
1241
}
 
1242
 
 
1243
// transforms the geometry of the moved window to a geometry on the desktop
 
1244
// internal method only used when a window is dropped onto a desktop
 
1245
QRectF DesktopGridEffect::moveGeometryToDesktop(int desktop) const
 
1246
{
 
1247
    QPointF point = unscalePos(m_windowMoveGeometry.topLeft() + cursorPos() - m_windowMoveStartPoint);
 
1248
    const double scaleFactor = scale[ windowMove->screen()];
 
1249
    if (posToDesktop(m_windowMoveGeometry.topLeft() + cursorPos() - m_windowMoveStartPoint) != desktop) {
 
1250
        // topLeft is not on the desktop - check other corners
 
1251
        // if all corners are not on the desktop the window is bigger than the desktop - no matter what it will look strange
 
1252
        if (posToDesktop(m_windowMoveGeometry.topRight() + cursorPos() - m_windowMoveStartPoint) == desktop) {
 
1253
            point = unscalePos(m_windowMoveGeometry.topRight() + cursorPos() - m_windowMoveStartPoint) -
 
1254
                    QPointF(m_windowMoveGeometry.width(), 0) / scaleFactor;
 
1255
        } else if (posToDesktop(m_windowMoveGeometry.bottomLeft() + cursorPos() - m_windowMoveStartPoint) == desktop) {
 
1256
            point = unscalePos(m_windowMoveGeometry.bottomLeft() + cursorPos() - m_windowMoveStartPoint) -
 
1257
                    QPointF(0, m_windowMoveGeometry.height()) / scaleFactor;
 
1258
        } else if (posToDesktop(m_windowMoveGeometry.bottomRight() + cursorPos() - m_windowMoveStartPoint) == desktop) {
 
1259
            point = unscalePos(m_windowMoveGeometry.bottomRight() + cursorPos() - m_windowMoveStartPoint) -
 
1260
                    QPointF(m_windowMoveGeometry.width(), m_windowMoveGeometry.height()) / scaleFactor;
 
1261
        }
 
1262
    }
 
1263
    return QRectF(point, m_windowMoveGeometry.size() / scaleFactor);
 
1264
}
 
1265
 
 
1266
void DesktopGridEffect::slotAddDesktop()
 
1267
{
 
1268
    effects->setNumberOfDesktops(effects->numberOfDesktops() + 1);
 
1269
}
 
1270
 
 
1271
void DesktopGridEffect::slotRemoveDesktop()
 
1272
{
 
1273
    effects->setNumberOfDesktops(effects->numberOfDesktops() - 1);
 
1274
}
 
1275
 
 
1276
void DesktopGridEffect::slotNumberDesktopsChanged(int old)
 
1277
{
 
1278
    if (!activated)
 
1279
        return;
 
1280
    const int desktop = effects->numberOfDesktops();
 
1281
    bool enableAdd = desktop < 20;
 
1282
    bool enableRemove = desktop > 1;
 
1283
    for (QHash< DesktopButtonsView*, EffectWindow* >::iterator it = m_desktopButtonsViews.begin();
 
1284
            it != m_desktopButtonsViews.end(); ++it) {
 
1285
        it.key()->setAddDesktopEnabled(enableAdd);
 
1286
        it.key()->setRemoveDesktopEnabled(enableRemove);
 
1287
    }
 
1288
    if (old < desktop)
 
1289
        desktopsAdded(old);
 
1290
    else
 
1291
        desktopsRemoved(old);
 
1292
}
 
1293
 
 
1294
void DesktopGridEffect::desktopsAdded(int old)
 
1295
{
 
1296
    const int desktop = effects->numberOfDesktops();
 
1297
    for (int i = old; i <= effects->numberOfDesktops(); i++) {
 
1298
        // add a timeline for the new desktop
 
1299
        QTimeLine *newTimeline = new QTimeLine(animationTime(zoomDuration), this);
 
1300
        newTimeline->setCurveShape(QTimeLine::EaseInOutCurve);
 
1301
        hoverTimeline.append(newTimeline);
 
1302
    }
 
1303
 
 
1304
    // Create desktop name textures if enabled
 
1305
    if (desktopNameAlignment) {
 
1306
        QFont font;
 
1307
        font.setBold(true);
 
1308
        font.setPointSize(12);
 
1309
        for (int i = old; i < desktop; i++) {
 
1310
            EffectFrame* frame = effects->effectFrame(EffectFrameUnstyled, false);
 
1311
            frame->setFont(font);
 
1312
            frame->setText(effects->desktopName(i + 1));
 
1313
            frame->setAlignment(desktopNameAlignment);
 
1314
            desktopNames.append(frame);
 
1315
        }
 
1316
    }
 
1317
 
 
1318
    if (isUsingPresentWindows()) {
 
1319
        for (int i = old; i <= effects->numberOfDesktops(); i++) {
 
1320
            for (int j = 0; j < effects->numScreens(); j++) {
 
1321
                WindowMotionManager manager;
 
1322
                foreach (EffectWindow * w, effects->stackingOrder()) {
 
1323
                    if (w->isOnDesktop(i) && w->screen() == j && !w->isDesktop() && !w->isDock() &&
 
1324
                            w->visibleInClientGroup()) {
 
1325
                        manager.manage(w);
 
1326
                    }
 
1327
                }
 
1328
                m_proxy->calculateWindowTransformations(manager.managedWindows(), j, manager);
 
1329
                m_managers.append(manager);
 
1330
            }
 
1331
        }
 
1332
    }
 
1333
 
 
1334
    setupGrid();
 
1335
 
 
1336
    // and repaint
 
1337
    effects->addRepaintFull();
 
1338
}
 
1339
 
 
1340
void DesktopGridEffect::desktopsRemoved(int old)
 
1341
{
 
1342
    const int desktop = effects->numberOfDesktops();
 
1343
    for (int i = desktop; i < old; i++) {
 
1344
        delete hoverTimeline.takeLast();
 
1345
        if (desktopNameAlignment) {
 
1346
            delete desktopNames.last();
 
1347
            desktopNames.removeLast();
 
1348
        }
 
1349
        if (isUsingPresentWindows()) {
 
1350
            for (int j = 0; j < effects->numScreens(); ++j) {
 
1351
                WindowMotionManager& manager = m_managers.last();
 
1352
                manager.unmanageAll();
 
1353
                m_managers.removeLast();
 
1354
            }
 
1355
        }
 
1356
    }
 
1357
    // add removed windows to the last desktop
 
1358
    if (isUsingPresentWindows()) {
 
1359
        for (int j = 0; j < effects->numScreens(); ++j) {
 
1360
            WindowMotionManager& manager = m_managers[(desktop-1)*(effects->numScreens())+j ];
 
1361
            foreach (EffectWindow * w, effects->stackingOrder()) {
 
1362
                if (!manager.isManaging(w) && w->isOnDesktop(desktop) && w->screen() == j &&
 
1363
                        !w->isDesktop() && !w->isDock() && w->visibleInClientGroup()) {
 
1364
                    manager.manage(w);
 
1365
                }
 
1366
            }
 
1367
            m_proxy->calculateWindowTransformations(manager.managedWindows(), j, manager);
 
1368
        }
 
1369
    }
 
1370
 
 
1371
    setupGrid();
 
1372
 
 
1373
    // and repaint
 
1374
    effects->addRepaintFull();
 
1375
}
 
1376
 
 
1377
/************************************************
 
1378
* DesktopButtonView
 
1379
************************************************/
 
1380
DesktopButtonsView::DesktopButtonsView(QWidget* parent)
 
1381
    : QGraphicsView(parent)
 
1382
{
 
1383
    setWindowFlags(Qt::X11BypassWindowManagerHint);
 
1384
    setAttribute(Qt::WA_TranslucentBackground);
 
1385
    setFrameShape(QFrame::NoFrame);
 
1386
    QPalette pal = palette();
 
1387
    pal.setColor(backgroundRole(), Qt::transparent);
 
1388
    setPalette(pal);
 
1389
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 
1390
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 
1391
 
 
1392
    // setup the scene
 
1393
    QGraphicsScene* scene = new QGraphicsScene(this);
 
1394
    m_addDesktopButton = new Plasma::PushButton();
 
1395
    m_addDesktopButton->setIcon(KIcon("list-add"));
 
1396
    m_removeDesktopButton = new Plasma::PushButton();
 
1397
    m_removeDesktopButton->setIcon(KIcon("list-remove"));
 
1398
    scene->addItem(m_addDesktopButton);
 
1399
    scene->addItem(m_removeDesktopButton);
 
1400
    connect(m_addDesktopButton, SIGNAL(clicked()), SIGNAL(addDesktop()));
 
1401
    connect(m_removeDesktopButton, SIGNAL(clicked()), SIGNAL(removeDesktop()));
 
1402
 
 
1403
    QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
 
1404
    layout->addItem(m_addDesktopButton);
 
1405
    layout->addItem(m_removeDesktopButton);
 
1406
 
 
1407
    QGraphicsWidget *form = new QGraphicsWidget;
 
1408
    form->setLayout(layout);
 
1409
    form->setGeometry(0, 0, 64 * 2, 64);
 
1410
    scene->addItem(form);
 
1411
 
 
1412
    m_frame = new Plasma::FrameSvg(this);
 
1413
    m_frame->setImagePath("dialogs/background");
 
1414
    m_frame->setCacheAllRenderedFrames(true);
 
1415
    m_frame->setEnabledBorders(Plasma::FrameSvg::AllBorders);
 
1416
    qreal left, top, right, bottom;
 
1417
    m_frame->getMargins(left, top, right, bottom);
 
1418
    qreal width = form->size().width() + left + right;
 
1419
    qreal height = form->size().height() + top + bottom;
 
1420
    m_frame->resizeFrame(QSizeF(width, height));
 
1421
    Plasma::WindowEffects::enableBlurBehind(winId(), true, m_frame->mask());
 
1422
    Plasma::WindowEffects::overrideShadow(winId(), true);
 
1423
    form->setPos(left, top);
 
1424
    scene->setSceneRect(QRectF(QPointF(0, 0), QSizeF(width, height)));
 
1425
    setScene(scene);
 
1426
}
 
1427
 
 
1428
void DesktopButtonsView::windowInputMouseEvent(QMouseEvent* e)
 
1429
{
 
1430
    if (e->type() == QEvent::MouseMove) {
 
1431
        mouseMoveEvent(e);
 
1432
    } else if (e->type() == QEvent::MouseButtonPress) {
 
1433
        mousePressEvent(e);
 
1434
    } else if (e->type() == QEvent::MouseButtonDblClick) {
 
1435
        mouseDoubleClickEvent(e);
 
1436
    } else if (e->type() == QEvent::MouseButtonRelease) {
 
1437
        mouseReleaseEvent(e);
 
1438
    }
 
1439
}
 
1440
 
 
1441
void DesktopButtonsView::setAddDesktopEnabled(bool enable)
 
1442
{
 
1443
    m_addDesktopButton->setEnabled(enable);
 
1444
}
 
1445
 
 
1446
void DesktopButtonsView::setRemoveDesktopEnabled(bool enable)
 
1447
{
 
1448
    m_removeDesktopButton->setEnabled(enable);
 
1449
}
 
1450
 
 
1451
void DesktopButtonsView::drawBackground(QPainter* painter, const QRectF& rect)
 
1452
{
 
1453
    Q_UNUSED(rect)
 
1454
    painter->setRenderHint(QPainter::Antialiasing);
 
1455
    m_frame->paintFrame(painter);
 
1456
}
 
1457
 
 
1458
} // namespace
 
1459
 
 
1460
#include "desktopgrid.moc"