~kzmd-deactivatedaccount/ubuntu/natty/compiz-plugins-main/popup-delay-fix-772177

« back to all changes in this revision

Viewing changes to staticswitcher/src/staticswitcher.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2011-02-24 17:34:18 UTC
  • Revision ID: james.westby@ubuntu.com-20110224173418-b81hfllshqpciq6n
Tags: upstream-0.9.4
ImportĀ upstreamĀ versionĀ 0.9.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 * Compiz application switcher plugin
 
4
 *
 
5
 * staticswitcher.cpp
 
6
 *
 
7
 * Copyright : (C) 2008 by Danny Baumann
 
8
 * E-mail    : maniac@compiz-fusion.org
 
9
 *
 
10
 * Based on switcher.c:
 
11
 * Copyright : (C) 2007 David Reveman
 
12
 * E-mail    : davidr@novell.com
 
13
 *
 
14
 * This program is free software; you can redistribute it and/or
 
15
 * modify it under the terms of the GNU General Public License
 
16
 * as published by the Free Software Foundation; either version 2
 
17
 * of the License, or (at your option) any later version.
 
18
 *
 
19
 * This program is distributed in the hope that it will be useful,
 
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
22
 * GNU General Public License for more details.
 
23
 *
 
24
 */
 
25
 
 
26
#include "staticswitcher.h"
 
27
 
 
28
COMPIZ_PLUGIN_20090315 (staticswitcher, StaticSwitchPluginVTable)
 
29
 
 
30
void
 
31
StaticSwitchScreen::updatePopupWindow ()
 
32
{
 
33
    int    newXCount, newYCount;
 
34
    int    winWidth, winHeight;
 
35
    float  aspect;
 
36
    int    count = windows.size ();
 
37
    double dCount = count;
 
38
    int    w = PREVIEWSIZE, h = PREVIEWSIZE, b = BORDER;
 
39
    int    x, y;
 
40
    XSizeHints   xsh;
 
41
 
 
42
    /* maximum window size is 2/3 of the current output */
 
43
    winWidth  = ::screen->currentOutputDev ().width () * 2 / 3;
 
44
    winHeight = ::screen->currentOutputDev ().height () * 2 / 3;
 
45
 
 
46
    if (count <= 4)
 
47
    {
 
48
        /* don't put 4 or less windows in multiple rows */
 
49
        newXCount = count;
 
50
        newYCount = 1;
 
51
    }
 
52
    else
 
53
    {
 
54
        aspect = (float) winWidth / winHeight;
 
55
        /* round is available in C99 only, so use a replacement for that */
 
56
        newYCount = floor (sqrt (dCount / aspect) + 0.5f);
 
57
        newXCount = ceil (dCount / newYCount);
 
58
    }
 
59
 
 
60
    while ((w + b) * newXCount > winWidth ||
 
61
           (h + b) * newYCount > winHeight)
 
62
    {
 
63
        /* shrink by 10% until all windows fit */
 
64
        w = w * 9 / 10;
 
65
        h = h * 9 / 10;
 
66
        b = b * 9 / 10;
 
67
    }
 
68
 
 
69
    winWidth = MIN (count, newXCount);
 
70
    winHeight = (count + newXCount - 1) / newXCount;
 
71
 
 
72
    winWidth = winWidth * w + (winWidth + 1) * b;
 
73
    winHeight = winHeight * h + (winHeight + 1) * b;
 
74
    xCount = MIN (newXCount, count);
 
75
 
 
76
    previewWidth = w;
 
77
    previewHeight = h;
 
78
    previewBorder = b;
 
79
 
 
80
    x = ::screen->currentOutputDev ().region ()->extents.x1 +
 
81
        ::screen->currentOutputDev ().width () / 2;
 
82
    y = ::screen->currentOutputDev ().region ()->extents.y1 +
 
83
        ::screen->currentOutputDev ().height () / 2;
 
84
 
 
85
    xsh.flags       = PSize | PPosition | PWinGravity;
 
86
    xsh.x           = x;
 
87
    xsh.y           = y;
 
88
    xsh.width       = winWidth;
 
89
    xsh.height      = winHeight;
 
90
    xsh.win_gravity = StaticGravity;
 
91
 
 
92
    XSetWMNormalHints (::screen->dpy (), popupWindow, &xsh);
 
93
 
 
94
    CompWindow *popup = screen->findWindow (popupWindow);
 
95
 
 
96
    XWindowChanges xwc;
 
97
    unsigned int valueMask = 0;
 
98
 
 
99
    valueMask |= (CWX | CWY | CWWidth | CWHeight);
 
100
 
 
101
    xwc.x = x - winWidth / 2;
 
102
    xwc.y = y - winHeight / 2;
 
103
    xwc.width = winWidth;
 
104
    xwc.height = winHeight;
 
105
 
 
106
    if (popup)
 
107
        popup->configureXWindow (valueMask, &xwc);
 
108
    else
 
109
        XConfigureWindow (::screen->dpy (), popupWindow,
 
110
                           valueMask, &xwc);
 
111
}
 
112
 
 
113
void
 
114
StaticSwitchScreen::updateWindowList ()
 
115
{
 
116
    pos  = 0;
 
117
    move = 0;
 
118
 
 
119
    selectedWindow = windows.front ();
 
120
 
 
121
    if (popupWindow)
 
122
        updatePopupWindow ();
 
123
}
 
124
 
 
125
void
 
126
StaticSwitchScreen::createWindowList ()
 
127
{
 
128
    windows.clear ();
 
129
 
 
130
    foreach (CompWindow *w, ::screen->windows ())
 
131
    {
 
132
        SWITCH_WINDOW (w);
 
133
 
 
134
        if (sw->isSwitchWin ())
 
135
        {
 
136
            windows.push_back (w);
 
137
 
 
138
            sw->cWindow->damageRectSetEnabled (sw, true);
 
139
        }
 
140
    }
 
141
 
 
142
    windows.sort (BaseSwitchScreen::compareWindows);
 
143
 
 
144
    updateWindowList ();
 
145
}
 
146
 
 
147
bool
 
148
StaticSwitchWindow::damageRect (bool initial, const CompRect &rect)
 
149
{
 
150
    return BaseSwitchWindow::damageRect (initial, rect);
 
151
}
 
152
 
 
153
BaseSwitchWindow::IconMode
 
154
StaticSwitchWindow::getIconMode ()
 
155
{
 
156
    if (sScreen->optionGetIconOnly ())
 
157
        return ShowIconOnly;
 
158
    if (!sScreen->optionGetIcon ())
 
159
        return HideIcon;
 
160
 
 
161
    return ShowIcon;
 
162
}
 
163
 
 
164
bool
 
