Merge lp:~smspillaz/compiz-core/compiz-core.decor_synchronization into lp:compiz-core/0.9.8
- compiz-core.decor_synchronization
- Merge into 0.9.8
Status: | Superseded |
---|---|
Proposed branch: | lp:~smspillaz/compiz-core/compiz-core.decor_synchronization |
Merge into: | lp:compiz-core/0.9.8 |
Prerequisite: | lp:~smspillaz/compiz-core/compiz-core.work_923683 |
Diff against target: |
1457 lines (+849/-66) 15 files modified
gtk/window-decorator/decorator.c (+48/-24) gtk/window-decorator/events.c (+12/-1) gtk/window-decorator/gtk-window-decorator.c (+9/-0) gtk/window-decorator/gtk-window-decorator.h (+8/-0) gtk/window-decorator/wnck.c (+13/-11) include/decoration.h (+18/-0) libdecoration/decoration.c (+86/-0) plugins/decor/CMakeLists.txt (+3/-1) plugins/decor/src/decor.cpp (+99/-22) plugins/decor/src/decor.h (+35/-7) plugins/decor/src/pixmap-requests/CMakeLists.txt (+62/-0) plugins/decor/src/pixmap-requests/include/pixmap-requests.h (+188/-0) plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp (+93/-0) plugins/decor/src/pixmap-requests/tests/CMakeLists.txt (+15/-0) plugins/decor/src/pixmap-requests/tests/pixmap-requests/src/test-decor-pixmap-requests.cpp (+160/-0) |
To merge this branch: | bzr merge lp:~smspillaz/compiz-core/compiz-core.decor_synchronization |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel van Vugt | Pending | ||
Review via email: mp+103434@code.launchpad.net |
This proposal supersedes a proposal from 2012-04-20.
This proposal has been superseded by a proposal from 2012-04-25.
Commit message
Description of the change
Add synchronization primitives to the decoration protocol so that there isn't a race where we bind a texture that's being freed.
Tests included
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
For starters, there are non-trivial conflicts that need fixing.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
I've linked the two related bugs that I think this branch is designed to fix. It seems to.
Regression: Active windows often get inactive title bar decorations. For example, if I open a new terminal (Ctrl+Shift+N) then the new window gets activated and focused (and is usable), but keeps inactive decorations. There's not a single window on my screen with active window decorations now.
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
On Tue, 24 Apr 2012, Daniel van Vugt wrote:
> Review: Needs Fixing
>
> I've linked the two related bugs that I think this branch is designed to fix. It seems to.
>
> Regression: Active windows often get inactive title bar decorations. For
example, if I open a new terminal (Ctrl+Shift+N) then the new window gets
activated and focused (and is usable), but keeps inactive decorations.
There's not a single window on my screen with active window decorations now.\\\
I did not see this on my system. However, maybe it would be worth
requesting a pixmap redraw whenever the active state changes.
> --
> https:/
> You are the owner of lp:~smspillaz/compiz-core/compiz-core.decor_synchronization.
>
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal | # |
I'll deal with this a little later.
Unmerged revisions
Preview Diff
1 | === modified file 'gtk/window-decorator/decorator.c' |
2 | --- gtk/window-decorator/decorator.c 2012-03-30 07:01:48 +0000 |
3 | +++ gtk/window-decorator/decorator.c 2012-04-25 09:48:25 +0000 |
4 | @@ -564,6 +564,49 @@ |
5 | } |
6 | } |
7 | |
8 | +/* |
9 | + * request_update_window_decoration_size |
10 | + * Description: asks the rendering process to allow a size update |
11 | + * for pixmap synchronization */ |
12 | + |
13 | + |
14 | +gboolean |
15 | +request_update_window_decoration_size (WnckWindow *win) |
16 | +{ |
17 | + decor_t *d; |
18 | + gint width, height; |
19 | + gint x, y, w, h, name_width; |
20 | + |
21 | + if (win == NULL) |
22 | + return FALSE; |
23 | + |
24 | + d = g_object_get_data (G_OBJECT (win), "decor"); |
25 | + |
26 | + /* Get the geometry of the window, we'll need it later */ |
27 | + wnck_window_get_client_window_geometry (win, &x, &y, &w, &h); |
28 | + |
29 | + /* Get the width of the name */ |
30 | + name_width = max_window_name_width (win); |
31 | + |
32 | + /* Ask the theme to tell us how much space it needs. If this is not successful |
33 | + * update the decoration name and return false */ |
34 | + if (!(*theme_calc_decoration_size) (d, w, h, name_width, &width, &height)) |
35 | + { |
36 | + update_window_decoration_name (win); |
37 | + return FALSE; |
38 | + } |
39 | + |
40 | + d->width = width; |
41 | + d->height = height; |
42 | + |
43 | + decor_post_pending (gdk_x11_display_get_xdisplay (gdk_display_get_default ()), |
44 | + wnck_window_get_xid (win), |
45 | + populate_frame_type (d), |
46 | + populate_frame_state (d), |
47 | + populate_frame_actions (d)); |
48 | + |
49 | + return TRUE; |
50 | +} |
51 | |
52 | /* |
53 | * update_window_decoration_size |
54 | @@ -581,8 +624,6 @@ |
55 | decor_t *d; |
56 | GdkPixmap *pixmap, *buffer_pixmap = NULL; |
57 | Picture picture; |
58 | - gint width, height; |
59 | - gint x, y, w, h, name_width; |
60 | Display *xdisplay; |
61 | XRenderPictFormat *format; |
62 | |
63 | @@ -593,28 +634,14 @@ |
64 | |
65 | xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); |
66 | |
67 | - /* Get the geometry of the window, we'll need it later */ |
68 | - wnck_window_get_client_window_geometry (win, &x, &y, &w, &h); |
69 | - |
70 | - /* Get the width of the name */ |
71 | - name_width = max_window_name_width (win); |
72 | - |
73 | - /* Ask the theme to tell us how much space it needs. If this is not successful |
74 | - * update the decoration name and return false */ |
75 | - if (!(*theme_calc_decoration_size) (d, w, h, name_width, &width, &height)) |
76 | - { |
77 | - update_window_decoration_name (win); |
78 | - return FALSE; |
79 | - } |
80 | - |
81 | gdk_error_trap_push (); |
82 | |
83 | /* Get the correct depth for the frame window in reparenting mode, otherwise |
84 | * enforce 32 */ |
85 | if (d->frame_window) |
86 | - pixmap = create_pixmap (width, height, d->frame->style_window_rgb); |
87 | + pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgb); |
88 | else |
89 | - pixmap = create_pixmap (width, height, d->frame->style_window_rgba); |
90 | + pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgba); |
91 | |
92 | gdk_flush (); |
93 | |
94 | @@ -628,9 +655,9 @@ |
95 | gdk_error_trap_push (); |
96 | |
97 | if (d->frame_window) |
98 | - buffer_pixmap = create_pixmap (width, height, d->frame->style_window_rgb); |
99 | + buffer_pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgb); |
100 | else |
101 | - buffer_pixmap = create_pixmap (width, height, d->frame->style_window_rgba); |
102 | + buffer_pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgba); |
103 | |
104 | gdk_flush (); |
105 | |
106 | @@ -649,7 +676,7 @@ |
107 | |
108 | /* Destroy the old pixmaps and pictures */ |
109 | if (d->pixmap) |
110 | - g_object_unref (G_OBJECT (d->pixmap)); |
111 | + g_hash_table_insert (destroyed_pixmaps_table, GINT_TO_POINTER (GDK_PIXMAP_XID (d->pixmap)), d->pixmap); |
112 | |
113 | if (d->buffer_pixmap) |
114 | g_object_unref (G_OBJECT (d->buffer_pixmap)); |
115 | @@ -667,9 +694,6 @@ |
116 | |
117 | d->picture = picture; |
118 | |
119 | - d->width = width; |
120 | - d->height = height; |
121 | - |
122 | d->prop_xid = wnck_window_get_xid (win); |
123 | |
124 | update_window_decoration_name (win); |
125 | |
126 | === modified file 'gtk/window-decorator/events.c' |
127 | --- gtk/window-decorator/events.c 2012-03-30 07:01:48 +0000 |
128 | +++ gtk/window-decorator/events.c 2012-04-25 09:48:25 +0000 |
129 | @@ -1014,7 +1014,7 @@ |
130 | update_window_decoration_state (win); |
131 | update_window_decoration_actions (win); |
132 | update_window_decoration_icon (win); |
133 | - update_window_decoration_size (win); |
134 | + request_update_window_decoration_size (win); |
135 | update_event_windows (win); |
136 | } |
137 | else |
138 | @@ -1069,6 +1069,17 @@ |
139 | } |
140 | } |
141 | } |
142 | + else if (xevent->xclient.message_type == decor_request_atom) |
143 | + { |
144 | + WnckWindow *win = wnck_window_get (xevent->xclient.window); |
145 | + |
146 | + if (win) |
147 | + update_window_decoration_size (win); |
148 | + } |
149 | + else if (xevent->xclient.message_type == decor_delete_pixmap_atom) |
150 | + { |
151 | + g_hash_table_remove (destroyed_pixmaps_table, GINT_TO_POINTER (xevent->xclient.data.l[0])); |
152 | + } |
153 | default: |
154 | break; |
155 | } |
156 | |
157 | === modified file 'gtk/window-decorator/gtk-window-decorator.c' |
158 | --- gtk/window-decorator/gtk-window-decorator.c 2012-03-30 07:01:48 +0000 |
159 | +++ gtk/window-decorator/gtk-window-decorator.c 2012-04-25 09:48:25 +0000 |
160 | @@ -48,6 +48,9 @@ |
161 | Atom toolkit_action_atom; |
162 | Atom toolkit_action_window_menu_atom; |
163 | Atom toolkit_action_force_quit_dialog_atom; |
164 | +Atom decor_request_atom; |
165 | +Atom decor_pending_atom; |
166 | +Atom decor_delete_pixmap_atom; |
167 | |
168 | Atom net_wm_state_atom; |
169 | Atom net_wm_state_modal_atom; |
170 | @@ -103,6 +106,7 @@ |
171 | GtkWidget *switcher_label; |
172 | |
173 | GHashTable *frame_table; |
174 | +GHashTable *destroyed_pixmaps_table; |
175 | GtkWidget *action_menu = NULL; |
176 | gboolean action_menu_mapped = FALSE; |
177 | decor_color_t _title_color[2]; |
178 | @@ -305,6 +309,10 @@ |
179 | net_wm_state_atom = XInternAtom (xdisplay,"_NET_WM_STATE", 0); |
180 | net_wm_state_modal_atom = XInternAtom (xdisplay, "_NET_WM_STATE_MODAL", 0); |
181 | |
182 | + decor_request_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_REQUEST", 0); |
183 | + decor_pending_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_PENDING", 0); |
184 | + decor_delete_pixmap_atom = XInternAtom (xdisplay, "_COMPIZ_DECOR_DELETE_PIXMAP", 0); |
185 | + |
186 | status = decor_acquire_dm_session (xdisplay, |
187 | gdk_screen_get_number (gdkscreen), |
188 | "gwd", replace, &dm_sn_timestamp); |
189 | @@ -390,6 +398,7 @@ |
190 | xformat_rgb = XRenderFindStandardFormat (xdisplay, PictStandardRGB24); |
191 | |
192 | frame_table = g_hash_table_new (NULL, NULL); |
193 | + destroyed_pixmaps_table = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref); |
194 | |
195 | if (!create_tooltip_window ()) |
196 | { |
197 | |
198 | === modified file 'gtk/window-decorator/gtk-window-decorator.h' |
199 | --- gtk/window-decorator/gtk-window-decorator.h 2012-03-30 07:01:48 +0000 |
200 | +++ gtk/window-decorator/gtk-window-decorator.h 2012-04-25 09:48:25 +0000 |
201 | @@ -306,6 +306,9 @@ |
202 | extern Atom toolkit_action_force_quit_dialog_atom; |
203 | extern Atom net_wm_state_atom; |
204 | extern Atom net_wm_state_modal_atom; |
205 | +extern Atom decor_request_atom; |
206 | +extern Atom decor_pending_atom; |
207 | +extern Atom decor_delete_pixmap_atom; |
208 | |
209 | extern Time dm_sn_timestamp; |
210 | |
211 | @@ -511,6 +514,7 @@ |
212 | |
213 | /* list of all decorations */ |
214 | extern GHashTable *frame_table; |
215 | +extern GHashTable *destroyed_pixmaps_table; |
216 | |
217 | /* action menu */ |
218 | extern GtkWidget *action_menu; |
219 | @@ -628,9 +632,13 @@ |
220 | void |
221 | destroy_bare_frame (); |
222 | |
223 | +/* Don't use directly */ |
224 | gboolean |
225 | update_window_decoration_size (WnckWindow *win); |
226 | |
227 | +gboolean |
228 | +request_update_window_decoration_size (WnckWindow *win); |
229 | + |
230 | void |
231 | update_window_decoration_name (WnckWindow *win); |
232 | |
233 | |
234 | === modified file 'gtk/window-decorator/wnck.c' |
235 | --- gtk/window-decorator/wnck.c 2012-03-30 07:01:48 +0000 |
236 | +++ gtk/window-decorator/wnck.c 2012-04-25 09:48:25 +0000 |
237 | @@ -80,7 +80,7 @@ |
238 | |
239 | if (d->decorated) |
240 | { |
241 | - if (!update_window_decoration_size (win)) |
242 | + if (!request_update_window_decoration_size (win)) |
243 | queue_decor_draw (d); |
244 | } |
245 | } |
246 | @@ -102,7 +102,7 @@ |
247 | d->client_width = width; |
248 | d->client_height = height; |
249 | |
250 | - update_window_decoration_size (win); |
251 | + request_update_window_decoration_size (win); |
252 | update_event_windows (win); |
253 | } |
254 | } |
255 | @@ -128,7 +128,7 @@ |
256 | if (d->decorated) |
257 | { |
258 | update_window_decoration_state (win); |
259 | - if (!update_window_decoration_size (win)) |
260 | + if (!request_update_window_decoration_size (win)) |
261 | queue_decor_draw (d); |
262 | |
263 | update_event_windows (win); |
264 | @@ -143,7 +143,7 @@ |
265 | if (d->decorated) |
266 | { |
267 | update_window_decoration_actions (win); |
268 | - if (!update_window_decoration_size (win)) |
269 | + if (!request_update_window_decoration_size (win)) |
270 | queue_decor_draw (d); |
271 | |
272 | update_event_windows (win); |
273 | @@ -422,7 +422,7 @@ |
274 | update_window_decoration_state (win); |
275 | update_window_decoration_actions (win); |
276 | update_window_decoration_icon (win); |
277 | - update_window_decoration_size (win); |
278 | + request_update_window_decoration_size (win); |
279 | |
280 | update_event_windows (win); |
281 | } |
282 | @@ -585,7 +585,7 @@ |
283 | if (win) |
284 | { |
285 | d = g_object_get_data (G_OBJECT (win), "decor"); |
286 | - if (d && d->pixmap) |
287 | + if (d) |
288 | { |
289 | d->active = wnck_window_is_active (win); |
290 | |
291 | @@ -642,8 +642,9 @@ |
292 | * then we need to redraw the decoration anyways |
293 | * since the image would have changed */ |
294 | if (d->win != NULL && |
295 | - !update_window_decoration_size (d->win) && |
296 | - d->decorated) |
297 | + !request_update_window_decoration_size (d->win) && |
298 | + d->decorated && |
299 | + d->pixmap) |
300 | queue_decor_draw (d); |
301 | |
302 | } |
303 | @@ -653,7 +654,7 @@ |
304 | if (win) |
305 | { |
306 | d = g_object_get_data (G_OBJECT (win), "decor"); |
307 | - if (d && d->pixmap) |
308 | + if (d) |
309 | { |
310 | d->active = wnck_window_is_active (win); |
311 | |
312 | @@ -710,8 +711,9 @@ |
313 | * then we need to redraw the decoration anyways |
314 | * since the image would have changed */ |
315 | if (d->win != NULL && |
316 | - !update_window_decoration_size (d->win) && |
317 | - d->decorated) |
318 | + !request_update_window_decoration_size (d->win) && |
319 | + d->decorated && |
320 | + d->pixmap) |
321 | queue_decor_draw (d); |
322 | |
323 | } |
324 | |
325 | === modified file 'include/decoration.h' |
326 | --- include/decoration.h 2012-02-25 05:14:18 +0000 |
327 | +++ include/decoration.h 2012-04-25 09:48:25 +0000 |
328 | @@ -492,6 +492,24 @@ |
329 | XEvent *event, |
330 | Time dm_sn_timestamp); |
331 | |
332 | +int |
333 | +decor_post_pending (Display *xdisplay, |
334 | + Window client, |
335 | + unsigned int frame_state, |
336 | + unsigned int frame_type, |
337 | + unsigned int frame_actions); |
338 | + |
339 | +int |
340 | +decor_post_delete_pixmap (Display *xdisplay, |
341 | + Pixmap pixmap); |
342 | + |
343 | +int |
344 | +decor_post_generate_request (Display *xdisplay, |
345 | + Window client, |
346 | + unsigned int frame_type, |
347 | + unsigned int frame_state, |
348 | + unsigned int frame_actions); |
349 | + |
350 | #ifdef __cplusplus |
351 | } |
352 | #endif |
353 | |
354 | === modified file 'libdecoration/decoration.c' |
355 | --- libdecoration/decoration.c 2012-02-28 09:46:31 +0000 |
356 | +++ libdecoration/decoration.c 2012-04-25 09:48:25 +0000 |
357 | @@ -2877,6 +2877,92 @@ |
358 | } |
359 | |
360 | int |
361 | +decor_post_pending (Display *xdisplay, |
362 | + Window client, |
363 | + unsigned int frame_state, |
364 | + unsigned int frame_type, |
365 | + unsigned int frame_actions) |
366 | +{ |
367 | + XEvent event; |
368 | + |
369 | + Atom decor_pending = XInternAtom (xdisplay, "_COMPIZ_DECOR_PENDING", FALSE); |
370 | + |
371 | + /* Send a client message indicating that a new |
372 | + * decoration can be generated for this window |
373 | + */ |
374 | + event.xclient.type = ClientMessage; |
375 | + event.xclient.window = client; |
376 | + event.xclient.message_type = decor_pending; |
377 | + event.xclient.format = 32; |
378 | + event.xclient.data.l[0] = frame_type; |
379 | + event.xclient.data.l[1] = frame_state; |
380 | + event.xclient.data.l[2] = frame_actions; |
381 | + event.xclient.data.l[3] = 0; |
382 | + event.xclient.data.l[4] = 0; |
383 | + |
384 | + XSendEvent (xdisplay, DefaultRootWindow (xdisplay), 0, |
385 | + StructureNotifyMask, &event); |
386 | + |
387 | + return 1; |
388 | +} |
389 | + |
390 | +int |
391 | +decor_post_generate_request (Display *xdisplay, |
392 | + Window client, |
393 | + unsigned int frame_type, |
394 | + unsigned int frame_state, |
395 | + unsigned int frame_actions) |
396 | +{ |
397 | + XEvent event; |
398 | + |
399 | + Atom decor_request = XInternAtom (xdisplay, "_COMPIZ_DECOR_REQUEST", FALSE); |
400 | + |
401 | + /* Send a client message indicating that a new |
402 | + * decoration can be generated for this window |
403 | + */ |
404 | + event.xclient.type = ClientMessage; |
405 | + event.xclient.window = client; |
406 | + event.xclient.message_type = decor_request; |
407 | + event.xclient.format = 32; |
408 | + event.xclient.data.l[0] = frame_type; |
409 | + event.xclient.data.l[1] = frame_state; |
410 | + event.xclient.data.l[2] = frame_actions; |
411 | + event.xclient.data.l[3] = 0; |
412 | + event.xclient.data.l[4] = 0; |
413 | + |
414 | + XSendEvent (xdisplay, DefaultRootWindow (xdisplay), 0, |
415 | + StructureNotifyMask, &event); |
416 | + |
417 | + return 1; |
418 | +} |
419 | + |
420 | +int |
421 | +decor_post_delete_pixmap (Display *xdisplay, |
422 | + Pixmap pixmap) |
423 | +{ |
424 | + XEvent event; |
425 | + |
426 | + Atom decor_delete_pixmap = XInternAtom (xdisplay, "_COMPIZ_DECOR_DELETE_PIXMAP", FALSE); |
427 | + |
428 | + /* Send a client message indicating that a new |
429 | + * decoration can be generated for this window |
430 | + */ |
431 | + event.xclient.type = ClientMessage; |
432 | + event.xclient.window = DefaultRootWindow (xdisplay); |
433 | + event.xclient.message_type = decor_delete_pixmap; |
434 | + event.xclient.format = 32; |
435 | + event.xclient.data.l[0] = pixmap; |
436 | + event.xclient.data.l[1] = 0; |
437 | + event.xclient.data.l[2] = 0; |
438 | + event.xclient.data.l[3] = 0; |
439 | + event.xclient.data.l[4] = 0; |
440 | + |
441 | + XSendEvent (xdisplay, DefaultRootWindow (xdisplay), 0, |
442 | + StructureNotifyMask, &event); |
443 | + |
444 | + return 1; |
445 | +} |
446 | +int |
447 | decor_acquire_dm_session (Display *xdisplay, |
448 | int screen, |
449 | const char *name, |
450 | |
451 | === modified file 'plugins/decor/CMakeLists.txt' |
452 | --- plugins/decor/CMakeLists.txt 2012-03-30 14:29:18 +0000 |
453 | +++ plugins/decor/CMakeLists.txt 2012-04-25 09:48:25 +0000 |
454 | @@ -4,10 +4,12 @@ |
455 | include (CompizCommon) |
456 | |
457 | include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/clip-groups/include/) |
458 | +include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/pixmap-requests/include/) |
459 | |
460 | -compiz_plugin(decor PLUGINDEPS composite opengl LIBRARIES decoration compiz_decor_clip_groups) |
461 | +compiz_plugin(decor PLUGINDEPS composite opengl LIBRARIES decoration compiz_decor_clip_groups compiz_decor_pixmap_requests) |
462 | |
463 | add_subdirectory (src/clip-groups) |
464 | +add_subdirectory (src/pixmap-requests) |
465 | |
466 | if (COMPIZ_BUILD_WITH_RPATH AND NOT COMPIZ_DISABLE_PLUGIN_DECOR) |
467 | |
468 | |
469 | === modified file 'plugins/decor/src/decor.cpp' |
470 | --- plugins/decor/src/decor.cpp 2012-04-23 05:36:16 +0000 |
471 | +++ plugins/decor/src/decor.cpp 2012-04-25 09:48:25 +0000 |
472 | @@ -314,7 +314,6 @@ |
473 | } |
474 | |
475 | static bool bindFailed; |
476 | - |
477 | /* |
478 | * DecorTexture::DecorTexture |
479 | * |
480 | @@ -325,7 +324,7 @@ |
481 | * for this pixmap |
482 | */ |
483 | |
484 | -DecorTexture::DecorTexture (Pixmap pixmap) : |
485 | +DecorTexture::DecorTexture (DecorPixmapInterface::Ptr pixmap) : |
486 | status (true), |
487 | refCount (1), |
488 | pixmap (pixmap), |
489 | @@ -335,7 +334,7 @@ |
490 | Window root; |
491 | int i; |
492 | |
493 | - if (!XGetGeometry (screen->dpy (), pixmap, &root, |
494 | + if (!XGetGeometry (screen->dpy (), pixmap->getPixmap (), &root, |
495 | &i, &i, &width, &height, &ui, &depth)) |
496 | { |
497 | status = false; |
498 | @@ -343,7 +342,7 @@ |
499 | } |
500 | |
501 | bindFailed = false; |
502 | - textures = GLTexture::bindPixmapToTexture (pixmap, width, height, depth); |
503 | + textures = GLTexture::bindPixmapToTexture (pixmap->getPixmap (), width, height, depth); |
504 | if (textures.size () != 1) |
505 | { |
506 | bindFailed = true; |
507 | @@ -354,7 +353,7 @@ |
508 | if (!DecorScreen::get (screen)->optionGetMipmap ()) |
509 | textures[0]->setMipmap (false); |
510 | |
511 | - damage = XDamageCreate (screen->dpy (), pixmap, |
512 | + damage = XDamageCreate (screen->dpy (), pixmap->getPixmap (), |
513 | XDamageReportRawRectangles); |
514 | } |
515 | |
516 | @@ -389,13 +388,16 @@ |
517 | return NULL; |
518 | |
519 | foreach (DecorTexture *t, textures) |
520 | - if (t->pixmap == pixmap) |
521 | + if (t->pixmap->getPixmap () == pixmap) |
522 | { |
523 | t->refCount++; |
524 | return t; |
525 | } |
526 | |
527 | - DecorTexture *texture = new DecorTexture (pixmap); |
528 | + X11PixmapDeletor::Ptr dl = boost::make_shared <X11PixmapDeletor> (screen->dpy ()); |
529 | + DecorPixmap::Ptr pm = boost::make_shared <DecorPixmap> (pixmap, dl); |
530 | + |
531 | + DecorTexture *texture = new DecorTexture (boost::shared_static_cast <DecorPixmapInterface> (pm)); |
532 | |
533 | if (!texture->status) |
534 | { |
535 | @@ -531,7 +533,8 @@ |
536 | long *prop, |
537 | unsigned int size, |
538 | unsigned int type, |
539 | - unsigned int nOffset) |
540 | + unsigned int nOffset, |
541 | + DecorPixmapRequestorInterface *requestor) |
542 | { |
543 | unsigned int frameType, frameState, frameActions; |
544 | Pixmap pixmap = None; |
545 | @@ -579,7 +582,7 @@ |
546 | throw std::exception (); |
547 | } |
548 | |
549 | - return Decoration::Ptr (new Decoration (type, border, input, maxBorder, maxInput, frameType, frameState, frameActions, minWidth, minHeight, pixmap, quad, nQuad)); |
550 | + return Decoration::Ptr (new Decoration (type, border, input, maxBorder, maxInput, frameType, frameState, frameActions, minWidth, minHeight, pixmap, quad, nQuad, id, requestor)); |
551 | } |
552 | |
553 | Decoration::Decoration (int type, |
554 | @@ -594,7 +597,9 @@ |
555 | unsigned int minHeight, |
556 | Pixmap pixmap, |
557 | const boost::shared_array <decor_quad_t> &quad, |
558 | - unsigned int nQuad) : |
559 | + unsigned int nQuad, |
560 | + Window owner, |
561 | + DecorPixmapRequestorInterface *requestor) : |
562 | texture (DecorScreen::get (screen)->getTexture (pixmap)), |
563 | border (border.left, border.right, border.top, border.bottom), |
564 | input (input.left, input.right, input.top, input.bottom), |
565 | @@ -607,7 +612,9 @@ |
566 | frameActions (frameActions), |
567 | quad (quad), |
568 | nQuad (nQuad), |
569 | - type (type) |
570 | + type (type), |
571 | + updateState (0), |
572 | + mPixmapReceiver (requestor, this) |
573 | { |
574 | int left, right, top, bottom; |
575 | int x1, y1, x2, y2; |
576 | @@ -668,6 +675,30 @@ |
577 | DecorScreen::get (screen)->releaseTexture (texture); |
578 | } |
579 | |
580 | +DecorPixmapReceiverInterface & |
581 | +Decoration::receiverInterface () |
582 | +{ |
583 | + return mPixmapReceiver; |
584 | +} |
585 | + |
586 | +unsigned int |
587 | +Decoration::getFrameType () const |
588 | +{ |
589 | + return frameType; |
590 | +} |
591 | + |
592 | +unsigned int |
593 | +Decoration::getFrameState () const |
594 | +{ |
595 | + return frameState; |
596 | +} |
597 | + |
598 | +unsigned int |
599 | +Decoration::getFrameActions () const |
600 | +{ |
601 | + return frameActions; |
602 | +} |
603 | + |
604 | /* |
605 | * DecorationList is a class which allows multiple decorations |
606 | * to be stored in a list and read from a window property, which |
607 | @@ -703,7 +734,8 @@ |
608 | |
609 | bool |
610 | DecorationList::updateDecoration (Window id, |
611 | - Atom decorAtom) |
612 | + Atom decorAtom, |
613 | + DecorPixmapRequestorInterface *requestor) |
614 | { |
615 | unsigned long n, nleft; |
616 | unsigned char *data; |
617 | @@ -712,6 +744,12 @@ |
618 | int result, format; |
619 | unsigned int type; |
620 | |
621 | + /* Dispatch any new updates */ |
622 | + foreach (const Decoration::Ptr &d, mList) |
623 | + { |
624 | + d->mPixmapReceiver.update (); |
625 | + } |
626 | + |
627 | result = XGetWindowProperty (screen->dpy (), id, |
628 | decorAtom, 0L, |
629 | PROP_HEADER_SIZE + 6 * (BASE_PROP_SIZE + |
630 | @@ -781,7 +819,9 @@ |
631 | maxBorder.top = d->maxBorder.top; |
632 | maxBorder.bottom = d->maxBorder.bottom; |
633 | |
634 | - int num = decor_match_pixmap (prop, n, &d->texture->pixmap, &input, &border, &maxInput, &maxBorder, |
635 | + Pixmap pm = d->texture->pixmap->getPixmap (); |
636 | + |
637 | + int num = decor_match_pixmap (prop, n, &pm, &input, &border, &maxInput, &maxBorder, |
638 | d->minWidth, d->minHeight, d->frameType, d->frameState, d->frameActions, |
639 | d->quad.get (), d->nQuad); |
640 | if (num != -1) |
641 | @@ -799,7 +839,7 @@ |
642 | try |
643 | { |
644 | std::list <Decoration::Ptr>::iterator it = mList.begin (); |
645 | - Decoration::Ptr d = Decoration::create (id, prop, n, type, i); |
646 | + Decoration::Ptr d = Decoration::create (id, prop, n, type, i, requestor); |
647 | |
648 | /* Try to replace an existing decoration */ |
649 | for (; it != mList.end (); it++) |
650 | @@ -884,7 +924,7 @@ |
651 | { |
652 | bindFailed = false; |
653 | |
654 | - decor.updateDecoration (window->id (), dScreen->winDecorAtom); |
655 | + decor.updateDecoration (window->id (), dScreen->winDecorAtom, &mRequestor); |
656 | if (bindFailed) |
657 | pixmapFailed = true; |
658 | else |
659 | @@ -1253,6 +1293,22 @@ |
660 | return (decorActions == 0); |
661 | } |
662 | |
663 | +DecorationInterface::Ptr |
664 | +DecorationList::findMatchingDecoration (unsigned int frameType, |
665 | + unsigned int frameState, |
666 | + unsigned int frameActions) |
667 | +{ |
668 | + foreach (const Decoration::Ptr &d, mList) |
669 | + { |
670 | + if (d->frameType == frameType && |
671 | + d->frameState == frameState && |
672 | + d->frameActions == frameActions) |
673 | + return boost::shared_static_cast <DecorationInterface> (d); |
674 | + } |
675 | + |
676 | + return DecorationInterface::Ptr (); |
677 | +} |
678 | + |
679 | /* |
680 | * DecorationList::findMatchingDecoration |
681 | * |
682 | @@ -2077,7 +2133,7 @@ |
683 | { |
684 | for (i = 0; i < DECOR_NUM; i++) |
685 | { |
686 | - decor[i].updateDecoration (screen->root (), decorAtom[i]); |
687 | + decor[i].updateDecoration (screen->root (), decorAtom[i], &mRequestor); |
688 | } |
689 | } |
690 | else |
691 | @@ -2289,6 +2345,7 @@ |
692 | isSwitcher = false; |
693 | } |
694 | |
695 | + |
696 | /* |
697 | * DecorScreen::handleEvent |
698 | * |
699 | @@ -2323,6 +2380,18 @@ |
700 | if (w) |
701 | DecorWindow::get (w)->update (true); |
702 | } |
703 | + /* A decoration is pending creation, allow it to be created */ |
704 | + if (event->xclient.message_type == decorPendingAtom) |
705 | + { |
706 | + CompWindow *w = screen->findWindow (event->xclient.window); |
707 | + |
708 | + if (w) |
709 | + { |
710 | + DecorWindow *dw = DecorWindow::get (w); |
711 | + |
712 | + dw->mRequestor.handlePending (event->xclient.data.l); |
713 | + } |
714 | + } |
715 | default: |
716 | /* Check for damage events. If the output or input window |
717 | * or a texture is updated then damage output extents. |
718 | @@ -2337,7 +2406,7 @@ |
719 | |
720 | foreach (DecorTexture *t, textures) |
721 | { |
722 | - if (t->pixmap == de->drawable) |
723 | + if (t->pixmap->getPixmap () == de->drawable) |
724 | { |
725 | foreach (CompWindow *w, screen->windows ()) |
726 | { |
727 | @@ -2397,7 +2466,6 @@ |
728 | DECOR_WINDOW (w); |
729 | |
730 | dw->updateDecoration (); |
731 | - |
732 | dw->update (true); |
733 | } |
734 | } |
735 | @@ -2430,7 +2498,8 @@ |
736 | if (event->xproperty.atom == decorAtom[i]) |
737 | { |
738 | decor[i].updateDecoration (screen->root (), |
739 | - decorAtom[i]); |
740 | + decorAtom[i], |
741 | + &mRequestor); |
742 | |
743 | foreach (CompWindow *w, screen->windows ()) |
744 | DecorWindow::get (w)->update (true); |
745 | @@ -2947,8 +3016,11 @@ |
746 | 0, |
747 | None, |
748 | boost::shared_array <decor_quad_t> (NULL), |
749 | - 0)), |
750 | - mMenusClipGroup (CompMatch ("type=Dock | type=DropdownMenu | type=PopupMenu")) |
751 | + 0, |
752 | + screen->root (), |
753 | + NULL)), |
754 | + mMenusClipGroup (CompMatch ("type=Dock | type=DropdownMenu | type=PopupMenu")), |
755 | + mRequestor (screen->dpy (), screen->root (), &(decor[DECOR_ACTIVE])) |
756 | { |
757 | supportingDmCheckAtom = |
758 | XInternAtom (s->dpy (), DECOR_SUPPORTING_DM_CHECK_ATOM_NAME, 0); |
759 | @@ -2970,6 +3042,10 @@ |
760 | XInternAtom (s->dpy (), DECOR_TYPE_WINDOW_ATOM_NAME, 0); |
761 | decorSwitchWindowAtom = |
762 | XInternAtom (s->dpy (), DECOR_SWITCH_WINDOW_ATOM_NAME, 0); |
763 | + decorPendingAtom = |
764 | + XInternAtom (s->dpy (), "_COMPIZ_DECOR_PENDING", 0); |
765 | + decorRequestAtom = |
766 | + XInternAtom (s->dpy (), "_COMPIZ_DECOR_REQUEST", 0); |
767 | requestFrameExtentsAtom = |
768 | XInternAtom (s->dpy (), "_NET_REQUEST_FRAME_EXTENTS", 0); |
769 | shadowColorAtom = |
770 | @@ -3026,7 +3102,8 @@ |
771 | frameExtentsRequested (false), |
772 | mClipGroup (NULL), |
773 | mOutputRegion (window->outputRect ()), |
774 | - mInputRegion (window->inputRect ()) |
775 | + mInputRegion (window->inputRect ()), |
776 | + mRequestor (screen->dpy (), w->id (), &decor) |
777 | { |
778 | WindowInterface::setHandler (window); |
779 | |
780 | |
781 | === modified file 'plugins/decor/src/decor.h' |
782 | --- plugins/decor/src/decor.h 2012-04-23 05:36:16 +0000 |
783 | +++ plugins/decor/src/decor.h 2012-04-25 09:48:25 +0000 |
784 | @@ -25,6 +25,7 @@ |
785 | |
786 | #include <boost/shared_ptr.hpp> |
787 | #include <boost/shared_array.hpp> |
788 | +#include <boost/make_shared.hpp> |
789 | #include <core/window.h> |
790 | #include <core/pluginclasshandler.h> |
791 | |
792 | @@ -34,6 +35,7 @@ |
793 | #include <core/windowextents.h> |
794 | |
795 | #include <clip-groups.h> |
796 | +#include <pixmap-requests.h> |
797 | |
798 | #include "decor_options.h" |
799 | |
800 | @@ -76,30 +78,36 @@ |
801 | class DecorTexture { |
802 | |
803 | public: |
804 | - DecorTexture (Pixmap pixmap); |
805 | + DecorTexture (DecorPixmapInterface::Ptr pixmap); |
806 | ~DecorTexture (); |
807 | |
808 | public: |
809 | bool status; |
810 | int refCount; |
811 | - Pixmap pixmap; |
812 | + DecorPixmapInterface::Ptr pixmap; |
813 | Damage damage; |
814 | GLTexture::List textures; |
815 | }; |
816 | |
817 | class DecorWindow; |
818 | |
819 | -class Decoration { |
820 | +class Decoration : |
821 | + public DecorationInterface |
822 | +{ |
823 | |
824 | public: |
825 | |
826 | typedef boost::shared_ptr <Decoration> Ptr; |
827 | |
828 | + static const unsigned int UpdateRequested = 1 << 0; |
829 | + static const unsigned int UpdatesPending = 1 << 1; |
830 | + |
831 | static Decoration::Ptr create (Window id, |
832 | long *prop, |
833 | unsigned int size, |
834 | unsigned int type, |
835 | - unsigned int nOffset); |
836 | + unsigned int nOffset, |
837 | + DecorPixmapRequestorInterface *requestor); |
838 | |
839 | Decoration (int type, |
840 | const decor_extents_t &border, |
841 | @@ -113,10 +121,18 @@ |
842 | unsigned int minHeight, |
843 | Pixmap pixmap, |
844 | const boost::shared_array <decor_quad_t> &quad, |
845 | - unsigned int nQuad); |
846 | + unsigned int nQuad, |
847 | + Window owner, |
848 | + DecorPixmapRequestorInterface *); |
849 | |
850 | ~Decoration (); |
851 | |
852 | + DecorPixmapReceiverInterface & receiverInterface (); |
853 | + |
854 | + unsigned int getFrameType () const; |
855 | + unsigned int getFrameState () const; |
856 | + unsigned int getFrameActions () const; |
857 | + |
858 | public: |
859 | int refCount; |
860 | DecorTexture *texture; |
861 | @@ -133,12 +149,19 @@ |
862 | boost::shared_array <decor_quad_t> quad; |
863 | int nQuad; |
864 | int type; |
865 | + |
866 | + unsigned int updateState; |
867 | + X11DecorPixmapReceiver mPixmapReceiver; |
868 | }; |
869 | |
870 | -class DecorationList |
871 | +class DecorationList : |
872 | + public DecorationListFindMatchingInterface |
873 | { |
874 | public: |
875 | - bool updateDecoration (Window id, Atom decorAtom); |
876 | + bool updateDecoration (Window id, Atom decorAtom, DecorPixmapRequestorInterface *requestor); |
877 | + DecorationInterface::Ptr findMatchingDecoration(unsigned int frameType, |
878 | + unsigned int frameState, |
879 | + unsigned int frameActions); |
880 | const Decoration::Ptr & findMatchingDecoration (CompWindow *w, bool sizeCheck); |
881 | void clear () |
882 | { |
883 | @@ -215,6 +238,8 @@ |
884 | Atom shadowColorAtom; |
885 | Atom shadowInfoAtom; |
886 | Atom decorSwitchWindowAtom; |
887 | + Atom decorPendingAtom; |
888 | + Atom decorRequestAtom; |
889 | |
890 | Window dmWin; |
891 | int dmSupports; |
892 | @@ -229,6 +254,7 @@ |
893 | CompTimer decoratorStart; |
894 | |
895 | MatchedDecorClipGroup mMenusClipGroup; |
896 | + X11DecorPixmapRequestor mRequestor; |
897 | }; |
898 | |
899 | class DecorWindow : |
900 | @@ -334,6 +360,8 @@ |
901 | DecorClipGroupInterface *mClipGroup; |
902 | CompRegion mOutputRegion; |
903 | CompRegion mInputRegion; |
904 | + |
905 | + X11DecorPixmapRequestor mRequestor; |
906 | }; |
907 | |
908 | class DecorPluginVTable : |
909 | |
910 | === added directory 'plugins/decor/src/pixmap-requests' |
911 | === added file 'plugins/decor/src/pixmap-requests/CMakeLists.txt' |
912 | --- plugins/decor/src/pixmap-requests/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
913 | +++ plugins/decor/src/pixmap-requests/CMakeLists.txt 2012-04-25 09:48:25 +0000 |
914 | @@ -0,0 +1,62 @@ |
915 | +pkg_check_modules ( |
916 | + GLIBMM |
917 | + REQUIRED |
918 | + glibmm-2.4 glib-2.0 |
919 | +) |
920 | + |
921 | +INCLUDE_DIRECTORIES ( |
922 | + ${CMAKE_CURRENT_SOURCE_DIR}/include |
923 | + ${CMAKE_CURRENT_SOURCE_DIR}/src |
924 | + |
925 | + ${compiz_SOURCE_DIR}/src/point/include |
926 | + ${compiz_SOURCE_DIR}/src/rect/include |
927 | + ${compiz_SOURCE_DIR}/src/window/geometry/include |
928 | + ${compiz_SOURCE_DIR}/src/window/geometry-saver/include |
929 | + ${compiz_SOURCE_DIR}/src/window/extents/include |
930 | + ${compiz_SOURCE_DIR}/include |
931 | + |
932 | + ${Boost_INCLUDE_DIRS} |
933 | + |
934 | + ${GLIBMM_INCLUDE_DIRS} |
935 | +) |
936 | + |
937 | +LINK_DIRECTORIES (${GLIBMM_LIBRARY_DIRS}) |
938 | + |
939 | +SET ( |
940 | + PUBLIC_HEADERS |
941 | +) |
942 | + |
943 | +SET ( |
944 | + PRIVATE_HEADERS |
945 | + ${CMAKE_CURRENT_SOURCE_DIR}/include/pixmap-requests.h |
946 | +) |
947 | + |
948 | +SET( |
949 | + SRCS |
950 | + ${CMAKE_CURRENT_SOURCE_DIR}/src/pixmap-requests.cpp |
951 | +) |
952 | + |
953 | +ADD_LIBRARY( |
954 | + compiz_decor_pixmap_requests STATIC |
955 | + |
956 | + ${SRCS} |
957 | + |
958 | + ${PUBLIC_HEADERS} |
959 | + ${PRIVATE_HEADERS} |
960 | +) |
961 | + |
962 | +if (COMPIZ_BUILD_TESTING) |
963 | +ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests ) |
964 | +endif (COMPIZ_BUILD_TESTING) |
965 | + |
966 | +SET_TARGET_PROPERTIES( |
967 | + compiz_decor_pixmap_requests PROPERTIES |
968 | + PUBLIC_HEADER "${PUBLIC_HEADERS}" |
969 | +) |
970 | + |
971 | +TARGET_LINK_LIBRARIES( |
972 | + compiz_decor_pixmap_requests |
973 | + |
974 | + compiz_core |
975 | + ${GLIBMM_LIBRARIES} |
976 | +) |
977 | |
978 | === added directory 'plugins/decor/src/pixmap-requests/include' |
979 | === added file 'plugins/decor/src/pixmap-requests/include/pixmap-requests.h' |
980 | --- plugins/decor/src/pixmap-requests/include/pixmap-requests.h 1970-01-01 00:00:00 +0000 |
981 | +++ plugins/decor/src/pixmap-requests/include/pixmap-requests.h 2012-04-25 09:48:25 +0000 |
982 | @@ -0,0 +1,188 @@ |
983 | +/* |
984 | + * Copyright © 2005 Novell, Inc. |
985 | + * |
986 | + * Permission to use, copy, modify, distribute, and sell this software |
987 | + * and its documentation for any purpose is hereby granted without |
988 | + * fee, provided that the above copyright notice appear in all copies |
989 | + * and that both that copyright notice and this permission notice |
990 | + * appear in supporting documentation, and that the name of |
991 | + * Novell, Inc. not be used in advertising or publicity pertaining to |
992 | + * distribution of the software without specific, written prior permission. |
993 | + * Novell, Inc. makes no representations about the suitability of this |
994 | + * software for any purpose. It is provided "as is" without express or |
995 | + * implied warranty. |
996 | + * |
997 | + * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
998 | + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
999 | + * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
1000 | + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
1001 | + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
1002 | + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
1003 | + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
1004 | + * |
1005 | + * Author: David Reveman <davidr@novell.com> |
1006 | + */ |
1007 | + |
1008 | +#ifndef _COMPIZ_DECOR_PIXMAP_REQUESTS_H |
1009 | +#define _COMPIZ_DECOR_PIXMAP_REQUESTS_H |
1010 | + |
1011 | +#include <boost/shared_ptr.hpp> |
1012 | +#include <boost/shared_array.hpp> |
1013 | +#include <boost/make_shared.hpp> |
1014 | +#include <decoration.h> |
1015 | + |
1016 | +#include <X11/Xlib.h> |
1017 | + |
1018 | +class DecorPixmapInterface |
1019 | +{ |
1020 | + public: |
1021 | + |
1022 | + typedef boost::shared_ptr <DecorPixmapInterface> Ptr; |
1023 | + |
1024 | + virtual ~DecorPixmapInterface () {}; |
1025 | + |
1026 | + virtual Pixmap getPixmap () = 0; |
1027 | +}; |
1028 | + |
1029 | +class DecorPixmapReceiverInterface |
1030 | +{ |
1031 | + public: |
1032 | + |
1033 | + virtual ~DecorPixmapReceiverInterface () {} |
1034 | + |
1035 | + virtual void pending () = 0; |
1036 | + virtual void update () = 0; |
1037 | +}; |
1038 | + |
1039 | +/* So far, nothing particularly interesting here |
1040 | + * we just need a way to pass around pointers for |
1041 | + * testing */ |
1042 | +class DecorationInterface |
1043 | +{ |
1044 | + public: |
1045 | + |
1046 | + typedef boost::shared_ptr <DecorationInterface> Ptr; |
1047 | + |
1048 | + virtual ~DecorationInterface () {} |
1049 | + |
1050 | + virtual DecorPixmapReceiverInterface & receiverInterface () = 0; |
1051 | + virtual unsigned int getFrameType () const = 0; |
1052 | + virtual unsigned int getFrameState () const = 0; |
1053 | + virtual unsigned int getFrameActions () const = 0; |
1054 | +}; |
1055 | + |
1056 | +class DecorPixmapDeletionInterface |
1057 | +{ |
1058 | + public: |
1059 | + |
1060 | + typedef boost::shared_ptr <DecorPixmapDeletionInterface> Ptr; |
1061 | + |
1062 | + virtual ~DecorPixmapDeletionInterface () {} |
1063 | + |
1064 | + virtual int postDeletePixmap (Pixmap pixmap) = 0; |
1065 | +}; |
1066 | + |
1067 | +class X11PixmapDeletor : |
1068 | + public DecorPixmapDeletionInterface |
1069 | +{ |
1070 | + public: |
1071 | + |
1072 | + typedef boost::shared_ptr <X11PixmapDeletor> Ptr; |
1073 | + |
1074 | + X11PixmapDeletor (Display *dpy) : |
1075 | + mDisplay (dpy) |
1076 | + { |
1077 | + } |
1078 | + |
1079 | + int postDeletePixmap (Pixmap pixmap) { return decor_post_delete_pixmap (mDisplay, pixmap); } |
1080 | + |
1081 | + private: |
1082 | + |
1083 | + Display *mDisplay; |
1084 | +}; |
1085 | + |
1086 | +class DecorPixmap : |
1087 | + public DecorPixmapInterface |
1088 | +{ |
1089 | + public: |
1090 | + |
1091 | + typedef boost::shared_ptr <DecorPixmap> Ptr; |
1092 | + |
1093 | + DecorPixmap (Pixmap p, DecorPixmapDeletionInterface::Ptr deletor); |
1094 | + ~DecorPixmap (); |
1095 | + |
1096 | + Pixmap getPixmap (); |
1097 | + |
1098 | + private: |
1099 | + |
1100 | + Pixmap mPixmap; |
1101 | + DecorPixmapDeletionInterface::Ptr mDeletor; |
1102 | +}; |
1103 | + |
1104 | +class DecorPixmapRequestorInterface |
1105 | +{ |
1106 | + public: |
1107 | + |
1108 | + virtual ~DecorPixmapRequestorInterface () {} |
1109 | + |
1110 | + virtual int postGenerateRequest (unsigned int frameType, |
1111 | + unsigned int frameState, |
1112 | + unsigned int frameActions) = 0; |
1113 | + |
1114 | + virtual void handlePending (long *data) = 0; |
1115 | +}; |
1116 | + |
1117 | +class DecorationListFindMatchingInterface |
1118 | +{ |
1119 | + public: |
1120 | + |
1121 | + virtual ~DecorationListFindMatchingInterface () {} |
1122 | + |
1123 | + virtual DecorationInterface::Ptr findMatchingDecoration (unsigned int frameType, |
1124 | + unsigned int frameState, |
1125 | + unsigned int frameActions) = 0; |
1126 | +}; |
1127 | + |
1128 | +class X11DecorPixmapRequestor : |
1129 | + public DecorPixmapRequestorInterface |
1130 | +{ |
1131 | + public: |
1132 | + |
1133 | + X11DecorPixmapRequestor (Display *dpy, |
1134 | + Window xid, |
1135 | + DecorationListFindMatchingInterface *listFinder); |
1136 | + |
1137 | + int postGenerateRequest (unsigned int frameType, |
1138 | + unsigned int frameState, |
1139 | + unsigned int frameActions); |
1140 | + |
1141 | + void handlePending (long *data); |
1142 | + |
1143 | + private: |
1144 | + |
1145 | + Display *mDpy; |
1146 | + Window mWindow; |
1147 | + DecorationListFindMatchingInterface *mListFinder; |
1148 | +}; |
1149 | + |
1150 | +class X11DecorPixmapReceiver : |
1151 | + public DecorPixmapReceiverInterface |
1152 | +{ |
1153 | + public: |
1154 | + |
1155 | + static const unsigned int UpdateRequested = 1 << 0; |
1156 | + static const unsigned int UpdatesPending = 1 << 1; |
1157 | + |
1158 | + X11DecorPixmapReceiver (DecorPixmapRequestorInterface *, |
1159 | + DecorationInterface *decor); |
1160 | + |
1161 | + void pending (); |
1162 | + void update (); |
1163 | + private: |
1164 | + |
1165 | + unsigned int mUpdateState; |
1166 | + DecorPixmapRequestorInterface *mDecorPixmapRequestor; |
1167 | + DecorationInterface *mDecoration; |
1168 | +}; |
1169 | + |
1170 | +#endif |
1171 | |
1172 | === added directory 'plugins/decor/src/pixmap-requests/src' |
1173 | === added file 'plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp' |
1174 | --- plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp 1970-01-01 00:00:00 +0000 |
1175 | +++ plugins/decor/src/pixmap-requests/src/pixmap-requests.cpp 2012-04-25 09:48:25 +0000 |
1176 | @@ -0,0 +1,93 @@ |
1177 | +#include "pixmap-requests.h" |
1178 | +#include <boost/foreach.hpp> |
1179 | +#include <algorithm> |
1180 | + |
1181 | +#ifndef foreach |
1182 | +#define foreach BOOST_FOREACH |
1183 | +#endif |
1184 | + |
1185 | +DecorPixmap::DecorPixmap (Pixmap pixmap, DecorPixmapDeletionInterface::Ptr d) : |
1186 | + mPixmap (pixmap), |
1187 | + mDeletor (d) |
1188 | +{ |
1189 | +} |
1190 | + |
1191 | +DecorPixmap::~DecorPixmap () |
1192 | +{ |
1193 | + mDeletor->postDeletePixmap (mPixmap); |
1194 | +} |
1195 | + |
1196 | +Pixmap |
1197 | +DecorPixmap::getPixmap () |
1198 | +{ |
1199 | + return mPixmap; |
1200 | +} |
1201 | + |
1202 | +X11DecorPixmapReceiver::X11DecorPixmapReceiver (DecorPixmapRequestorInterface *requestor, |
1203 | + DecorationInterface *decor) : |
1204 | + mUpdateState (0), |
1205 | + mDecorPixmapRequestor (requestor), |
1206 | + mDecoration (decor) |
1207 | +{ |
1208 | +} |
1209 | + |
1210 | +void |
1211 | +X11DecorPixmapReceiver::pending () |
1212 | +{ |
1213 | + if (mUpdateState & X11DecorPixmapReceiver::UpdateRequested) |
1214 | + mUpdateState |= X11DecorPixmapReceiver::UpdatesPending; |
1215 | + else |
1216 | + { |
1217 | + mUpdateState |= X11DecorPixmapReceiver::UpdateRequested; |
1218 | + |
1219 | + mDecorPixmapRequestor->postGenerateRequest (mDecoration->getFrameType (), |
1220 | + mDecoration->getFrameState (), |
1221 | + mDecoration->getFrameActions ()); |
1222 | + } |
1223 | +} |
1224 | + |
1225 | +void X11DecorPixmapReceiver::update () |
1226 | +{ |
1227 | + if (mUpdateState & X11DecorPixmapReceiver::UpdatesPending) |
1228 | + mDecorPixmapRequestor->postGenerateRequest (mDecoration->getFrameType (), |
1229 | + mDecoration->getFrameState (), |
1230 | + mDecoration->getFrameActions ()); |
1231 | + |
1232 | + mUpdateState = 0; |
1233 | +} |
1234 | + |
1235 | +X11DecorPixmapRequestor::X11DecorPixmapRequestor (Display *dpy, |
1236 | + Window window, |
1237 | + DecorationListFindMatchingInterface *listFinder) : |
1238 | + mDpy (dpy), |
1239 | + mWindow (window), |
1240 | + mListFinder (listFinder) |
1241 | +{ |
1242 | +} |
1243 | + |
1244 | +int |
1245 | +X11DecorPixmapRequestor::postGenerateRequest (unsigned int frameType, |
1246 | + unsigned int frameState, |
1247 | + unsigned int frameActions) |
1248 | +{ |
1249 | + return decor_post_generate_request (mDpy, |
1250 | + mWindow, |
1251 | + frameType, |
1252 | + frameState, |
1253 | + frameActions); |
1254 | +} |
1255 | + |
1256 | +void |
1257 | +X11DecorPixmapRequestor::handlePending (long *data) |
1258 | +{ |
1259 | + DecorationInterface::Ptr d = mListFinder->findMatchingDecoration (static_cast <unsigned int> (data[0]), |
1260 | + static_cast <unsigned int> (data[1]), |
1261 | + static_cast <unsigned int> (data[2])); |
1262 | + |
1263 | + if (d) |
1264 | + d->receiverInterface ().pending (); |
1265 | + else |
1266 | + postGenerateRequest (static_cast <unsigned int> (data[0]), |
1267 | + static_cast <unsigned int> (data[1]), |
1268 | + static_cast <unsigned int> (data[2])); |
1269 | +} |
1270 | |
1271 | === added directory 'plugins/decor/src/pixmap-requests/tests' |
1272 | === added file 'plugins/decor/src/pixmap-requests/tests/CMakeLists.txt' |
1273 | --- plugins/decor/src/pixmap-requests/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1274 | +++ plugins/decor/src/pixmap-requests/tests/CMakeLists.txt 2012-04-25 09:48:25 +0000 |
1275 | @@ -0,0 +1,15 @@ |
1276 | +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) |
1277 | + |
1278 | +add_executable (compiz_test_decor_pixmap_requests |
1279 | + ${CMAKE_CURRENT_SOURCE_DIR}/pixmap-requests/src/test-decor-pixmap-requests.cpp) |
1280 | + |
1281 | +target_link_libraries (compiz_test_decor_pixmap_requests |
1282 | + compiz_decor_pixmap_requests |
1283 | + decoration |
1284 | + ${GTEST_BOTH_LIBRARIES} |
1285 | + ${GMOCK_LIBRARY} |
1286 | + ${GMOCK_MAIN_LIBRARY} |
1287 | + ${CMAKE_THREAD_LIBS_INIT} # Link in pthread. |
1288 | + ) |
1289 | + |
1290 | +gtest_add_tests (compiz_test_decor_pixmap_requests "" ${CMAKE_CURRENT_SOURCE_DIR}/pixmap-requests/src/test-decor-pixmap-requests.cpp) |
1291 | |
1292 | === added directory 'plugins/decor/src/pixmap-requests/tests/pixmap-requests' |
1293 | === added directory 'plugins/decor/src/pixmap-requests/tests/pixmap-requests/src' |
1294 | === added file 'plugins/decor/src/pixmap-requests/tests/pixmap-requests/src/test-decor-pixmap-requests.cpp' |
1295 | --- plugins/decor/src/pixmap-requests/tests/pixmap-requests/src/test-decor-pixmap-requests.cpp 1970-01-01 00:00:00 +0000 |
1296 | +++ plugins/decor/src/pixmap-requests/tests/pixmap-requests/src/test-decor-pixmap-requests.cpp 2012-04-25 09:48:25 +0000 |
1297 | @@ -0,0 +1,160 @@ |
1298 | +/* |
1299 | + * Copyright © 2012 Canonical Ltd. |
1300 | + * |
1301 | + * Permission to use, copy, modify, distribute, and sell this software |
1302 | + * and its documentation for any purpose is hereby granted without |
1303 | + * fee, provided that the above copyright notice appear in all copies |
1304 | + * and that both that copyright notice and this permission notice |
1305 | + * appear in supporting documentation, and that the name of |
1306 | + * Canonical Ltd. not be used in advertising or publicity pertaining to |
1307 | + * distribution of the software without specific, written prior permission. |
1308 | + * Canonical Ltd. makes no representations about the suitability of this |
1309 | + * software for any purpose. It is provided "as is" without express or |
1310 | + * implied warranty. |
1311 | + * |
1312 | + * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
1313 | + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN |
1314 | + * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
1315 | + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |
1316 | + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
1317 | + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION |
1318 | + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
1319 | + * |
1320 | + * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com> |
1321 | + */ |
1322 | + |
1323 | +#include <gtest/gtest.h> |
1324 | +#include <gmock/gmock.h> |
1325 | +#include <iostream> |
1326 | +#include "pixmap-requests.h" |
1327 | + |
1328 | +using ::testing::Return; |
1329 | + |
1330 | +class DecorPixmapRequestsTest : |
1331 | + public ::testing::Test |
1332 | +{ |
1333 | +}; |
1334 | + |
1335 | +class MockDecorPixmapDeletor : |
1336 | + public DecorPixmapDeletionInterface |
1337 | +{ |
1338 | + public: |
1339 | + |
1340 | + MOCK_METHOD1 (postDeletePixmap, int (Pixmap p)); |
1341 | +}; |
1342 | + |
1343 | +class MockDecorPixmapReceiver : |
1344 | + public DecorPixmapReceiverInterface |
1345 | +{ |
1346 | + public: |
1347 | + |
1348 | + MOCK_METHOD0 (pending, void ()); |
1349 | + MOCK_METHOD0 (update, void ()); |
1350 | +}; |
1351 | + |
1352 | +class MockDecoration : |
1353 | + public DecorationInterface |
1354 | +{ |
1355 | + public: |
1356 | + |
1357 | + MOCK_METHOD0 (receiverInterface, DecorPixmapReceiverInterface & ()); |
1358 | + MOCK_CONST_METHOD0 (getFrameType, unsigned int ()); |
1359 | + MOCK_CONST_METHOD0 (getFrameState, unsigned int ()); |
1360 | + MOCK_CONST_METHOD0 (getFrameActions, unsigned int ()); |
1361 | +}; |
1362 | + |
1363 | +class MockDecorationListFindMatching : |
1364 | + public DecorationListFindMatchingInterface |
1365 | +{ |
1366 | + public: |
1367 | + |
1368 | + MOCK_METHOD3 (findMatchingDecoration, DecorationInterface::Ptr (unsigned int, unsigned int, unsigned int)); |
1369 | +}; |
1370 | + |
1371 | +class MockDecorPixmapRequestor : |
1372 | + public DecorPixmapRequestorInterface |
1373 | +{ |
1374 | + public: |
1375 | + |
1376 | + MOCK_METHOD3 (postGenerateRequest, int (unsigned int, unsigned int, unsigned int)); |
1377 | + MOCK_METHOD1 (handlePending, void (long *)); |
1378 | +}; |
1379 | + |
1380 | +TEST(DecorPixmapRequestsTest, TestDestroyPixmapDeletes) |
1381 | +{ |
1382 | + boost::shared_ptr <MockDecorPixmapDeletor> mockDeletor = boost::make_shared <MockDecorPixmapDeletor> (); |
1383 | + DecorPixmap pm (1, boost::shared_static_cast<DecorPixmapDeletionInterface> (mockDeletor)); |
1384 | + |
1385 | + EXPECT_CALL (*(mockDeletor.get ()), postDeletePixmap (1)).WillOnce (Return (1)); |
1386 | +} |
1387 | + |
1388 | +TEST(DecorPixmapRequestsTest, TestPendingGeneratesRequest) |
1389 | +{ |
1390 | + MockDecorPixmapRequestor mockRequestor; |
1391 | + MockDecoration mockDecoration; |
1392 | + X11DecorPixmapReceiver receiver (&mockRequestor, &mockDecoration); |
1393 | + |
1394 | + EXPECT_CALL (mockDecoration, getFrameActions ()).WillOnce (Return (3)); |
1395 | + EXPECT_CALL (mockDecoration, getFrameState ()).WillOnce (Return (2)); |
1396 | + EXPECT_CALL (mockDecoration, getFrameType ()).WillOnce (Return (1)); |
1397 | + |
1398 | + EXPECT_CALL (mockRequestor, postGenerateRequest (1, 2, 3)); |
1399 | + |
1400 | + receiver.pending (); |
1401 | +} |
1402 | + |
1403 | +TEST(DecorPixmapRequestsTest, TestPendingGeneratesOnlyOneRequest) |
1404 | +{ |
1405 | + MockDecorPixmapRequestor mockRequestor; |
1406 | + MockDecoration mockDecoration; |
1407 | + X11DecorPixmapReceiver receiver (&mockRequestor, &mockDecoration); |
1408 | + |
1409 | + EXPECT_CALL (mockDecoration, getFrameActions ()).WillOnce (Return (3)); |
1410 | + EXPECT_CALL (mockDecoration, getFrameState ()).WillOnce (Return (2)); |
1411 | + EXPECT_CALL (mockDecoration, getFrameType ()).WillOnce (Return (1)); |
1412 | + |
1413 | + EXPECT_CALL (mockRequestor, postGenerateRequest (1, 2, 3)); |
1414 | + |
1415 | + receiver.pending (); |
1416 | + receiver.pending (); |
1417 | +} |
1418 | + |
1419 | +TEST(DecorPixmapRequestsTest, TestUpdateGeneratesRequestIfNewOnePending) |
1420 | +{ |
1421 | + MockDecorPixmapRequestor mockRequestor; |
1422 | + MockDecoration mockDecoration; |
1423 | + X11DecorPixmapReceiver receiver (&mockRequestor, &mockDecoration); |
1424 | + |
1425 | + EXPECT_CALL (mockDecoration, getFrameActions ()).WillOnce (Return (3)); |
1426 | + EXPECT_CALL (mockDecoration, getFrameState ()).WillOnce (Return (2)); |
1427 | + EXPECT_CALL (mockDecoration, getFrameType ()).WillOnce (Return (1)); |
1428 | + |
1429 | + EXPECT_CALL (mockRequestor, postGenerateRequest (1, 2, 3)); |
1430 | + |
1431 | + receiver.pending (); |
1432 | + receiver.pending (); |
1433 | + |
1434 | + EXPECT_CALL (mockDecoration, getFrameActions ()).WillOnce (Return (3)); |
1435 | + EXPECT_CALL (mockDecoration, getFrameState ()).WillOnce (Return (2)); |
1436 | + EXPECT_CALL (mockDecoration, getFrameType ()).WillOnce (Return (1)); |
1437 | + |
1438 | + EXPECT_CALL (mockRequestor, postGenerateRequest (1, 2, 3)); |
1439 | + |
1440 | + receiver.update (); |
1441 | +} |
1442 | + |
1443 | +TEST(DecorPixmapRequestsTest, TestUpdateGeneratesNoRequestIfNoNewOnePending) |
1444 | +{ |
1445 | + MockDecorPixmapRequestor mockRequestor; |
1446 | + MockDecoration mockDecoration; |
1447 | + X11DecorPixmapReceiver receiver (&mockRequestor, &mockDecoration); |
1448 | + |
1449 | + EXPECT_CALL (mockDecoration, getFrameActions ()).WillOnce (Return (3)); |
1450 | + EXPECT_CALL (mockDecoration, getFrameState ()).WillOnce (Return (2)); |
1451 | + EXPECT_CALL (mockDecoration, getFrameType ()).WillOnce (Return (1)); |
1452 | + |
1453 | + EXPECT_CALL (mockRequestor, postGenerateRequest (1, 2, 3)); |
1454 | + |
1455 | + receiver.pending (); |
1456 | + receiver.update (); |
1457 | +} |
I haven't reviewed this, but please fix and/or resubmit to resolve the conflicts.