2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
1 |
/*
|
2 |
* Copyright © 2011 Canonical Ltd.
|
|
3 |
*
|
|
4 |
* Permission to use, copy, modify, distribute, and sell this software
|
|
5 |
* and its documentation for any purpose is hereby granted without
|
|
6 |
* fee, provided that the above copyright notice appear in all copies
|
|
7 |
* and that both that copyright notice and this permission notice
|
|
8 |
* appear in supporting documentation, and that the name of
|
|
9 |
* Canonical Ltd. not be used in advertising or publicity pertaining to
|
|
10 |
* distribution of the software without specific, written prior permission.
|
|
11 |
* Canonical Ltd. makes no representations about the suitability of this
|
|
12 |
* software for any purpose. It is provided "as is" without express or
|
|
13 |
* implied warranty.
|
|
14 |
*
|
|
15 |
* CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
16 |
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
|
17 |
* NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
18 |
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
19 |
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
|
20 |
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
|
21 |
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
22 |
*
|
|
23 |
* Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
|
|
24 |
*/
|
|
25 |
||
26 |
#include "privatestackdebugger.h" |
|
3233.1.2
by smspillaz
Fetch the events directly from the Xlib queue if we don't need to |
27 |
#include "privatescreen.h" |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
28 |
#include "privatewindow.h" |
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
29 |
#include <poll.h> |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
30 |
|
31 |
namespace
|
|
32 |
{
|
|
33 |
StackDebugger * gStackDebugger = NULL; |
|
34 |
}
|
|
35 |
||
36 |
StackDebugger * |
|
37 |
StackDebugger::Default () |
|
38 |
{
|
|
39 |
return gStackDebugger; |
|
40 |
}
|
|
41 |
||
42 |
void
|
|
43 |
StackDebugger::SetDefault (StackDebugger *dbg) |
|
44 |
{
|
|
45 |
if (gStackDebugger) |
|
46 |
delete gStackDebugger; |
|
47 |
||
48 |
gStackDebugger = dbg; |
|
49 |
}
|
|
50 |
||
3233.1.2
by smspillaz
Fetch the events directly from the Xlib queue if we don't need to |
51 |
StackDebugger::StackDebugger (Display *dpy, Window root, FetchXEventInterface *fetchXEvent) : |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
52 |
mServerNChildren (0), |
53 |
mServerChildren (NULL), |
|
2800.2.13
by Sam Spilsbury
Merge in StackDebugger stack sanity checker |
54 |
mWindowsChanged (false), |
55 |
mServerWindowsChanged (false), |
|
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
56 |
mRoot (root), |
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
57 |
mDpy (dpy), |
3446.2.7
by MC Return
Also initialize the member variable bool mTimeoutRequired in the Stackdebugger::Stackdebugger (...) constructor |
58 |
mFetchXEvent (fetchXEvent), |
59 |
mTimeoutRequired (false) |
|
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
60 |
{
|
61 |
}
|
|
62 |
||
63 |
StackDebugger::~StackDebugger () |
|
64 |
{
|
|
65 |
if (mServerChildren) |
|
66 |
{
|
|
67 |
XFree (mServerChildren); |
|
68 |
mServerChildren = NULL; |
|
69 |
mServerNChildren = 0; |
|
70 |
}
|
|
71 |
}
|
|
72 |
||
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
73 |
bool
|
74 |
StackDebugger::timedOut () |
|
75 |
{
|
|
76 |
return mTimeoutRequired; |
|
77 |
}
|
|
78 |
||
79 |
void
|
|
80 |
StackDebugger::removeServerWindow (Window id) |
|
81 |
{
|
|
82 |
/* Find the toplevel window in the list and remove it */
|
|
83 |
for (CompWindowList::iterator it = mLastServerWindows.begin (); |
|
84 |
it != mLastServerWindows.end (); |
|
3294.4.142
by MC Return
Hopefully fixed indentation |
85 |
++it) |
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
86 |
{
|
87 |
if ((*it)->id () == id) |
|
88 |
{
|
|
89 |
mLastServerWindows.erase (it); |
|
90 |
break; |
|
91 |
}
|
|
92 |
}
|
|
93 |
}
|
|
94 |
||
95 |
void
|
|
96 |
StackDebugger::overrideRedirectRestack (Window toplevel, Window sibling) |
|
97 |
{
|
|
98 |
CompWindow *tl = screen->findWindow (toplevel); |
|
99 |
||
100 |
removeServerWindow (toplevel); |
|
101 |
||
102 |
/* Find the sibling of this window and insert above it or at
|
|
103 |
* the bottom if the sibling is 0 */
|
|
104 |
||
105 |
if (sibling) |
|
106 |
{
|
|
107 |
for (CompWindowList::iterator it = mLastServerWindows.begin (); |
|
108 |
it != mLastServerWindows.end (); |
|
3294.4.142
by MC Return
Hopefully fixed indentation |
109 |
++it) |
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
110 |
{
|
111 |
if (sibling == (*it)->id () || |
|
112 |
sibling == (*it)->frame ()) |
|
113 |
{
|
|
114 |
mLastServerWindows.insert (++it, tl); |
|
115 |
break; |
|
116 |
}
|
|
117 |
}
|
|
118 |
}
|
|
119 |
else
|
|
120 |
mLastServerWindows.push_front (tl); |
|
121 |
}
|
|
122 |
||
3233.1.2
by smspillaz
Fetch the events directly from the Xlib queue if we don't need to |
123 |
bool
|
124 |
StackDebugger::getNextEvent (XEvent &ev) |
|
125 |
{
|
|
126 |
if (mEvents.empty ()) |
|
127 |
return false; |
|
128 |
||
129 |
ev = mEvents.front (); |
|
130 |
||
131 |
mEvents.pop_front (); |
|
132 |
||
133 |
return true; |
|
134 |
}
|
|
135 |
||
136 |
void
|
|
2800.2.17
by Sam Spilsbury
Merge in further stacking fixes |
137 |
StackDebugger::loadStack (CompWindowList &serverWindows, bool wait) |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
138 |
{
|
139 |
Window rootRet, parentRet; |
|
140 |
||
141 |
if (mServerChildren) |
|
142 |
XFree (mServerChildren); |
|
143 |
||
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
144 |
XSync (mDpy, FALSE); |
145 |
XGrabServer (mDpy); |
|
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
146 |
XQueryTree (mDpy, mRoot, &rootRet, &parentRet, |
147 |
&mServerChildren, &mServerNChildren); |
|
148 |
||
3233.1.2
by smspillaz
Fetch the events directly from the Xlib queue if we don't need to |
149 |
unsigned int n = XEventsQueued (mDpy, QueuedAfterFlush); |
150 |
mEvents.clear (); |
|
151 |
mEvents.resize (n); |
|
3233.1.4
by Sam Spilsbury
Use list |
152 |
std::list <XEvent>::iterator it = mEvents.begin (); |
3233.1.2
by smspillaz
Fetch the events directly from the Xlib queue if we don't need to |
153 |
|
154 |
while (it != mEvents.end ()) |
|
155 |
{
|
|
156 |
mFetchXEvent->getNextXEvent ((*it)); |
|
3294.4.142
by MC Return
Hopefully fixed indentation |
157 |
++it; |
3233.1.2
by smspillaz
Fetch the events directly from the Xlib queue if we don't need to |
158 |
}
|
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
159 |
|
160 |
XSync (mDpy, FALSE); |
|
161 |
||
162 |
/* It is possible that X might not be keeping up with us, so
|
|
163 |
* we should give it about 300 ms in case the stacks are out of sync
|
|
164 |
* in order to deliver any more events that might be pending */
|
|
165 |
||
166 |
mTimeoutRequired = false; |
|
167 |
mLastServerWindows = serverWindows; |
|
168 |
||
2800.2.17
by Sam Spilsbury
Merge in further stacking fixes |
169 |
if (mServerNChildren != serverWindows.size () && wait) |
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
170 |
{
|
171 |
struct pollfd pfd; |
|
172 |
||
173 |
pfd.events = POLLIN; |
|
174 |
pfd.revents = 0; |
|
175 |
pfd.fd = ConnectionNumber (mDpy); |
|
176 |
||
177 |
poll (&pfd, 1, 300); |
|
178 |
||
3233.1.2
by smspillaz
Fetch the events directly from the Xlib queue if we don't need to |
179 |
XEvent e; |
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
180 |
|
3233.1.2
by smspillaz
Fetch the events directly from the Xlib queue if we don't need to |
181 |
while (mFetchXEvent->getNextXEvent (e)) |
182 |
mEvents.push_back (e); |
|
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
183 |
|
184 |
mTimeoutRequired = true; |
|
185 |
}
|
|
186 |
||
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
187 |
mDestroyedFrames.clear (); |
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
188 |
|
189 |
XUngrabServer (mDpy); |
|
190 |
XSync (mDpy, FALSE); |
|
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
191 |
}
|
192 |
||
193 |
void
|
|
194 |
StackDebugger::addDestroyedFrame (Window f) |
|
195 |
{
|
|
196 |
mDestroyedFrames.push_back (f); |
|
197 |
}
|
|
198 |
||
2800.2.9
by Sam Spilsbury
Immediately remove destroyed windows from the stacks last sent to the server |
199 |
void
|
200 |
StackDebugger::removeDestroyedFrame (Window f) |
|
201 |
{
|
|
202 |
mDestroyedFrames.remove (f); |
|
203 |
}
|
|
204 |
||
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
205 |
bool
|
206 |
StackDebugger::cmpStack (CompWindowList &windows, |
|
207 |
CompWindowList &serverWindows, |
|
208 |
bool verbose) |
|
209 |
{
|
|
210 |
std::vector <Window> serverSideWindows; |
|
211 |
CompWindowList::reverse_iterator lrrit = windows.rbegin (); |
|
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
212 |
CompWindowList::reverse_iterator lsrit = mLastServerWindows.rbegin (); |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
213 |
unsigned int i = 0; |
214 |
bool err = false; |
|
215 |
||
216 |
for (unsigned int n = 0; n < mServerNChildren; n++) |
|
217 |
{
|
|
218 |
if (std::find (mDestroyedFrames.begin (), |
|
219 |
mDestroyedFrames.end (), mServerChildren[n]) |
|
220 |
== mDestroyedFrames.end ()) |
|
221 |
serverSideWindows.push_back (mServerChildren[n]); |
|
222 |
}
|
|
223 |
||
224 |
if (verbose) |
|
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
225 |
compLogMessage ("core", CompLogLevelDebug, "sent | recv | server |"); |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
226 |
|
227 |
for (;(lrrit != windows.rend () || |
|
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
228 |
lsrit != mLastServerWindows.rend () || |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
229 |
i != serverSideWindows.size ());) |
230 |
{
|
|
231 |
Window lrXid = 0; |
|
232 |
Window lsXid = 0; |
|
233 |
Window sXid = 0; |
|
234 |
||
235 |
if (lrrit != windows.rend ()) |
|
2800.2.11
by Sam Spilsbury
Fix a typo that was causing decoration frames to be added as normal windows (causing |
236 |
lrXid = (*lrrit)->priv->frame ? (*lrrit)->priv->frame : (*lrrit)->id (); |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
237 |
|
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
238 |
if (lsrit != mLastServerWindows.rend ()) |
2800.2.11
by Sam Spilsbury
Fix a typo that was causing decoration frames to be added as normal windows (causing |
239 |
lsXid = (*lsrit)->priv->frame ? (*lsrit)->priv->frame : (*lsrit)->id (); |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
240 |
|
241 |
if (i != serverSideWindows.size ()) |
|
242 |
sXid = serverSideWindows[serverSideWindows.size () - (i + 1)]; |
|
243 |
||
244 |
if (verbose) |
|
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
245 |
compLogMessage ("core", CompLogLevelDebug, "id 0x%x id 0x%x id 0x%x %s", |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
246 |
(unsigned int) lsXid, (unsigned int) lrXid, |
2800.2.17
by Sam Spilsbury
Merge in further stacking fixes |
247 |
(unsigned int) sXid, (lrXid != sXid) ? " /!\\ " : ""); |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
248 |
|
2800.2.17
by Sam Spilsbury
Merge in further stacking fixes |
249 |
if (lrXid != sXid) |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
250 |
err = true; |
251 |
||
252 |
if (lrrit != windows.rend ()) |
|
3294.4.142
by MC Return
Hopefully fixed indentation |
253 |
++lrrit; |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
254 |
|
2800.2.16
by Sam Spilsbury
Merge in more stacking fixes |
255 |
if (lsrit != mLastServerWindows.rend()) |
3294.4.142
by MC Return
Hopefully fixed indentation |
256 |
++lsrit; |
2800.2.2
by Sam Spilsbury
Merge in the fixes for the various out of sync bugs and an object to debug stacking sync problems |
257 |
|
258 |
if (i != serverSideWindows.size ()) |
|
259 |
i++; |
|
260 |
}
|
|
261 |
||
262 |
return err; |
|
263 |
}
|
|
2800.2.13
by Sam Spilsbury
Merge in StackDebugger stack sanity checker |
264 |
|
265 |
/* Checks the sanity of the list of windows last sent to the server.
|
|
266 |
*
|
|
267 |
* There are a few stacking "layers" here. From top to bottom:
|
|
268 |
* - 1) Docks stacked above toplevel windows which are stacked
|
|
269 |
* above fullscreen windows
|
|
270 |
* - 2) "Keep above" toplevel windows above fullscreen windows
|
|
271 |
* where a toplevel is in focus
|
|
272 |
* - 3) Toplevel windows in focus above fullscreen windows
|
|
273 |
* - 4) Fullscreen windows
|
|
274 |
* - 5) Dock windows
|
|
275 |
* - 6) Keep above windows
|
|
276 |
* - 7) Toplevel windows
|
|
277 |
* - 8) Docks which are marked "Keep Below"
|
|
278 |
* - 9) "Keep Below" windows
|
|
279 |
* - 10) Desktop windows
|
|
280 |
*
|
|
281 |
* There are also a few rules which apply here:
|
|
282 |
* - 1) Dock windows should always be above normal windows
|
|
283 |
* except if marked keep below on any layer.
|
|
284 |
* - 2) Dock windows should ONLY be on one layer at a time,
|
|
285 |
* eg if they are on layer 1 then there cannot
|
|
286 |
* also be dock windows on layer 5 (except in the
|
|
287 |
* case of below dock windows on layer 8)
|
|
288 |
* - 3) Fullscreen windows must always be above docks when in
|
|
289 |
* focus, no matter if there is another window with "Keep Above"
|
|
290 |
* - 4) Focused windows take priority over fullscreen windows and
|
|
291 |
* docks must always be above them (see rule 1)
|
|
292 |
*
|
|
293 |
* As we pass through each layer, this function flags each one from
|
|
294 |
* lowest being the most bits set to highest being the least bits
|
|
295 |
* set. If a window violates this it raises a warning */
|
|
296 |
||
297 |
#define DOCKS_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN 0xffffffff >> 1
|
|
298 |
#define KEEP_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN 0xffffffff >> 2
|
|
299 |
#define TOPLEVELS_ABOVE_FULLSCREEN 0xffffffff >> 3
|
|
300 |
#define FULLSCREEN 0xffffffff >> 4
|
|
301 |
#define DOCKS 0xffffffff >> 5
|
|
302 |
#define KEEP_ABOVE 0xffffffff >> 6
|
|
303 |
#define TOPLEVELS 0xffffffff >> 7
|
|
304 |
#define DOCKS_BELOW 0xffffffff >> 8
|
|
305 |
#define KEEP_BELOW 0xffffffff >> 9
|
|
306 |
#define DESKTOP 0xffffffff >> 10
|
|
307 |
||
308 |
namespace
|
|
309 |
{
|
|
310 |
bool setCurrentLayer (Window requestingWindow, int layer, int ¤t) |
|
311 |
{
|
|
312 |
bool ret = false; |
|
313 |
/* Only allow steps down */
|
|
314 |
if ((current & layer) != layer) |
|
315 |
{
|
|
316 |
ret = true; |
|
317 |
compLogMessage ("stackdebugger", CompLogLevelWarn, "0x%x requested invalid layer 0x%x", |
|
318 |
requestingWindow, layer, current); |
|
319 |
}
|
|
320 |
||
321 |
current = layer; |
|
322 |
||
323 |
return ret; |
|
324 |
}
|
|
325 |
}
|
|
326 |
||
327 |
bool
|
|
328 |
StackDebugger::checkSanity (CompWindowList &serverWindows, bool verbose) |
|
329 |
{
|
|
330 |
int current = 0xffffffff; |
|
331 |
int oldCurrent = current; |
|
332 |
bool err = false; |
|
333 |
||
334 |
if (verbose) |
|
335 |
compLogMessage ("stackdebugger", CompLogLevelDebug, "processing new stack --------"); |
|
336 |
||
337 |
/* go backwards down the stack */
|
|
338 |
for (CompWindowList::reverse_iterator rit = serverWindows.rbegin (); |
|
3294.4.165
by MC Return
Fixed intendation |
339 |
rit != serverWindows.rend (); ++rit) |
2800.2.13
by Sam Spilsbury
Merge in StackDebugger stack sanity checker |
340 |
{
|
341 |
CompWindow *w = (*rit); |
|
342 |
||
343 |
/* Override redirect windows set all kinds
|
|
344 |
* of crazy stuff and are required to stack
|
|
345 |
* themselves so skip those */
|
|
346 |
if (w->overrideRedirect ()) |
|
347 |
continue; |
|
348 |
||
349 |
/* ignore non-override redirect unmanaged windows */
|
|
350 |
if (!w->managed ()) |
|
351 |
continue; |
|
352 |
||
2838.4.1
by Sam Spilsbury
Since we are the only one to make ConfigureWindow requests on toplevels which the |
353 |
/* ignore any windows that just got created */
|
354 |
if (!w->mapNum ()) |
|
355 |
continue; |
|
356 |
||
2800.2.13
by Sam Spilsbury
Merge in StackDebugger stack sanity checker |
357 |
/* determine the current layer */
|
358 |
if (w->type () == CompWindowTypeDockMask) |
|
359 |
{
|
|
360 |
if ((current & DOCKS_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN) == |
|
361 |
DOCKS_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN) |
|
362 |
{
|
|
363 |
bool fullscreenWindow = false; |
|
364 |
||
365 |
/* search down the stack to check if there is a fullscreen
|
|
366 |
* window, otherwise we are not on the fullscreen layer */
|
|
2856.3.1
by Sam Spilsbury
When a window loses focus and is no longer capable of gaining focus we should |
367 |
for (CompWindow *rw = w->prev; rw; rw = rw->prev) |
2800.2.13
by Sam Spilsbury
Merge in StackDebugger stack sanity checker |
368 |
{
|
369 |
if (rw->type () & CompWindowTypeFullscreenMask) |
|
370 |
{
|
|
371 |
fullscreenWindow = true; |
|
372 |
break; |
|
373 |
}
|
|
374 |
}
|
|
375 |
||
376 |
/* if there is no fullscreen window, change the layer */
|
|
377 |
if (!fullscreenWindow) |
|
378 |
err |= setCurrentLayer (w->id (), DOCKS, current); |
|
379 |
else
|
|
380 |
err |= setCurrentLayer (w->id (), DOCKS_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN, current); |
|
381 |
}
|
|
382 |
else if (w->state () & CompWindowStateBelowMask) |
|
383 |
err |= setCurrentLayer (w->id (), DOCKS_BELOW, current); |
|
384 |
else
|
|
385 |
err |= setCurrentLayer (w->id (), DOCKS, current); |
|
386 |
}
|
|
387 |
else if (w->type () == CompWindowTypeFullscreenMask) |
|
388 |
{
|
|
389 |
err |= setCurrentLayer (w->id (), FULLSCREEN, current); |
|
390 |
}
|
|
391 |
else if (w->type () == CompWindowTypeDesktopMask) |
|
392 |
{
|
|
393 |
err |= setCurrentLayer (w->id (), DESKTOP, current); |
|
394 |
}
|
|
395 |
/* everything else that is not a fullscreen window or a desktop */
|
|
396 |
else
|
|
397 |
{
|
|
398 |
if (w->state () & CompWindowStateAboveMask) |
|
399 |
{
|
|
400 |
if ((current & KEEP_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN) == |
|
401 |
KEEP_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN) |
|
402 |
{
|
|
403 |
bool fullscreenWindow = false; |
|
404 |
||
405 |
/* search down the stack to check if there is a fullscreen
|
|
406 |
* window, otherwise we are not on the fullscreen layer */
|
|
2856.3.1
by Sam Spilsbury
When a window loses focus and is no longer capable of gaining focus we should |
407 |
for (CompWindow *rw = w->prev; rw; rw = rw->prev) |
2800.2.13
by Sam Spilsbury
Merge in StackDebugger stack sanity checker |
408 |
{
|
2856.3.1
by Sam Spilsbury
When a window loses focus and is no longer capable of gaining focus we should |
409 |
if (rw->type () & CompWindowTypeFullscreenMask) |
2800.2.13
by Sam Spilsbury
Merge in StackDebugger stack sanity checker |
410 |
{
|
411 |
fullscreenWindow = true; |
|
412 |
break; |
|
413 |
}
|
|
414 |
}
|
|
415 |
||
416 |
if (!fullscreenWindow) |
|
417 |
err |= setCurrentLayer (w->id (), KEEP_ABOVE, current); |
|
418 |
else
|
|
419 |
err |= setCurrentLayer (w->id (), KEEP_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN, current); |
|
420 |
}
|
|
421 |
else
|
|
422 |
err |= setCurrentLayer (w->id (), KEEP_ABOVE, current); |
|
423 |
}
|
|
424 |
else if (w->state () & CompWindowStateBelowMask) |
|
425 |
err |= setCurrentLayer (w->id (), KEEP_BELOW, current); |
|
426 |
else
|
|
427 |
{
|
|
428 |
if ((current & TOPLEVELS_ABOVE_FULLSCREEN) == |
|
429 |
TOPLEVELS_ABOVE_FULLSCREEN) |
|
430 |
{
|
|
431 |
bool fullscreenWindow = false; |
|
432 |
||
433 |
/* search down the stack to check if there is a fullscreen
|
|
434 |
* window, otherwise we are not on the fullscreen layer */
|
|
2856.3.1
by Sam Spilsbury
When a window loses focus and is no longer capable of gaining focus we should |
435 |
for (CompWindow *rw = w->prev; rw; rw = rw->prev) |
2800.2.13
by Sam Spilsbury
Merge in StackDebugger stack sanity checker |
436 |
{
|
2856.3.1
by Sam Spilsbury
When a window loses focus and is no longer capable of gaining focus we should |
437 |
if (rw->type () & CompWindowTypeFullscreenMask) |
2800.2.13
by Sam Spilsbury
Merge in StackDebugger stack sanity checker |
438 |
{
|
439 |
fullscreenWindow = true; |
|
440 |
break; |
|
441 |
}
|
|
442 |
}
|
|
443 |
||
444 |
if (!fullscreenWindow) |
|
445 |
err |= setCurrentLayer (w->id (), TOPLEVELS, current); |
|
446 |
else
|
|
447 |
err |= setCurrentLayer (w->id (), TOPLEVELS_ABOVE_FULLSCREEN, current); |
|
448 |
}
|
|
449 |
else
|
|
450 |
err |= setCurrentLayer (w->id (), TOPLEVELS, current); |
|
451 |
}
|
|
452 |
}
|
|
453 |
||
454 |
if ((current & DOCKS_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN) == |
|
455 |
DOCKS_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN) |
|
456 |
{
|
|
457 |
if (verbose && current != oldCurrent) |
|
458 |
compLogMessage ("stackdebugger", CompLogLevelDebug, "on layer DOCKS_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN"); |
|
459 |
}
|
|
460 |
else if ((current & KEEP_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN) == |
|
461 |
KEEP_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN) |
|
462 |
{
|
|
463 |
if (verbose && current != oldCurrent) |
|
464 |
compLogMessage ("stackdebugger", CompLogLevelDebug, "on layer KEEP_ABOVE_TOPLEVELS_ABOVE_FULLSCREEN"); |
|
465 |
}
|
|
466 |
else if ((current & TOPLEVELS_ABOVE_FULLSCREEN) == TOPLEVELS_ABOVE_FULLSCREEN) |
|
467 |
{
|
|
468 |
if (verbose && current != oldCurrent) |
|
469 |
compLogMessage ("stackdebugger", CompLogLevelDebug, "on layer TOPLEVELS_ABOVE_FULLSCREEN"); |
|
470 |
}
|
|
471 |
else if ((current & FULLSCREEN) == FULLSCREEN) |
|
472 |
{
|
|
473 |
if (verbose && current != oldCurrent) |
|
474 |
compLogMessage ("stackdebugger", CompLogLevelDebug, "on layer FULLSCREEN"); |
|
475 |
}
|
|
476 |
else if ((current & DOCKS) == DOCKS) |
|
477 |
{
|
|
478 |
if (verbose && current != oldCurrent) |
|
479 |
compLogMessage ("stackdebugger", CompLogLevelDebug, "on layer DOCKS"); |
|
480 |
}
|
|
481 |
else if ((current & KEEP_ABOVE) == KEEP_ABOVE) |
|
482 |
{
|
|
483 |
if (verbose && current != oldCurrent) |
|
484 |
compLogMessage ("stackdebugger", CompLogLevelDebug, "on layer KEEP_ABOVE"); |
|
485 |
}
|
|
486 |
else if ((current & TOPLEVELS) == TOPLEVELS) |
|
487 |
{
|
|
488 |
if (verbose && current != oldCurrent) |
|
489 |
compLogMessage ("stackdebugger", CompLogLevelDebug, "on layer TOPLEVELS"); |
|
490 |
}
|
|
491 |
else if ((current & DOCKS_BELOW) == DOCKS_BELOW) |
|
492 |
{
|
|
493 |
if (verbose && current != oldCurrent) |
|
494 |
compLogMessage ("stackdebugger", CompLogLevelDebug, "on layer DOCKS_BELOW"); |
|
495 |
}
|
|
496 |
else if ((current & KEEP_BELOW) == KEEP_BELOW) |
|
497 |
{
|
|
498 |
if (verbose && current != oldCurrent) |
|
499 |
compLogMessage ("stackdebugger", CompLogLevelDebug, "on layer KEEP_BELOW"); |
|
500 |
}
|
|
501 |
else if ((current & DESKTOP) == DESKTOP) |
|
502 |
{
|
|
503 |
if (verbose && current != oldCurrent) |
|
504 |
compLogMessage ("stackdebugger", CompLogLevelDebug, "on layer DESKTOP"); |
|
505 |
}
|
|
506 |
||
507 |
oldCurrent = current; |
|
508 |
}
|
|
509 |
||
510 |
return err; |
|
511 |
}
|