165
StaticSwitchScreen::getPaintRectangle (CompWindow *w,
 
166
                                       CompRect   &rect,
 
167
                                       int        *opacity)
 
168
{
 
169
    int mode;
 
170
 
 
171
    mode = optionGetHighlightRectHidden ();
 
172
 
 
173
    if (w->isViewable () || w->shaded ())
 
174
    {
 
175
        rect = w->inputRect ();
 
176
        return true;
 
177
    }
 
178
    else if (mode == HighlightRectHiddenTaskbarEntry &&
 
179
             (w->iconGeometry ().x1 () != 0 ||
 
180
              w->iconGeometry ().y1 () != 0 ||
 
181
              w->iconGeometry ().x2 () != 0 ||
 
182
              w->iconGeometry ().y2 () != 0))
 
183
    {
 
184
        rect = w->iconGeometry ();
 
185
        return true;
 
186
    }
 
187
    else if (mode == HighlightRectHiddenOriginalWindowPosition)
 
188
    {
 
189
        rect = w->serverInputRect ();
 
190
 
 
191
        if (opacity)
 
192
            *opacity /= 4;
 
193
 
 
194
        return true;
 
195
    }
 
196
 
 
197
    return false;
 
198
}
 
199
 
 
200
void
 
201
StaticSwitchScreen::doWindowDamage (CompWindow *w)
 
202
{
 
203
    if (w->isViewable () || w->shaded ())
 
204
    {
 
205
        CompositeWindow::get (w)->addDamage ();
 
206
    }
 
207
    else
 
208
    {
 
209
        CompRect box;
 
210
        if (getPaintRectangle (w, box, NULL))
 
211
        {
 
212
            CompRect boxExtended (box.x () - 2,
 
213
                                  box.y () - 2,
 
214
                                  box.width () + 4,
 
215
                                  box.height () + 4);
 
216
 
 
217
            cScreen->damageRegion (CompRegion (boxExtended));
 
218
        }
 
219
    }
 
220
}
 
221
 
 
222
void
 
223
StaticSwitchScreen::handleSelectionChange (bool toNext, int nextIdx)
 
224
{
 
225
    move = nextIdx;
 
226
    moreAdjust = true;
 
227
}
 
228
 
 
229
void
 
230
StaticSwitchScreen::createPopup ()
 
231
{
 
232
    if (!popupWindow)
 
233
    {
 
234
        Display              *dpy = ::screen->dpy ();
 
235
        XWMHints             xwmh;
 
236
        XClassHint           xch;
 
237
        Atom                 state[4];
 
238
        int                  nState = 0;
 
239
        XSetWindowAttributes attr;
 
240
        Visual               *visual;
 
241
 
 
242
        visual = findArgbVisual (dpy, ::screen->screenNum ());
 
243
        if (!visual)
 
244
            return;
 
245
 
 
246
        xwmh.flags = InputHint;
 
247
        xwmh.input = 0;
 
248
 
 
249
        xch.res_name  = (char *)"compiz";
 
250
        xch.res_class = (char *)"switcher-window";
 
251
 
 
252
        attr.background_pixel = 0;
 
253
        attr.border_pixel     = 0;
 
254
        attr.colormap         = XCreateColormap (dpy, ::screen->root (), visual,
 
255
                                                 AllocNone);
 
256
        attr.override_redirect = 1;
 
257
 
 
258
        popupWindow =
 
259
            XCreateWindow (dpy, ::screen->root (),
 
260
                           -1, -1, 1, 1, 0,
 
261
                           32, InputOutput, visual,
 
262
                           CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect, &attr);
 
263
 
 
264
        XSetWMProperties (dpy, popupWindow, NULL, NULL,
 
265
                          programArgv, programArgc,
 
266
                          NULL, &xwmh, &xch);
 
267
 
 
268
        state[nState++] = Atoms::winStateAbove;
 
269
        state[nState++] = Atoms::winStateSticky;
 
270
        state[nState++] = Atoms::winStateSkipTaskbar;
 
271
        state[nState++] = Atoms::winStateSkipPager;
 
272
 
 
273
        XChangeProperty (dpy, popupWindow,
 
274
                         Atoms::winState,
 
275
                         XA_ATOM, 32, PropModeReplace,
 
276
                         (unsigned char *) state, nState);
 
277
 
 
278
        XChangeProperty (dpy, popupWindow,
 
279
                         Atoms::winType,
 
280
                         XA_ATOM, 32, PropModeReplace,
 
281
                         (unsigned char *) &Atoms::winTypeUtil, 1);
 
282
 
 
283
        ::screen->setWindowProp (popupWindow, Atoms::winDesktop, 0xffffffff);
 
284
 
 
285
        setSelectedWindowHint ();
 
286
 
 
287
        updatePopupWindow ();
 
288
    }
 
289
}
 
290
 
 
291
bool
 
292
StaticSwitchScreen::showPopup ()
 
293
{
 
294
    /* Always checks for an existing popup */
 
295
    createPopup ();
 
296
 
 
297
    XMapWindow (::screen->dpy (), popupWindow);
 
298
 
 
299
    cScreen->damageScreen ();
 
300
 
 
301
    popupDelayTimer.stop ();
 
302
 
 
303
    return false;
 
304
}
 
305
 
 
306
Cursor
 
307
StaticSwitchScreen::getCursor (bool mouseSelectOn)
 
308
{
 
309
    if (mouseSelectOn)
 
310
        return ::screen->normalCursor ();
 
311
 
 
312
    return ::screen->invisibleCursor ();
 
313
}
 
314
 
 
315
void
 
316
StaticSwitchScreen::initiate (SwitchWindowSelection selection,
 
317
                              bool                  shouldShowPopup)
 
