6
* Copyright (c) 2006 Kristian LyngstĆøl <kristian@beryl-project.org>
7
* Ported to Compiz and BCOP usage by Danny Baumann <maniac@beryl-project.org>
8
* Ported to Compiz 0.9 by Sam Spilsbury <smspillaz@gmail.com>
10
* This program is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU General Public License
12
* as published by the Free Software Foundation; either version 2
13
* of the License, or (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.
21
* Opacify increases opacity on targeted windows and reduces it on
22
* blocking windows, making whatever window you are targeting easily
29
COMPIZ_PLUGIN_20090315 (opacify, OpacifyPluginVTable);
32
setFunctions (bool enabled)
34
OPACIFY_SCREEN (screen);
36
screen->handleEventSetEnabled (os, enabled);
38
foreach (CompWindow *w, screen->windows ())
42
ow->gWindow->glPaintSetEnabled (ow, enabled);
46
/* Core opacify functions. These do the real work. ---------------------*/
48
/* Sets the real opacity and damages the window if actual opacity and
49
* requested opacity differs. */
52
OpacifyWindow::setOpacity (int fOpacity)
54
if (opacified || (gWindow->paintAttrib ().opacity != opacity))
55
cWindow->addDamage ();
61
/* Resets the Window to the original opacity if it still exists.
65
OpacifyScreen::resetOpacity (Window id)
69
w = screen->findWindow (id);
75
ow->opacified = false;
76
ow->cWindow->addDamage ();
79
/* Resets the opacity of windows on the passive list.
82
OpacifyScreen::clearPassive ()
87
/* Dim an (inactive) window. Place it on the passive list and
88
* update passiveNum. Then change the opacity.
94
OPACIFY_SCREEN (screen);
96
os->passive.push_back (window->id ());
98
setOpacity (MIN (OPAQUE * os->optionGetPassiveOpacity () / 100,
99
gWindow->paintAttrib ().opacity));
102
/* Walk through all windows, skip until we've passed the active
103
* window, skip if it's invisible, hidden or minimized, skip if
104
* it's not a window type we're looking for.
105
* Dim it if it intersects.
107
* Returns number of changed windows.
111
OpacifyScreen::passiveWindows (CompRegion fRegion)
116
/* Clear the list first to prevent memleaks */
117
foreach (Window xid, passive)
119
CompWindow *win = screen->findWindow (xid);
124
OPACIFY_WINDOW (win);
127
ow->setOpacity (MAX (OPAQUE * optionGetActiveOpacity () / 100,
128
ow->gWindow->paintAttrib ().opacity));
132
foreach (CompWindow *w, screen->windows ())
134
if (w->id () == active)
141
if (!optionGetWindowMatch ().evaluate (w))
143
if (!w->isViewable () || w->minimized ())
146
intersect = w->region ().intersected (fRegion);
147
if (!intersect.isEmpty ())
149
OpacifyWindow::get (w)->dim ();
157
/* Check if we switched active window, reset the old passive windows
158
* if we did. If we have an active window and switched: reset that too.
159
* If we have a window (w is true), update the active id and
160
* passive list. justMoved is to make sure we recalculate opacity after
161
* moving. We can't reset before moving because if we're using a delay
162
* and the window being moved is not the active but overlapping, it will
163
* be reset, which would conflict with move's opacity change.
166
OpacifyWindow::handleEnter ()
168
OPACIFY_SCREEN (screen);
170
if (screen->otherGrabExist (NULL))
172
if (!screen->otherGrabExist ("move", NULL))
174
os->justMoved = true;
179
os->resetOpacity (os->active);
184
if (!window || os->active != window->id () || os->justMoved)
186
os->justMoved = false;
187
os->resetOpacity (os->active);
194
if (window->id () != os->active && !window->shaded () &&
195
os->optionGetWindowMatch ().evaluate (window))
199
os->active = window->id ();
200
num = os->passiveWindows (window->region ());
202
if (num || os->optionGetOnlyIfBlock ())
203
setOpacity (MAX (OPAQUE * os->optionGetActiveOpacity () / 100,
204
gWindow->paintAttrib ().opacity));
208
/* Timeout-time! Unset the timeout handler, make sure we're on the same
209
* screen, handle the event.
212
OpacifyScreen::handleTimeout ()
215
OpacifyWindow::get (newActive)->handleEnter ();
220
/* Checks whether we should delay or not.
221
* Returns true if immediate execution.
224
OpacifyScreen::checkDelay ()
226
if (optionGetFocusInstant () && newActive &&
227
(newActive->id () == screen->activeWindow ()))
229
if (!optionGetTimeout ())
231
if (!newActive || (newActive->id () == screen->root ()))
233
if (newActive->type () & (CompWindowTypeDesktopMask |
234
CompWindowTypeDockMask))
238
if (optionGetNoDelayChange () && passive.size ())
245
OpacifyWindow::glPaint (const GLWindowPaintAttrib &attrib,
246
const GLMatrix &transform,
247
const CompRegion ®ion,
252
GLWindowPaintAttrib wAttrib = attrib;
254
wAttrib.opacity = opacity;
256
return gWindow->glPaint (wAttrib, transform, region, mask);
260
return gWindow->glPaint (attrib, transform, region, mask);
266
/* Takes the inital event.
267
* If we were configured, recalculate the opacify-windows if
269
* If a window was entered: call upon handle_timeout after od->timeout
270
* micro seconds, or directly if od->timeout is 0 (no delay).
275
OpacifyScreen::handleEvent (XEvent *event)
278
screen->handleEvent (event);
283
switch (event->type) {
287
id = event->xcrossing.window;
288
newActive = screen->findTopLevelWindow (id);
290
if (timeoutHandle.active ())
291
timeoutHandle.stop ();
296
timeoutHandle.start ();
298
case ConfigureNotify:
300
if (active != event->xconfigure.window)
308
w = screen->findWindow (active);
310
passiveWindows (w->region ());
318
/* Toggle opacify on/off. We are in Display-context, make sure we handle all
323
OpacifyScreen::toggle (CompAction *action,
324
CompAction::State state,
325
CompOption::Vector options)
327
isToggle = !isToggle;
328
if (!isToggle && optionGetToggleReset ())
333
resetOpacity (active);
338
setFunctions (isToggle);
343
/* Configuration, initialization, boring stuff. ----------------------- */
345
/** This is called when an option changes. The only option we are looking for
346
* here is 'init_toggle' so when that changes, we adjust our internal values
351
OpacifyScreen::optionChanged (CompOption *option,
352
OpacifyOptions::Options num)
355
case OpacifyOptions::InitToggle:
356
isToggle = option->value ().b ();
357
setFunctions (isToggle);
361
resetOpacity (active);
370
/** Constructor for OpacifyWindow. This is called whenever a new window
371
* is created and we set our custom variables to it and also register to
375
OpacifyWindow::OpacifyWindow (CompWindow *window) :
376
PluginClassHandler <OpacifyWindow, CompWindow> (window),
378
cWindow (CompositeWindow::get (window)),
379
gWindow (GLWindow::get (window)),
383
GLWindowInterface::setHandler (gWindow, false);
387
OpacifyScreen::postLoad ()
389
setFunctions (isToggle);
392
/** Constructor for OpacifyScreen. This is called whenever a new screen
393
* is created and we set our custom variables to it and also register to
394
* handle X.org events when they come through
397
OpacifyScreen::OpacifyScreen (CompScreen *screen) :
398
PluginClassHandler <OpacifyScreen, CompScreen> (screen),
399
PluginStateWriter <OpacifyScreen> (this, screen->root ()),
402
active (screen->activeWindow ()),
403
intersect (emptyRegion),
406
ScreenInterface::setHandler (screen, false);
408
timeoutHandle.setTimes (optionGetTimeout (), optionGetTimeout () * 1.2);
409
timeoutHandle.setCallback (boost::bind (&OpacifyScreen::handleTimeout,
412
optionSetToggleKeyInitiate (boost::bind (&OpacifyScreen::toggle, this, _1,
414
optionSetInitToggleNotify (boost::bind (&OpacifyScreen::optionChanged,
418
OpacifyScreen::~OpacifyScreen ()
420
writeSerializedData ();
424
OpacifyPluginVTable::init ()
426
if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
428
if (!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI))
430
if (!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))