Merge lp:~smspillaz/compiz-core/compiz-core.decor_synchronization into lp:compiz-core/0.9.8

Proposed by Sam Spilsbury
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
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.

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

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

I haven't reviewed this, but please fix and/or resubmit to resolve the conflicts.

review: Needs Resubmitting
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

For starters, there are non-trivial conflicts that need fixing.

review: Needs Fixing
Revision history for this message
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.

review: Needs Fixing
Revision history for this message
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://code.launchpad.net/~smspillaz/compiz-core/compiz-core.decor_synchronization/+merge/102801
> You are the owner of lp:~smspillaz/compiz-core/compiz-core.decor_synchronization.
>

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

I'll deal with this a little later.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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+}

Subscribers

People subscribed via source and target branches