318
{
 
319
    bool noSwitchWindows;
 
320
    bool newMouseSelect;
 
321
 
 
322
    if (::screen->otherGrabExist ("switcher", "scale", "cube", 0))
 
323
        return;
 
324
 
 
325
    this->selection      = selection;
 
326
    selectedWindow       = NULL;
 
327
 
 
328
    noSwitchWindows = true;
 
329
    foreach (CompWindow *w, ::screen->windows ())
 
330
    {
 
331
        if (StaticSwitchWindow::get (w)->isSwitchWin ())
 
332
        {
 
333
            noSwitchWindows = false;
 
334
            break;
 
335
        }
 
336
    }
 
337
    if (noSwitchWindows)
 
338
        return;
 
339
 
 
340
    newMouseSelect = optionGetMouseSelect () &&
 
341
                     selection != Panels && shouldShowPopup;
 
342
 
 
343
    if (!grabIndex)
 
344
        grabIndex = ::screen->pushGrab (getCursor (newMouseSelect), "switcher");
 
345
    else if (newMouseSelect != mouseSelect)
 
346
        ::screen->updateGrab (grabIndex, getCursor (newMouseSelect));
 
347
 
 
348
    mouseSelect = newMouseSelect;
 
349
 
 
350
    if (grabIndex)
 
351
    {
 
352
        if (!switching)
 
353
        {
 
354
            lastActiveNum = ::screen->activeNum ();
 
355
 
 
356
            createWindowList ();
 
357
 
 
358
            if (shouldShowPopup)
 
359
            {
 
360
                unsigned int delay;
 
361
 
 
362
                delay = optionGetPopupDelay () * 1000;
 
363
                if (delay)
 
364
                {
 
365
                    if (popupDelayTimer.active ())
 
366
                        popupDelayTimer.stop ();
 
367
 
 
368
                    popupDelayTimer.start
 
369
                        (boost::bind (&StaticSwitchScreen::showPopup, this),
 
370
                         delay, delay * 1.2);
 
371
                }
 
372
                else
 
373
                {
 
374
                    showPopup ();
 
375
                }
 
376
 
 
377
                setSelectedWindowHint ();
 
378
            }
 
379
 
 
380
            lastActiveWindow = screen->activeWindow ();
 
381
            activateEvent (true);
 
382
        }
 
383
 
 
384
        cScreen->damageScreen ();
 
385
 
 
386
        switching  = true;
 
387
        moreAdjust = true;
 
388
 
 
389
        ::screen->handleEventSetEnabled (this, true);
 
390
        cScreen->preparePaintSetEnabled (this, true);
 
391
        cScreen->donePaintSetEnabled (this, true);
 
392
        gScreen->glPaintOutputSetEnabled (this, true);
 
393
 
 
394
        foreach (CompWindow *w, ::screen->windows ())
 
395
        {
 
396
            SWITCH_WINDOW (w);
 
397
 
 
398
            sw->gWindow->glPaintSetEnabled (sw, true);
 
399
        }
 
400
    }
 
401
}
 
402
 
 
403
static bool
 
404
switchTerminate (CompAction         *action,
 
405
                 CompAction::State  state,
 
406
                 CompOption::Vector &options)
 
407
{
 
408
    Window     xid;
 
409
 
 
410
    xid = (Window) CompOption::getIntOptionNamed (options, "root");
 
411
 
 
412
    if (action)
 
413
        action->setState (action->state () &
 
414
                          (unsigned)~(CompAction::StateTermKey |
 
415
                                      CompAction::StateTermButton));
 
416
 
 
417
    if (xid && xid != ::screen->root ())
 
418
        return false;
 
419
 
 
420
    SWITCH_SCREEN (screen);
 
421
 
 
422
    if (ss->grabIndex)
 
423
    {
 
424
        if (ss->popupDelayTimer.active ())
 
425
            ss->popupDelayTimer.stop ();
 
426
 
 
427
        if (ss->popupWindow)
 
428
            XUnmapWindow (::screen->dpy (), ss->popupWindow);
 
429
 
 
430
        ss->switching = false;
 
431
 
 
432
        if (state & CompAction::StateCancel)
 
433
            ss->selectedWindow = NULL;
 
434
 
 
435
        if (state && ss->selectedWindow && !ss->selectedWindow->destroyed ())
 
436
            ::screen->sendWindowActivationRequest (ss->selectedWindow->id ());
 
437
 
 
438
        ::screen->removeGrab (ss->grabIndex, 0);
 
439
        ss->grabIndex = NULL;
 
440
 
 
441
        if (!ss->popupWindow)
 
442
            ::screen->handleEventSetEnabled (ss, false);
 
443
 
 
444
        ss->selectedWindow = NULL;
 
445
 
 
446
        if (screen->activeWindow () != ss->lastActiveWindow)
 
447
        {
 
448
            CompWindow *w = screen->findWindow (ss->lastActiveWindow);
 
449
 
 
450
            if (w)
 
451
                w->moveInputFocusTo ();
 
452
        }
 
453
 
 
454
        ss->setSelectedWindowHint ();
 
455
 
 
456
        ss->lastActiveNum = 0;
 
457
 
 
458
        ss->cScreen->damageScreen ();
 
459
    }
 
460
 
 
461
    return false;
 
462
}
 
463
 
 
464
static bool
 
465
switchInitiateCommon (CompAction            *action,
 
466
                      CompAction::State     state,
 
467
                      CompOption::Vector    &options,
 
468
                      SwitchWindowSelection selection,
 
469
                      bool                  shouldShowPopup,
 
470
                      bool                  nextWindow)
 
471
{
 
472
    Window     xid;
 
473
 
 
474
    xid = (Window) CompOption::getIntOptionNamed (options, "root");
 
475
 
 
476
    if (xid != ::screen->root ())
 
477
        return false;
 
478
 
 
479
    SWITCH_SCREEN (::screen);
 
480
 
 
481
    if (!ss->switching)
 
482
    {
 
483
        if (selection == Group)
 
484
        {
 
485
            CompWindow *w;
 
486
            Window     xid;
 
487
 
 
488
            xid = (Window) CompOption::getIntOptionNamed (options, "window");
 
489
            w = ::screen->findWindow (xid);
 
490
            if (w)
 
491
                ss->clientLeader = (w->clientLeader ()) ?
 
492
                                   w->clientLeader () : xid;
 
493
            else
 
494
                ss->clientLeader = None;
 
495
        }
 
496
 
 
497
        ss->initiate (selection, shouldShowPopup);
 
498
 
 
499
        if (state & CompAction::StateInitKey)
 
500
            action->setState (action->state () | CompAction::StateTermKey);
 
501
 
 
502
        if (state & CompAction::StateInitEdge)
 
503
            action->setState (action->state () | CompAction::StateTermEdge);
 
504
        else if (state & CompAction::StateInitButton)
 
505
            action->setState (action->state () | CompAction::StateTermButton);
 
506
    }
 
507
 
 
508
    ss->switchToWindow (nextWindow, ss->optionGetAutoChangeVp ());
 
509
 
 
510
    return false;
 
511
}
 
512
 
 
513
void
 
514
StaticSwitchScreen::getMinimizedAndMatch (bool &minimizedOption,
 
515
                                          CompMatch *&matchOption)
 
516
{
 
517
    minimizedOption = optionGetMinimized ();
 
518
    matchOption = &optionGetWindowMatch ();
 
519
}
 
520
 
 
521
bool
 
522
StaticSwitchScreen::getMipmap ()
 
523
{
 
524
    return optionGetMipmap ();
 
525
}
 
526
 
 
527
void
 
528
StaticSwitchScreen::windowRemove (CompWindow *w)
 
