2
* Compiz Fusion Grid plugin
4
* Copyright (c) 2008 Stephen Kennedy <suasol@gmail.com>
5
* Copyright (c) 2010 Scott Moreau <oreaus@gmail.com>
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 2
10
* of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
19
* Plugin to act like winsplit revolution (http://www.winsplit-revolution.com/)
20
* use <Control><Alt>NUMPAD_KEY to move and tile your windows.
22
* Press the tiling keys several times to cycle through some tiling options.
27
using namespace GridWindowType;
29
static std::map <unsigned int, GridProps> gridProps;
32
GridScreen::handleCompizEvent(const char* plugin,
34
CompOption::Vector& o)
36
if (strcmp(event, "start_viewport_switch") == 0)
40
else if (strcmp(event, "end_viewport_switch") == 0)
45
screen->handleCompizEvent(plugin, event, o);
49
GridScreen::slotToRect (CompWindow *w,
52
return CompRect (slot.x () + w->border ().left,
53
slot.y () + w->border ().top,
54
slot.width () - (w->border ().left + w->border ().right),
55
slot.height () - (w->border ().top + w->border ().bottom));
59
GridScreen::constrainSize (CompWindow *w,
65
result = slotToRect (w, slot);
67
if (w->constrainNewWindowSize (result.width (), result.height (), &cw, &ch))
69
/* constrained size may put window offscreen, adjust for that case */
70
int dx = result.x () + cw - workarea.right () + w->border ().right;
71
int dy = result.y () + ch - workarea.bottom () + w->border ().bottom;
74
result.setX (result.x () - dx);
76
result.setY (result.y () - dy);
79
result.setHeight (ch);
86
GridScreen::getPaintRectangle (CompRect &cRect)
88
if (typeToMask (edgeToGridType ()) != GridUnknown && optionGetDrawIndicator ())
91
cRect.setGeometry (0, 0, 0, 0);
95
applyProgress (int a, int b, float progress)
98
b - (ABS (a - b) * progress) :
99
b + (ABS (a - b) * progress);
103
GridScreen::setCurrentRect (Animation &anim)
105
anim.currentRect.setLeft (applyProgress (anim.targetRect.x1 (),
108
anim.currentRect.setRight (applyProgress (anim.targetRect.x2 (),
111
anim.currentRect.setTop (applyProgress (anim.targetRect.y1 (),
114
anim.currentRect.setBottom (applyProgress (anim.targetRect.y2 (),
120
GridScreen::initiateCommon (CompAction *action,
121
CompAction::State state,
122
CompOption::Vector &option,
130
xid = CompOption::getIntOptionNamed (option, "window");
131
cw = screen->findWindow (xid);
136
bool maximizeH = where & (GridBottom | GridTop | GridMaximize);
137
bool maximizeV = where & (GridLeft | GridRight | GridMaximize);
139
if (!(cw->actions () & CompWindowActionResizeMask))
142
if (maximizeH && !(cw->actions () & CompWindowActionMaximizeHorzMask))
145
if (maximizeV && !(cw->actions () & CompWindowActionMaximizeVertMask))
148
if (where & GridUnknown)
153
if (gw->lastTarget & ~(where))
158
props = gridProps[where];
160
/* get current available area */
161
if (cw == mGrabWindow)
162
workarea = screen->getWorkareaForOutput
163
(screen->outputDeviceForPoint (pointerX, pointerY));
166
workarea = screen->getWorkareaForOutput (cw->outputDevice ());
168
if (props.numCellsX == 1)
171
if (!gw->isGridResized)
172
/* Store size not including borders when using a keybinding */
173
gw->originalSize = slotToRect(cw, cw->serverBorderRect ());
176
if ((cw->state () & MAXIMIZE_STATE) &&
177
(resize || optionGetSnapoffMaximized ()))
179
/* maximized state interferes with us, clear it */
183
if ((where & GridMaximize) && resize)
185
/* move the window to the correct output */
186
if (cw == mGrabWindow)
188
xwc.x = workarea.x () + 50;
189
xwc.y = workarea.y () + 50;
190
xwc.width = workarea.width ();
191
xwc.height = workarea.height ();
192
cw->configureXWindow (CWX | CWY, &xwc);
194
cw->maximize (MAXIMIZE_STATE);
195
gw->isGridResized = true;
196
gw->isGridMaximized = true;
197
for (unsigned int i = 0; i < animations.size (); i++)
198
animations.at (i).fadingOut = true;
203
* xxxSlot include decorations (it's the screen area occupied)
204
* xxxRect are undecorated (it's the constrained position
208
/* slice and dice to get desired slot - including decorations */
209
desiredSlot.setY (workarea.y () + props.gravityDown *
210
(workarea.height () / props.numCellsY));
211
desiredSlot.setHeight (workarea.height () / props.numCellsY);
212
desiredSlot.setX (workarea.x () + props.gravityRight *
213
(workarea.width () / props.numCellsX));
214
desiredSlot.setWidth (workarea.width () / props.numCellsX);
216
/* Adjust for constraints and decorations */
217
desiredRect = constrainSize (cw, desiredSlot);
218
/* Get current rect not including decorations */
219
currentRect.setGeometry (cw->serverX (), cw->serverY (),
221
cw->serverHeight ());
223
if (desiredRect.y () == currentRect.y () &&
224
desiredRect.height () == currentRect.height () &&
225
where & ~(GridMaximize) && gw->lastTarget & where)
227
int slotWidth25 = workarea.width () / 4;
228
int slotWidth33 = (workarea.width () / 3) + cw->border ().left;
229
int slotWidth17 = slotWidth33 - slotWidth25;
230
int slotWidth66 = workarea.width () - slotWidth33;
231
int slotWidth75 = workarea.width () - slotWidth25;
233
if (props.numCellsX == 2) /* keys (1, 4, 7, 3, 6, 9) */
235
if ((currentRect.width () == desiredRect.width () &&
236
currentRect.x () == desiredRect.x ()) ||
237
(gw->resizeCount < 1) || (gw->resizeCount > 5))
240
/* tricky, have to allow for window constraints when
241
* computing what the 33% and 66% offsets would be
243
switch (gw->resizeCount)
246
desiredSlot.setWidth (slotWidth66);
247
desiredSlot.setX (workarea.x () +
248
props.gravityRight * slotWidth33);
255
desiredSlot.setWidth (slotWidth33);
256
desiredSlot.setX (workarea.x () +
257
props.gravityRight * slotWidth66);
261
desiredSlot.setWidth (slotWidth25);
262
desiredSlot.setX (workarea.x () +
263
props.gravityRight * slotWidth75);
267
desiredSlot.setWidth (slotWidth75);
268
desiredSlot.setX (workarea.x () +
269
props.gravityRight * slotWidth25);
276
else /* keys (2, 5, 8) */
279
if ((currentRect.width () == desiredRect.width () &&
280
currentRect.x () == desiredRect.x ()) ||
281
(gw->resizeCount < 1) || (gw->resizeCount > 5))
284
switch (gw->resizeCount)
287
desiredSlot.setWidth (workarea.width () -
289
desiredSlot.setX (workarea.x () + slotWidth17);
293
desiredSlot.setWidth ((slotWidth25 * 2) +
295
desiredSlot.setX (workarea.x () +
296
(slotWidth25 - slotWidth17));
300
desiredSlot.setWidth ((slotWidth25 * 2));
301
desiredSlot.setX (workarea.x () + slotWidth25);
305
desiredSlot.setWidth (slotWidth33 -
306
(cw->border ().left + cw->border ().right));
307
desiredSlot.setX (workarea.x () + slotWidth33);
318
if (gw->resizeCount == 6)
321
desiredRect = constrainSize (cw, desiredSlot);
324
xwc.x = desiredRect.x ();
325
xwc.y = desiredRect.y ();
326
xwc.width = desiredRect.width ();
327
xwc.height = desiredRect.height ();
329
/* Store a copy of xwc since configureXWindow changes it's values */
330
XWindowChanges wc = xwc;
333
cw->sendSyncRequest ();
335
/* TODO: animate move+resize */
338
unsigned int valueMask = CWX | CWY | CWWidth | CWHeight;
339
gw->lastTarget = where;
340
gw->currentSize = CompRect (wc.x, wc.y, wc.width, wc.height);
342
/* Special case for left and right, actually vertically maximize
344
if (where & GridLeft || where & GridRight)
346
/* First restore the window to its original size */
349
rwc.x = gw->originalSize.x ();
350
rwc.y = gw->originalSize.y ();
351
rwc.width = gw->originalSize.width ();
352
rwc.height = gw->originalSize.height ();
354
cw->configureXWindow (CWX | CWY | CWWidth | CWHeight, &rwc);
356
gw->isGridMaximized = true;
357
gw->isGridResized = false;
359
gw->lastBorder = cw->border ();
360
/* Maximize the window */
361
printf ("maximizing window\n");
362
cw->maximize (CompWindowStateMaximizedVertMask);
366
gw->isGridResized = true;
367
gw->isGridMaximized = false;
370
/* Make window the size that we want */
371
cw->configureXWindow (valueMask, &xwc);
373
for (unsigned int i = 0; i < animations.size (); i++)
374
animations.at (i).fadingOut = true;
377
/* This centers a window if it could not be resized to the desired
378
* width. Without this, it can look buggy when desired width is
379
* beyond the minimum or maximum width of the window.
383
if ((cw->serverBorderRect ().width () >
384
desiredSlot.width ()) ||
385
cw->serverBorderRect ().width () <
386
desiredSlot.width ())
388
wc.x = (workarea.width () >> 1) -
389
((cw->serverBorderRect ().width () >> 1) -
391
cw->configureXWindow (CWX, &wc);
402
GridScreen::glPaintRectangle (const GLScreenPaintAttrib &sAttrib,
403
const GLMatrix &transform,
407
GLMatrix sTransform (transform);
408
std::vector<Animation>::iterator iter;
410
getPaintRectangle (rect);
412
for (unsigned int i = 0; i < animations.size (); i++)
413
setCurrentRect (animations.at (i));
417
sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
419
glLoadMatrixf (sTransform.getMatrix ());
421
glDisableClientState (GL_TEXTURE_COORD_ARRAY);
424
for (iter = animations.begin (); iter != animations.end () && animating; iter++)
426
Animation& anim = *iter;
427
float alpha = ((float) optionGetFillColorAlpha () / 65535.0f) * anim.opacity;
430
glColor4f (((float) optionGetFillColorRed () / 65535.0f) * alpha,
431
((float) optionGetFillColorGreen () / 65535.0f) * alpha,
432
((float) optionGetFillColorBlue () / 65535.0f) * alpha,
436
glRecti (anim.currentRect.x1 (), anim.currentRect.y2 (),
437
anim.currentRect.x2 (), anim.currentRect.y1 ());
439
/* Set outline rect smaller to avoid damage issues */
440
anim.currentRect.setGeometry (anim.currentRect.x () + 1,
441
anim.currentRect.y () + 1,
442
anim.currentRect.width () - 2,
443
anim.currentRect.height () - 2);
445
alpha = (float) (optionGetOutlineColorAlpha () / 65535.0f) * anim.opacity;
448
glColor4f (((float) optionGetOutlineColorRed () / 65535.0f) * alpha,
449
((float) optionGetOutlineColorGreen () / 65535.0f) * alpha,
450
((float) optionGetOutlineColorBlue () / 65535.0f) * alpha,
455
glBegin (GL_LINE_LOOP);
456
glVertex2i (anim.currentRect.x1 (), anim.currentRect.y1 ());
457
glVertex2i (anim.currentRect.x2 (), anim.currentRect.y1 ());
458
glVertex2i (anim.currentRect.x2 (), anim.currentRect.y2 ());
459
glVertex2i (anim.currentRect.x1 (), anim.currentRect.y2 ());
466
float alpha = (float) optionGetFillColorAlpha () / 65535.0f;
469
glColor4f (((float) optionGetFillColorRed () / 65535.0f) * alpha,
470
((float) optionGetFillColorGreen () / 65535.0f) * alpha,
471
((float) optionGetFillColorBlue () / 65535.0f) * alpha,
473
glRecti (rect.x1 (), rect.y2 (), rect.x2 (), rect.y1 ());
475
/* Set outline rect smaller to avoid damage issues */
476
rect.setGeometry (rect.x () + 1, rect.y () + 1,
477
rect.width () - 2, rect.height () - 2);
480
alpha = (float) optionGetOutlineColorAlpha () / 65535.0f;
483
glColor4f (((float) optionGetOutlineColorRed () / 65535.0f) * alpha,
484
((float) optionGetOutlineColorGreen () / 65535.0f) * alpha,
485
((float) optionGetOutlineColorBlue () / 65535.0f) * alpha,
489
glBegin (GL_LINE_LOOP);
490
glVertex2i (rect.x1 (), rect.y1 ());
491
glVertex2i (rect.x2 (), rect.y1 ());
492
glVertex2i (rect.x2 (), rect.y2 ());
493
glVertex2i (rect.x1 (), rect.y2 ());
498
glColor4usv (defaultColor);
499
glDisable (GL_BLEND);
500
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
505
GridScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
506
const GLMatrix &matrix,
507
const CompRegion ®ion,
513
status = glScreen->glPaintOutput (attrib, matrix, region, output, mask);
515
glPaintRectangle (attrib, matrix, output);
521
GridScreen::typeToMask (int t)
528
std::vector <GridTypeMask> type =
530
{ GridWindowType::GridUnknown, 0 },
531
{ GridWindowType::GridBottomLeft, 1 },
532
{ GridWindowType::GridBottom, 2 },
533
{ GridWindowType::GridBottomRight, 3 },
534
{ GridWindowType::GridLeft, 4 },
535
{ GridWindowType::GridCenter, 5 },
536
{ GridWindowType::GridRight, 6 },
537
{ GridWindowType::GridTopLeft, 7 },
538
{ GridWindowType::GridTop, 8 },
539
{ GridWindowType::GridTopRight, 9 },
540
{ GridWindowType::GridMaximize, 10 }
543
for (unsigned int i = 0; i < type.size (); i++)
545
GridTypeMask &tm = type[i];
550
return GridWindowType::GridUnknown;
554
GridScreen::edgeToGridType ()
560
ret = (int) optionGetLeftEdgeAction ();
563
ret = (int) optionGetRightEdgeAction ();
566
ret = (int) optionGetTopEdgeAction ();
569
ret = (int) optionGetBottomEdgeAction ();
572
ret = (int) optionGetTopLeftCornerAction ();
575
ret = (int) optionGetTopRightCornerAction ();
578
ret = (int) optionGetBottomLeftCornerAction ();
581
ret = (int) optionGetBottomRightCornerAction ();
593
GridScreen::handleEvent (XEvent *event)
599
screen->handleEvent (event);
601
if (event->type != MotionNotify || !mGrabWindow)
604
out = screen->outputDevs ().at (
605
screen->outputDeviceForPoint (CompPoint (pointerX, pointerY)));
607
/* Detect corners first */
609
if (pointerY > (out.y () + out.height () - optionGetBottomEdgeThreshold()) &&
610
pointerX < out.x () + optionGetLeftEdgeThreshold())
613
else if (pointerY > (out.y () + out.height () - optionGetBottomEdgeThreshold()) &&
614
pointerX > (out.x () + out.width () - optionGetRightEdgeThreshold()))
617
else if (pointerY < optionGetTopEdgeThreshold() &&
618
pointerX < optionGetLeftEdgeThreshold())
621
else if (pointerY < out.y () + optionGetTopEdgeThreshold() &&
622
pointerX > (out.x () + out.width () - optionGetRightEdgeThreshold()))
625
else if (pointerX < out.x () + optionGetLeftEdgeThreshold())
628
else if (pointerX > (out.x () + out.width () - optionGetRightEdgeThreshold()))
631
else if (pointerY < out.y () + optionGetTopEdgeThreshold())
634
else if (pointerY > (out.y () + out.height () - optionGetBottomEdgeThreshold()))
640
/* Detect when cursor enters another output */
642
currentWorkarea = screen->getWorkareaForOutput
643
(screen->outputDeviceForPoint (pointerX, pointerY));
644
if (lastWorkarea != currentWorkarea)
646
lastWorkarea = currentWorkarea;
649
cScreen->damageRegion (desiredSlot);
651
initiateCommon (0, 0, o, typeToMask (edgeToGridType ()), false, false);
654
cScreen->damageRegion (desiredSlot);
657
/* Detect edge region change */
659
if (lastEdge != edge)
661
lastSlot = desiredSlot;
664
desiredSlot.setGeometry (0, 0, 0, 0);
667
cScreen->damageRegion (desiredSlot);
669
check = initiateCommon (NULL, 0, o, typeToMask (edgeToGridType ()), false, false);
672
cScreen->damageRegion (desiredSlot);
674
if (lastSlot != desiredSlot)
676
if (animations.size ())
677
/* Begin fading previous animation instance */
678
animations.at (animations.size () - 1).fadingOut = true;
680
if (edge != NoEdge && check)
682
CompWindow *cw = screen->findWindow (screen->activeWindow ());
683
animations.push_back (Animation ());
684
int current = animations.size () - 1;
685
animations.at (current).fromRect = cw->serverBorderRect ();
686
animations.at (current).currentRect = cw->serverBorderRect ();
687
animations.at (current).timer = animations.at (current).duration;
688
animations.at (current).targetRect = desiredSlot;
690
if (lastEdge == NoEdge || !animating)
692
/* Cursor has entered edge region from non-edge region */
694
glScreen->glPaintOutputSetEnabled (this, true);
695
cScreen->preparePaintSetEnabled (this, true);
696
cScreen->donePaintSetEnabled (this, true);
704
w = screen->findWindow (CompOption::getIntOptionNamed (o, "window"));
710
if ((gw->pointerBufDx > SNAPOFF_THRESHOLD ||
711
gw->pointerBufDy > SNAPOFF_THRESHOLD ||
712
gw->pointerBufDx < -SNAPOFF_THRESHOLD ||
713
gw->pointerBufDy < -SNAPOFF_THRESHOLD) &&
715
optionGetSnapbackWindows ())
716
restoreWindow (0, 0, o);
721
GridWindow::grabNotify (int x,
726
if (mask & (CompWindowGrabMoveMask | CompWindowGrabButtonMask))
728
gScreen->o[0].value ().set ((int) window->id ());
730
screen->handleEventSetEnabled (gScreen, true);
731
gScreen->mGrabWindow = window;
732
pointerBufDx = pointerBufDy = 0;
735
if (!isGridResized && !isGridMaximized && gScreen->optionGetSnapbackWindows ())
736
/* Store size not including borders when grabbing with cursor */
737
originalSize = gScreen->slotToRect(window,
738
window->serverBorderRect ());
741
if (mask & CompWindowGrabResizeMask)
743
isGridResized = false;
747
window->grabNotify (x, y, state, mask);
751
GridWindow::ungrabNotify ()
753
if (window == gScreen->mGrabWindow)
755
gScreen->initiateCommon
756
(NULL, 0, gScreen->o, gScreen->typeToMask (gScreen->edgeToGridType ()), true,
757
gScreen->edge != gScreen->lastResizeEdge);
759
screen->handleEventSetEnabled (gScreen, false);
761
gScreen->mGrabWindow = NULL;
762
gScreen->o[0].value ().set (0);
763
gScreen->cScreen->damageRegion (gScreen->desiredSlot);
766
gScreen->lastResizeEdge = gScreen->edge;
767
gScreen->edge = NoEdge;
769
window->ungrabNotify ();
773
GridWindow::moveNotify (int dx, int dy, bool immediate)
775
window->moveNotify (dx, dy, immediate);
777
if (isGridResized && !isGridMaximized && !GridScreen::get (screen)->mSwitchingVp)
779
if (window->grabbed () && (grabMask & CompWindowGrabMoveMask))
785
/* Do not allow the window to be moved while it
787
dx = currentSize.x () - window->geometry ().x ();
788
dy = currentSize.y () - window->geometry ().y ();
790
printf ("offset move\n");
792
window->move (dx, dy);
797
GridWindow::stateChangeNotify (unsigned int lastState)
799
if (lastState & MAXIMIZE_STATE &&
800
!(window->state () & MAXIMIZE_STATE))
801
lastTarget = GridUnknown;
802
else if (!(lastState & MAXIMIZE_STATE) &&
803
window->state () & MAXIMIZE_STATE)
805
lastTarget = GridMaximize;
806
if (window->grabbed ())
808
originalSize = gScreen->slotToRect (window,
809
window->serverBorderRect ());
813
window->stateChangeNotify (lastState);
817
GridWindow::windowNotify (CompWindowNotify n)
819
if (n == CompWindowNotifyFrameUpdate)
821
if (isGridMaximized && !((window->state () & MAXIMIZE_STATE) == MAXIMIZE_STATE))
823
unsigned int valueMask = 0;
826
int dw = (lastBorder.left + lastBorder.right) -
827
(window->border ().left + window->border ().right);
829
int dh = (lastBorder.top + lastBorder.bottom) -
830
(window->border ().top + window->border ().bottom);
833
valueMask |= CWWidth;
835
valueMask |= CWHeight;
836
xwc.width = window->serverGeometry ().width () + dw;
837
xwc.height = window->serverGeometry ().height () + dh;
839
window->configureXWindow (valueMask, &xwc);
842
lastBorder = window->border ();
845
window->windowNotify (n);
848
GridScreen::restoreWindow (CompAction *action,
849
CompAction::State state,
850
CompOption::Vector &option)
853
CompWindow *cw = screen->findWindow (screen->activeWindow ());
860
if (!gw->isGridResized)
863
if (gw->isGridMaximized & !(cw->state () & MAXIMIZE_STATE))
864
gw->isGridMaximized = false;
867
if (cw == mGrabWindow)
869
xwc.x = pointerX - (gw->originalSize.width () >> 1);
870
xwc.y = pointerY + (cw->border ().top >> 1);
874
xwc.x = gw->originalSize.x ();
875
xwc.y = gw->originalSize.y ();
877
xwc.width = gw->originalSize.width ();
878
xwc.height = gw->originalSize.height ();
880
gw->currentSize = CompRect ();
881
printf ("attempting snapBack\n");
882
cw->configureXWindow (CWX | CWY | CWWidth | CWHeight, &xwc);
883
gw->pointerBufDx = 0;
884
gw->pointerBufDy = 0;
886
gw->isGridResized = false;
888
gw->lastTarget = GridUnknown;
894
GridScreen::snapbackOptionChanged (CompOption *option,
897
GRID_WINDOW (screen->findWindow
898
(CompOption::getIntOptionNamed (o, "window")));
899
gw->isGridResized = false;
900
gw->isGridMaximized = false;
905
GridScreen::preparePaint (int msSinceLastPaint)
907
std::vector<Animation>::iterator iter;
909
for (iter = animations.begin (); iter != animations.end (); iter++)
911
Animation& anim = *iter;
912
anim.timer -= msSinceLastPaint;
918
anim.opacity -= msSinceLastPaint * 0.002;
920
if (anim.opacity < 1.0f)
921
anim.opacity = anim.progress * anim.progress;
925
if (anim.opacity < 0)
928
anim.fadingOut = false;
929
anim.complete = true;
932
anim.progress = (anim.duration - anim.timer) / anim.duration;
935
cScreen->preparePaint (msSinceLastPaint);
939
GridScreen::donePaint ()
941
std::vector<Animation>::iterator iter;
943
for (iter = animations.begin (); iter != animations.end (); )
945
Animation& anim = *iter;
947
iter = animations.erase(iter);
952
if (animations.empty ())
954
cScreen->preparePaintSetEnabled (this, false);
955
cScreen->donePaintSetEnabled (this, false);
957
glScreen->glPaintOutputSetEnabled (this, false);
962
cScreen->damageScreen ();
964
cScreen->donePaint ();
967
Animation::Animation ()
970
fromRect = CompRect (0, 0, 0, 0);
971
targetRect = CompRect (0, 0, 0, 0);
972
currentRect = CompRect (0, 0, 0, 0);
981
GridScreen::GridScreen (CompScreen *screen) :
982
PluginClassHandler<GridScreen, CompScreen> (screen),
983
cScreen (CompositeScreen::get (screen)),
984
glScreen (GLScreen::get (screen)),
990
o.push_back (CompOption ("window", CompOption::TypeInt));
992
ScreenInterface::setHandler (screen, false);
993
screen->handleCompizEventSetEnabled (this, true);
994
CompositeScreenInterface::setHandler (cScreen, false);
995
GLScreenInterface::setHandler (glScreen, false);
997
edge = lastEdge = lastResizeEdge = NoEdge;
998
currentWorkarea = lastWorkarea = screen->getWorkareaForOutput
999
(screen->outputDeviceForPoint (pointerX, pointerY));
1000
gridProps[GridUnknown] = GridProps {0,1, 1,1};
1001
gridProps[GridBottomLeft] = GridProps {0,1, 2,2};
1002
gridProps[GridBottom] = GridProps {0,1, 1,2};
1003
gridProps[GridBottomRight] = GridProps {1,1, 2,2};
1004
gridProps[GridLeft] = GridProps {0,0, 2,1};
1005
gridProps[GridCenter] = GridProps{0,0, 1,1};
1006
gridProps[GridRight] = GridProps {1,0, 2,1};
1007
gridProps[GridTopLeft] = GridProps{0,0, 2,2};
1008
gridProps[GridTop] = GridProps {0,0, 1,2};
1009
gridProps[GridTopRight] = GridProps {0,0, 1,2};
1010
gridProps[GridMaximize] = GridProps {0,0, 1,1};
1012
animations.clear ();
1014
#define GRIDSET(opt,where,resize,key) \
1015
optionSet##opt##Initiate (boost::bind (&GridScreen::initiateCommon, this, \
1016
_1, _2, _3, where, resize, key))
1018
GRIDSET (PutCenterKey, GridWindowType::GridCenter, true, true);
1019
GRIDSET (PutLeftKey, GridWindowType::GridLeft, true, true);
1020
GRIDSET (PutRightKey, GridWindowType::GridRight, true, true);
1021
GRIDSET (PutTopKey, GridWindowType::GridTop, true, true);
1022
GRIDSET (PutBottomKey, GridWindowType::GridBottom, true, true);
1023
GRIDSET (PutTopleftKey, GridWindowType::GridTopLeft, true, true);
1024
GRIDSET (PutToprightKey, GridWindowType::GridTopRight, true, true);
1025
GRIDSET (PutBottomleftKey, GridWindowType::GridBottomLeft, true, true);
1026
GRIDSET (PutBottomrightKey, GridWindowType::GridBottomRight, true, true);
1027
GRIDSET (PutMaximizeKey, GridWindowType::GridMaximize, true, true);
1031
optionSetSnapbackWindowsNotify (boost::bind (&GridScreen::
1032
snapbackOptionChanged, this, _1, _2));
1034
optionSetPutRestoreKeyInitiate (boost::bind (&GridScreen::
1035
restoreWindow, this, _1, _2, _3));
1039
GridWindow::GridWindow (CompWindow *window) :
1040
PluginClassHandler <GridWindow, CompWindow> (window),
1042
gScreen (GridScreen::get (screen)),
1043
isGridResized (false),
1044
isGridMaximized (false),
1049
lastTarget (GridUnknown)
1051
WindowInterface::setHandler (window);
1054
GridWindow::~GridWindow ()
1056
if (gScreen->mGrabWindow == window)
1057
gScreen->mGrabWindow = NULL;
1059
gScreen->o[0].value ().set (0);
1062
/* Initial plugin init function called. Checks to see if we are ABI
1063
* compatible with core, otherwise unload */
1066
GridPluginVTable::init ()
1068
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))