Merge lp:~compiz-team/compiz-core/compiz-core.fix_864330 into lp:compiz-core/0.9.5
- compiz-core.fix_864330
- Merge into 0.9.5
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 2877 | ||||
Proposed branch: | lp:~compiz-team/compiz-core/compiz-core.fix_864330 | ||||
Merge into: | lp:compiz-core/0.9.5 | ||||
Diff against target: |
563 lines (+198/-74) 4 files modified
plugins/move/src/move.cpp (+1/-1) src/privatescreen.h (+6/-0) src/privatewindow.h (+2/-1) src/window.cpp (+189/-72) |
||||
To merge this branch: | bzr merge lp:~compiz-team/compiz-core/compiz-core.fix_864330 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jason Smith (community) | Approve | ||
Review via email: mp+78935@code.launchpad.net |
Commit message
Description of the change
Rework the event tracking system slightly to cover more cases where events would
not be recorded properly:
1. When determining restack requests relative to another window which is pending
a restack, check to see if we already requested to restack relative to it
after it was pending the restack, rather than unconditionally submitting
the restack and risking that being a no-op
2. When a window gets closed, its frame window is marked "None" immediately
so we must discard tracking of any remaining pending configure events
as they wont come to the frame window as we know it
3. Remove the static timeout and replace it with a timer object that clears up
any stale configure requests which didn't get matched to events (note that
this will be removed, but exists only to safeguard against performance regressions
with the current API)
4. Make the move plugin lock down server geometry updates whenever it receives the
"lock_position" signal on either the frame or the client window
5. Fix a problem with maximizing undecorated windows (resized to height = 0)
Preview Diff
1 | === modified file 'plugins/move/src/move.cpp' | |||
2 | --- plugins/move/src/move.cpp 2011-09-29 03:29:41 +0000 | |||
3 | +++ plugins/move/src/move.cpp 2011-10-11 09:53:25 +0000 | |||
4 | @@ -525,7 +525,7 @@ | |||
5 | 525 | Window xid = CompOption::getIntOptionNamed (options, "window", 0); | 525 | Window xid = CompOption::getIntOptionNamed (options, "window", 0); |
6 | 526 | int lock = CompOption::getIntOptionNamed (options, "active", 0); | 526 | int lock = CompOption::getIntOptionNamed (options, "active", 0); |
7 | 527 | 527 | ||
9 | 528 | if (xid == w->id ()) | 528 | if (xid == ROOTPARENT (w)) |
10 | 529 | MoveWindow::get (w)->mLocked = lock ? true : false; | 529 | MoveWindow::get (w)->mLocked = lock ? true : false; |
11 | 530 | } | 530 | } |
12 | 531 | } | 531 | } |
13 | 532 | 532 | ||
14 | === modified file 'src/privatescreen.h' | |||
15 | --- src/privatescreen.h 2011-10-04 11:28:15 +0000 | |||
16 | +++ src/privatescreen.h 2011-10-11 09:53:25 +0000 | |||
17 | @@ -111,6 +111,8 @@ | |||
18 | 111 | virtual ~PendingEvent (); | 111 | virtual ~PendingEvent (); |
19 | 112 | 112 | ||
20 | 113 | virtual bool match (XEvent *); | 113 | virtual bool match (XEvent *); |
21 | 114 | unsigned int serial () { return mSerial; } // HACK: will be removed | ||
22 | 115 | virtual void dump (); | ||
23 | 114 | 116 | ||
24 | 115 | typedef boost::shared_ptr<PendingEvent> Ptr; | 117 | typedef boost::shared_ptr<PendingEvent> Ptr; |
25 | 116 | 118 | ||
26 | @@ -131,6 +133,8 @@ | |||
27 | 131 | 133 | ||
28 | 132 | virtual bool match (XEvent *); | 134 | virtual bool match (XEvent *); |
29 | 133 | bool matchVM (unsigned int valueMask); | 135 | bool matchVM (unsigned int valueMask); |
30 | 136 | bool matchRequest (XWindowChanges &xwc, unsigned int); | ||
31 | 137 | virtual void dump (); | ||
32 | 134 | 138 | ||
33 | 135 | typedef boost::shared_ptr<PendingConfigureEvent> Ptr; | 139 | typedef boost::shared_ptr<PendingConfigureEvent> Ptr; |
34 | 136 | 140 | ||
35 | @@ -154,6 +158,8 @@ | |||
36 | 154 | bool match (XEvent *); | 158 | bool match (XEvent *); |
37 | 155 | bool pending (); | 159 | bool pending (); |
38 | 156 | bool forEachIf (boost::function <bool (compiz::X11::PendingEvent::Ptr)>); | 160 | bool forEachIf (boost::function <bool (compiz::X11::PendingEvent::Ptr)>); |
39 | 161 | void clear () { mEvents.clear (); } // HACK will be removed | ||
40 | 162 | void dump (); | ||
41 | 157 | 163 | ||
42 | 158 | protected: | 164 | protected: |
43 | 159 | bool removeIfMatching (const PendingEvent::Ptr &p, XEvent *); | 165 | bool removeIfMatching (const PendingEvent::Ptr &p, XEvent *); |
44 | 160 | 166 | ||
45 | === modified file 'src/privatewindow.h' | |||
46 | --- src/privatewindow.h 2011-10-04 11:28:15 +0000 | |||
47 | +++ src/privatewindow.h 2011-10-11 09:53:25 +0000 | |||
48 | @@ -211,7 +211,7 @@ | |||
49 | 211 | 211 | ||
50 | 212 | void readIconHint (); | 212 | void readIconHint (); |
51 | 213 | 213 | ||
53 | 214 | void addPendingConfigure (XWindowChanges &, unsigned int); | 214 | bool checkClear (); |
54 | 215 | 215 | ||
55 | 216 | public: | 216 | public: |
56 | 217 | 217 | ||
57 | @@ -293,6 +293,7 @@ | |||
58 | 293 | typedef std::pair <XWindowChanges, unsigned int> XWCValueMask; | 293 | typedef std::pair <XWindowChanges, unsigned int> XWCValueMask; |
59 | 294 | 294 | ||
60 | 295 | compiz::X11::PendingEventQueue pendingConfigures; | 295 | compiz::X11::PendingEventQueue pendingConfigures; |
61 | 296 | CompTimer mClearCheckTimeout; | ||
62 | 296 | bool pendingPositionUpdates; | 297 | bool pendingPositionUpdates; |
63 | 297 | 298 | ||
64 | 298 | char *startupId; | 299 | char *startupId; |
65 | 299 | 300 | ||
66 | === modified file 'src/window.cpp' | |||
67 | --- src/window.cpp 2011-10-08 11:38:21 +0000 | |||
68 | +++ src/window.cpp 2011-10-11 09:53:25 +0000 | |||
69 | @@ -897,13 +897,16 @@ | |||
70 | 897 | 897 | ||
71 | 898 | } | 898 | } |
72 | 899 | 899 | ||
73 | 900 | gettimeofday (&lastConfigureRequest, NULL); | ||
74 | 901 | compiz::X11::PendingEvent::Ptr pc = | 900 | compiz::X11::PendingEvent::Ptr pc = |
75 | 902 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( | 901 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
76 | 903 | new compiz::X11::PendingConfigureEvent ( | 902 | new compiz::X11::PendingConfigureEvent ( |
77 | 904 | screen->dpy (), serverFrame, valueMask, &xwc))); | 903 | screen->dpy (), serverFrame, valueMask, &xwc))); |
78 | 905 | 904 | ||
79 | 906 | pendingConfigures.add (pc); | 905 | pendingConfigures.add (pc); |
80 | 906 | if (priv->mClearCheckTimeout.active ()) | ||
81 | 907 | priv->mClearCheckTimeout.stop (); | ||
82 | 908 | priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv), | ||
83 | 909 | 2000, 2500); | ||
84 | 907 | 910 | ||
85 | 908 | XSendEvent (screen->dpy (), screen->root (), false, | 911 | XSendEvent (screen->dpy (), screen->root (), false, |
86 | 909 | SubstructureNotifyMask, (XEvent *) &xev); | 912 | SubstructureNotifyMask, (XEvent *) &xev); |
87 | @@ -913,13 +916,16 @@ | |||
88 | 913 | } | 916 | } |
89 | 914 | else | 917 | else |
90 | 915 | { | 918 | { |
91 | 916 | gettimeofday (&lastConfigureRequest, NULL); | ||
92 | 917 | compiz::X11::PendingEvent::Ptr pc = | 919 | compiz::X11::PendingEvent::Ptr pc = |
93 | 918 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( | 920 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
94 | 919 | new compiz::X11::PendingConfigureEvent ( | 921 | new compiz::X11::PendingConfigureEvent ( |
95 | 920 | screen->dpy (), serverFrame, valueMask, &xwc))); | 922 | screen->dpy (), serverFrame, valueMask, &xwc))); |
96 | 921 | 923 | ||
97 | 922 | pendingConfigures.add (pc); | 924 | pendingConfigures.add (pc); |
98 | 925 | if (priv->mClearCheckTimeout.active ()) | ||
99 | 926 | priv->mClearCheckTimeout.stop (); | ||
100 | 927 | priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv), | ||
101 | 928 | 2000, 2500); | ||
102 | 923 | XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc); | 929 | XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc); |
103 | 924 | } | 930 | } |
104 | 925 | 931 | ||
105 | @@ -951,10 +957,7 @@ | |||
106 | 951 | if (shaded) | 957 | if (shaded) |
107 | 952 | xwc.height = bw; | 958 | xwc.height = bw; |
108 | 953 | else | 959 | else |
113 | 954 | xwc.height = bw; | 960 | xwc.height = serverGeometry.height () + bw; |
110 | 955 | |||
111 | 956 | if (shaded) | ||
112 | 957 | height = 0; | ||
114 | 958 | 961 | ||
115 | 959 | if (serverFrameGeometry.x () == xwc.x) | 962 | if (serverFrameGeometry.x () == xwc.x) |
116 | 960 | valueMask &= ~(CWX); | 963 | valueMask &= ~(CWX); |
117 | @@ -1032,13 +1035,16 @@ | |||
118 | 1032 | 1035 | ||
119 | 1033 | } | 1036 | } |
120 | 1034 | 1037 | ||
121 | 1035 | gettimeofday (&lastConfigureRequest, NULL); | ||
122 | 1036 | compiz::X11::PendingEvent::Ptr pc = | 1038 | compiz::X11::PendingEvent::Ptr pc = |
123 | 1037 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( | 1039 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
124 | 1038 | new compiz::X11::PendingConfigureEvent ( | 1040 | new compiz::X11::PendingConfigureEvent ( |
125 | 1039 | screen->dpy (), serverFrame, valueMask, &xwc))); | 1041 | screen->dpy (), serverFrame, valueMask, &xwc))); |
126 | 1040 | 1042 | ||
127 | 1041 | pendingConfigures.add (pc); | 1043 | pendingConfigures.add (pc); |
128 | 1044 | if (priv->mClearCheckTimeout.active ()) | ||
129 | 1045 | priv->mClearCheckTimeout.stop (); | ||
130 | 1046 | priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv), | ||
131 | 1047 | 2000, 2500); | ||
132 | 1042 | 1048 | ||
133 | 1043 | XSendEvent (screen->dpy (), screen->root (), false, | 1049 | XSendEvent (screen->dpy (), screen->root (), false, |
134 | 1044 | SubstructureNotifyMask, (XEvent *) &xev); | 1050 | SubstructureNotifyMask, (XEvent *) &xev); |
135 | @@ -1048,13 +1054,16 @@ | |||
136 | 1048 | } | 1054 | } |
137 | 1049 | else | 1055 | else |
138 | 1050 | { | 1056 | { |
139 | 1051 | gettimeofday (&lastConfigureRequest, NULL); | ||
140 | 1052 | compiz::X11::PendingEvent::Ptr pc = | 1057 | compiz::X11::PendingEvent::Ptr pc = |
141 | 1053 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( | 1058 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
142 | 1054 | new compiz::X11::PendingConfigureEvent ( | 1059 | new compiz::X11::PendingConfigureEvent ( |
143 | 1055 | screen->dpy (), serverFrame, valueMask, &xwc))); | 1060 | screen->dpy (), serverFrame, valueMask, &xwc))); |
144 | 1056 | 1061 | ||
145 | 1057 | pendingConfigures.add (pc); | 1062 | pendingConfigures.add (pc); |
146 | 1063 | if (priv->mClearCheckTimeout.active ()) | ||
147 | 1064 | priv->mClearCheckTimeout.stop (); | ||
148 | 1065 | priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv), | ||
149 | 1066 | 2000, 2500); | ||
150 | 1058 | 1067 | ||
151 | 1059 | XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc); | 1068 | XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc); |
152 | 1060 | } | 1069 | } |
153 | @@ -2088,7 +2097,7 @@ | |||
154 | 2088 | #ifdef DEBUG | 2097 | #ifdef DEBUG |
155 | 2089 | abort (); | 2098 | abort (); |
156 | 2090 | #else | 2099 | #else |
158 | 2091 | pendingConfigures = compiz::X11::PendingEventQueue (screen->dpy ()); | 2100 | pendingConfigures.clear (); |
159 | 2092 | #endif | 2101 | #endif |
160 | 2093 | } | 2102 | } |
161 | 2094 | 2103 | ||
162 | @@ -2199,28 +2208,13 @@ | |||
163 | 2199 | { | 2208 | { |
164 | 2200 | XWindowChanges xwc; | 2209 | XWindowChanges xwc; |
165 | 2201 | unsigned int valueMask = CWX | CWY; | 2210 | unsigned int valueMask = CWX | CWY; |
168 | 2202 | struct timeval tv, old; | 2211 | compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x, "\ |
167 | 2203 | compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x,"\ | ||
169 | 2204 | "moving window asyncrhonously!", (unsigned int) priv->serverId); | 2212 | "moving window asyncrhonously!", (unsigned int) priv->serverId); |
170 | 2205 | 2213 | ||
171 | 2206 | old = priv->lastConfigureRequest; | ||
172 | 2207 | gettimeofday (&tv, NULL); | ||
173 | 2208 | |||
174 | 2209 | xwc.x = priv->serverGeometry.x () + dx; | 2214 | xwc.x = priv->serverGeometry.x () + dx; |
175 | 2210 | xwc.y = priv->serverGeometry.y () + dy; | 2215 | xwc.y = priv->serverGeometry.y () + dy; |
176 | 2211 | 2216 | ||
177 | 2212 | configureXWindow (valueMask, &xwc); | 2217 | configureXWindow (valueMask, &xwc); |
178 | 2213 | |||
179 | 2214 | priv->lastConfigureRequest = old; | ||
180 | 2215 | |||
181 | 2216 | /* FIXME: This is a hack to avoid performance regressions | ||
182 | 2217 | * and must be removed in 0.9.6 */ | ||
183 | 2218 | if (tv.tv_usec - priv->lastConfigureRequest.tv_usec > 30000) | ||
184 | 2219 | { | ||
185 | 2220 | compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event from request at %i (now: %i)\n", | ||
186 | 2221 | priv->lastConfigureRequest.tv_usec, tv.tv_usec); | ||
187 | 2222 | priv->pendingConfigures = compiz::X11::PendingEventQueue (screen->dpy ()); | ||
188 | 2223 | } | ||
189 | 2224 | } | 2218 | } |
190 | 2225 | } | 2219 | } |
191 | 2226 | } | 2220 | } |
192 | @@ -2231,16 +2225,59 @@ | |||
193 | 2231 | return !mEvents.empty (); | 2225 | return !mEvents.empty (); |
194 | 2232 | } | 2226 | } |
195 | 2233 | 2227 | ||
196 | 2228 | bool | ||
197 | 2229 | PrivateWindow::checkClear () | ||
198 | 2230 | { | ||
199 | 2231 | if (pendingConfigures.pending ()) | ||
200 | 2232 | { | ||
201 | 2233 | /* FIXME: This is a hack to avoid performance regressions | ||
202 | 2234 | * and must be removed in 0.9.6 */ | ||
203 | 2235 | compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event on 0x%x\n", | ||
204 | 2236 | id); | ||
205 | 2237 | pendingConfigures.dump (); | ||
206 | 2238 | pendingConfigures.clear (); | ||
207 | 2239 | } | ||
208 | 2240 | |||
209 | 2241 | return false; | ||
210 | 2242 | } | ||
211 | 2243 | |||
212 | 2234 | void | 2244 | void |
213 | 2235 | compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p) | 2245 | compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p) |
214 | 2236 | { | 2246 | { |
215 | 2247 | compLogMessage ("core", CompLogLevelDebug, "pending request:"); | ||
216 | 2248 | p->dump (); | ||
217 | 2249 | |||
218 | 2237 | mEvents.push_back (p); | 2250 | mEvents.push_back (p); |
219 | 2238 | } | 2251 | } |
220 | 2239 | 2252 | ||
221 | 2240 | bool | 2253 | bool |
222 | 2241 | compiz::X11::PendingEventQueue::removeIfMatching (const PendingEvent::Ptr &p, XEvent *event) | 2254 | compiz::X11::PendingEventQueue::removeIfMatching (const PendingEvent::Ptr &p, XEvent *event) |
223 | 2242 | { | 2255 | { |
225 | 2243 | return p->match (event); | 2256 | if (p->match (event)) |
226 | 2257 | { | ||
227 | 2258 | compLogMessage ("core", CompLogLevelDebug, "received event:"); | ||
228 | 2259 | p->dump (); | ||
229 | 2260 | return true; | ||
230 | 2261 | } | ||
231 | 2262 | |||
232 | 2263 | return false; | ||
233 | 2264 | } | ||
234 | 2265 | |||
235 | 2266 | void | ||
236 | 2267 | compiz::X11::PendingEvent::dump () | ||
237 | 2268 | { | ||
238 | 2269 | compLogMessage ("core", CompLogLevelDebug, "- event serial: %i", mSerial); | ||
239 | 2270 | compLogMessage ("core", CompLogLevelDebug, "- event window 0x%x", mWindow); | ||
240 | 2271 | } | ||
241 | 2272 | |||
242 | 2273 | void | ||
243 | 2274 | compiz::X11::PendingConfigureEvent::dump () | ||
244 | 2275 | { | ||
245 | 2276 | compiz::X11::PendingEvent::dump (); | ||
246 | 2277 | |||
247 | 2278 | compLogMessage ("core", CompLogLevelDebug, "- x: %i y: %i width: %i height: %i "\ | ||
248 | 2279 | "border: %i, sibling: 0x%x", | ||
249 | 2280 | mXwc.x, mXwc.y, mXwc.width, mXwc.height, mXwc.border_width, mXwc.sibling); | ||
250 | 2244 | } | 2281 | } |
251 | 2245 | 2282 | ||
252 | 2246 | bool | 2283 | bool |
253 | @@ -2266,8 +2303,21 @@ | |||
254 | 2266 | return false; | 2303 | return false; |
255 | 2267 | } | 2304 | } |
256 | 2268 | 2305 | ||
257 | 2306 | void | ||
258 | 2307 | compiz::X11::PendingEventQueue::dump () | ||
259 | 2308 | { | ||
260 | 2309 | foreach (compiz::X11::PendingEvent::Ptr p, mEvents) | ||
261 | 2310 | p->dump (); | ||
262 | 2311 | } | ||
263 | 2312 | |||
264 | 2269 | compiz::X11::PendingEventQueue::PendingEventQueue (Display *d) | 2313 | compiz::X11::PendingEventQueue::PendingEventQueue (Display *d) |
265 | 2270 | { | 2314 | { |
266 | 2315 | /* mClearCheckTimeout.setTimes (0, 0) | ||
267 | 2316 | * | ||
268 | 2317 | * XXX: For whatever reason, calling setTimes (0, 0) here causes | ||
269 | 2318 | * the destructor of the timer object to be called twice later on | ||
270 | 2319 | * in execution and the stack gets smashed. This could be a | ||
271 | 2320 | * compiler bug, but requires further investigation */ | ||
272 | 2271 | } | 2321 | } |
273 | 2272 | 2322 | ||
274 | 2273 | compiz::X11::PendingEventQueue::~PendingEventQueue () | 2323 | compiz::X11::PendingEventQueue::~PendingEventQueue () |
275 | @@ -2310,7 +2360,44 @@ | |||
276 | 2310 | bool | 2360 | bool |
277 | 2311 | compiz::X11::PendingConfigureEvent::matchVM (unsigned int valueMask) | 2361 | compiz::X11::PendingConfigureEvent::matchVM (unsigned int valueMask) |
278 | 2312 | { | 2362 | { |
280 | 2313 | return valueMask & mValueMask; | 2363 | unsigned int result = mValueMask != 0 ? valueMask & mValueMask : 1; |
281 | 2364 | |||
282 | 2365 | return result != 0; | ||
283 | 2366 | } | ||
284 | 2367 | |||
285 | 2368 | bool | ||
286 | 2369 | compiz::X11::PendingConfigureEvent::matchRequest (XWindowChanges &xwc, unsigned int valueMask) | ||
287 | 2370 | { | ||
288 | 2371 | if (matchVM (valueMask)) | ||
289 | 2372 | { | ||
290 | 2373 | if (valueMask & CWX) | ||
291 | 2374 | if (xwc.x != mXwc.x) | ||
292 | 2375 | return false; | ||
293 | 2376 | |||
294 | 2377 | if (valueMask & CWY) | ||
295 | 2378 | if (xwc.y != mXwc.y) | ||
296 | 2379 | return false; | ||
297 | 2380 | |||
298 | 2381 | if (valueMask & CWWidth) | ||
299 | 2382 | if (xwc.width != mXwc.width) | ||
300 | 2383 | return false; | ||
301 | 2384 | |||
302 | 2385 | if (valueMask & CWHeight) | ||
303 | 2386 | if (xwc.height != mXwc.height) | ||
304 | 2387 | return false; | ||
305 | 2388 | |||
306 | 2389 | if (valueMask & CWBorderWidth) | ||
307 | 2390 | if (xwc.border_width != mXwc.border_width) | ||
308 | 2391 | return false; | ||
309 | 2392 | |||
310 | 2393 | if (valueMask & (CWStackMode | CWSibling)) | ||
311 | 2394 | if (xwc.sibling != mXwc.sibling) | ||
312 | 2395 | return false; | ||
313 | 2396 | |||
314 | 2397 | return true; | ||
315 | 2398 | } | ||
316 | 2399 | |||
317 | 2400 | return false; | ||
318 | 2314 | } | 2401 | } |
319 | 2315 | 2402 | ||
320 | 2316 | bool | 2403 | bool |
321 | @@ -2322,29 +2409,16 @@ | |||
322 | 2322 | if (!compiz::X11::PendingEvent::match (event)) | 2409 | if (!compiz::X11::PendingEvent::match (event)) |
323 | 2323 | return false; | 2410 | return false; |
324 | 2324 | 2411 | ||
348 | 2325 | if (mValueMask & CWX) | 2412 | XWindowChanges xwc; |
349 | 2326 | if (ce->x != mXwc.x) | 2413 | |
350 | 2327 | matched = false; | 2414 | xwc.x = ce->x; |
351 | 2328 | 2415 | xwc.y = ce->y; | |
352 | 2329 | if (mValueMask & CWY) | 2416 | xwc.width = ce->width; |
353 | 2330 | if (ce->y != mXwc.y) | 2417 | xwc.height = ce->height; |
354 | 2331 | matched = false; | 2418 | xwc.border_width = ce->border_width; |
355 | 2332 | 2419 | xwc.sibling = ce->above; | |
356 | 2333 | if (mValueMask & CWWidth) | 2420 | |
357 | 2334 | if (ce->width != mXwc.width) | 2421 | matched = matchRequest (xwc, mValueMask); |
335 | 2335 | matched = false; | ||
336 | 2336 | |||
337 | 2337 | if (mValueMask & CWHeight) | ||
338 | 2338 | if (ce->height != mXwc.height) | ||
339 | 2339 | matched = false; | ||
340 | 2340 | |||
341 | 2341 | if (mValueMask & CWBorderWidth) | ||
342 | 2342 | if (ce->border_width != mXwc.border_width) | ||
343 | 2343 | matched = false; | ||
344 | 2344 | |||
345 | 2345 | if (mValueMask & (CWStackMode | CWSibling)) | ||
346 | 2346 | if (ce->above != mXwc.sibling) | ||
347 | 2347 | matched = false; | ||
358 | 2348 | 2422 | ||
359 | 2349 | /* Remove events from the queue | 2423 | /* Remove events from the queue |
360 | 2350 | * even if they didn't match what | 2424 | * even if they didn't match what |
361 | @@ -2440,7 +2514,6 @@ | |||
362 | 2440 | xwc.x = priv->serverFrameGeometry.x (); | 2514 | xwc.x = priv->serverFrameGeometry.x (); |
363 | 2441 | xwc.y = priv->serverFrameGeometry.y (); | 2515 | xwc.y = priv->serverFrameGeometry.y (); |
364 | 2442 | 2516 | ||
365 | 2443 | gettimeofday (&priv->lastConfigureRequest, NULL); | ||
366 | 2444 | compiz::X11::PendingEvent::Ptr pc = | 2517 | compiz::X11::PendingEvent::Ptr pc = |
367 | 2445 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( | 2518 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
368 | 2446 | new compiz::X11::PendingConfigureEvent ( | 2519 | new compiz::X11::PendingConfigureEvent ( |
369 | @@ -2448,6 +2521,11 @@ | |||
370 | 2448 | 2521 | ||
371 | 2449 | priv->pendingConfigures.add (pc); | 2522 | priv->pendingConfigures.add (pc); |
372 | 2450 | 2523 | ||
373 | 2524 | /* Got 3 seconds to get its stuff together */ | ||
374 | 2525 | if (priv->mClearCheckTimeout.active ()) | ||
375 | 2526 | priv->mClearCheckTimeout.stop (); | ||
376 | 2527 | priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv), | ||
377 | 2528 | 2000, 2500); | ||
378 | 2451 | XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc); | 2529 | XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc); |
379 | 2452 | 2530 | ||
380 | 2453 | if (priv->serverFrame) | 2531 | if (priv->serverFrame) |
381 | @@ -3259,11 +3337,18 @@ | |||
382 | 3259 | return pc->matchVM (CWStackMode | CWSibling); | 3337 | return pc->matchVM (CWStackMode | CWSibling); |
383 | 3260 | } | 3338 | } |
384 | 3261 | 3339 | ||
385 | 3340 | static bool isExistingRequest (compiz::X11::PendingEvent::Ptr p, XWindowChanges &xwc, unsigned int valueMask) | ||
386 | 3341 | { | ||
387 | 3342 | compiz::X11::PendingConfigureEvent::Ptr pc = boost::shared_static_cast <compiz::X11::PendingConfigureEvent> (p); | ||
388 | 3343 | |||
389 | 3344 | return pc->matchRequest (xwc, valueMask); | ||
390 | 3345 | } | ||
391 | 3346 | |||
392 | 3262 | void | 3347 | void |
393 | 3263 | PrivateWindow::reconfigureXWindow (unsigned int valueMask, | 3348 | PrivateWindow::reconfigureXWindow (unsigned int valueMask, |
394 | 3264 | XWindowChanges *xwc) | 3349 | XWindowChanges *xwc) |
395 | 3265 | { | 3350 | { |
397 | 3266 | unsigned int frameValueMask = valueMask; | 3351 | unsigned int frameValueMask = 0; |
398 | 3267 | 3352 | ||
399 | 3268 | /* Immediately sync window position | 3353 | /* Immediately sync window position |
400 | 3269 | * if plugins were updating w->geometry () directly | 3354 | * if plugins were updating w->geometry () directly |
401 | @@ -3273,28 +3358,37 @@ | |||
402 | 3273 | 3358 | ||
403 | 3274 | /* Remove redundant bits */ | 3359 | /* Remove redundant bits */ |
404 | 3275 | 3360 | ||
406 | 3276 | if (serverGeometry.x () == xwc->x) | 3361 | if (valueMask & CWX && serverGeometry.x () == xwc->x) |
407 | 3277 | valueMask &= ~(CWX); | 3362 | valueMask &= ~(CWX); |
408 | 3278 | 3363 | ||
410 | 3279 | if (serverGeometry.y () == xwc->y) | 3364 | if (valueMask & CWY && serverGeometry.y () == xwc->y) |
411 | 3280 | valueMask &= ~(CWY); | 3365 | valueMask &= ~(CWY); |
412 | 3281 | 3366 | ||
414 | 3282 | if (serverGeometry.width () == xwc->width) | 3367 | if (valueMask & CWWidth && serverGeometry.width () == xwc->width) |
415 | 3283 | valueMask &= ~(CWWidth); | 3368 | valueMask &= ~(CWWidth); |
416 | 3284 | 3369 | ||
418 | 3285 | if (serverGeometry.height () == xwc->height) | 3370 | if (valueMask & CWHeight && serverGeometry.height () == xwc->height) |
419 | 3286 | valueMask &= ~(CWHeight); | 3371 | valueMask &= ~(CWHeight); |
420 | 3287 | 3372 | ||
422 | 3288 | if (serverGeometry.border () == xwc->border_width) | 3373 | if (valueMask & CWBorderWidth && serverGeometry.border () == xwc->border_width) |
423 | 3289 | valueMask &= ~(CWBorderWidth); | 3374 | valueMask &= ~(CWBorderWidth); |
424 | 3290 | 3375 | ||
426 | 3291 | if (window->serverPrev && ROOTPARENT (window->serverPrev) == xwc->sibling) | 3376 | if (valueMask & CWSibling && window->serverPrev) |
427 | 3292 | { | 3377 | { |
428 | 3293 | /* check if the sibling is also pending a restack, | 3378 | /* check if the sibling is also pending a restack, |
429 | 3294 | * if not, then setting this bit is useless */ | 3379 | * if not, then setting this bit is useless */ |
433 | 3295 | 3380 | if (ROOTPARENT (window->serverPrev) == xwc->sibling) | |
434 | 3296 | if (window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1))) | 3381 | { |
435 | 3297 | valueMask &= ~(CWSibling | CWStackMode); | 3382 | bool matchingRequest = priv->pendingConfigures.forEachIf (boost::bind (isExistingRequest, _1, *xwc, valueMask)); |
436 | 3383 | bool restackPending = window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1)); | ||
437 | 3384 | bool remove = matchingRequest; | ||
438 | 3385 | |||
439 | 3386 | if (!remove) | ||
440 | 3387 | remove = !restackPending; | ||
441 | 3388 | |||
442 | 3389 | if (remove) | ||
443 | 3390 | valueMask &= ~(CWSibling | CWStackMode); | ||
444 | 3391 | } | ||
445 | 3298 | } | 3392 | } |
446 | 3299 | 3393 | ||
447 | 3300 | if (valueMask & CWBorderWidth) | 3394 | if (valueMask & CWBorderWidth) |
448 | @@ -3330,13 +3424,18 @@ | |||
449 | 3330 | compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above"); | 3424 | compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above"); |
450 | 3331 | } | 3425 | } |
451 | 3332 | 3426 | ||
453 | 3333 | if (serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left) | 3427 | frameValueMask = valueMask; |
454 | 3428 | |||
455 | 3429 | if (frameValueMask & CWX && | ||
456 | 3430 | serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left) | ||
457 | 3334 | frameValueMask &= ~(CWX); | 3431 | frameValueMask &= ~(CWX); |
458 | 3335 | 3432 | ||
460 | 3336 | if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top) | 3433 | if (frameValueMask & CWY && |
461 | 3434 | serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top) | ||
462 | 3337 | frameValueMask &= ~(CWY); | 3435 | frameValueMask &= ~(CWY); |
463 | 3338 | 3436 | ||
465 | 3339 | if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2 | 3437 | if (frameValueMask & CWWidth && |
466 | 3438 | serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2 | ||
467 | 3340 | + serverInput.left + serverInput.right) | 3439 | + serverInput.left + serverInput.right) |
468 | 3341 | frameValueMask &= ~(CWWidth); | 3440 | frameValueMask &= ~(CWWidth); |
469 | 3342 | 3441 | ||
470 | @@ -3346,13 +3445,15 @@ | |||
471 | 3346 | 3445 | ||
472 | 3347 | if (shaded) | 3446 | if (shaded) |
473 | 3348 | { | 3447 | { |
475 | 3349 | if (serverFrameGeometry.height () == serverGeometry.border () * 2 | 3448 | if (frameValueMask & CWHeight && |
476 | 3449 | serverFrameGeometry.height () == serverGeometry.border () * 2 | ||
477 | 3350 | + serverInput.top + serverInput.bottom) | 3450 | + serverInput.top + serverInput.bottom) |
478 | 3351 | frameValueMask &= ~(CWHeight); | 3451 | frameValueMask &= ~(CWHeight); |
479 | 3352 | } | 3452 | } |
480 | 3353 | else | 3453 | else |
481 | 3354 | { | 3454 | { |
483 | 3355 | if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2 | 3455 | if (frameValueMask & CWHeight && |
484 | 3456 | serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2 | ||
485 | 3356 | + serverInput.top + serverInput.bottom) | 3457 | + serverInput.top + serverInput.bottom) |
486 | 3357 | frameValueMask &= ~(CWHeight); | 3458 | frameValueMask &= ~(CWHeight); |
487 | 3358 | } | 3459 | } |
488 | @@ -3397,14 +3498,16 @@ | |||
489 | 3397 | wc.width = serverFrameGeometry.width (); | 3498 | wc.width = serverFrameGeometry.width (); |
490 | 3398 | wc.height = serverFrameGeometry.height (); | 3499 | wc.height = serverFrameGeometry.height (); |
491 | 3399 | 3500 | ||
492 | 3400 | gettimeofday (&lastConfigureRequest, NULL); | ||
493 | 3401 | |||
494 | 3402 | compiz::X11::PendingEvent::Ptr pc = | 3501 | compiz::X11::PendingEvent::Ptr pc = |
495 | 3403 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( | 3502 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
496 | 3404 | new compiz::X11::PendingConfigureEvent ( | 3503 | new compiz::X11::PendingConfigureEvent ( |
497 | 3405 | screen->dpy (), priv->serverFrame, frameValueMask, &wc))); | 3504 | screen->dpy (), priv->serverFrame, frameValueMask, &wc))); |
498 | 3406 | 3505 | ||
499 | 3407 | pendingConfigures.add (pc); | 3506 | pendingConfigures.add (pc); |
500 | 3507 | if (priv->mClearCheckTimeout.active ()) | ||
501 | 3508 | priv->mClearCheckTimeout.stop (); | ||
502 | 3509 | priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv), | ||
503 | 3510 | 2000, 2500); | ||
504 | 3408 | 3511 | ||
505 | 3409 | XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc); | 3512 | XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc); |
506 | 3410 | } | 3513 | } |
507 | @@ -4196,13 +4299,16 @@ | |||
508 | 4196 | 4299 | ||
509 | 4197 | if (serverFrame) | 4300 | if (serverFrame) |
510 | 4198 | { | 4301 | { |
511 | 4199 | gettimeofday (&lastConfigureRequest, NULL); | ||
512 | 4200 | compiz::X11::PendingEvent::Ptr pc = | 4302 | compiz::X11::PendingEvent::Ptr pc = |
513 | 4201 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( | 4303 | boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
514 | 4202 | new compiz::X11::PendingConfigureEvent ( | 4304 | new compiz::X11::PendingConfigureEvent ( |
515 | 4203 | screen->dpy (), serverFrame, valueMask, &lxwc))); | 4305 | screen->dpy (), serverFrame, valueMask, &lxwc))); |
516 | 4204 | 4306 | ||
517 | 4205 | pendingConfigures.add (pc); | 4307 | pendingConfigures.add (pc); |
518 | 4308 | if (priv->mClearCheckTimeout.active ()) | ||
519 | 4309 | priv->mClearCheckTimeout.stop (); | ||
520 | 4310 | priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv), | ||
521 | 4311 | 2000, 2500); | ||
522 | 4206 | } | 4312 | } |
523 | 4207 | 4313 | ||
524 | 4208 | /* Below with no sibling puts the window at the bottom | 4314 | /* Below with no sibling puts the window at the bottom |
525 | @@ -4215,8 +4321,15 @@ | |||
526 | 4215 | } | 4321 | } |
527 | 4216 | else if (sibling) | 4322 | else if (sibling) |
528 | 4217 | { | 4323 | { |
529 | 4324 | bool matchingRequest = priv->pendingConfigures.forEachIf (boost::bind (isExistingRequest, _1, *xwc, (CWStackMode | CWSibling))); | ||
530 | 4325 | bool restackPending = window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1)); | ||
531 | 4326 | bool processAnyways = restackPending; | ||
532 | 4327 | |||
533 | 4328 | if (matchingRequest) | ||
534 | 4329 | processAnyways = false; | ||
535 | 4330 | |||
536 | 4218 | if (sibling->priv->id != window->serverPrev->priv->id || | 4331 | if (sibling->priv->id != window->serverPrev->priv->id || |
538 | 4219 | window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1))) | 4332 | processAnyways) |
539 | 4220 | { | 4333 | { |
540 | 4221 | mask |= CWSibling | CWStackMode; | 4334 | mask |= CWSibling | CWStackMode; |
541 | 4222 | 4335 | ||
542 | @@ -6295,8 +6408,6 @@ | |||
543 | 6295 | if (dbg) | 6408 | if (dbg) |
544 | 6296 | dbg->overrideRedirectRestack (priv->id, aboveId); | 6409 | dbg->overrideRedirectRestack (priv->id, aboveId); |
545 | 6297 | 6410 | ||
546 | 6298 | gettimeofday (&priv->lastConfigureRequest, NULL); | ||
547 | 6299 | |||
548 | 6300 | priv->attrib = wa; | 6411 | priv->attrib = wa; |
549 | 6301 | priv->serverGeometry.set (priv->attrib.x, priv->attrib.y, | 6412 | priv->serverGeometry.set (priv->attrib.x, priv->attrib.y, |
550 | 6302 | priv->attrib.width, priv->attrib.height, | 6413 | priv->attrib.width, priv->attrib.height, |
551 | @@ -7229,6 +7340,12 @@ | |||
552 | 7229 | XDestroyWindow (screen->dpy (), wrapper); | 7340 | XDestroyWindow (screen->dpy (), wrapper); |
553 | 7230 | 7341 | ||
554 | 7231 | window->windowNotify (CompWindowNotifyUnreparent); | 7342 | window->windowNotify (CompWindowNotifyUnreparent); |
555 | 7343 | /* This window is no longer "managed" in the | ||
556 | 7344 | * reparenting sense so clear its pending event | ||
557 | 7345 | * queue ... though maybe in future it would | ||
558 | 7346 | * be better to bookeep these events too and | ||
559 | 7347 | * handle the ReparentNotify */ | ||
560 | 7348 | pendingConfigures.clear (); | ||
561 | 7232 | 7349 | ||
562 | 7233 | frame = None; | 7350 | frame = None; |
563 | 7234 | wrapper = None; | 7351 | wrapper = None; |
code looks good, testing hasn't yet revealed any issues