529
{
 
530
    if (w)
 
531
    {
 
532
        bool   inList = false;
 
533
 
 
534
        CompWindow *selected;
 
535
        CompWindow *old;
 
536
 
 
537
        SWITCH_WINDOW (w);
 
538
 
 
539
        if (!sw->isSwitchWin (true))
 
540
            return;
 
541
 
 
542
        sw->cWindow->damageRectSetEnabled (sw, false);
 
543
        sw->gWindow->glPaintSetEnabled (sw, false);
 
544
 
 
545
        old = selected = selectedWindow;
 
546
 
 
547
        CompWindowList::iterator it = windows.begin ();
 
548
        while (it != windows.end ())
 
549
        {
 
550
            if (*it == w)
 
551
            {
 
552
                inList = true;
 
553
 
 
554
                if (w == selected)
 
555
                {
 
556
                    it++;
 
557
                    if (it == windows.end ())
 
558
                        selected = windows.front ();
 
559
                    else
 
560
                        selected = *it;
 
561
                    it--;
 
562
                }
 
563
 
 
564
                CompWindowList::iterator del = it;
 
565
                it++;
 
566
                windows.erase (del);
 
567
            }
 
568
            else
 
569
                it++;
 
570
        }
 
571
 
 
572
        if (!inList)
 
573
            return;
 
574
 
 
575
        if (windows.size () == 0)
 
576
        {
 
577
            CompOption::Vector o (0);
 
578
            o.push_back (CompOption ("root", CompOption::TypeInt));
 
579
            o[0].value ().set ((int) ::screen->root ());
 
580
 
 
581
            switchTerminate (NULL, 0, o);
 
582
            return;
 
583
        }
 
584
 
 
585
        if (!grabIndex)
 
586
            return;
 
587
 
 
588
        updateWindowList ();
 
589
 
 
590
        int i = 0;
 
591
        foreach (CompWindow *w, windows)
 
592
        {
 
593
            selectedWindow = w;
 
594
            move = pos = i;
 
595
 
 
596
            if (selectedWindow == selected)
 
597
                break;
 
598
            i++;
 
599
        }
 
600
 
 
601
        if (popupWindow)
 
602
        {
 
603
            CompWindow *popup;
 
604
 
 
605
            popup = ::screen->findWindow (popupWindow);
 
606
            if (popup)
 
607
                CompositeWindow::get (popup)->addDamage ();
 
608
 
 
609
            setSelectedWindowHint ();
 
610
        }
 
611
 
 
612
        if (old != selectedWindow)
 
613
        {
 
614
            CompositeWindow::get (selectedWindow)->addDamage ();
 
615
            CompositeWindow::get (w)->addDamage ();
 
616
 
 
617
            if (old && !old->destroyed ())
 
618
                CompositeWindow::get (old)->addDamage ();
 
619
 
 
620
            moreAdjust = true;
 
621
        }
 
622
    }
 
623
}
 
624
 
 
625
int
 
626
StaticSwitchScreen::getRowXOffset (int y)
 
627
{
 
628
    int retval = 0;
 
629
    int count = windows.size ();
 
630
 
 
631
    if (count - (y * (int)xCount) >= (int)xCount)
 
632
        return 0;
 
633
 
 
634
    switch (optionGetRowAlign ()) {
 
635
    case RowAlignLeft:
 
636
        break;
 
637
    case RowAlignCentered:
 
638
        retval = (xCount - count + (y * (int)xCount)) *
 
639
                 (previewWidth + previewBorder) / 2;
 
640
        break;
 
641
    case RowAlignRight:
 
642
        retval = (xCount - count + (y * (int)xCount)) *
 
643
                 (previewWidth + previewBorder);
 
644
        break;
 
645
    }
 
646
 
 
647
    return retval;
 
648
}
 
649
 
 
650
void
 
651
StaticSwitchScreen::getWindowPosition (unsigned int index,
 
652
                                       int          *x,
 
653
                                       int          *y)
 
654
{
 
655
    int row, column;
 
656
 
 
657
    if (index >= windows.size ())
 
658
        return;
 
659
 
 
660
    column = (int)index % xCount;
 
661
    row    = (int)index / xCount;
 
662
 
 
663
    *x = column * previewWidth + (column + 1) * previewBorder;
 
664
    *x += getRowXOffset (row);
 
665
 
 
666
    *y = row * previewHeight + (row + 1) * previewBorder;
 
667
}
 
668
 
 
669
CompWindow *
 
670
StaticSwitchScreen::findWindowAt (int x,
 
671
                                  int y)
 
672
{
 
673
    CompWindow *popup;
 
674
 
 
675
    popup = ::screen->findWindow (popupWindow);
 
676
    if (popup)
 
677
    {
 
678
        unsigned int i = 0;
 
679
        foreach (CompWindow *w, windows)
 
680
        {
 
681
            int x1, x2, y1, y2;
 
682
 
 
683
            getWindowPosition (i, &x1, &y1);
 
684
 
 
685
            x1 += popup->geometry ().x ();
 
686
            y1 += popup->geometry ().y ();
 
687
 
 
688
            x2 = x1 + previewWidth;
 
689
            y2 = y1 + previewHeight;
 
690
 
 
691
            if (x >= x1 && x < x2 && y >= y1 && y < y2)
 
692
                return w;
 
693
 
 
694
            i++;
 
695
        }
 
696
    }
 
697
 
 
698
    return NULL;
 
699
}
 
700
 
 
701
void
 
702
StaticSwitchScreen::handleEvent (XEvent *event)
 
703
{
 
704
    BaseSwitchScreen::handleEvent (event);
 
705
 
 
706
    switch (event->type)
 
707
    {
 
708
    case ButtonPress:
 
709
        if (grabIndex && mouseSelect)
 
710
        {
 
711
            CompWindow *selected;
 
712
 
 
713
            selected = findWindowAt (event->xbutton.x_root,
 
714
                                     event->xbutton.y_root);
 
715
            if (selected)
 
716
            {
 
717
                selectedWindow = selected;
 
718
 
 
719
                CompOption::Vector o (0);
 
720
                o.push_back (CompOption ("root", CompOption::TypeInt));
 
721
                o[0].value ().set ((int) ::screen->root ());
 
722
 
 
723
                switchTerminate (NULL, CompAction::StateTermButton, o);
 
724
            }
 
725
        }
 
726
        break;
 
727
    default:
 
728
        break;
 
729
    }
 
730
}
 
731
 
 
732
bool
 
733
StaticSwitchScreen::adjustVelocity ()
 
