1
/********************************************************************
2
KWin - the KDE window manager
3
This file is part of the KDE project.
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>
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.
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.
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
*********************************************************************/
23
#include "desktopgrid.h"
25
#include "../presentwindows/presentwindows_proxy.h"
30
#include <kactioncollection.h>
33
#include <kconfiggroup.h>
34
#include <netwm_def.h>
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>
47
// WARNING, TODO: This effect relies on the desktop layout being EWMH-compliant.
49
KWIN_EFFECT(desktopgrid, DesktopGridEffect)
51
DesktopGridEffect::DesktopGridEffect()
55
, wasWindowMove(false)
56
, wasDesktopMove(false)
61
, orientation(Qt::Horizontal)
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)));
83
// Load all other configuration details
84
reconfigure(ReconfigureAll);
87
DesktopGridEffect::~DesktopGridEffect()
89
foreach (ElectricBorder border, borderActivate) {
90
effects->unreserveElectricBorder(border);
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);
100
void DesktopGridEffect::reconfigure(ReconfigureFlags)
102
KConfigGroup conf = effects->effectConfig("DesktopGrid");
104
foreach (ElectricBorder border, borderActivate) {
105
effects->unreserveElectricBorder(border);
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));
116
zoomDuration = animationTime(conf, "ZoomDuration", 300);
117
timeline.setCurveShape(QTimeLine::EaseInOutCurve);
118
timeline.setDuration(zoomDuration);
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);
127
//-----------------------------------------------------------------------------
130
void DesktopGridEffect::prePaintScreen(ScreenPrePaintData& data, int time)
132
if (timeline.currentValue() != 0 || activated || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
134
timeline.setCurrentTime(timeline.currentTime() + time);
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);
141
hoverTimeline[i]->setCurrentTime(hoverTimeline[i]->currentTime() - time);
143
if (isUsingPresentWindows()) {
144
QList<WindowMotionManager>::iterator i;
145
for (i = m_managers.begin(); i != m_managers.end(); ++i)
146
(*i).calculate(time);
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()))
155
effects->prePaintScreen(data, time);
158
void DesktopGridEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
160
if (timeline.currentValue() == 0 && !isUsingPresentWindows()) {
161
effects->paintScreen(mask, region, data);
164
for (int desktop = 1; desktop <= effects->numberOfDesktops(); desktop++) {
165
ScreenPaintData d = data;
166
paintingDesktop = desktop;
167
effects->paintScreen(mask, region, d);
170
// paint the add desktop button
171
for (QHash< DesktopButtonsView*, EffectWindow*>::iterator it = m_desktopButtonsViews.begin();
172
it != m_desktopButtonsViews.end(); ++it) {
174
EffectWindow *view = effects->findWindow(it.key()->winId());
176
view->setData(WindowForceBlurRole, QVariant(true));
181
WindowPaintData d(it.value());
182
d.opacity *= timeline.currentValue();
183
effects->drawWindow(it.value(), PAINT_WINDOW_TRANSLUCENT,
184
infiniteRegion(), d);
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);
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?
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);
212
if (desktopNameAlignment & Qt::AlignLeft)
214
else if (desktopNameAlignment & Qt::AlignRight)
215
x = textArea.right();
217
x = textArea.center().x();
218
if (desktopNameAlignment & Qt::AlignTop)
220
else if (desktopNameAlignment & Qt::AlignBottom)
221
y = textArea.bottom();
223
y = textArea.center().y();
224
frame->setPosition(QPoint(x, y));
225
frame->render(region, timeline.currentValue(), 0.7);
232
void DesktopGridEffect::postPaintScreen()
234
if (activated ? timeline.currentValue() != 1 : timeline.currentValue() != 0)
235
effects->addRepaintFull(); // Repaint during zoom
236
if (isUsingPresentWindows() && isMotionManagerMovingWindows())
237
effects->addRepaintFull();
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();
247
effects->postPaintScreen();
250
//-----------------------------------------------------------------------------
253
void DesktopGridEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int time)
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;
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());
274
if (windowMove && wasWindowMove && windowMove->findModal() == w)
275
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
277
w->disablePainting(EffectWindow::PAINT_DISABLED_BY_DESKTOP);
279
effects->prePaintWindow(w, data, time);
282
void DesktopGridEffect::paintWindow(EffectWindow* w, int mask, QRegion region, WindowPaintData& data)
284
if (timeline.currentValue() != 0 || (isUsingPresentWindows() && isMotionManagerMovingWindows())) {
285
if (isUsingPresentWindows() && w == windowMove && wasWindowMove) {
286
return; // will be painted on top of all other windows
288
if (m_desktopButtonsViews.values().contains(w))
289
return; // will be painted on top of all other windows
291
double xScale = data.xScale;
292
double yScale = data.yScale;
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()));
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)
301
screen = w->screen();
302
QRect screenGeom = effects->clientArea(ScreenArea, screen, 0);
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);
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
321
foreach (const WindowQuad & quad, data.quads) {
323
w->x() + quad.left(), w->y() + quad.top(),
324
quad.right() - quad.left(), quad.bottom() - quad.top()
326
if (quadRect.intersects(screenGeom))
327
screenQuads.append(quad);
330
if (screenQuads.isEmpty())
331
continue; // Nothing is being displayed, don't bother
332
WindowPaintData d = data;
333
d.quads = screenQuads;
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());
342
if (isUsingPresentWindows() && (w->isDock() || w->isSkipSwitcher())) {
343
// fade out panels if present windows is used
344
d.opacity *= (1.0 - timeline.currentValue());
346
if (isUsingPresentWindows() && w->isMinimized()) {
347
d.opacity *= timeline.currentValue();
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();
354
qRound(screenPosF.x()),
355
qRound(screenPosF.y())
358
qRound(interpolate(screenGeom.width(), scaledSize[screen].width(), progress)),
359
qRound(interpolate(screenGeom.height(), scaledSize[screen].height(), progress))
361
PaintClipper pc(effects->clientArea(ScreenArea, screen, 0) & QRect(screenPos, screenSize));
362
effects->paintWindow(w, mask, region, d);
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;
370
effects->paintWindow(w, mask, region, d);
372
// Assume desktop windows can never be on two screens at once (Plasma makes one window per screen)
377
effects->paintWindow(w, mask, region, data);
380
//-----------------------------------------------------------------------------
383
void DesktopGridEffect::slotWindowAdded(EffectWindow* w)
387
if (isUsingPresentWindows()) {
388
if (w->isDesktop() || w->isDock() || !w->visibleInClientGroup())
390
if (w->isOnAllDesktops()) {
391
for (int i = 0; i < effects->numberOfDesktops(); i++) {
392
WindowMotionManager& manager = m_managers[ i*effects->numScreens()+w->screen()];
394
m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
397
WindowMotionManager& manager = m_managers[(w->desktop()-1)*effects->numScreens()+w->screen()];
399
m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
402
effects->addRepaintFull();
405
void DesktopGridEffect::slotWindowClosed(EffectWindow* w)
407
if (!activated && timeline.currentValue() == 0)
409
if (w == windowMove) {
410
effects->setElevatedWindow(windowMove, false);
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()];
418
m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
421
if (w->desktop() <= effects->numberOfDesktops()) {
422
WindowMotionManager& manager = m_managers[(w->desktop()-1)*effects->numScreens()+w->screen()];
424
m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
428
for (QHash< DesktopButtonsView*, EffectWindow*>::iterator it = m_desktopButtonsViews.begin();
429
it != m_desktopButtonsViews.end(); ++it) {
430
if (it.value() && it.value() == w) {
435
effects->addRepaintFull();
438
void DesktopGridEffect::slotWindowDeleted(EffectWindow* w)
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);
452
void DesktopGridEffect::slotWindowGeometryShapeChanged(EffectWindow* w, const QRect& old)
457
if (w == windowMove && wasWindowMove)
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);
466
WindowMotionManager& manager = m_managers[(w->desktop()-1)*effects->numScreens()+w->screen()];
467
m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
472
void DesktopGridEffect::windowInputMouseEvent(Window, QEvent* e)
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
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);
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()];
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();
509
manager.unmanage(windowMove);
510
if (EffectWindow* modal = windowMove->findModal()) {
511
if (manager.isManaging(modal))
512
manager.unmanage(modal);
514
m_proxy->calculateWindowTransformations(manager.managedWindows(), windowMove->screen(), manager);
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();
525
manager.unmanage(windowMove);
526
if (EffectWindow* modal = windowMove->findModal()) {
527
if (manager.isManaging(modal))
528
manager.unmanage(modal);
530
m_proxy->calculateWindowTransformations(manager.managedWindows(), windowMove->screen(), manager);
532
XDefineCursor(display(), input, QCursor(Qt::ClosedHandCursor).handle());
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]);
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);
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());
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())
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);
565
} else if (w->isOnDesktop(d))
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);
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);
582
effects->addRepaintFull();
585
setHighlightedDesktop(d);
588
if (e->type() == QEvent::MouseButtonPress) {
589
if (me->buttons() == Qt::LeftButton) {
592
dragStartPos = me->pos();
593
bool isDesktop = (me->modifiers() & Qt::ControlModifier);
594
EffectWindow* w = isDesktop ? NULL : windowAt(me->pos());
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);
601
effects->setElevatedWindow(windowMove, true);
603
} else if ((me->buttons() == Qt::MidButton || me->buttons() == Qt::RightButton) && windowMove == NULL) {
604
EffectWindow* w = windowAt(me->pos());
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()];
614
m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
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()];
625
m_proxy->calculateWindowTransformations(manager.managedWindows(), w->screen(), manager);
629
effects->windowToDesktop(w, NET::OnAllDesktops);
631
effects->addRepaintFull();
635
if (e->type() == QEvent::MouseButtonRelease && me->button() == Qt::LeftButton) {
637
if (!wasWindowMove && !wasDesktopMove) {
638
setCurrentDesktop(posToDesktop(me->pos()));
640
effects->activateWindow(windowMove);
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));
657
m_proxy->calculateWindowTransformations(manager.managedWindows(), windowMove->screen(), manager);
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);
667
effects->addRepaintFull();
670
effects->setElevatedWindow(windowMove, false);
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;
680
void DesktopGridEffect::grabbedKeyboardEvent(QKeyEvent* e)
682
if (timeline.currentValue() != 1) // Block user input during animations
684
if (windowMove != NULL)
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())) {
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;
701
if (desktop <= effects->numberOfDesktops()) {
702
setHighlightedDesktop(desktop);
703
setCurrentDesktop(desktop);
709
// Wrap only on autorepeat
711
setHighlightedDesktop(desktopToLeft(highlightedDesktop, !e->isAutoRepeat()));
714
setHighlightedDesktop(desktopToRight(highlightedDesktop, !e->isAutoRepeat()));
717
setHighlightedDesktop(desktopUp(highlightedDesktop, !e->isAutoRepeat()));
720
setHighlightedDesktop(desktopDown(highlightedDesktop, !e->isAutoRepeat()));
728
setCurrentDesktop(highlightedDesktop);
743
bool DesktopGridEffect::borderActivated(ElectricBorder border)
745
if (!borderActivate.contains(border))
747
if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this)
753
//-----------------------------------------------------------------------------
756
// Transform a point to its position on the scaled grid
757
QPointF DesktopGridEffect::scalePos(const QPoint& pos, int desktop, int screen) const
760
screen = effects->screenNumber(pos);
761
QRect screenGeom = effects->clientArea(ScreenArea, screen, 0);
763
if (orientation == Qt::Horizontal) {
764
desktopCell.setX((desktop - 1) % gridSize.width() + 1);
765
desktopCell.setY((desktop - 1) / gridSize.width() + 1);
767
desktopCell.setX((desktop - 1) / gridSize.height() + 1);
768
desktopCell.setY((desktop - 1) % gridSize.height() + 1);
771
double progress = timeline.currentValue();
775
(screenGeom.width() + unscaledBorder[screen]) *(desktopCell.x() - 1)
776
- (screenGeom.width() + unscaledBorder[screen]) *(activeCell.x() - 1)
779
(scaledSize[screen].width() + border) *(desktopCell.x() - 1)
780
+ scaledOffset[screen].x()
781
+ (pos.x() - screenGeom.x()) * scale[screen]
786
(screenGeom.height() + unscaledBorder[screen]) *(desktopCell.y() - 1)
787
- (screenGeom.height() + unscaledBorder[screen]) *(activeCell.y() - 1)
790
(scaledSize[screen].height() + border) *(desktopCell.y() - 1)
791
+ scaledOffset[screen].y()
792
+ (pos.y() - screenGeom.y()) * scale[screen]
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
804
int screen = effects->screenNumber(pos);
805
QRect screenGeom = effects->clientArea(ScreenArea, screen, 0);
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)/*,
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)/*,
816
int gx = qBound(0, int(scaledX), gridSize.width() - 1); // Zero-based
817
int gy = qBound(0, int(scaledY), gridSize.height() - 1);
820
if (desktop != NULL) {
821
if (orientation == Qt::Horizontal)
822
*desktop = gy * gridSize.width() + gx + 1;
824
*desktop = gx * gridSize.height() + gy + 1;
831
scaledX * (screenGeom.width() + unscaledBorder[screen])
832
- unscaledBorder[screen] / 2.0
840
scaledY * (screenGeom.height() + unscaledBorder[screen])
841
- unscaledBorder[screen] / 2.0
849
int DesktopGridEffect::posToDesktop(const QPoint& pos) const
851
// Copied from unscalePos()
852
int screen = effects->screenNumber(pos);
853
QRect screenGeom = effects->clientArea(ScreenArea, screen, 0);
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)/*,
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)/*,
864
int gx = qBound(0, int(scaledX), gridSize.width() - 1); // Zero-based
865
int gy = qBound(0, int(scaledY), gridSize.height() - 1);
868
if (orientation == Qt::Horizontal)
869
return gy * gridSize.width() + gx + 1;
870
return gx * gridSize.height() + gy + 1;
873
EffectWindow* DesktopGridEffect::windowAt(QPoint pos) const
875
// Get stacking order top first
876
EffectWindowList windows = effects->stackingOrder();
877
EffectWindowList::Iterator begin = windows.begin();
878
EffectWindowList::Iterator end = windows.end();
881
qSwap(*begin++, *end--);
884
pos = unscalePos(pos, &desktop);
885
if (desktop > effects->numberOfDesktops())
887
if (isUsingPresentWindows()) {
888
const int screen = effects->screenNumber(pos);
890
m_managers.at((desktop - 1) * (effects->numScreens()) + screen).windowAtPoint(pos, false);
893
foreach (EffectWindow * w, windows) {
894
if (w->isOnDesktop(desktop) && w->isDesktop() && w->geometry().contains(pos))
898
foreach (EffectWindow * w, windows) {
899
if (w->isOnDesktop(desktop) && !w->isMinimized() && w->geometry().contains(pos))
906
void DesktopGridEffect::setCurrentDesktop(int desktop)
908
if (orientation == Qt::Horizontal) {
909
activeCell.setX((desktop - 1) % gridSize.width() + 1);
910
activeCell.setY((desktop - 1) / gridSize.width() + 1);
912
activeCell.setX((desktop - 1) / gridSize.height() + 1);
913
activeCell.setY((desktop - 1) % gridSize.height() + 1);
915
if (effects->currentDesktop() != desktop)
916
effects->setCurrentDesktop(desktop);
919
void DesktopGridEffect::setHighlightedDesktop(int d)
921
if (d == highlightedDesktop || d <= 0 || d > effects->numberOfDesktops())
923
highlightedDesktop = d;
924
effects->addRepaintFull();
927
int DesktopGridEffect::desktopToRight(int desktop, bool wrap) const
929
// Copied from Workspace::desktopToRight()
930
int dt = desktop - 1;
931
if (orientation == Qt::Vertical) {
932
dt += gridSize.height();
933
if (dt >= effects->numberOfDesktops()) {
935
dt -= effects->numberOfDesktops();
940
int d = (dt % gridSize.width()) + 1;
941
if (d >= gridSize.width()) {
943
d -= gridSize.width();
947
dt = dt - (dt % gridSize.width()) + d;
952
int DesktopGridEffect::desktopToLeft(int desktop, bool wrap) const
954
// Copied from Workspace::desktopToLeft()
955
int dt = desktop - 1;
956
if (orientation == Qt::Vertical) {
957
dt -= gridSize.height();
960
dt += effects->numberOfDesktops();
965
int d = (dt % gridSize.width()) - 1;
968
d += gridSize.width();
972
dt = dt - (dt % gridSize.width()) + d;
977
int DesktopGridEffect::desktopUp(int desktop, bool wrap) const
979
// Copied from Workspace::desktopUp()
980
int dt = desktop - 1;
981
if (orientation == Qt::Horizontal) {
982
dt -= gridSize.width();
985
dt += effects->numberOfDesktops();
990
int d = (dt % gridSize.height()) - 1;
993
d += gridSize.height();
997
dt = dt - (dt % gridSize.height()) + d;
1002
int DesktopGridEffect::desktopDown(int desktop, bool wrap) const
1004
// Copied from Workspace::desktopDown()
1005
int dt = desktop - 1;
1006
if (orientation == Qt::Horizontal) {
1007
dt += gridSize.width();
1008
if (dt >= effects->numberOfDesktops()) {
1010
dt -= effects->numberOfDesktops();
1015
int d = (dt % gridSize.height()) + 1;
1016
if (d >= gridSize.height()) {
1018
d -= gridSize.height();
1022
dt = dt - (dt % gridSize.height()) + d;
1027
//-----------------------------------------------------------------------------
1030
void DesktopGridEffect::toggle()
1032
setActive(!activated);
1035
void DesktopGridEffect::setActive(bool active)
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
1045
if (activated && timeline.currentValue() == 0)
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());
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) {
1062
effects->addRepaintFull();
1065
void DesktopGridEffect::setup()
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());
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);
1081
hoverTimeline[effects->currentDesktop() - 1]->setCurrentTime(hoverTimeline[effects->currentDesktop() - 1]->duration());
1083
// Create desktop name textures if enabled
1084
if (desktopNameAlignment) {
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);
1097
setCurrentDesktop(effects->currentDesktop());
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()) {
1112
m_proxy->calculateWindowTransformations(manager.managedWindows(), j, manager);
1113
m_managers.append(manager);
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());
1130
m_desktopButtonsViews.insert(view, NULL);
1134
void DesktopGridEffect::setupGrid()
1136
// We need these variables for every paint so lets cache them
1138
int numDesktops = effects->numberOfDesktops();
1139
switch(layoutMode) {
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);
1149
case LayoutAutomatic:
1150
y = sqrt(float(numDesktops)) + 0.5;
1151
x = float(numDesktops) / float(y) + 0.5;
1152
if (x * y < numDesktops)
1154
orientation = Qt::Horizontal;
1155
gridSize.setWidth(x);
1156
gridSize.setHeight(y);
1159
orientation = Qt::Horizontal;
1160
gridSize.setWidth(ceil(effects->numberOfDesktops() / double(customLayoutRows)));
1161
gridSize.setHeight(customLayoutRows);
1165
unscaledBorder.clear();
1167
scaledOffset.clear();
1168
for (int i = 0; i < effects->numScreens(); i++) {
1169
QRect geom = effects->clientArea(ScreenArea, i, 0);
1171
if (gridSize.width() > gridSize.height())
1172
sScale = (geom.width() - border * (gridSize.width() + 1)) / double(geom.width() * gridSize.width());
1174
sScale = (geom.height() - border * (gridSize.height() + 1)) / double(geom.height() * gridSize.height());
1175
double sBorder = border / sScale;
1177
double(geom.width()) * sScale,
1178
double(geom.height()) * sScale
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
1184
scale.append(sScale);
1185
unscaledBorder.append(sBorder);
1186
scaledSize.append(size);
1187
scaledOffset.append(offset);
1191
void DesktopGridEffect::finish()
1193
if (desktopNameAlignment) {
1194
qDeleteAll(desktopNames);
1195
desktopNames.clear();
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();
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();
1221
void DesktopGridEffect::globalShortcutChanged(const QKeySequence& seq)
1223
shortcut = KShortcut(seq);
1226
bool DesktopGridEffect::isMotionManagerMovingWindows()
1228
if (isUsingPresentWindows()) {
1229
QList<WindowMotionManager>::iterator it;
1230
for (it = m_managers.begin(); it != m_managers.end(); ++it) {
1231
if ((*it).areWindowsMoving())
1238
bool DesktopGridEffect::isUsingPresentWindows() const
1240
return (m_proxy != NULL);
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
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;
1263
return QRectF(point, m_windowMoveGeometry.size() / scaleFactor);
1266
void DesktopGridEffect::slotAddDesktop()
1268
effects->setNumberOfDesktops(effects->numberOfDesktops() + 1);
1271
void DesktopGridEffect::slotRemoveDesktop()
1273
effects->setNumberOfDesktops(effects->numberOfDesktops() - 1);
1276
void DesktopGridEffect::slotNumberDesktopsChanged(int old)
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);
1291
desktopsRemoved(old);
1294
void DesktopGridEffect::desktopsAdded(int old)
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);
1304
// Create desktop name textures if enabled
1305
if (desktopNameAlignment) {
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);
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()) {
1328
m_proxy->calculateWindowTransformations(manager.managedWindows(), j, manager);
1329
m_managers.append(manager);
1337
effects->addRepaintFull();
1340
void DesktopGridEffect::desktopsRemoved(int old)
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();
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();
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()) {
1367
m_proxy->calculateWindowTransformations(manager.managedWindows(), j, manager);
1374
effects->addRepaintFull();
1377
/************************************************
1379
************************************************/
1380
DesktopButtonsView::DesktopButtonsView(QWidget* parent)
1381
: QGraphicsView(parent)
1383
setWindowFlags(Qt::X11BypassWindowManagerHint);
1384
setAttribute(Qt::WA_TranslucentBackground);
1385
setFrameShape(QFrame::NoFrame);
1386
QPalette pal = palette();
1387
pal.setColor(backgroundRole(), Qt::transparent);
1389
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1390
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
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()));
1403
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
1404
layout->addItem(m_addDesktopButton);
1405
layout->addItem(m_removeDesktopButton);
1407
QGraphicsWidget *form = new QGraphicsWidget;
1408
form->setLayout(layout);
1409
form->setGeometry(0, 0, 64 * 2, 64);
1410
scene->addItem(form);
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)));
1428
void DesktopButtonsView::windowInputMouseEvent(QMouseEvent* e)
1430
if (e->type() == QEvent::MouseMove) {
1432
} else if (e->type() == QEvent::MouseButtonPress) {
1434
} else if (e->type() == QEvent::MouseButtonDblClick) {
1435
mouseDoubleClickEvent(e);
1436
} else if (e->type() == QEvent::MouseButtonRelease) {
1437
mouseReleaseEvent(e);
1441
void DesktopButtonsView::setAddDesktopEnabled(bool enable)
1443
m_addDesktopButton->setEnabled(enable);
1446
void DesktopButtonsView::setRemoveDesktopEnabled(bool enable)
1448
m_removeDesktopButton->setEnabled(enable);
1451
void DesktopButtonsView::drawBackground(QPainter* painter, const QRectF& rect)
1454
painter->setRenderHint(QPainter::Antialiasing);
1455
m_frame->paintFrame(painter);
1460
#include "desktopgrid.moc"