2
* Copyright (C) 2007 Andrew Riedi <andrewriedi@gmail.com>
4
* Sticky window handling and OpenGL fixes:
5
* Copyright (c) 2007 Dennis Kasprzyk <onestone@opencompositing.org>
7
* Ported to Compiz 0.9:
8
* Copyright (c) 2008 Sam Spilsbury <smspillaz@gmail.com>
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
* This plug-in for Metacity-like workarounds.
27
#include "workarounds.h"
31
COMPIZ_PLUGIN_20090315 (workarounds, WorkaroundsPluginVTable);
34
* WorkaroundsWindow::clearInputShape
38
WorkaroundsWindow::clearInputShape (HideInfo *hideInfo)
41
int count = 0, ordering;
42
Window xid = hideInfo->shapeWindow;
44
rects = XShapeGetRectangles (screen->dpy (), xid, ShapeInput,
50
/* check if the returned shape exactly matches the window shape -
51
* if that is true, the window currently has no set input shape */
53
(rects[0].x == -window->serverGeometry ().border ()) &&
54
(rects[0].y == -window->serverGeometry ().border ()) &&
55
(rects[0].width == (window->serverGeometry ().width () +
56
window->serverGeometry ().border ())) &&
57
(rects[0].height == (window->serverGeometry ().height () +
58
window->serverGeometry ().border ())))
63
if (hideInfo->inputRects)
64
XFree (hideInfo->inputRects);
66
hideInfo->inputRects = rects;
67
hideInfo->nInputRects = count;
68
hideInfo->inputRectOrdering = ordering;
70
XShapeSelectInput (screen->dpy (), xid, NoEventMask);
72
XShapeCombineRectangles (screen->dpy (), xid, ShapeInput, 0, 0,
73
NULL, 0, ShapeSet, 0);
75
XShapeSelectInput (screen->dpy (), xid, ShapeNotify);
79
* GroupWindow::restoreInputShape
83
WorkaroundsWindow::restoreInputShape (HideInfo *info)
85
Window xid = info->shapeWindow;
87
if (info->nInputRects)
89
XShapeCombineRectangles (screen->dpy (), xid, ShapeInput, 0, 0,
90
info->inputRects, info->nInputRects,
91
ShapeSet, info->inputRectOrdering);
95
XShapeCombineMask (screen->dpy (), xid, ShapeInput,
96
0, 0, None, ShapeSet);
100
XFree (info->inputRects);
102
XShapeSelectInput (screen->dpy (), xid, info->shapeMask);
105
* groupSetWindowVisibility
109
WorkaroundsWindow::setVisibility (bool visible)
111
if (!visible && !windowHideInfo)
115
windowHideInfo = info = new HideInfo ();
119
info->inputRects = NULL;
120
info->nInputRects = 0;
121
info->shapeMask = XShapeInputSelected (screen->dpy (), window->id ());
123
/* We are a reparenting window manager now, which means that we either
124
* shape the frame window, or if it does not exist, shape the window **/
126
if (window->frame ())
127
info->shapeWindow = window->frame ();
129
info->shapeWindow = window->id ();
131
clearInputShape (info);
133
info->skipState = window->state () & (CompWindowStateSkipPagerMask |
134
CompWindowStateSkipTaskbarMask);
136
else if (visible && windowHideInfo)
138
HideInfo *info = windowHideInfo;
140
restoreInputShape (info);
142
XShapeSelectInput (screen->dpy (), window->id (), info->shapeMask);
144
windowHideInfo = NULL;
147
cWindow->addDamage ();
148
gWindow->glPaintSetEnabled (this, !visible);
152
WorkaroundsWindow::isGroupTransient (Window clientLeader)
157
if (window->transientFor () == None || window->transientFor () == screen->root ())
159
if (window->type () & (CompWindowTypeUtilMask |
160
CompWindowTypeToolbarMask |
161
CompWindowTypeMenuMask |
162
CompWindowTypeDialogMask |
163
CompWindowTypeModalDialogMask))
165
if (window->clientLeader () == clientLeader)
175
WorkaroundsWindow::minimize ()
177
if (!window->managed ())
182
WORKAROUNDS_SCREEN (screen);
184
unsigned long data[2];
185
int state = IconicState;
186
CompOption::Vector propTemplate = ws->inputDisabledAtom.getReadTemplate ();
187
CompOption::Value enabled = CompOption::Value (true);
189
screen->handleCompizEventSetEnabled (ws, true);
191
window->windowNotify (CompWindowNotifyMinimize);
192
window->changeState (window->state () | CompWindowStateHiddenMask);
194
foreach (CompWindow *w, screen->windows ())
196
if (w->transientFor () == window->id () ||
197
WorkaroundsWindow::get (w)->isGroupTransient (window->clientLeader ()))
201
window->windowNotify (CompWindowNotifyHide);
203
setVisibility (false);
210
XChangeProperty (screen->dpy (), window->id (),
211
Atoms::wmState, Atoms::wmState,
212
32, PropModeReplace, (unsigned char *) data, 2);
214
propTemplate.at (0).set (enabled);
215
ws->inputDisabledAtom.updateProperty (window->id (),
225
WorkaroundsWindow::unminimize ()
229
WORKAROUNDS_SCREEN (screen);
231
unsigned long data[2];
232
int state = NormalState;
233
CompOption::Vector propTemplate = ws->inputDisabledAtom.getReadTemplate ();
234
CompOption::Value enabled = CompOption::Value (false);
236
window->windowNotify (CompWindowNotifyUnminimize);
237
window->changeState (window->state () & ~CompWindowStateHiddenMask);
241
window->windowNotify (CompWindowNotifyShow);
243
setVisibility (true);
245
if (!ws->skipTransients)
247
foreach (CompWindow *w, screen->windows ())
249
if (w->transientFor () == window->id () ||
250
WorkaroundsWindow::get (w)->isGroupTransient (window->clientLeader ()))
260
XChangeProperty (screen->dpy (), window->id (),
261
Atoms::wmState, Atoms::wmState,
262
32, PropModeReplace, (unsigned char *) data, 2);
264
propTemplate.at (0).set (enabled);
265
ws->inputDisabledAtom.updateProperty (window->id (),
272
WorkaroundsWindow::minimized ()
278
WorkaroundsWindow::glPaint (const GLWindowPaintAttrib &attrib,
279
const GLMatrix &transform,
280
const CompRegion ®ion,
285
WORKAROUNDS_SCREEN (screen);
288
foreach (CompWindow *w, ws->minimizingWindows)
290
if (w->id () == window->id ())
296
mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
299
return gWindow->glPaint (attrib, transform, region, mask);
303
WorkaroundsScreen::checkFunctions (bool checkWindow, bool checkScreen)
305
if (haveOpenGL && optionGetForceGlxSync () && checkScreen)
307
gScreen->glPaintOutputSetEnabled (this, true);
309
else if (haveOpenGL && checkScreen)
311
gScreen->glPaintOutputSetEnabled (this, false);
314
if (haveOpenGL && optionGetForceSwapBuffers () && checkScreen)
316
cScreen->preparePaintSetEnabled (this, true);
318
else if (haveOpenGL && checkScreen)
320
cScreen->preparePaintSetEnabled (this, false);
323
if ((optionGetLegacyFullscreen () ||
324
optionGetFirefoxMenuFix () ||
325
optionGetOooMenuFix () ||
326
optionGetNotificationDaemonFix () ||
327
optionGetJavaFix () ||
329
optionGetConvertUrgency () ) && checkScreen)
331
screen->handleEventSetEnabled (this, true);
333
else if (checkScreen)
335
screen->handleEventSetEnabled (this, false);
340
bool legacyFullscreen = optionGetLegacyFullscreen ();
341
bool keepMinimized = optionGetKeepMinimizedWindows ();
343
foreach (CompWindow *w, screen->windows ())
345
WORKAROUNDS_WINDOW (w);
347
bool m = ww->window->minimized ();
349
ww->window->getAllowedActionsSetEnabled (ww, legacyFullscreen);
350
ww->window->resizeNotifySetEnabled (ww, legacyFullscreen);
353
ww->window->unminimize ();
354
ww->window->minimizeSetEnabled (ww, keepMinimized);
355
ww->window->unminimizeSetEnabled (ww, keepMinimized);
356
ww->window->minimizedSetEnabled (ww, keepMinimized);
358
ww->window->minimize ();
365
WorkaroundsScreen::addToFullscreenList (CompWindow *w)
367
mfwList.push_back (w->id ());
371
WorkaroundsScreen::removeFromFullscreenList (CompWindow *w)
373
mfwList.remove (w->id ());
377
workaroundsProgramEnvParameter4f (GLenum target,
384
WorkaroundsScreen *ws;
387
ws = WorkaroundsScreen::get (screen);
394
(*ws->programEnvParameter4dv) (target, index, data);
398
WorkaroundsScreen::updateParameterFix ()
400
if (!GL::programEnvParameter4f || !programEnvParameter4dv)
402
if (optionGetAiglxFragmentFix ())
403
GL::programEnvParameter4f = workaroundsProgramEnvParameter4f;
405
GL::programEnvParameter4f = origProgramEnvParameter4f;
409
WorkaroundsScreen::updateVideoSyncFix ()
411
if ((!GL::getVideoSync || origGetVideoSync) ||
412
(!GL::waitVideoSync || origWaitVideoSync))
414
if (optionGetNoWaitForVideoSync ())
416
GL::getVideoSync = NULL;
417
GL::waitVideoSync = NULL;
421
GL::getVideoSync = origGetVideoSync;
422
GL::waitVideoSync = origWaitVideoSync;
427
WorkaroundsScreen::preparePaint (int ms)
429
if (optionGetForceSwapBuffers ())
430
cScreen->damageScreen (); // Massive CPU usage here
432
cScreen->preparePaint (ms);
436
WorkaroundsScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
437
const GLMatrix &transform,
438
const CompRegion ®ion,
442
if (optionGetForceGlxSync ())
445
return gScreen->glPaintOutput (attrib, transform, region, output, mask);
449
WorkaroundsWindow::getRoleAtom ()
452
unsigned long nItems;
453
unsigned long bytesAfter;
454
unsigned char *str = NULL;
458
WORKAROUNDS_SCREEN (screen);
460
result = XGetWindowProperty (screen->dpy (), window->id (), ws->roleAtom,
461
0, LONG_MAX, FALSE, XA_STRING,
462
&type, &format, &nItems, &bytesAfter,
463
(unsigned char **) &str);
465
if (result != Success)
468
if (type != XA_STRING)
474
retval = CompString ((const char *) str);
480
WorkaroundsWindow::removeSticky ()
482
if (window->state () & CompWindowStateStickyMask && madeSticky)
483
window->changeState (window->state () & ~CompWindowStateStickyMask);
488
WorkaroundsWindow::updateSticky ()
490
Bool makeSticky = FALSE;
492
WORKAROUNDS_SCREEN (screen);
494
if (ws->optionGetStickyAlldesktops () && window->desktop () == 0xffffffff &&
495
ws->optionGetAlldesktopStickyMatch ().evaluate (window))
500
if (!(window->state () & CompWindowStateStickyMask))
503
window->changeState (
504
window->state () | CompWindowStateStickyMask);
512
WorkaroundsWindow::updateUrgencyState ()
517
xwmh = XGetWMHints (screen->dpy (), window->id ());
525
urgent = (xwmh->flags & XUrgencyHint);
531
madeDemandAttention = TRUE;
532
window->changeState (window->state () |
533
CompWindowStateDemandsAttentionMask);
535
else if (madeDemandAttention)
537
madeDemandAttention = FALSE;
538
window->changeState (window->state () &
539
~CompWindowStateDemandsAttentionMask);
543
/* Use this function to forcibly refresh java window properties when they
544
* have been unmarked as transient. This is just a copy of
545
* PrivateScreen::setWindowState. I would use CompWindow::changeState, but
546
* it checks whether oldstate==newstate
549
WorkaroundsScreen::setWindowState (unsigned int state, Window id)
554
if (state & CompWindowStateModalMask)
555
data[i++] = Atoms::winStateModal;
556
if (state & CompWindowStateStickyMask)
557
data[i++] = Atoms::winStateSticky;
558
if (state & CompWindowStateMaximizedVertMask)
559
data[i++] = Atoms::winStateMaximizedVert;
560
if (state & CompWindowStateMaximizedHorzMask)
561
data[i++] = Atoms::winStateMaximizedHorz;
562
if (state & CompWindowStateShadedMask)
563
data[i++] = Atoms::winStateShaded;
564
if (state & CompWindowStateSkipTaskbarMask)
565
data[i++] = Atoms::winStateSkipTaskbar;
566
if (state & CompWindowStateSkipPagerMask)
567
data[i++] = Atoms::winStateSkipPager;
568
if (state & CompWindowStateHiddenMask)
569
data[i++] = Atoms::winStateHidden;
570
if (state & CompWindowStateFullscreenMask)
571
data[i++] = Atoms::winStateFullscreen;
572
if (state & CompWindowStateAboveMask)
573
data[i++] = Atoms::winStateAbove;
574
if (state & CompWindowStateBelowMask)
575
data[i++] = Atoms::winStateBelow;
576
if (state & CompWindowStateDemandsAttentionMask)
577
data[i++] = Atoms::winStateDemandsAttention;
578
if (state & CompWindowStateDisplayModalMask)
579
data[i++] = Atoms::winStateDisplayModal;
581
XChangeProperty (screen->dpy (), id, Atoms::winState,
582
XA_ATOM, 32, PropModeReplace,
583
(unsigned char *) data, i);
587
WorkaroundsWindow::getAllowedActions (unsigned int &setActions,
588
unsigned int &clearActions)
591
window->getAllowedActions (setActions, clearActions);
594
setActions |= CompWindowActionFullscreenMask;
598
WorkaroundsWindow::fixupFullscreen ()
603
WORKAROUNDS_SCREEN (screen);
605
if (!ws->optionGetLegacyFullscreen ())
608
if (window->wmType () & CompWindowTypeDesktopMask)
610
/* desktop windows are implicitly fullscreen */
615
/* get output region for window */
616
int output = screen->outputDeviceForGeometry (window->geometry ());
617
box = &screen->outputDevs ().at (output).region ()->extents;
619
/* does the size match the output rectangle? */
620
isFullSize = (window->serverX () == box->x1) &&
621
(window->serverY () == box->y1) &&
622
(window->serverWidth () == (box->x2 - box->x1)) &&
623
(window->serverHeight () == (box->y2 - box->y1));
625
/* if not, check if it matches the whole screen */
628
if ((window->serverX () == 0) && (window->serverY () == 0) &&
629
(window->serverWidth () == screen->width ()) &&
630
(window->serverHeight () == screen->height ()))
637
isFullscreen = isFullSize;
638
if (isFullSize && !(window->state () & CompWindowStateFullscreenMask))
640
unsigned int state = window->state () &
641
~CompWindowStateFullscreenMask;
644
state |= CompWindowStateFullscreenMask;
645
madeFullscreen = isFullSize;
647
if (state != window->state ())
649
window->changeState (state);
650
window->updateAttributes (CompStackingUpdateModeNormal);
652
/* keep track of windows that we interact with */
653
ws->addToFullscreenList (window);
656
else if (!isFullSize && !ws->mfwList.empty () &&
657
(window->state () & CompWindowStateFullscreenMask))
659
/* did we set the flag? */
661
foreach (Window mfw, ws->mfwList)
663
if (mfw == window->id ())
665
unsigned int state = window->state () &
666
~CompWindowStateFullscreenMask;
669
state |= CompWindowStateFullscreenMask;
671
madeFullscreen = isFullSize;
673
if (state != window->state ())
675
window->changeState (state);
676
window->updateAttributes (CompStackingUpdateModeNormal);
679
ws->removeFromFullscreenList (window);
687
WorkaroundsWindow::updateFixedWindow (unsigned int newWmType)
689
if (newWmType != window->wmType ())
691
adjustedWinType = TRUE;
692
oldWmType = window->wmType ();
694
window->recalcType ();
695
window->recalcActions ();
697
screen->matchPropertyChanged (window);
699
window->wmType () = newWmType;
704
WorkaroundsWindow::getFixedWindowType ()
706
unsigned int newWmType;
707
XClassHint classHint;
710
WORKAROUNDS_SCREEN (screen);
712
newWmType = window->wmType ();
714
if (!XGetClassHint (screen->dpy (), window->id (), &classHint))
717
if (classHint.res_name)
719
resName = CompString (classHint.res_name);
720
XFree (classHint.res_name);
723
if (classHint.res_class)
725
XFree (classHint.res_class);
728
/* FIXME: Is this the best way to detect a notification type window? */
729
if (ws->optionGetNotificationDaemonFix ())
731
if (newWmType == CompWindowTypeNormalMask &&
732
window->overrideRedirect () && !resName.empty () &&
733
resName.compare("notification-daemon") == 0)
735
newWmType = CompWindowTypeNotificationMask;
740
if (ws->optionGetFirefoxMenuFix ())
742
if (newWmType == CompWindowTypeNormalMask &&
743
window->overrideRedirect () && !resName.empty ())
745
if ((resName.compare ( "gecko") == 0) ||
746
(resName.compare ( "popup") == 0))
748
newWmType = CompWindowTypeDropdownMenuMask;
754
if (ws->optionGetOooMenuFix ())
756
if (newWmType == CompWindowTypeNormalMask &&
757
window->overrideRedirect () && !resName.empty ())
759
if (resName.compare ( "VCLSalFrame") == 0)
761
newWmType = CompWindowTypeDropdownMenuMask;
766
/* FIXME: Basic hack to get Java windows working correctly. */
767
if (ws->optionGetJavaFix () && !resName.empty ())
769
if ((resName.compare ( "sun-awt-X11-XMenuWindow") == 0) ||
770
(resName.compare ( "sun-awt-X11-XWindowPeer") == 0))
772
newWmType = CompWindowTypeDropdownMenuMask;
775
else if (resName.compare ( "sun-awt-X11-XDialogPeer") == 0)
777
newWmType = CompWindowTypeDialogMask;
780
else if (resName.compare ( "sun-awt-X11-XFramePeer") == 0)
782
newWmType = CompWindowTypeNormalMask;
787
if (ws->optionGetQtFix ())
789
CompString windowRole;
792
windowRole = getRoleAtom ();
793
if (!windowRole.empty ())
795
if ((windowRole.compare ("toolTipTip") == 0) ||
796
(windowRole.compare ("qtooltip_label") == 0))
798
newWmType = CompWindowTypeTooltipMask;
803
/* fix Qt transients - FIXME: is there a better way to detect them? */
804
if (resName.empty () && window->overrideRedirect () &&
805
(window->windowClass () == InputOutput) &&
806
(newWmType == CompWindowTypeUnknownMask))
808
newWmType = CompWindowTypeDropdownMenuMask;
817
WorkaroundsScreen::optionChanged (CompOption *opt,
818
WorkaroundsOptions::Options num)
820
checkFunctions (true, true);
822
foreach (CompWindow *w, screen->windows ())
823
WorkaroundsWindow::get (w)->updateSticky ();
827
updateParameterFix ();
828
updateVideoSyncFix ();
830
if (optionGetFglrxXglFix ())
831
GL::copySubBuffer = NULL;
833
GL::copySubBuffer = origCopySubBuffer;
836
if (optionGetKeepMinimizedWindows ())
838
foreach (CompWindow *window, screen->windows ())
840
WORKAROUNDS_WINDOW (window);
841
bool m = window->minimized ();
843
window->unminimize ();
844
window->minimizeSetEnabled (ww, true);
845
window->unminimizeSetEnabled (ww, true);
846
window->minimizedSetEnabled (ww, true);
853
foreach (CompWindow *window, screen->windows ())
855
WORKAROUNDS_WINDOW (window);
856
bool m = window->minimized ();
858
window->unminimize ();
859
window->minimizeSetEnabled (ww, false);
860
window->unminimizeSetEnabled (ww, false);
861
window->minimizedSetEnabled (ww, false);
864
ww->isMinimized = false;
872
WorkaroundsScreen::handleCompizEvent (const char *pluginName,
873
const char *eventName,
874
CompOption::Vector &o)
876
if (strncmp (pluginName, "animation", 9) == 0 &&
877
strncmp (eventName, "window_animation", 16) == 0)
879
if (CompOption::getStringOptionNamed (o, "type", "") == "minimize")
881
CompWindow *w = screen->findWindow (CompOption::getIntOptionNamed (
885
if (CompOption::getBoolOptionNamed (o, "active", false))
886
minimizingWindows.push_back (w);
888
minimizingWindows.remove (w);
893
if (!CompOption::getBoolOptionNamed (o, "active", false) &&
894
minimizingWindows.empty ())
895
screen->handleCompizEventSetEnabled (this, false);
897
screen->handleCompizEvent (pluginName, eventName, o);
901
WorkaroundsScreen::handleEvent (XEvent *event)
905
switch (event->type) {
906
case ConfigureRequest:
907
w = screen->findWindow (event->xconfigurerequest.window);
910
WORKAROUNDS_WINDOW (w);
912
if (ww->madeFullscreen)
913
w->changeState (w->state () &= ~CompWindowStateFullscreenMask);
917
w = screen->findWindow (event->xmaprequest.window);
920
WORKAROUNDS_WINDOW (w);
922
ww->updateFixedWindow (ww->getFixedWindowType ());
923
ww->fixupFullscreen ();
927
w = screen->findWindow (event->xmap.window);
928
if (w && w->overrideRedirect ())
930
WORKAROUNDS_WINDOW (w);
931
ww->updateFixedWindow (ww->getFixedWindowType ());
935
w = screen->findWindow (event->xdestroywindow.window);
937
removeFromFullscreenList (w);
941
screen->handleEvent (event);
943
switch (event->type) {
944
case ConfigureRequest:
945
w = screen->findWindow (event->xconfigurerequest.window);
948
WORKAROUNDS_WINDOW (w);
950
if (ww->madeFullscreen)
951
w->state () |= CompWindowStateFullscreenMask;
955
if (event->xclient.message_type == Atoms::winDesktop)
957
w = screen->findWindow (event->xclient.window);
960
WORKAROUNDS_WINDOW (w);
966
if ((event->xproperty.atom == XA_WM_CLASS) ||
967
(event->xproperty.atom == Atoms::winType))
969
w = screen->findWindow (event->xproperty.window);
972
WORKAROUNDS_WINDOW (w);
973
ww->updateFixedWindow (ww->getFixedWindowType ());
976
else if (event->xproperty.atom == XA_WM_HINTS)
978
if (optionGetConvertUrgency ())
980
w = screen->findWindow (event->xproperty.window);
983
WORKAROUNDS_WINDOW (w);
984
ww->updateUrgencyState ();
988
else if (event->xproperty.atom == Atoms::clientList) {
989
if (optionGetJavaTaskbarFix ()) {
990
foreach (CompWindow *w, screen->windows ()) {
992
setWindowState (w->state (), w->id ());
1003
WorkaroundsWindow::resizeNotify (int dx, int dy,
1004
int dwidth, int dheight)
1006
if (window->isViewable ())
1009
window->resizeNotify (dx, dy, dwidth, dheight);
1012
WorkaroundsScreen::WorkaroundsScreen (CompScreen *screen) :
1013
PluginClassHandler <WorkaroundsScreen, CompScreen> (screen),
1014
cScreen (CompositeScreen::get (screen)),
1015
gScreen (GLScreen::get (screen)),
1016
roleAtom (XInternAtom (screen->dpy (), "WM_WINDOW_ROLE", 0)),
1017
skipTransients (false)
1019
CompOption::Vector propTemplate;
1021
ScreenInterface::setHandler (screen, false);
1024
CompositeScreenInterface::setHandler (cScreen, false);
1025
GLScreenInterface::setHandler (gScreen, false);
1028
propTemplate.push_back (CompOption ("enabled", CompOption::TypeBool));
1029
inputDisabledAtom = PropertyWriter ("COMPIZ_NET_WM_INPUT_DISABLED", propTemplate);
1031
optionSetStickyAlldesktopsNotify (boost::bind (
1032
&WorkaroundsScreen::optionChanged, this,
1034
optionSetAlldesktopStickyMatchNotify (boost::bind (
1035
&WorkaroundsScreen::optionChanged, this,
1038
optionSetAiglxFragmentFixNotify (boost::bind (
1039
&WorkaroundsScreen::optionChanged, this,
1042
optionSetFglrxXglFixNotify (boost::bind (
1043
&WorkaroundsScreen::optionChanged, this,
1045
optionSetForceSwapBuffersNotify (boost::bind (
1046
&WorkaroundsScreen::optionChanged, this,
1048
optionSetNoWaitForVideoSyncNotify (boost::bind (
1049
&WorkaroundsScreen::optionChanged, this,
1051
optionSetKeepMinimizedWindowsNotify (boost::bind (
1052
&WorkaroundsScreen::optionChanged, this,
1057
origProgramEnvParameter4f = GL::programEnvParameter4f;
1058
programEnvParameter4dv = (GLProgramParameter4dvProc)
1059
gScreen->getProcAddress ("glProgramEnvParameter4dvARB");
1060
origCopySubBuffer = GL::copySubBuffer;
1062
origGetVideoSync = GL::getVideoSync;
1063
origWaitVideoSync = GL::waitVideoSync;
1065
updateParameterFix ();
1066
updateVideoSyncFix ();
1069
if (optionGetFglrxXglFix () && haveOpenGL)
1070
GL::copySubBuffer = NULL;
1072
checkFunctions (false, true);
1075
WorkaroundsScreen::~WorkaroundsScreen ()
1079
GL::copySubBuffer = origCopySubBuffer;
1080
GL::getVideoSync = origGetVideoSync;
1081
GL::waitVideoSync = origWaitVideoSync;
1085
WorkaroundsWindow::WorkaroundsWindow (CompWindow *window) :
1086
PluginClassHandler <WorkaroundsWindow, CompWindow> (window),
1088
cWindow (CompositeWindow::get (window)),
1089
gWindow (GLWindow::get (window)),
1090
adjustedWinType (false),
1092
madeFullscreen (false),
1093
isFullscreen (false),
1094
madeDemandAttention (false),
1095
isMinimized (window->minimized ()),
1096
oldWmType (window->wmType ()),
1097
windowHideInfo (NULL)
1099
WindowInterface::setHandler (window, false);
1100
GLWindowInterface::setHandler (gWindow, false);
1102
WORKAROUNDS_SCREEN (screen);
1104
if (ws->optionGetLegacyFullscreen ())
1106
window->getAllowedActionsSetEnabled (this, false);
1107
window->resizeNotifySetEnabled (this, false);
1109
if (ws->optionGetKeepMinimizedWindows ())
1111
window->minimizeSetEnabled (this, true);
1112
window->unminimizeSetEnabled (this, true);
1113
window->minimizedSetEnabled (this, true);
1118
WorkaroundsWindow::~WorkaroundsWindow ()
1120
WORKAROUNDS_SCREEN (screen);
1122
/* It is not safe to loop the whole window list at this point
1123
* to _also_ unminimize transient windows because this could
1124
* be the plugin tear-down stage and other WorkaroundWindow
1125
* structures could be destroyed.
1127
* It is ok to skip transients in this case, since it is likely
1128
* that we will be unminimizing every single window as
1129
* WorkaroundsWindow is destroyed (in the case that the window
1130
* itself has been destroyed while the plugin is enabled, this
1131
* is not much of a problem since the transient windows go with
1132
* the destroyed window in this case)
1134
* FIXME: We need a ::fini stage before we do this!
1136
ws->skipTransients = true;
1141
window->minimizeSetEnabled (this, false);
1142
window->unminimizeSetEnabled (this, false);
1143
window->minimizedSetEnabled (this, false);
1144
window->minimize ();
1147
if (!window->destroyed ())
1149
if (adjustedWinType)
1151
window->wmType () = oldWmType;
1152
window->recalcType ();
1153
window->recalcActions ();
1156
if (window->state () & CompWindowStateStickyMask && madeSticky)
1158
window->state () &= ~CompWindowStateStickyMask;
1162
ws->skipTransients = false;
1166
WorkaroundsPluginVTable::init ()
1168
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
1171
if ((CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI)) &&
1172
(CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI)))