734
{
 
735
    float dx, adjust, amount;
 
736
    int   count = windows.size ();
 
737
 
 
738
    dx = move - pos;
 
739
    if (abs (dx) > abs (dx + count))
 
740
        dx += count;
 
741
    if (abs (dx) > abs (dx - count))
 
742
        dx -= count;
 
743
 
 
744
    adjust = dx * 0.15f;
 
745
    amount = fabs (dx) * 1.5f;
 
746
    if (amount < 0.2f)
 
747
        amount = 0.2f;
 
748
    else if (amount > 2.0f)
 
749
        amount = 2.0f;
 
750
 
 
751
    mVelocity = (amount * mVelocity + adjust) / (amount + 1.0f);
 
752
 
 
753
    if (fabs (dx) < 0.001f && fabs (mVelocity) < 0.001f)
 
754
    {
 
755
        mVelocity = 0.0f;
 
756
        return false;
 
757
    }
 
758
 
 
759
    return true;
 
760
}
 
761
 
 
762
void
 
763
StaticSwitchScreen::preparePaint (int msSinceLastPaint)
 
764
{
 
765
    if (moreAdjust)
 
766
    {
 
767
        int   steps;
 
768
        float amount, chunk;
 
769
        int   count = windows.size ();
 
770
 
 
771
        amount = msSinceLastPaint * 0.05f * optionGetSpeed ();
 
772
        steps  = amount / (0.5f * optionGetTimestep ());
 
773
        if (!steps) steps = 1;
 
774
        chunk  = amount / (float) steps;
 
775
 
 
776
        while (steps--)
 
777
        {
 
778
            moreAdjust = adjustVelocity ();
 
779
            if (!moreAdjust)
 
780
            {
 
781
                pos = move;
 
782
                break;
 
783
            }
 
784
 
 
785
            pos += mVelocity * chunk;
 
786
            pos = fmod (pos, count);
 
787
            if (pos < 0.0)
 
788
                pos += count;
 
789
        }
 
790
    }
 
791
 
 
792
    cScreen->preparePaint (msSinceLastPaint);
 
793
}
 
794
 
 
795
void
 
796
StaticSwitchScreen::paintRect (CompRect &box,
 
797
                               int offset,
 
798
                               unsigned short *color,
 
799
                               int opacity)
 
800
{
 
801
    glColor4us (color[0], color[1], color[2], color[3] * opacity / 100);
 
802
    glBegin (GL_LINE_LOOP);
 
803
    glVertex2i (box.x1 () + offset, box.y1 () + offset);
 
804
    glVertex2i (box.x2 () - offset, box.y1 () + offset);
 
805
    glVertex2i (box.x2 () - offset, box.y2 () - offset);
 
806
    glVertex2i (box.x1 () + offset, box.y2 () - offset);
 
807
    glEnd ();
 
808
}
 
809
 
 
810
bool
 
811
StaticSwitchScreen::glPaintOutput (const GLScreenPaintAttrib &sAttrib,
 
812
                                   const GLMatrix            &transform,
 
813
                                   const CompRegion          &region,
 
814
                                   CompOutput                *output,
 
815
                                   unsigned int              mask)
 
816
{
 
817
    bool status;
 
818
 
 
819
    if (grabIndex)
 
820
    {
 
821
        int        mode;
 
822
        CompWindow *switcher, *zoomed;
 
823
        Window     zoomedAbove = None;
 
824
 
 
825
        if (!popupDelayTimer.active ())
 
826
            mode = optionGetHighlightMode ();
 
827
        else
 
828
            mode = HighlightModeNone;
 
829
 
 
830
        if (mode == HighlightModeBringSelectedToFront)
 
831
        {
 
832
            CompWindow *frontWindow = ::screen->clientList ().back ();
 
833
 
 
834
            zoomed = selectedWindow;
 
835
            if (zoomed && zoomed != frontWindow)
 
836
            {
 
837
                CompWindow *w;
 
838
 
 
839
                for (w = zoomed->prev; w && w->id () <= 1; w = w->prev)
 
840
                    ;
 
841
                zoomedAbove = (w) ? w->id () : None;
 
842
 
 
843
                ::screen->unhookWindow (zoomed);
 
844
                ::screen->insertWindow (zoomed, frontWindow->id ());
 
845
            }
 
846
            else
 
847
            {
 
848
                zoomed = NULL;
 
849
            }
 
850
        }
 
851
        else
 
852
        {
 
853
            zoomed = NULL;
 
854
        }
 
855
 
 
856
        ignoreSwitcher = true;
 
857
 
 
858
        status = gScreen->glPaintOutput (sAttrib, transform, region, output,
 
859
                                         mask);
 
860
 
 
861
        if (zoomed)
 
862
        {
 
863
            ::screen->unhookWindow (zoomed);
 
864
            ::screen->insertWindow (zoomed, zoomedAbove);
 
865
        }
 
866
 
 
867
        ignoreSwitcher = false;
 
868
 
 
869
        switcher = ::screen->findWindow (popupWindow);
 
870
 
 
871
        if (switcher || mode == HighlightModeShowRectangle)
 
872
        {
 
873
            GLMatrix   sTransform (transform);
 
874
 
 
875
            sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
 
876
 
 
877
            glPushMatrix ();
 
878
            glLoadMatrixf (sTransform.getMatrix ());
 
879
 
 
880
            if (mode == HighlightModeShowRectangle)
 
881
            {
 
882
                CompWindow *w;
 
883
 
 
884
                w = selectedWindow;
 
885
 
 
886
                if (w)
 
887
                {
 
888
                    CompRect box;
 
889
                    int      opacity = 100;
 
890
 
 
891
                    if (getPaintRectangle (w, box, &opacity))
 
892
                    {
 
893
                        unsigned short *color;
 
894
                        GLushort       r, g, b, a;
 
895
 
 
896
                        glEnable (GL_BLEND);
 
897
 
 
898
                        /* fill rectangle */
 
899
                        r = optionGetHighlightColorRed ();
 
900
                        g = optionGetHighlightColorGreen ();
 
901
                        b = optionGetHighlightColorBlue ();
 
902
                        a = optionGetHighlightColorAlpha ();
 
903
                        a = a * opacity / 100;
 
904
 
 
905
                        glColor4us (r, g, b, a);
 
906
                        glRecti (box.x1 (), box.y2 (), box.x2 (), box.y1 ());
 
907
 
 
908
                        /* draw outline */
 
909
                        glLineWidth (1.0);
 
910
                        glDisable (GL_LINE_SMOOTH);
 
911
 
 
912
                        color = optionGetHighlightBorderColor ();
 
913
                        paintRect (box, 0, color, opacity);
 
914
                        paintRect (box, 2, color, opacity);
 
915
                        color = optionGetHighlightBorderInlayColor ();
 
916
                        paintRect (box, 1, color, opacity);
 
917
 
 
918
                        /* clean up */
 
919
                        glColor4usv (defaultColor);
 
920
                        glDisable (GL_BLEND);
 
921
                    }
 
922
                }
 
923
            }
 
924
 
 
925
            if (switcher)
 
926
            {
 
927
                SWITCH_WINDOW (switcher);
 
928
 
 
929
                if (!switcher->destroyed () &&
 
930
                    switcher->isViewable () &&
 
931
                    sw->cWindow->damaged ())
 
932
                {
 
933
                    sw->gWindow->glPaint (sw->gWindow->paintAttrib (),
 
934
                                          sTransform, infiniteRegion, 0);
 
935
                }
 
936
            }
 
937
 
 
938
            glPopMatrix ();
 
939
        }
 
940
    }
 
941
    else
 
942
    {
 
943
        status = gScreen->glPaintOutput (sAttrib, transform, region, output,
 
944
                                         mask);
 
945
    }
 
946
 
 
947
    return status;
 
948
}
 
