2
* winrules plugin for compiz
4
* Copyright (C) 2007 Bellegarde Cedric (gnumdk (at) gmail.com)
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the
17
* Free Software Foundation, Inc.,
18
* 51 Franklin Street, Fifth Floor,
19
* Boston, MA 02110-1301, USA.
24
COMPIZ_PLUGIN_20090315 (winrules, WinrulesPluginVTable);
27
WinrulesScreen::setProtocols (unsigned int protocols,
33
if (protocols & CompWindowProtocolDeleteMask)
34
protocol[count++] = Atoms::wmDeleteWindow;
35
if (protocols & CompWindowProtocolTakeFocusMask)
36
protocol[count++] = Atoms::wmTakeFocus;
37
if (protocols & CompWindowProtocolPingMask)
38
protocol[count++] = Atoms::wmPing;
39
if (protocols & CompWindowProtocolSyncRequestMask)
40
protocol[count++] = Atoms::wmSyncRequest;
42
XSetWMProtocols (screen->dpy (), id, protocol, count);
48
if (window->overrideRedirect ())
51
if (window->wmType () & CompWindowTypeDesktopMask)
58
WinrulesWindow::isFocussable ()
60
window->isFocussable ();
62
return false; // We only want to return false else where we are not wrapped
66
WinrulesWindow::focus ()
70
return false; // We only want to return false for the window we are wrapped
74
WinrulesWindow::alpha ()
78
return false; // We only want to return false else where we are not wrapped
82
WinrulesWindow::setNoFocus (int optNum)
84
unsigned int newProtocol = window->protocols ();
86
WINRULES_SCREEN (screen);
91
if (ws->getOptions ().at (optNum). value ().match ().evaluate (window))
93
if (window->protocols () & CompWindowProtocolTakeFocusMask)
95
protocolSetMask |= (window->protocols () &
96
CompWindowProtocolTakeFocusMask);
97
newProtocol = window->protocols () & ~CompWindowProtocolTakeFocusMask;
99
window->isFocussableSetEnabled (this, true);// causes w->isFocussable ()
101
window->focusSetEnabled (this, true); // causes w->focus () to return
102
// false for this window
104
else if ((protocolSetMask & CompWindowProtocolTakeFocusMask))
106
newProtocol = window->protocols () |
107
(protocolSetMask & CompWindowProtocolTakeFocusMask);
108
protocolSetMask &= ~CompWindowProtocolTakeFocusMask;
109
window->isFocussableSetEnabled (this, false);
110
window->focusSetEnabled (this, false);
113
if (newProtocol != window->protocols ())
115
ws->setProtocols (newProtocol, window->id ());
120
WinrulesWindow::setNoAlpha (int optNum)
122
WINRULES_SCREEN (screen);
127
if (ws->getOptions ().at (optNum). value ().match ().evaluate (window))
129
window->alphaSetEnabled (this, true); // Causes w->alpha () to return
134
window->alphaSetEnabled (this, false);
139
WinrulesWindow::updateState (int optNum,
142
unsigned int newState = window->state ();
144
WINRULES_SCREEN (screen);
149
if (ws->getOptions ().at (optNum). value ().match ().evaluate (window))
152
newState = window->constrainWindowState (newState, window->actions ());
153
stateSetMask |= (newState & mask);
155
else if (stateSetMask & mask)
158
stateSetMask &= ~mask;
161
if (newState != window->state ())
163
window->changeState (newState);
165
if (mask & (CompWindowStateFullscreenMask |
166
CompWindowStateAboveMask |
167
CompWindowStateBelowMask ))
168
window->updateAttributes (CompStackingUpdateModeNormal);
170
window->updateAttributes (CompStackingUpdateModeNone);
175
WinrulesWindow::setAllowedActions (int optNum,
178
WINRULES_SCREEN (screen);
183
if (ws->getOptions ().at (optNum). value ().match ().evaluate (window))
184
allowedActions &= ~action;
185
else if (!(allowedActions & action))
186
allowedActions |= action;
188
window->recalcActions ();
192
WinrulesWindow::matchSizeValue (CompOption::Value::Vector matches,
193
CompOption::Value::Vector widthValues,
194
CompOption::Value::Vector heightValues,
203
if (window->type () & CompWindowTypeDesktopMask)
206
min = MIN (matches.size (), widthValues.size ());
207
min = MIN ((unsigned int) min, heightValues.size ());
208
min = MIN ((unsigned int) min, matches.size ());
210
for (int i = 0; i < min; i++)
212
if ((matches.at (i).match ().evaluate (window)))
214
*width = widthValues.at (i).i ();
215
*height = heightValues.at (i).i ();
225
WinrulesWindow::matchSize (int *width,
228
WINRULES_SCREEN (screen);
230
return matchSizeValue (ws->optionGetSizeMatches (),
231
ws->optionGetSizeWidthValues (),
232
ws->optionGetSizeHeightValues (),
237
WinrulesWindow::updateWindowSize (int width,
241
unsigned int xwcm = 0;
243
if (width != window->serverWidth ())
245
if (height != window->serverHeight ())
251
if (window->mapNum () && xwcm)
252
window->sendSyncRequest ();
254
window->configureXWindow (xwcm, &xwc);
258
WinrulesScreen::optionChanged (CompOption *option,
259
WinrulesOptions::Options num)
262
unsigned int updateStateMask = 0, updateActionsMask = 0;
266
case WinrulesOptions::SkiptaskbarMatch:
267
updateStateMask = CompWindowStateSkipTaskbarMask;
269
case WinrulesOptions::SkippagerMatch:
270
updateStateMask = CompWindowStateSkipPagerMask;
272
case WinrulesOptions::AboveMatch:
273
updateStateMask = CompWindowStateAboveMask;
275
case WinrulesOptions::BelowMatch:
276
updateStateMask = CompWindowStateBelowMask;
278
case WinrulesOptions::StickyMatch:
279
updateStateMask = CompWindowStateStickyMask;
281
case WinrulesOptions::FullscreenMatch:
282
updateStateMask = CompWindowStateFullscreenMask;
284
case WinrulesOptions::MaximizeMatch:
285
updateStateMask = CompWindowStateMaximizedHorzMask |
286
CompWindowStateMaximizedVertMask;
288
case WinrulesOptions::NoMoveMatch:
289
updateActionsMask = CompWindowActionMoveMask;
291
case WinrulesOptions::NoResizeMatch:
292
updateActionsMask = CompWindowActionResizeMask;
294
case WinrulesOptions::NoMinimizeMatch:
295
updateActionsMask = CompWindowActionMinimizeMask;
297
case WinrulesOptions::NoMaximizeMatch:
298
updateActionsMask = CompWindowActionMaximizeVertMask |
299
CompWindowActionMaximizeHorzMask;
301
case WinrulesOptions::NoCloseMatch:
302
updateActionsMask = CompWindowActionCloseMask;
304
case WinrulesOptions::NoArgbMatch:
305
foreach (CompWindow *w, screen->windows ())
308
ww->setNoAlpha (num);
313
case WinrulesOptions::SizeMatches:
314
foreach (CompOption::Value &v, option->value ().list ())
316
CompMatch &m = v.match ();
328
/* We traverse a copy of the list here because windows can be unhooked
329
* on state change rather than the delayed unhook that happens in <0.8.x
332
CompWindowList windows = screen->windows ();
334
foreach (CompWindow *w, windows)
337
ww->updateState (num, updateStateMask);
343
if (updateActionsMask)
345
foreach (CompWindow *w, screen->windows ())
348
ww->setAllowedActions (num, updateActionsMask);
359
WinrulesWindow::applyRules ()
363
updateState (WinrulesOptions::SkiptaskbarMatch,
364
CompWindowStateSkipTaskbarMask);
366
updateState (WinrulesOptions::SkippagerMatch,
367
CompWindowStateSkipPagerMask);
369
updateState (WinrulesOptions::AboveMatch,
370
CompWindowStateAboveMask);
372
updateState (WinrulesOptions::BelowMatch,
373
CompWindowStateBelowMask);
375
updateState (WinrulesOptions::StickyMatch,
376
CompWindowStateStickyMask);
378
updateState (WinrulesOptions::FullscreenMatch,
379
CompWindowStateFullscreenMask);
381
updateState (WinrulesOptions::MaximizeMatch,
382
CompWindowStateMaximizedHorzMask |
383
CompWindowStateMaximizedVertMask);
385
setAllowedActions (WinrulesOptions::NoMoveMatch,
386
CompWindowActionMoveMask);
388
setAllowedActions (WinrulesOptions::NoResizeMatch,
389
CompWindowActionResizeMask);
391
setAllowedActions (WinrulesOptions::NoMinimizeMatch,
392
CompWindowActionMinimizeMask);
394
setAllowedActions (WinrulesOptions::NoMaximizeMatch,
395
CompWindowActionMaximizeVertMask |
396
CompWindowActionMaximizeHorzMask);
398
setAllowedActions (WinrulesOptions::NoCloseMatch,
399
CompWindowActionCloseMask);
401
setNoAlpha (WinrulesOptions::NoArgbMatch);
403
if (matchSize (&width, &height))
404
updateWindowSize (width, height);
411
WinrulesScreen::handleEvent (XEvent *event)
413
if (event->type == MapRequest)
415
CompWindow *w = screen->findWindow (event->xmap.window);
419
ww->setNoFocus (WinrulesOptions::NoFocusMatch);
424
screen->handleEvent (event);
429
WinrulesWindow::getAllowedActions (unsigned int &setActions,
430
unsigned int &clearActions)
432
window->getAllowedActions (setActions, clearActions);
434
clearActions |= ~allowedActions;
438
WinrulesScreen::matchExpHandlerChanged ()
440
screen->matchExpHandlerChanged ();
442
/* match options are up to date after the call to matchExpHandlerChanged */
443
foreach (CompWindow *w, screen->windows ())
451
WinrulesScreen::matchPropertyChanged (CompWindow *w)
455
/* Re-apply rules on match property change */
458
screen->matchPropertyChanged (w);
461
WinrulesScreen::WinrulesScreen (CompScreen *screen) :
462
PluginClassHandler <WinrulesScreen, CompScreen> (screen)
464
ScreenInterface::setHandler (screen);
466
optionSetSkiptaskbarMatchNotify (boost::bind
467
(&WinrulesScreen::optionChanged, this,
470
optionSetSkippagerMatchNotify (boost::bind
471
(&WinrulesScreen::optionChanged, this,
474
optionSetAboveMatchNotify (boost::bind
475
(&WinrulesScreen::optionChanged, this,
478
optionSetBelowMatchNotify (boost::bind
479
(&WinrulesScreen::optionChanged, this,
482
optionSetFullscreenMatchNotify (boost::bind
483
(&WinrulesScreen::optionChanged, this,
486
optionSetStickyMatchNotify (boost::bind
487
(&WinrulesScreen::optionChanged, this,
490
optionSetMaximizeMatchNotify (boost::bind
491
(&WinrulesScreen::optionChanged, this,
494
optionSetNoArgbMatchNotify (boost::bind
495
(&WinrulesScreen::optionChanged, this,
498
optionSetNoMoveMatchNotify (boost::bind
499
(&WinrulesScreen::optionChanged, this,
502
optionSetNoResizeMatchNotify (boost::bind
503
(&WinrulesScreen::optionChanged, this,
506
optionSetNoMinimizeMatchNotify (boost::bind
507
(&WinrulesScreen::optionChanged, this,
510
optionSetNoMaximizeMatchNotify (boost::bind
511
(&WinrulesScreen::optionChanged, this,
514
optionSetNoCloseMatchNotify (boost::bind
515
(&WinrulesScreen::optionChanged, this,
518
optionSetNoFocusMatchNotify (boost::bind
519
(&WinrulesScreen::optionChanged, this,
524
WinrulesWindow::WinrulesWindow (CompWindow *window) :
525
PluginClassHandler <WinrulesWindow, CompWindow> (window),
533
WindowInterface::setHandler (window);
535
window->isFocussableSetEnabled (this, false);
536
window->alphaSetEnabled (this, false);
537
window->focusSetEnabled (this, false);
539
timer.setCallback (boost::bind(&WinrulesWindow::applyRules, this));
540
timer.setTimes (0, 0);
547
WinrulesPluginVTable::init ()
549
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))