3
* Compiz ring switcher plugin
7
* Copyright : (C) 2007 by Danny Baumann
8
* E-mail : maniac@opencompositing.org
10
* Based on scale.c and switcher.c:
11
* Copyright : (C) 2007 David Reveman
12
* E-mail : davidr@novell.com
14
* Ported to Compiz 0.9 by:
15
* Copyright : (C) 2009 Sam Spilsbury
16
* E-mail : smspillaz@gmail.com
18
* This program is free software; you can redistribute it and/or
19
* modify it under the terms of the GNU General Public License
20
* as published by the Free Software Foundation; either version 2
21
* of the License, or (at your option) any later version.
23
* This program is distributed in the hope that it will be useful,
24
* but WITHOUT ANY WARRANTY; without even the implied warranty of
25
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26
* GNU General Public License for more details.
32
COMPIZ_PLUGIN_20090315 (ring, RingPluginVTable);
37
toggleFunctions (bool enabled)
41
rs->cScreen->preparePaintSetEnabled (rs, enabled);
42
rs->cScreen->donePaintSetEnabled (rs, enabled);
43
rs->gScreen->glPaintOutputSetEnabled (rs, enabled);
44
screen->handleEventSetEnabled (rs, enabled);
46
foreach (CompWindow *w, screen->windows ())
49
rw->gWindow->glPaintSetEnabled (rw, enabled);
50
rw->cWindow->damageRectSetEnabled (rw, enabled);
55
RingScreen::switchActivateEvent (bool activating)
59
CompOption o1 ("root", CompOption::TypeInt);
60
o1.value ().set ((int) screen->root ());
64
CompOption o2 ("active", CompOption::TypeBool);
65
o2.value ().set (activating);
69
screen->handleCompizEvent ("ring", "activate", o);
73
RingWindow::is (bool removing)
77
if (!removing && window->destroyed ())
80
if (window->overrideRedirect ())
83
if (window->wmType () & (CompWindowTypeDockMask | CompWindowTypeDesktopMask))
86
if (!removing && (!window->mapNum () || !window->isViewable ()))
88
if (rs->optionGetMinimized ())
90
if (!window->minimized () && !window->inShowDesktopMode () &&
98
if (!removing && rs->mType == RingScreen::RingTypeNormal)
100
if (!window->mapNum () || !window->isViewable ())
102
if (window->serverX () + window->width () <= 0 ||
103
window->serverY () + window->height () <= 0 ||
104
window->serverX () >= screen->width () ||
105
window->serverY () >= screen->height ())
110
if (!window->focus ())
114
else if (rs->mType == RingScreen::RingTypeGroup &&
115
rs->mClientLeader != window->clientLeader () &&
116
rs->mClientLeader != window->id ())
121
if (window->state () & CompWindowStateSkipTaskbarMask)
124
if (!rs->mCurrentMatch.evaluate (window))
131
RingScreen::freeWindowTitle ()
136
RingScreen::renderWindowTitle ()
141
CompText::Attrib attrib;
146
if (!mSelectedWindow)
149
if (!optionGetWindowTitle ())
152
oe = screen->getCurrentOutputExtents ();
154
/* 75% of the output device as maximum width */
155
attrib.maxWidth = oe.width () * 3 / 4;
156
attrib.maxHeight = 100;
158
attrib.size = optionGetTitleFontSize ();
159
attrib.color[0] = optionGetTitleFontColorRed ();
160
attrib.color[1] = optionGetTitleFontColorGreen ();
161
attrib.color[2] = optionGetTitleFontColorBlue ();
162
attrib.color[3] = optionGetTitleFontColorAlpha ();
163
attrib.flags = CompText::WithBackground | CompText::Ellipsized;
164
if (optionGetTitleFontBold ())
165
attrib.flags |= CompText::StyleBold;
166
attrib.family = "Sans";
167
attrib.bgHMargin = 15;
168
attrib.bgVMargin = 15;
169
attrib.bgColor[0] = optionGetTitleBackColorRed ();
170
attrib.bgColor[1] = optionGetTitleBackColorGreen ();
171
attrib.bgColor[2] = optionGetTitleBackColorBlue ();
172
attrib.bgColor[3] = optionGetTitleBackColorAlpha ();
174
mText.renderWindowTitle (mSelectedWindow->id (),
175
mType == RingScreen::RingTypeAll,
180
RingScreen::drawWindowTitle ()
187
oe = screen->getCurrentOutputExtents ();
189
x = oe.centerX () - mText.getWidth () / 2;
191
/* assign y (for the lower corner!) according to the setting */
192
switch (optionGetTitleTextPlacement ())
194
case RingOptions::TitleTextPlacementCenteredOnScreen:
195
y = oe.centerY () + mText.getHeight () / 2;
197
case RingOptions::TitleTextPlacementAboveRing:
198
case RingOptions::TitleTextPlacementBelowRing:
200
CompRect workArea = screen->currentOutputDev ().workArea ();
202
if (optionGetTitleTextPlacement () ==
203
RingOptions::TitleTextPlacementAboveRing)
204
y = oe.y1 () + workArea.y () + mText.getHeight ();
206
y = oe.y1 () + workArea.y2 ();
214
mText.draw (floor (x), floor (y), 1.0f);
218
RingWindow::glPaint (const GLWindowPaintAttrib &attrib,
219
const GLMatrix &transform,
220
const CompRegion ®ion,
226
RING_SCREEN (screen);
228
if (rs->mState != RingScreen::RingStateNone)
230
GLWindowPaintAttrib sAttrib = attrib;
233
if (window->mapNum ())
235
if (gWindow->textures ().empty ())
239
if (mAdjust || mSlot)
241
scaled = mAdjust || (mSlot);
242
mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
244
else if (rs->mState != RingScreen::RingStateIn)
246
if (rs->optionGetDarkenBack ())
248
/* modify brightness of the other windows */
249
sAttrib.brightness = sAttrib.brightness / 2;
253
status = gWindow->glPaint (sAttrib, transform, region, mask);
255
pixmap = !gWindow->textures ().empty ();
257
if (scaled && pixmap)
259
GLFragment::Attrib fragment (gWindow->lastPaintAttrib ());
260
GLMatrix wTransform = transform;
262
if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
267
fragment.setBrightness((float) fragment.getBrightness () *
268
mSlot->depthBrightness);
270
if (window != rs->mSelectedWindow)
271
fragment.setOpacity ((float)fragment.getOpacity () *
272
rs->optionGetInactiveOpacity () / 100);
275
if (window->alpha () || fragment.getOpacity () != OPAQUE)
276
mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
278
wTransform.translate (window->x (), window->y (), 0.0f);
279
wTransform.scale (mScale, mScale, 1.0f);
280
wTransform.translate (mTx / mScale - window->x (),
281
mTy / mScale - window->y (),
285
glLoadMatrixf (wTransform.getMatrix ());
287
gWindow->glDraw (wTransform, fragment, region,
288
mask | PAINT_WINDOW_TRANSFORMED_MASK);
293
if (scaled && (rs->mState != RingScreen::RingStateIn) &&
294
((rs->optionGetOverlayIcon () != RingOptions::OverlayIconNone) ||
299
icon = gWindow->getIcon (256, 256);
301
icon = rs->gScreen->defaultIcon ();
305
GLTexture::Matrix matrix;
306
GLTexture::MatrixList matricies;
310
int scaledWinWidth, scaledWinHeight;
312
enum RingOptions::OverlayIcon iconOverlay;
314
scaledWinWidth = window->width () * mScale;
315
scaledWinHeight = window->height () * mScale;
318
iconOverlay = RingOptions::OverlayIconBig;
320
iconOverlay = (enum RingOptions::OverlayIcon)
321
rs->optionGetOverlayIcon ();
323
switch (iconOverlay) {
324
case RingOptions::OverlayIconNone:
325
case RingOptions::OverlayIconEmblem:
326
scale = (mSlot) ? mSlot->depthScale : 1.0f;
327
if (icon->width () > ICON_SIZE ||
328
icon->height () > ICON_SIZE)
329
scale = MIN ((scale * ICON_SIZE / icon->width ()),
330
(scale * ICON_SIZE / icon->height ()));
332
case RingOptions::OverlayIconBig:
334
/* only change opacity if not painting an
335
icon for a minimized window */
337
sAttrib.opacity /= 3;
338
scale = MIN (((float) scaledWinWidth / icon->width ()),
339
((float) scaledWinHeight / icon->height ()));
343
width = icon->width () * scale;
344
height = icon->height () * scale;
346
switch (iconOverlay) {
347
case RingOptions::OverlayIconNone:
348
case RingOptions::OverlayIconEmblem:
349
x = window->x () + scaledWinWidth - width;
350
y = window->y () + scaledWinHeight - height;
352
case RingOptions::OverlayIconBig:
354
x = window->x () + scaledWinWidth / 2 - width / 2;
355
y = window->y () + scaledWinHeight / 2 - height / 2;
362
mask |= PAINT_WINDOW_BLEND_MASK;
364
/* if we paint the icon for a minimized window, we need
365
to force the usage of a good texture filter */
367
mask |= PAINT_WINDOW_TRANSFORMED_MASK;
369
CompRegion iconReg (window->x (), window->y (),
370
icon->width (), icon->height ());
372
matrix = icon->matrix ();
373
matrix.x0 -= (window->x () * matrix.xx);
374
matrix.y0 -= (window->y () * matrix.yy);
376
matricies.push_back (matrix);
378
gWindow->geometry ().reset ();
380
gWindow->glAddGeometry (matricies, iconReg, iconReg);
382
if (gWindow->geometry ().vCount)
384
GLFragment::Attrib fragment (sAttrib);
385
GLMatrix wTransform = transform;
388
sAttrib.opacity = gWindow->paintAttrib ().opacity;
391
fragment.setBrightness (
392
(float) fragment.getBrightness () *
393
mSlot->depthBrightness);
395
wTransform.translate (window->x (), window->y (), 0.0f);
396
wTransform.scale (scale, scale, 1.0f);
397
wTransform.translate ((x - window->x ()) / scale -
399
(y - window->y ()) / scale -
404
glLoadMatrixf (wTransform.getMatrix ());
406
gWindow->glDrawTexture (icon, fragment, mask);
415
status = gWindow->glPaint (attrib, transform, region, mask);
422
ringLinearInterpolation (float valX,
423
float minX, float maxX,
424
float minY, float maxY)
426
double factor = (maxY - minY) / (maxX - minX);
427
return (minY + (factor * (valX - minX)));
431
RingWindow::compareWindows (CompWindow *w1,
434
if (w1->mapNum () && !w2->mapNum ())
437
if (w2->mapNum () && !w1->mapNum ())
440
return (w2->activeNum () < w1->activeNum ());
444
RingWindow::compareRingWindowDepth (RingScreen::RingDrawSlot e1,
445
RingScreen::RingDrawSlot e2)
447
RingScreen::RingSlot *a1 = (*(e1.slot));
448
RingScreen::RingSlot *a2 = (*(e2.slot));
452
else if (a1->y > a2->y)
459
RingScreen::layoutThumbs ()
461
float baseAngle, angle;
464
float xScale, yScale;
465
int centerX, centerY;
466
int ellipseA, ellipseB;
469
if ((mState == RingStateNone) || (mState == RingStateIn))
472
baseAngle = (2 * PI * mRotTarget) / 3600;
474
oe = screen->getCurrentOutputExtents ();
476
/* the center of the ellipse is in the middle
477
of the used output device */
478
centerX = oe.centerX ();
479
centerY = oe.centerY ();
480
ellipseA = oe.width () * optionGetRingWidth () / 200;
481
ellipseB = oe.height () * optionGetRingHeight () / 200;
483
mDrawSlots.resize (mWindows.size ());
485
foreach (CompWindow *w, mWindows)
490
rw->mSlot = new RingSlot ();
495
/* we subtract the angle from the base angle
496
to order the windows clockwise */
497
angle = baseAngle - (index * (2 * PI / mWindows.size ()));
499
rw->mSlot->x = centerX + (optionGetRingClockwise () ? -1 : 1) *
500
((float) ellipseA * sin (angle));
501
rw->mSlot->y = centerY + ((float) ellipseB * cos (angle));
503
ww = w->width () + w->input ().left + w->input ().right;
504
wh = w->height () + w->input ().top + w->input ().bottom;
506
if (ww > optionGetThumbWidth ())
507
xScale = (float)(optionGetThumbWidth ()) / (float) ww;
511
if (wh > optionGetThumbHeight ())
512
yScale = (float)(optionGetThumbHeight ()) / (float) wh;
516
rw->mSlot->scale = MIN (xScale, yScale);
518
/* scale and brightness are obtained by doing a linear inter-
519
polation - the y positions are the x values for the interpolation
520
(the larger Y is, the nearer is the window), and scale/brightness
521
are the y values for the interpolation */
522
rw->mSlot->depthScale =
523
ringLinearInterpolation (rw->mSlot->y,
524
centerY - ellipseB, centerY + ellipseB,
525
optionGetMinScale (), 1.0f);
527
rw->mSlot->depthBrightness =
528
ringLinearInterpolation (rw->mSlot->y,
529
centerY - ellipseB, centerY + ellipseB,
530
optionGetMinBrightness (), 1.0f);
532
mDrawSlots.at (index).w = w;
533
mDrawSlots.at (index).slot = &rw->mSlot;
538
/* sort the draw list so that the windows with the
539
lowest Y value (the windows being farest away)
542
sort (mDrawSlots.begin (), mDrawSlots.end (),
543
RingWindow::compareRingWindowDepth); // TODO
549
RingScreen::addWindowToList (CompWindow *w)
551
mWindows.push_back (w);
555
RingScreen::updateWindowList ()
557
sort (mWindows.begin (), mWindows.end (), RingWindow::compareWindows);
560
foreach (CompWindow *w, mWindows)
562
if (w == mSelectedWindow)
565
mRotTarget += DIST_ROT;
568
return layoutThumbs ();
572
RingScreen::createWindowList ()
576
foreach (CompWindow *w, screen->windows ())
586
return updateWindowList ();
590
RingScreen::switchToWindow (bool toNext)
592
CompWindow *w; // We need w to be in this scope
593
unsigned int cur = 0;
598
foreach (w, mWindows)
600
if (w == mSelectedWindow)
605
if (cur == mWindows.size ())
609
w = mWindows.at ((cur + 1) % mWindows.size ());
611
w = mWindows.at ((cur + mWindows.size () - 1) % mWindows.size ());
615
CompWindow *old = mSelectedWindow;
621
mRotAdjust += DIST_ROT;
623
mRotAdjust -= DIST_ROT;
625
mRotateAdjust = true;
627
cScreen->damageScreen ();
628
renderWindowTitle ();
634
RingScreen::countWindows ()
638
foreach (CompWindow *w, screen->windows ())
650
RingScreen::adjustRingRotation (float chunk)
652
float dx, adjust, amount;
658
amount = fabs (dx) * 1.5f;
661
else if (amount > 2.0f)
664
mRVelocity = (amount * mRVelocity + adjust) / (amount + 1.0f);
666
if (fabs (dx) < 0.1f && fabs (mRVelocity) < 0.2f)
669
mRotTarget += mRotAdjust;
674
change = mRVelocity * chunk;
678
change = (mRotAdjust > 0) ? 1 : -1;
681
mRotAdjust -= change;
682
mRotTarget += change;
684
if (!layoutThumbs ())
691
RingWindow::adjustVelocity ()
693
float dx, dy, ds, adjust, amount;
698
scale = mSlot->scale * mSlot->depthScale;
699
x1 = mSlot->x - (window->width () * scale) / 2;
700
y1 = mSlot->y - (window->height () * scale) / 2;
709
dx = x1 - (window->x () + mTx);
712
amount = fabs (dx) * 1.5f;
715
else if (amount > 5.0f)
718
mXVelocity = (amount * mXVelocity + adjust) / (amount + 1.0f);
720
dy = y1 - (window->y () + mTy);
723
amount = fabs (dy) * 1.5f;
726
else if (amount > 5.0f)
729
mYVelocity = (amount * mYVelocity + adjust) / (amount + 1.0f);
733
amount = fabs (ds) * 7.0f;
736
else if (amount > 0.15f)
739
mScaleVelocity = (amount * mScaleVelocity + adjust) /
742
if (fabs (dx) < 0.1f && fabs (mXVelocity) < 0.2f &&
743
fabs (dy) < 0.1f && fabs (mYVelocity) < 0.2f &&
744
fabs (ds) < 0.001f && fabs (mScaleVelocity) < 0.002f)
746
mXVelocity = mYVelocity = mScaleVelocity = 0.0f;
747
mTx = x1 - window->x ();
748
mTy = y1 - window->y ();
758
RingScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
759
const GLMatrix &transform,
760
const CompRegion ®ion,
766
if (mState != RingStateNone)
767
mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
769
//mask |= PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK;
771
status = gScreen->glPaintOutput (attrib, transform, region, output, mask);
773
if (mState != RingStateNone)
775
GLMatrix sTransform = transform;
777
sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
779
glLoadMatrixf (sTransform.getMatrix ());
781
/* TODO: This code here should be reworked */
783
if (mState == RingScreen::RingStateSwitching ||
784
mState == RingScreen::RingStateOut)
786
for (std::vector <RingDrawSlot>::iterator it = mDrawSlots.begin ();
787
it != mDrawSlots.end (); it++)
789
CompWindow *w = (*it).w;
793
status |= rw->gWindow->glPaint (rw->gWindow->paintAttrib (),
794
sTransform, infiniteRegion, 0);
798
if (mState != RingStateIn)
808
RingScreen::preparePaint (int msSinceLastPaint)
810
if (mState != RingStateNone && (mMoreAdjust || mRotateAdjust))
815
amount = msSinceLastPaint * 0.05f * optionGetSpeed ();
816
steps = amount / (0.5f * optionGetTimestep ());
820
chunk = amount / (float) steps;
824
mRotateAdjust = adjustRingRotation (chunk);
827
foreach (CompWindow *w, screen->windows ())
833
rw->mAdjust = rw->adjustVelocity ();
835
mMoreAdjust |= rw->mAdjust;
837
rw->mTx += rw->mXVelocity * chunk;
838
rw->mTy += rw->mYVelocity * chunk;
839
rw->mScale += rw->mScaleVelocity * chunk;
843
rw->mScale = rw->mSlot->scale * rw->mSlot->depthScale;
844
rw->mTx = rw->mSlot->x - w->x () -
845
(w->width () * rw->mScale) / 2;
846
rw->mTy = rw->mSlot->y - w->y () -
847
(w->height () * rw->mScale) / 2;
851
if (!mMoreAdjust && !mRotateAdjust)
853
switchActivateEvent (false);
859
cScreen->preparePaint (msSinceLastPaint);
863
RingScreen::donePaint ()
865
if (mState != RingStateNone)
869
cScreen->damageScreen ();
874
cScreen->damageScreen ();
876
if (mState == RingStateIn)
878
toggleFunctions (false);
879
mState = RingStateNone;
881
else if (mState == RingStateOut)
882
mState = RingStateSwitching;
886
cScreen->donePaint ();
890
RingScreen::terminate (CompAction *action,
891
CompAction::State state,
892
CompOption::Vector options)
896
screen->removeGrab (mGrabIndex, 0);
900
if (mState != RingStateNone)
902
foreach (CompWindow *w, screen->windows ())
915
mState = RingStateIn;
916
cScreen->damageScreen ();
918
if (!(state & CompAction::StateCancel) &&
919
mSelectedWindow && !mSelectedWindow->destroyed ())
921
screen->sendWindowActivationRequest (mSelectedWindow->id ());
926
action->setState ( ~(CompAction::StateTermKey |
927
CompAction::StateTermButton |
928
CompAction::StateTermEdge));
934
RingScreen::initiate (CompAction *action,
935
CompAction::State state,
936
CompOption::Vector options)
940
if (screen->otherGrabExist ("ring", NULL))
943
mCurrentMatch = optionGetWindowMatch ();
945
mMatch = CompOption::getMatchOptionNamed (options, "match", CompMatch ());
946
if (!mMatch.isEmpty ())
948
mCurrentMatch = mMatch;
951
count = countWindows ();
960
if (optionGetSelectWithMouse ())
961
mGrabIndex = screen->pushGrab (screen->normalCursor (), "ring");
963
mGrabIndex = screen->pushGrab (screen->invisibleCursor (), "ring");
968
mState = RingScreen::RingStateOut;
970
if (!createWindowList ())
973
mSelectedWindow = mWindows.front ();
974
renderWindowTitle ();
978
toggleFunctions (true);
979
cScreen->damageScreen ();
981
switchActivateEvent (true);
988
RingScreen::doSwitch (CompAction *action,
989
CompAction::State state,
990
CompOption::Vector options,
996
if ((mState == RingStateNone) || (mState == RingStateIn))
998
if (type == RingTypeGroup)
1001
w = screen->findWindow (CompOption::getIntOptionNamed (options,
1006
mType = RingTypeGroup;
1008
(w->clientLeader ()) ? w->clientLeader () : w->id ();
1009
ret = initiate (action, state, options);
1015
ret = initiate (action, mState, options);
1018
if (state & CompAction::StateInitKey)
1019
action->setState (action->state () | CompAction::StateTermKey);
1021
if (state & CompAction::StateInitEdge)
1022
action->setState (action->state () | CompAction::StateTermEdge);
1023
else if (mState & CompAction::StateInitButton)
1024
action->setState (action->state () |
1025
CompAction::StateTermButton);
1029
switchToWindow (nextWindow);
1036
RingScreen::windowSelectAt (int x,
1038
bool shouldTerminate)
1040
CompWindow *selected = NULL;
1042
if (!optionGetSelectWithMouse ())
1045
/* first find the top-most window the mouse
1047
foreach (CompWindow *w, mWindows)
1052
if ((x >= (rw->mTx + w->x ())) &&
1053
(x <= (rw->mTx + w->x () + (w->width () * rw->mScale))) &&
1054
(y >= (rw->mTy + w->y ())) &&
1055
(y <= (rw->mTy + w->y () + (w->height () * rw->mScale))))
1057
/* we have found one, select it */
1064
if (selected && shouldTerminate)
1066
CompOption o ("root", CompOption::TypeInt);
1067
CompOption::Vector opts;
1069
o.value ().set ((int) screen->root ());
1073
mSelectedWindow = selected;
1075
terminate (NULL, 0, opts);
1077
else if (!shouldTerminate && (selected != mSelectedWindow ))
1085
mSelectedWindow = selected;
1086
renderWindowTitle ();
1088
cScreen->damageScreen ();
1093
RingScreen::windowRemove (CompWindow *w)
1097
bool inList = false;
1098
CompWindow *selected;
1099
CompWindowVector::iterator it = mWindows.begin ();
1103
if (mState == RingStateNone)
1109
selected = mSelectedWindow;
1111
while (it != mWindows.end ())
1120
if (it != mWindows.end ())
1123
selected = mWindows.front ();
1126
mSelectedWindow = selected;
1127
renderWindowTitle ();
1130
mWindows.erase (it);
1139
/* Terminate if the window closed was the last window in the list */
1141
if (!mWindows.size ())
1143
CompOption o ("root", CompOption::TypeInt);
1144
CompOption::Vector opts;
1146
o.value ().set ((int) screen->root ());
1150
terminate (NULL, 0, opts);
1154
// Let the window list be updated to avoid crash
1155
// when a window is closed while ending (RingStateIn).
1156
if (!mGrabIndex && mState != RingStateIn)
1159
if (updateWindowList ())
1162
mState = RingStateOut;
1163
cScreen->damageScreen ();
1169
RingScreen::handleEvent (XEvent *event)
1171
CompWindow *w = NULL;
1173
switch (event->type) {
1175
/* We need to get the CompWindow * for event->xdestroywindow.window
1176
here because in the ::screen->handleEvent call below, that
1177
CompWindow's id will become 1, so findWindow won't be
1178
able to find the CompWindow after that. */
1179
w = ::screen->findWindow (event->xdestroywindow.window);
1185
screen->handleEvent (event);
1187
switch (event->type) {
1188
case PropertyNotify:
1189
if (event->xproperty.atom == XA_WM_NAME)
1191
w = screen->findWindow (event->xproperty.window);
1194
if (mGrabIndex && (w == mSelectedWindow))
1196
renderWindowTitle ();
1197
cScreen->damageScreen ();
1203
if (event->xbutton.button == Button1)
1206
windowSelectAt (event->xbutton.x_root,
1207
event->xbutton.y_root,
1213
windowSelectAt (event->xmotion.x_root,
1214
event->xmotion.y_root,
1217
w = ::screen->findWindow (event->xunmap.window);
1227
RingWindow::damageRect (bool initial,
1228
const CompRect &rect)
1230
bool status = false;
1232
RING_SCREEN (screen);
1236
if (rs->mGrabIndex && is ())
1238
rs->addWindowToList (window);
1239
if (rs->updateWindowList ())
1242
rs->mMoreAdjust = true;
1243
rs->mState = RingScreen::RingStateOut;
1244
rs->cScreen->damageScreen ();
1248
else if (rs->mState == RingScreen::RingStateSwitching)
1253
cWindow->damageTransformedRect (mScale, mScale,
1261
status |= cWindow->damageRect (initial, rect);
1266
RingScreen::RingScreen (CompScreen *screen) :
1267
PluginClassHandler <RingScreen, CompScreen> (screen),
1268
cScreen (CompositeScreen::get (screen)),
1269
gScreen (GLScreen::get (screen)),
1271
mState (RingScreen::RingStateNone),
1272
mMoreAdjust (false),
1273
mRotateAdjust (false),
1276
mSelectedWindow (NULL)
1279
ScreenInterface::setHandler (screen, false);
1280
CompositeScreenInterface::setHandler (cScreen, false);
1281
GLScreenInterface::setHandler (gScreen, false);
1283
#define RINGTERMBIND(opt, func) \
1284
optionSet##opt##Terminate (boost::bind (&RingScreen::func, \
1287
#define RINGSWITCHBIND(opt, func, next, type) \
1288
optionSet##opt##Initiate (boost::bind (&RingScreen::func, \
1292
RINGSWITCHBIND (NextKey, doSwitch, true, RingTypeNormal);
1293
RINGSWITCHBIND (PrevKey, doSwitch, false, RingTypeNormal);
1294
RINGSWITCHBIND (NextAllKey, doSwitch, true, RingTypeAll);
1295
RINGSWITCHBIND (PrevAllKey, doSwitch, false, RingTypeAll);
1296
RINGSWITCHBIND (NextGroupKey, doSwitch, true, RingTypeGroup);
1297
RINGSWITCHBIND (PrevGroupKey, doSwitch, false, RingTypeGroup);
1299
RINGTERMBIND (NextKey, terminate);
1300
RINGTERMBIND (PrevKey, terminate);
1301
RINGTERMBIND (NextAllKey, terminate);
1302
RINGTERMBIND (PrevAllKey, terminate);
1303
RINGTERMBIND (NextGroupKey, terminate);
1304
RINGTERMBIND (PrevGroupKey, terminate);
1306
RINGSWITCHBIND (NextButton, doSwitch, true, RingTypeNormal);
1307
RINGSWITCHBIND (PrevButton, doSwitch, false, RingTypeNormal);
1308
RINGSWITCHBIND (NextAllButton, doSwitch, true, RingTypeAll);
1309
RINGSWITCHBIND (PrevAllButton, doSwitch, false, RingTypeAll);
1310
RINGSWITCHBIND (NextGroupButton, doSwitch, true, RingTypeGroup);
1311
RINGSWITCHBIND (PrevGroupButton, doSwitch, false, RingTypeGroup);
1313
RINGTERMBIND (NextButton, terminate);
1314
RINGTERMBIND (PrevButton, terminate);
1315
RINGTERMBIND (NextAllButton, terminate);
1316
RINGTERMBIND (PrevAllButton, terminate);
1317
RINGTERMBIND (NextGroupButton, terminate);
1318
RINGTERMBIND (PrevGroupButton, terminate);
1322
RingScreen::~RingScreen ()
1325
mDrawSlots.clear ();
1328
RingWindow::RingWindow (CompWindow *window) :
1329
PluginClassHandler <RingWindow, CompWindow> (window),
1331
cWindow (CompositeWindow::get (window)),
1332
gWindow (GLWindow::get (window)),
1336
mScaleVelocity (0.0f),
1342
CompositeWindowInterface::setHandler (cWindow, false);
1343
GLWindowInterface::setHandler (gWindow, false);
1346
RingWindow::~RingWindow ()
1353
RingPluginVTable::init ()
1355
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
1356
!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
1357
!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
1360
if (!CompPlugin::checkPluginABI ("text", COMPIZ_TEXT_ABI))
1362
compLogMessage ("ring", CompLogLevelWarn, "No compatible text plugin"\
1364
textAvailable = false;
1367
textAvailable = true;