949
 
 
950
void
 
951
StaticSwitchScreen::donePaint ()
 
952
{
 
953
    if (grabIndex && moreAdjust)
 
954
    {
 
955
        CompWindow *w;
 
956
 
 
957
        w = ::screen->findWindow (popupWindow);
 
958
        if (w)
 
959
            CompositeWindow::get (w)->addDamage ();
 
960
    }
 
961
    else if (!grabIndex && !moreAdjust)
 
962
    {
 
963
        activateEvent (false);
 
964
 
 
965
        cScreen->preparePaintSetEnabled (this, false);
 
966
        cScreen->donePaintSetEnabled (this, false);
 
967
        gScreen->glPaintOutputSetEnabled (this, false);
 
968
 
 
969
        foreach (CompWindow *w, ::screen->windows ())
 
970
        {
 
971
            SWITCH_WINDOW (w);
 
972
            sw->cWindow->damageRectSetEnabled (sw, false);
 
973
            sw->gWindow->glPaintSetEnabled (sw, false);
 
974
        }
 
975
    }
 
976
 
 
977
    cScreen->donePaint ();
 
978
}
 
979
 
 
980
void
 
981
StaticSwitchScreen::paintSelectionRect (int          x,
 
982
                                        int          y,
 
983
                                        float        dx,
 
984
                                        float        dy,
 
985
                                        unsigned int opacity)
 
986
{
 
987
    float color[4], op;
 
988
    int   w, h;
 
989
    int   count = windows.size ();
 
990
 
 
991
    w = previewWidth + previewBorder;
 
992
    h = previewHeight + previewBorder;
 
993
 
 
994
    glEnable (GL_BLEND);
 
995
 
 
996
    if (dx > xCount - 1)
 
997
        op = 1.0 - MIN (1.0, dx - (xCount - 1));
 
998
    else if (dx + (dy * xCount) > count - 1)
 
999
        op = 1.0 - MIN (1.0, dx - (count - 1 - (dy * xCount)));
 
1000
    else if (dx < 0.0)
 
1001
        op = 1.0 + MAX (-1.0, dx);
 
1002
    else
 
1003
        op = 1.0;
 
1004
 
 
1005
    for (unsigned int i = 0; i < 4; i++)
 
1006
        color[i] = (float)fgColor[i] * opacity * op / 0xffffffff;
 
1007
 
 
1008
    glColor4fv (color);
 
1009
    glPushMatrix ();
 
1010
    glTranslatef (x + previewBorder / 2 + (dx * w),
 
1011
                  y + previewBorder / 2 + (dy * h), 0.0f);
 
1012
 
 
1013
    glBegin (GL_QUADS);
 
1014
    glVertex2i (-1, -1);
 
1015
    glVertex2i (-1, 1);
 
1016
    glVertex2i (w + 1, 1);
 
1017
    glVertex2i (w + 1, -1);
 
1018
    glVertex2i (-1, h - 1);
 
1019
    glVertex2i (-1, h + 1);
 
1020
    glVertex2i (w + 1, h + 1);
 
1021
    glVertex2i (w + 1, h - 1);
 
1022
    glVertex2i (-1, 1);
 
1023
    glVertex2i (-1, h - 1);
 
1024
    glVertex2i (1, h - 1);
 
1025
    glVertex2i (1, 1);
 
1026
    glVertex2i (w - 1, 1);
 
1027
    glVertex2i (w - 1, h - 1);
 
1028
    glVertex2i (w + 1, h - 1);
 
1029
    glVertex2i (w + 1, 1);
 
1030
    glEnd ();
 
1031
 
 
1032
    glPopMatrix ();
 
1033
    glColor4usv (defaultColor);
 
1034
    glDisable (GL_BLEND);
 
1035
}
 
1036
 
 
1037
bool
 
1038
StaticSwitchWindow::isSwitchWin (bool removing)
 
1039
{
 
1040
    bool baseIsSwitchWin = BaseSwitchWindow::isSwitchWin (removing);
 
1041
 
 
1042
    if (baseIsSwitchWin && sScreen->selection == Group)
 
1043
    {
 
1044
        if (sScreen->clientLeader != window->clientLeader () &&
 
1045
            sScreen->clientLeader != window->id ())
 
1046
            return false;
 
1047
    }
 
1048
 
 
1049
    return baseIsSwitchWin;
 
1050
}
 
1051
 
 
1052
void
 
1053
StaticSwitchWindow::updateIconTexturedWindow (GLWindowPaintAttrib  &sAttrib,
 
1054
                                              int                  &wx,
 
1055
                                              int                  &wy,
 
1056
                                              int                  x,
 
1057
                                              int                  y,
 
1058
                                              GLTexture            *icon)
 
1059
{
 
1060
    float xScale, yScale;
 
1061
 
 
1062
    xScale = (float) ICON_SIZE / icon->width ();
 
1063
    yScale = (float) ICON_SIZE / icon->height ();
 
1064
 
 
1065
    if (xScale < yScale)
 
1066
        yScale = xScale;
 
1067
    else
 
1068
        xScale = yScale;
 
1069
 
 
1070
    sAttrib.xScale = (float) sScreen->previewWidth * xScale / PREVIEWSIZE;
 
1071
    sAttrib.yScale = (float) sScreen->previewWidth * yScale / PREVIEWSIZE;
 
1072
 
 
1073
    wx = x + sScreen->previewWidth - (sAttrib.xScale * icon->width ());
 
1074
    wy = y + sScreen->previewHeight - (sAttrib.yScale * icon->height ());
 
1075
}
 
1076
 
 
1077
void
 
1078
StaticSwitchWindow::updateIconNontexturedWindow (GLWindowPaintAttrib  &sAttrib,
 
1079
                                                 int                  &wx,
 
1080
                                                 int                  &wy,
 
1081
                                                 float                &width,
 
1082
                                                 float                &height,
 
1083
                                                 int                  x,
 
1084
                                                 int                  y,
 
1085
                                                 GLTexture            *icon)
 
1086
{
 
1087
    sAttrib.xScale = width / icon->width ();
 
1088
    sAttrib.yScale = height / icon->height ();
 
1089
 
 
1090
    if (sAttrib.xScale < sAttrib.yScale)
 
1091
        sAttrib.yScale = sAttrib.xScale;
 
1092
    else
 
1093
        sAttrib.xScale = sAttrib.yScale;
 
1094
 
 
1095
    width  = icon->width ()  * sAttrib.xScale;
 
1096
    height = icon->height () * sAttrib.yScale;
 
1097
 
 
1098
    wx = x + (sScreen->previewWidth / 2) - (width / 2);
 
1099
    wy = y + (sScreen->previewHeight / 2) - (height / 2);
 
1100
}
 
1101
 
 
1102
void
 
1103
StaticSwitchWindow::updateIconPos (int   &wx,
 
1104
                                   int   &wy,
 
1105
                                   int   x,
 
1106
                                   int   y,
 
1107
                                   float width,
 
1108
                                   float height)
 
1109
{
 
1110
    wx = x + (sScreen->previewWidth / 2) - (width / 2);
 
1111
    wy = y + (sScreen->previewHeight / 2) - (height / 2);
 
1112
}
 
1113
 
 
1114
void
 
1115
StaticSwitchWindow::paintThumb (const GLWindowPaintAttrib &attrib,
 
1116
                          const GLMatrix            &transform,
 
1117
                          unsigned int              mask,
 
1118
                          int                       x,
 
1119
                          int                       y)
 
1120
{
 
1121
    BaseSwitchWindow::paintThumb (attrib,
 
1122
                                  transform,
 
1123
                                  mask,
 
1124
                                  x,
 
1125
                                  y,
 
1126
                                  sScreen->previewWidth,
 
1127
                                  sScreen->previewHeight,
 
1128
                                  sScreen->previewWidth * 3 / 4,
 
1129
                                  sScreen->previewHeight * 3 / 4);
 
1130
}
 
1131
 
 
1132
bool
 
1133
StaticSwitchWindow::glPaint (const GLWindowPaintAttrib &attrib,
 
1134
                             const GLMatrix            &transform,
 
1135
                             const CompRegion          &region,
 
1136
                             unsigned int              mask)
 
1137
{
 
1138
    bool       status;
 
1139
 
 
1140
    /* We are painting the switcher popup window:
 
1141
     * Paint the popup window first and then paint
 
1142
     * the relevant thumbnails */
 
1143
    if (window->id () == sScreen->popupWindow)
 
1144
    {
 
1145
        int            x, y, offX;
 
1146
        float          px, py, pos;
 
1147
        int            count = sScreen->windows.size ();
 
1148
 
 
1149
        CompWindow::Geometry &g = window->geometry ();
 
1150
 
 
1151
        if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK ||
 
1152
            sScreen->ignoreSwitcher)
 
1153
            return false;
 
1154
 
 
1155
        status = gWindow->glPaint (attrib, transform, region, mask);
 
1156
 
 
1157
        if (!(mask & PAINT_WINDOW_TRANSFORMED_MASK) && region.isEmpty ())
 
1158
            return true;
 
1159
 
 
1160
        glPushAttrib (GL_SCISSOR_BIT);
 
1161
 
 
1162
        glEnable (GL_SCISSOR_TEST);
 
1163
        glScissor (g.x (), 0, g.width (), ::screen->height ());
 
1164
 
 
1165
        unsigned int i = 0;
 
1166
        foreach (CompWindow *w, sScreen->windows)
 
1167
        {
 
1168
            sScreen->getWindowPosition (i, &x, &y);
 
1169
            StaticSwitchWindow::get (w)->paintThumb (
 
1170
               gWindow->lastPaintAttrib (), transform,
 
1171
               mask, x + g.x (), y + g.y ());
 
1172
            i++;
 
1173
        }
 
1174
 
 
1175
        pos = fmod (sScreen->pos, count);
 
1176
        px  = fmod (pos, sScreen->xCount);
 
1177
        py  = floor (pos / sScreen->xCount);
 
1178
 
 
1179
        offX = sScreen->getRowXOffset (py);
 
1180
 
 
1181
        if (pos > count - 1)
 
1182
        {
 
1183
            px = fmod (pos - count, sScreen->xCount);
 
1184
            sScreen->paintSelectionRect (g.x (), g.y (), px, 0.0,
 
1185
                                         gWindow->lastPaintAttrib ().opacity);
 
1186
 
 
1187
            px = fmod (pos, sScreen->xCount);
 
1188
            sScreen->paintSelectionRect (g.x () + offX, g.y (),
 
1189
                                         px, py,
 
1190
                                         gWindow->lastPaintAttrib ().opacity);
 
1191
        }
 
1192
        if (px > sScreen->xCount - 1)
 
1193
        {
 
1194
            sScreen->paintSelectionRect (g.x (), g.y (), px, py,
 
1195
                                         gWindow->lastPaintAttrib ().opacity);
 
1196
 
 
1197
            py = fmod (py + 1, ceil ((double) count / sScreen->xCount));
 
1198
            offX = sScreen->getRowXOffset (py);
 
1199
 
 
1200
            sScreen->paintSelectionRect (g.x () + offX, g.y (),
 
1201
                                         px - sScreen->xCount, py,
 
1202
                                         gWindow->lastPaintAttrib ().opacity);
 
1203
        }
 
1204
        else
 
1205
        {
 
1206
            sScreen->paintSelectionRect (g.x () + offX, g.y (),
 
1207
                                         px, py,
 
1208
                                         gWindow->lastPaintAttrib ().opacity);
 
1209
        }
 
1210
        glDisable (GL_SCISSOR_TEST);
 
1211
        glPopAttrib ();
 
1212
    }
 
1213
    /* Adjust opacity/brightness/saturation of windows that are
 
1214
     * not selected
 
1215
     */
 
1216
    else if (sScreen->switching && !sScreen->popupDelayTimer.active () &&
 
1217
             (window != sScreen->selectedWindow))
 
1218
    {
 
1219
        GLWindowPaintAttrib sAttrib (attrib);
 
1220
        GLuint              value;
 
1221
 
 
1222
        value = (GLuint) sScreen->optionGetSaturation ();
 
1223
        if (value != 100)
 
1224
            sAttrib.saturation = sAttrib.saturation * value / 100;
 
1225
 
 
1226
        value = (GLuint) sScreen->optionGetBrightness ();
 
1227
        if (value != 100)
 
1228
            sAttrib.brightness = sAttrib.brightness * value / 100;
 
1229
 
 
1230
        if (window->wmType () & (unsigned)~(CompWindowTypeDockMask |
 
1231
                                            CompWindowTypeDesktopMask))
 
1232
        {
 
1233
            value = (GLuint) sScreen->optionGetOpacity ();
 
1234
            if (value != 100)
 
1235
                sAttrib.opacity = sAttrib.opacity * value / 100;
 
1236
        }
 
1237
 
 
1238
        status = gWindow->glPaint (sAttrib, transform, region, mask);
 
1239
    }
 
1240
    /* Fallback case for selected window */
 
1241
    else
 
1242
    {
 
1243
        status = gWindow->glPaint (attrib, transform, region, mask);
 
1244
    }
 
1245
 
 
1246
    return status;
 
1247
}
 
1248
 
 
1249
StaticSwitchScreen::StaticSwitchScreen (CompScreen *screen) :
 
1250
    BaseSwitchScreen (screen),
 
1251
    PluginClassHandler<StaticSwitchScreen,CompScreen> (screen),
 
1252
    clientLeader (None),
 
1253
    switching (false),
 
1254
    mVelocity (0.0),
 
1255
    pos (0),
 
1256
    move (0),
 
1257
    mouseSelect (false)
 
1258
{
 
1259
#define SWITCHBIND(a,b,c) boost::bind (switchInitiateCommon, _1, _2, _3, a, b, c)
 
1260
 
 
1261
    optionSetNextButtonInitiate (SWITCHBIND (CurrentViewport, true, true));
 
1262
    optionSetNextButtonTerminate (switchTerminate);
 
1263
    optionSetNextKeyInitiate (SWITCHBIND (CurrentViewport, true, true));
 
1264
    optionSetNextKeyTerminate (switchTerminate);
 
1265
    optionSetPrevButtonInitiate (SWITCHBIND (CurrentViewport, true, false));
 
1266
    optionSetPrevButtonTerminate (switchTerminate);
 
1267
    optionSetPrevKeyInitiate (SWITCHBIND (CurrentViewport, true, false));
 
1268
    optionSetPrevKeyTerminate (switchTerminate);
 
1269
 
 
1270
    optionSetNextAllButtonInitiate (SWITCHBIND (AllViewports, true, true));
 
1271
    optionSetNextAllButtonTerminate (switchTerminate);
 
1272
    optionSetNextAllKeyInitiate (SWITCHBIND (AllViewports, true, true));
 
1273
    optionSetNextAllKeyTerminate (switchTerminate);
 
1274
    optionSetPrevAllButtonInitiate (SWITCHBIND (AllViewports, true, false));
 
1275
    optionSetPrevAllButtonTerminate (switchTerminate);
 
1276
    optionSetPrevAllKeyInitiate (SWITCHBIND (AllViewports, true, false));
 
1277
    optionSetPrevAllKeyTerminate (switchTerminate);
 
1278
 
 
1279
    optionSetNextGroupButtonInitiate (SWITCHBIND (Group, true, true));
 
1280
    optionSetNextGroupButtonTerminate (switchTerminate);
 
1281
    optionSetNextGroupKeyInitiate (SWITCHBIND (Group, true, true));
 
1282
    optionSetNextGroupKeyTerminate (switchTerminate);
 
1283
    optionSetPrevGroupButtonInitiate (SWITCHBIND (Group, true, false));
 
1284
    optionSetPrevGroupButtonTerminate (switchTerminate);
 
1285
    optionSetPrevGroupKeyInitiate (SWITCHBIND (Group, true, false));
 
1286
    optionSetPrevGroupKeyTerminate (switchTerminate);
 
1287
 
 
1288
    optionSetNextNoPopupButtonInitiate (SWITCHBIND (CurrentViewport, false, true));
 
1289
    optionSetNextNoPopupButtonTerminate (switchTerminate);
 
1290
    optionSetNextNoPopupKeyInitiate (SWITCHBIND (CurrentViewport, false, true));
 
1291
    optionSetNextNoPopupKeyTerminate (switchTerminate);
 
1292
    optionSetPrevNoPopupButtonInitiate (SWITCHBIND (CurrentViewport, false, false));
 
1293
    optionSetPrevNoPopupButtonTerminate (switchTerminate);
 
1294
    optionSetPrevNoPopupKeyInitiate (SWITCHBIND (CurrentViewport, false, false));
 
1295
    optionSetPrevNoPopupKeyTerminate (switchTerminate);
 
1296
 
 
1297
    optionSetNextPanelButtonInitiate (SWITCHBIND (Panels, false, true));
 
1298
    optionSetNextPanelButtonTerminate (switchTerminate);
 
1299
    optionSetNextPanelKeyInitiate (SWITCHBIND (Panels, false, true));
 
1300
    optionSetNextPanelKeyTerminate (switchTerminate);
 
1301
    optionSetPrevPanelButtonInitiate (SWITCHBIND (Panels, false, false));
 
1302
    optionSetPrevPanelButtonTerminate (switchTerminate);
 
1303
    optionSetPrevPanelKeyInitiate (SWITCHBIND (Panels, false, false));
 
1304
    optionSetPrevPanelKeyTerminate (switchTerminate);
 
1305
 
 
1306
#undef SWITCHBIND
 
1307
 
 
1308
    ScreenInterface::setHandler (screen, false);
 
1309
    CompositeScreenInterface::setHandler (cScreen, false);
 
1310
    GLScreenInterface::setHandler (gScreen, false);
 
1311
}
 
1312
 
 
1313
 
 
1314
StaticSwitchScreen::~StaticSwitchScreen ()
 
1315
{
 
1316
    if (popupDelayTimer.active ())
 
1317
        popupDelayTimer.stop ();
 
1318
 
 
1319
    if (popupWindow)
 
1320
        XDestroyWindow (::screen->dpy (), popupWindow);
 
1321
}
 
1322
 
 
1323
StaticSwitchWindow::StaticSwitchWindow (CompWindow *window) :
 
1324
    BaseSwitchWindow (dynamic_cast<BaseSwitchScreen *>
 
1325
                      (StaticSwitchScreen::get (screen)), window),
 
1326
    PluginClassHandler<StaticSwitchWindow,CompWindow> (window),
 
1327
    sScreen (StaticSwitchScreen::get (screen))
 
1328
{
 
1329
    GLWindowInterface::setHandler (gWindow, false);
 
1330
    CompositeWindowInterface::setHandler (cWindow, false);
 
1331
 
 
1332
    if (sScreen->popupWindow && sScreen->popupWindow == window->id ())
 
1333
        gWindow->glPaintSetEnabled (this, true);
 
1334
}
 
1335
 
 
1336
bool
 
1337
StaticSwitchPluginVTable::init ()
 
1338
{
 
1339
    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
 
1340
        !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
 
1341
        !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI) ||
 
1342
        !CompPlugin::checkPluginABI ("compiztoolbox", COMPIZ_COMPIZTOOLBOX_ABI))
 
1343
         return false;
 
1344
 
 
1345
    return true;
 
1346
}
 
1347