Merge lp:~smspillaz/compiz-core/compiz-core.lim into lp:compiz-core/0.9.5
- compiz-core.lim
- Merge into 0.9.5
Status: | Superseded | ||||||||
---|---|---|---|---|---|---|---|---|---|
Proposed branch: | lp:~smspillaz/compiz-core/compiz-core.lim | ||||||||
Merge into: | lp:compiz-core/0.9.5 | ||||||||
Diff against target: |
843 lines (+623/-8) 15 files modified
gtk/window-decorator/CMakeLists.txt (+6/-0) gtk/window-decorator/decorator.c (+32/-6) gtk/window-decorator/events.c (+48/-0) gtk/window-decorator/gtk-window-decorator.h (+7/-1) gtk/window-decorator/local-menus/CMakeLists.txt (+60/-0) gtk/window-decorator/local-menus/src/local-menus.c (+200/-0) gtk/window-decorator/local-menus/src/local-menus.h (+69/-0) gtk/window-decorator/local-menus/tests/CMakeLists.txt (+3/-0) gtk/window-decorator/local-menus/tests/check_local_menu_on_off/CMakeLists.txt (+21/-0) gtk/window-decorator/local-menus/tests/check_local_menu_on_off/test-local-menu-on-off.cpp (+17/-0) gtk/window-decorator/local-menus/tests/force_local_menu_on/CMakeLists.txt (+21/-0) gtk/window-decorator/local-menus/tests/force_local_menu_on/test-force-local-menu-on.cpp (+67/-0) gtk/window-decorator/local-menus/tests/test-local-menu.h (+48/-0) gtk/window-decorator/metacity.c (+22/-0) gtk/window-decorator/wnck.c (+2/-1) |
||||||||
To merge this branch: | bzr merge lp:~smspillaz/compiz-core/compiz-core.lim | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel van Vugt | Needs Resubmitting | ||
Review via email: mp+91231@code.launchpad.net |
This proposal has been superseded by a proposal from 2012-02-06.
Commit message
Description of the change
Adds support for Ubuntu's "locally integrated menu bars" into gtk-window-
No tests as of yet, but I'll try and write some for
showing/hiding
forcing them on/off
positions etc
soonish.
Alan Griffiths (alan-griffiths) wrote : | # |
- 2980. By Sam Spilsbury
-
Split the local menus stuff out into its own file(s)
- 2981. By Sam Spilsbury
-
Move the code into a more testable state, add unit tests, etc
Sam Spilsbury (smspillaz) wrote : | # |
> 8 +#define GWD_SHOW_LOCAL_MENU (WNCK_WINDOW_
>
> No plausible reason for using a macro. In C++ constants (enum or unsigned
> int) are better as they respect scope rules. Also, should this be inside
> "#ifdef META_HAS_
>
Its C
>
> 296 button_
> 297
> 298 - for (i = 3; i < MAX_BUTTONS_
> 299 + for (i = 4; i < MAX_BUTTONS_
> 300 button_
> 301 }
>
> I'm not sure what the magic number "3"->"4" is. But we now seem to miss 3
> entirely. Is that correct?
Its for initializing the array, though maybe thats wrong. Good find let me check
- 2982. By Sam Spilsbury
-
Fix typo
- 2983. By Sam Spilsbury
-
Fix typo
Daniel van Vugt (vanvugt) wrote : | # |
Please resubmit for target branch lp:compiz-core (0.9.7)
- 2984. By Sam Spilsbury
-
Also show the menu on the window titlebar and adapt for changed wire protocol
- 2985. By Sam Spilsbury
-
Move window if we've held the button down for a bit
- 2986. By Sam Spilsbury
-
Theoretically provide the information required for the flair on the decoration
- 2987. By Sam Spilsbury
-
Show the flair in the right place
- 2988. By Sam Spilsbury
-
Use the right key
- 2989. By Sam Spilsbury
-
Use the correct key
- 2990. By Sam Spilsbury
-
Merged from lp:compiz-core
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
+ gboolean empty = g_strcmp0 (entry_id, "") == 0;
You can do the same with:
gboolean empty = (!entry_id || entry_id[0] == '\0');
- 2991. By Sam Spilsbury
-
Merged from lp:compiz-core
- 2992. By Sam Spilsbury
-
Merged from lp:compiz-core
- 2993. By Sam Spilsbury
-
Merge lp:compiz-core
- 2994. By Sam Spilsbury
-
Fix incorrect variant and initial button layout
- 2995. By Sam Spilsbury
-
Fix build without META_HAS_
LOCAL_MENUS - 2996. By Sam Spilsbury
-
Also ifdef the local menus tests
- 2997. By Sam Spilsbury
-
Don't run global setup or teardown functions if no local menus
- 2998. By Sam Spilsbury
-
Merge lp:compiz-core and allow alt-accelerator to open menus as well as reading the xprop
to determine if local menus are applicable - 2999. By Sam Spilsbury
-
Fix memory error and menu button not showing
- 3000. By Sam Spilsbury
-
Fix placement of menus on alt-accelerator, remove debug messages
- 3001. By Sam Spilsbury
-
Fix build failure without META_HAS_
LOCAL_MENUS - 3002. By Sam Spilsbury
-
Fix a crash when trying to show the window menu on a non decorated window
- 3003. By Sam Spilsbury
-
Tell us if we have them
- 3004. By Sam Spilsbury
-
Merged lp:compiz-core
- 3005. By Sam Spilsbury
-
We also need to test the property too
- 3006. By Sam Spilsbury
-
Grab buttons too so that we can process motion events on the titlebar and
move the window instead.
Unmerged revisions
- 3006. By Sam Spilsbury
-
Grab buttons too so that we can process motion events on the titlebar and
move the window instead. - 3005. By Sam Spilsbury
-
We also need to test the property too
- 3004. By Sam Spilsbury
-
Merged lp:compiz-core
- 3003. By Sam Spilsbury
-
Tell us if we have them
- 3002. By Sam Spilsbury
-
Fix a crash when trying to show the window menu on a non decorated window
- 3001. By Sam Spilsbury
-
Fix build failure without META_HAS_
LOCAL_MENUS - 3000. By Sam Spilsbury
-
Fix placement of menus on alt-accelerator, remove debug messages
- 2999. By Sam Spilsbury
-
Fix memory error and menu button not showing
- 2998. By Sam Spilsbury
-
Merge lp:compiz-core and allow alt-accelerator to open menus as well as reading the xprop
to determine if local menus are applicable - 2997. By Sam Spilsbury
-
Don't run global setup or teardown functions if no local menus
Preview Diff
1 | === modified file 'gtk/window-decorator/CMakeLists.txt' |
2 | --- gtk/window-decorator/CMakeLists.txt 2011-02-16 17:39:56 +0000 |
3 | +++ gtk/window-decorator/CMakeLists.txt 2012-02-02 17:13:31 +0000 |
4 | @@ -4,7 +4,10 @@ |
5 | set (CMAKE_INSTALL_RPATH ${libdir}) |
6 | endif (COMPIZ_BUILD_WITH_RPATH) |
7 | |
8 | + add_subdirectory (local-menus) |
9 | + |
10 | include_directories ( |
11 | + ${CMAKE_CURRENT_SOURCE_DIR}/local-menus/src |
12 | ${compiz_SOURCE_DIR}/include |
13 | ${CMAKE_BINARY_DIR}/gtk |
14 | ${GTK_WINDOW_DECORATOR_INCLUDE_DIRS} |
15 | @@ -63,6 +66,9 @@ |
16 | target_link_libraries ( |
17 | gtk-window-decorator |
18 | decoration |
19 | + |
20 | + gtk_window_decorator_local_menus |
21 | + |
22 | ${GTK_WINDOW_DECORATOR_LIBRARIES} |
23 | ${GCONF_LIBRARIES} |
24 | ${DBUS_GLIB_LIBRARIES} |
25 | |
26 | === modified file 'gtk/window-decorator/decorator.c' |
27 | --- gtk/window-decorator/decorator.c 2011-10-13 11:31:37 +0000 |
28 | +++ gtk/window-decorator/decorator.c 2012-02-02 17:13:31 +0000 |
29 | @@ -24,6 +24,7 @@ |
30 | */ |
31 | |
32 | #include "gtk-window-decorator.h" |
33 | +#include "local-menus.h" |
34 | |
35 | decor_frame_t * |
36 | create_normal_frame (const gchar *type) |
37 | @@ -230,12 +231,16 @@ |
38 | void |
39 | update_event_windows (WnckWindow *win) |
40 | { |
41 | +#define GWD_SHOW_LOCAL_MENU (WNCK_WINDOW_ACTION_BELOW << 1) |
42 | Display *xdisplay; |
43 | decor_t *d = g_object_get_data (G_OBJECT (win), "decor"); |
44 | gint x0, y0, width, height, x, y, w, h; |
45 | gint i, j, k, l; |
46 | gint actions = d->actions; |
47 | |
48 | + if (gwd_window_should_have_local_menu (win)) |
49 | + d->actions |= GWD_SHOW_LOCAL_MENU; |
50 | + |
51 | xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); |
52 | |
53 | /* Get the geometry of the client */ |
54 | @@ -298,11 +303,19 @@ |
55 | XMapWindow (xdisplay, d->event_windows[i][j].window); |
56 | XMoveResizeWindow (xdisplay, d->event_windows[i][j].window, |
57 | x, y, w, h); |
58 | + |
59 | + BoxPtr box = &d->event_windows[i][j].pos; |
60 | + box->x1 = x; |
61 | + box->x2 = x + w; |
62 | + box->y1 = y; |
63 | + box->y2 = y + h; |
64 | } |
65 | /* No parent and no geometry - unmap all event windows */ |
66 | else if (!d->frame_window) |
67 | { |
68 | XUnmapWindow (xdisplay, d->event_windows[i][j].window); |
69 | + |
70 | + memset (&d->event_windows[i][j].pos, 0, sizeof (Box)); |
71 | } |
72 | } |
73 | } |
74 | @@ -326,12 +339,18 @@ |
75 | WNCK_WINDOW_ACTION_STICK, |
76 | WNCK_WINDOW_ACTION_UNSHADE, |
77 | WNCK_WINDOW_ACTION_ABOVE, |
78 | - WNCK_WINDOW_ACTION_UNSTICK |
79 | -#else |
80 | - 0, |
81 | - 0, |
82 | - 0, |
83 | - 0, |
84 | + WNCK_WINDOW_ACTION_UNSTICK, |
85 | +#else |
86 | + 0, |
87 | + 0, |
88 | + 0, |
89 | + 0, |
90 | + 0, |
91 | +#endif |
92 | + |
93 | +#ifdef META_HAS_LOCAL_MENUS |
94 | + GWD_SHOW_LOCAL_MENU |
95 | +#else |
96 | 0 |
97 | #endif |
98 | |
99 | @@ -371,10 +390,17 @@ |
100 | Window win = d->button_windows[i].window; |
101 | XMapWindow (xdisplay, win); |
102 | XMoveResizeWindow (xdisplay, win, x, y, w, h); |
103 | + |
104 | + BoxPtr box = &d->button_windows[i].pos; |
105 | + box->x1 = x; |
106 | + box->x2 = x + w; |
107 | + box->y1 = y; |
108 | + box->y2 = y + h; |
109 | } |
110 | else if (!d->frame_window) |
111 | { |
112 | XUnmapWindow (xdisplay, d->button_windows[i].window); |
113 | + memset (&d->button_windows[i].pos, 0, sizeof (Box)); |
114 | } |
115 | } |
116 | |
117 | |
118 | === modified file 'gtk/window-decorator/events.c' |
119 | --- gtk/window-decorator/events.c 2011-10-13 12:22:14 +0000 |
120 | +++ gtk/window-decorator/events.c 2012-02-02 17:13:31 +0000 |
121 | @@ -24,6 +24,7 @@ |
122 | */ |
123 | |
124 | #include "gtk-window-decorator.h" |
125 | +#include "local-menus.h" |
126 | |
127 | void |
128 | move_resize_window (WnckWindow *win, |
129 | @@ -380,6 +381,53 @@ |
130 | } |
131 | |
132 | void |
133 | +on_local_menu_hidden (gpointer user_data) |
134 | +{ |
135 | + decor_t *d = (decor_t *) user_data; |
136 | + |
137 | + d->button_states[BUTTON_WINDOW_MENU] &= ~PRESSED_EVENT_WINDOW; |
138 | + |
139 | + queue_decor_draw (d); |
140 | +} |
141 | + |
142 | +void |
143 | +window_menu_button_event (WnckWindow *win, |
144 | + decor_event *gtkwd_event, |
145 | + decor_event_type gtkwd_type) |
146 | +{ |
147 | + decor_t *d = g_object_get_data (G_OBJECT (win), "decor"); |
148 | + |
149 | + common_button_event (win, gtkwd_event, gtkwd_type, |
150 | + BUTTON_WINDOW_MENU, 1, _("Window Menu")); |
151 | + |
152 | + switch (gtkwd_type) { |
153 | + case GButtonPress: |
154 | + if (gtkwd_event->button == 1) |
155 | + if (d->button_states[BUTTON_WINDOW_MENU] == BUTTON_EVENT_ACTION_STATE) |
156 | + { |
157 | + int win_x, win_y; |
158 | + int box_x = d->button_windows[BUTTON_WINDOW_MENU].pos.x1; |
159 | + |
160 | + wnck_window_get_geometry (win, &win_x, &win_y, NULL, NULL); |
161 | + |
162 | + int x = win_x + box_x; |
163 | + int y = win_y + d->context->extents.top; |
164 | + |
165 | + gwd_show_local_menu (gdk_x11_display_get_xdisplay (gdk_display_get_default ()), |
166 | + wnck_window_get_xid (win), |
167 | + x, y, |
168 | + gtkwd_event->button, |
169 | + gtkwd_event->time, |
170 | + (show_window_menu_hidden_cb) on_local_menu_hidden, |
171 | + (gpointer) d); |
172 | + } |
173 | + break; |
174 | + default: |
175 | + break; |
176 | + } |
177 | +} |
178 | + |
179 | +void |
180 | handle_title_button_event (WnckWindow *win, |
181 | int action, |
182 | decor_event *gtkwd_event) |
183 | |
184 | === modified file 'gtk/window-decorator/gtk-window-decorator.h' |
185 | --- gtk/window-decorator/gtk-window-decorator.h 2011-10-13 12:22:14 +0000 |
186 | +++ gtk/window-decorator/gtk-window-decorator.h 2012-02-02 17:13:31 +0000 |
187 | @@ -328,7 +328,8 @@ |
188 | #define BUTTON_UNSHADE 7 |
189 | #define BUTTON_UNABOVE 8 |
190 | #define BUTTON_UNSTICK 9 |
191 | -#define BUTTON_NUM 10 |
192 | +#define BUTTON_WINDOW_MENU 10 |
193 | +#define BUTTON_NUM 11 |
194 | |
195 | struct _pos { |
196 | int x, y, w, h; |
197 | @@ -1013,6 +1014,11 @@ |
198 | decor_event_type gtkwd_type); |
199 | |
200 | void |
201 | +window_menu_button_event (WnckWindow *win, |
202 | + decor_event *gtkwd_event, |
203 | + decor_event_type gtkwd_type); |
204 | + |
205 | +void |
206 | handle_title_button_event (WnckWindow *win, |
207 | int action, |
208 | decor_event *gtkwd_event); |
209 | |
210 | === added directory 'gtk/window-decorator/local-menus' |
211 | === added file 'gtk/window-decorator/local-menus/CMakeLists.txt' |
212 | --- gtk/window-decorator/local-menus/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
213 | +++ gtk/window-decorator/local-menus/CMakeLists.txt 2012-02-02 17:13:31 +0000 |
214 | @@ -0,0 +1,60 @@ |
215 | +pkg_check_modules( |
216 | + LOCAL_MENUS |
217 | + REQUIRED |
218 | + glib-2.0 gio-2.0 libwnck-1.0 gtk+-2.0>=2.18.0 |
219 | +) |
220 | + |
221 | +INCLUDE_DIRECTORIES( |
222 | + ${CMAKE_CURRENT_SOURCE_DIR}/include |
223 | + ${CMAKE_CURRENT_SOURCE_DIR}/src |
224 | + |
225 | + ${compiz_SOURCE_DIR}/gtk/window-decorator |
226 | + |
227 | + ${Boost_INCLUDE_DIRS} |
228 | + |
229 | + ${LOCAL_MENUS_INCLUDE_DIRS} |
230 | + ${METACITY_INCLUDE_DIRS} |
231 | +) |
232 | + |
233 | +LINK_DIRECTORIES (${LOCAL_MENUS_LIBRARY_DIRS}) |
234 | + |
235 | +SET( |
236 | + PUBLIC_HEADERS |
237 | +) |
238 | + |
239 | +SET( |
240 | + PRIVATE_HEADERS |
241 | + ${CMAKE_CURRENT_SOURCE_DIR}/src/local-menus.h |
242 | +) |
243 | + |
244 | +SET( |
245 | + SRCS |
246 | + ${CMAKE_CURRENT_SOURCE_DIR}/src/local-menus.c |
247 | +) |
248 | + |
249 | +ADD_LIBRARY( |
250 | + gtk_window_decorator_local_menus STATIC |
251 | + |
252 | + ${SRCS} |
253 | + |
254 | + ${PUBLIC_HEADERS} |
255 | + ${PRIVATE_HEADERS} |
256 | +) |
257 | + |
258 | +IF (COMPIZ_BUILD_TESTING) |
259 | +ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests ) |
260 | +ENDIF (COMPIZ_BUILD_TESTING) |
261 | + |
262 | +SET_TARGET_PROPERTIES( |
263 | + gtk_window_decorator_local_menus PROPERTIES |
264 | + PUBLIC_HEADER "${PUBLIC_HEADERS}" |
265 | +) |
266 | + |
267 | +install (FILES ${PUBLIC_HEADERS} DESTINATION ${COMPIZ_CORE_INCLUDE_DIR}) |
268 | + |
269 | +TARGET_LINK_LIBRARIES( |
270 | + gtk_window_decorator_local_menus |
271 | + |
272 | + ${LOCAL_MENUS_LIBRARIES} |
273 | +) |
274 | + |
275 | |
276 | === added directory 'gtk/window-decorator/local-menus/include' |
277 | === added directory 'gtk/window-decorator/local-menus/src' |
278 | === added file 'gtk/window-decorator/local-menus/src/local-menus.c' |
279 | --- gtk/window-decorator/local-menus/src/local-menus.c 1970-01-01 00:00:00 +0000 |
280 | +++ gtk/window-decorator/local-menus/src/local-menus.c 2012-02-02 17:13:31 +0000 |
281 | @@ -0,0 +1,200 @@ |
282 | +/* |
283 | + * Copyright © 2006 Novell, Inc. |
284 | + * |
285 | + * This library is free software; you can redistribute it and/or |
286 | + * modify it under the terms of the GNU Lesser General Public |
287 | + * License as published by the Free Software Foundation; either |
288 | + * version 2 of the License, or (at your option) any later version. |
289 | + * |
290 | + * This library is distributed in the hope that it will be useful, |
291 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
292 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
293 | + * Lesser General Public License for more details. |
294 | + * |
295 | + * You should have received a copy of the GNU Lesser General Public |
296 | + * License along with this library; if not, write to the |
297 | + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
298 | + * Boston, MA 02111-1307, USA. |
299 | + * |
300 | + * Author: David Reveman <davidr@novell.com> |
301 | + * |
302 | + * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com> |
303 | + * Frames Management: Copright © 2011 Canonical Ltd. |
304 | + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> |
305 | + */ |
306 | + |
307 | +#include "local-menus.h" |
308 | +#include <gdk/gdk.h> |
309 | +#include <gdk/gdkx.h> |
310 | + |
311 | +gboolean |
312 | +gwd_window_should_have_local_menu (WnckWindow *win) |
313 | +{ |
314 | +#ifdef META_HAS_LOCAL_MENUS |
315 | + const gchar * const *schemas = g_settings_list_schemas (); |
316 | + static GSettings *lim_settings = NULL; |
317 | + while (*schemas != NULL && !lim_settings) |
318 | + { |
319 | + if (g_str_equal (*schemas, "com.canonical.Unity.Menus")) |
320 | + { |
321 | + lim_settings = g_settings_new ("com.canonical.Unity.Menus"); |
322 | + break; |
323 | + } |
324 | + ++schemas; |
325 | + } |
326 | + |
327 | + if (lim_settings) |
328 | + { |
329 | + if (g_settings_get_boolean (lim_settings, "force-local-menus")) |
330 | + { |
331 | + return TRUE; |
332 | + } |
333 | + } |
334 | +#endif |
335 | + |
336 | + return FALSE; |
337 | +} |
338 | + |
339 | +static void |
340 | +on_local_menu_activated (GDBusProxy *proxy, |
341 | + gchar *sender_name, |
342 | + gchar *signal_name, |
343 | + GVariant *parameters, |
344 | + gpointer user_data) |
345 | +{ |
346 | +#ifdef META_HAS_LOCAL_MENUS |
347 | + if (g_strcmp0 (signal_name, "EntryActivated") == 0) |
348 | + { |
349 | + gchar *entry_id = NULL; |
350 | + |
351 | + g_variant_get (parameters, "(s)", &entry_id, NULL); |
352 | + |
353 | + gboolean empty = g_strcmp0 (entry_id, "") == 0; |
354 | + |
355 | + if (empty) |
356 | + { |
357 | + show_local_menu_data *d = (show_local_menu_data *) user_data; |
358 | + |
359 | + (*d->cb) (d->user_data); |
360 | + |
361 | + g_signal_handlers_disconnect_by_func (d->proxy, on_local_menu_activated, d); |
362 | + |
363 | + g_object_unref (d->proxy); |
364 | + g_object_unref (d->conn); |
365 | + g_free (d->entry_id); |
366 | + } |
367 | + } |
368 | +#endif |
369 | +} |
370 | + |
371 | +void |
372 | +gwd_show_local_menu (Display *xdisplay, |
373 | + Window frame_xwindow, |
374 | + int x, |
375 | + int y, |
376 | + int button, |
377 | + guint32 timestamp, |
378 | + show_window_menu_hidden_cb cb, |
379 | + gpointer user_data) |
380 | +{ |
381 | +#ifdef META_HAS_LOCAL_MENUS |
382 | + GError *error = NULL; |
383 | + GDBusConnection *conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); |
384 | + |
385 | + XUngrabPointer (gdk_x11_display_get_xdisplay (gdk_display_get_default ()), CurrentTime); |
386 | + XUngrabKeyboard (gdk_x11_display_get_xdisplay (gdk_display_get_default ()), CurrentTime); |
387 | + XSync (gdk_x11_display_get_xdisplay (gdk_display_get_default ()), FALSE); |
388 | + |
389 | + if (!conn) |
390 | + { |
391 | + g_print ("error getting connection: %s\n", error->message); |
392 | + return; |
393 | + } |
394 | + |
395 | + GDBusProxy *proxy = g_dbus_proxy_new_sync (conn, 0, NULL, "com.canonical.Unity.Panel.Service", |
396 | + "/com/canonical/Unity/Panel/Service", |
397 | + "com.canonical.Unity.Panel.Service", |
398 | + NULL, &error); |
399 | + |
400 | + if (proxy) |
401 | + { |
402 | + GVariant *message = g_variant_new ("(uiiu)", frame_xwindow, x, y, time); |
403 | + GVariant *reply = g_dbus_proxy_call_sync (proxy, "ShowAppMenu", message, 0, 500, NULL, &error); |
404 | + if (error) |
405 | + { |
406 | + g_print ("error calling ShowAppMenu: %s\n", error->message); |
407 | + g_object_unref (proxy); |
408 | + g_object_unref (conn); |
409 | + return; |
410 | + } |
411 | + |
412 | + show_local_menu_data *data = g_new0 (show_local_menu_data, 1); |
413 | + g_variant_get (reply, "(s)", data->entry_id, NULL); |
414 | + |
415 | + data->conn = g_object_ref (conn); |
416 | + data->proxy = g_object_ref (proxy); |
417 | + data->cb = cb; |
418 | + data->user_data = user_data; |
419 | + |
420 | + g_signal_connect (proxy, "g-signal", G_CALLBACK (on_local_menu_activated), data); |
421 | + |
422 | + g_object_unref (conn); |
423 | + g_object_unref (proxy); |
424 | + |
425 | + return; |
426 | + } |
427 | + else |
428 | + { |
429 | + g_print ("error getting proxy: %s\n", error->message); |
430 | + } |
431 | + |
432 | + g_object_unref (conn); |
433 | +#endif |
434 | +} |
435 | + |
436 | +void |
437 | +force_local_menus_on (WnckWindow *win, |
438 | + MetaButtonLayout *button_layout) |
439 | +{ |
440 | +#ifdef META_HAS_LOCAL_MENUS |
441 | + if (gwd_window_should_have_local_menu (win)) |
442 | + { |
443 | + if (button_layout->left_buttons[0] != META_BUTTON_FUNCTION_LAST) |
444 | + { |
445 | + unsigned int i = 0; |
446 | + for (; i < MAX_BUTTONS_PER_CORNER; i++) |
447 | + { |
448 | + if (button_layout->left_buttons[i] == META_BUTTON_FUNCTION_WINDOW_MENU) |
449 | + break; |
450 | + else if (button_layout->left_buttons[i] == META_BUTTON_FUNCTION_LAST) |
451 | + { |
452 | + if ((i + 1) < MAX_BUTTONS_PER_CORNER) |
453 | + { |
454 | + button_layout->left_buttons[i + 1] = META_BUTTON_FUNCTION_LAST; |
455 | + button_layout->left_buttons[i] = META_BUTTON_FUNCTION_WINDOW_MENU; |
456 | + } |
457 | + } |
458 | + } |
459 | + } |
460 | + if (button_layout->right_buttons[0] != META_BUTTON_FUNCTION_LAST) |
461 | + { |
462 | + unsigned int i = 0; |
463 | + for (; i < MAX_BUTTONS_PER_CORNER; i++) |
464 | + { |
465 | + if (button_layout->right_buttons[i] == META_BUTTON_FUNCTION_WINDOW_MENU) |
466 | + break; |
467 | + else if (button_layout->right_buttons[i] == META_BUTTON_FUNCTION_LAST) |
468 | + { |
469 | + if ((i + 1) < MAX_BUTTONS_PER_CORNER) |
470 | + { |
471 | + button_layout->right_buttons[i + 1] = META_BUTTON_FUNCTION_LAST; |
472 | + button_layout->right_buttons[i] = META_BUTTON_FUNCTION_WINDOW_MENU; |
473 | + } |
474 | + } |
475 | + } |
476 | + } |
477 | + } |
478 | +#endif |
479 | +} |
480 | + |
481 | + |
482 | |
483 | === added file 'gtk/window-decorator/local-menus/src/local-menus.h' |
484 | --- gtk/window-decorator/local-menus/src/local-menus.h 1970-01-01 00:00:00 +0000 |
485 | +++ gtk/window-decorator/local-menus/src/local-menus.h 2012-02-02 17:13:31 +0000 |
486 | @@ -0,0 +1,69 @@ |
487 | +/* |
488 | + * Copyright © 2006 Novell, Inc. |
489 | + * |
490 | + * This library is free software; you can redistribute it and/or |
491 | + * modify it under the terms of the GNU Lesser General Public |
492 | + * License as published by the Free Software Foundation; either |
493 | + * version 2 of the License, or (at your option) any later version. |
494 | + * |
495 | + * This library is distributed in the hope that it will be useful, |
496 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
497 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
498 | + * Lesser General Public License for more details. |
499 | + * |
500 | + * You should have received a copy of the GNU Lesser General Public |
501 | + * License along with this library; if not, write to the |
502 | + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
503 | + * Boston, MA 02111-1307, USA. |
504 | + * |
505 | + * Author: David Reveman <davidr@novell.com> |
506 | + * |
507 | + * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com> |
508 | + * Frames Management: Copright © 2011 Canonical Ltd. |
509 | + * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com> |
510 | + */ |
511 | + |
512 | +#ifdef __cplusplus |
513 | +extern "C" |
514 | +{ |
515 | +#endif |
516 | + |
517 | +#include <glib.h> |
518 | +#include <gio/gio.h> |
519 | +#ifndef WNCK_I_KNOW_THIS_IS_UNSTABLE |
520 | +#define WNCK_I_KNOW_THIS_IS_UNSTABLE |
521 | +#endif |
522 | +#include <libwnck/libwnck.h> |
523 | +#include <libwnck/window-action-menu.h> |
524 | +#include <metacity-private/theme.h> |
525 | + |
526 | +typedef void (*show_window_menu_hidden_cb) (gpointer); |
527 | + |
528 | +typedef struct _show_local_menu_data |
529 | +{ |
530 | + GDBusConnection *conn; |
531 | + GDBusProxy *proxy; |
532 | + gchar *entry_id; |
533 | + show_window_menu_hidden_cb cb; |
534 | + gpointer user_data; |
535 | +} show_local_menu_data; |
536 | + |
537 | +gboolean |
538 | +gwd_window_should_have_local_menu (WnckWindow *win); |
539 | + |
540 | +void |
541 | +force_local_menus_on (WnckWindow *win, |
542 | + MetaButtonLayout *layout); |
543 | + |
544 | +void |
545 | +gwd_show_local_menu (Display *xdisplay, |
546 | + Window frame_xwindow, |
547 | + int x, |
548 | + int y, |
549 | + int button, |
550 | + guint32 timestamp, |
551 | + show_window_menu_hidden_cb cb, |
552 | + gpointer user_data); |
553 | +#ifdef __cplusplus |
554 | +} |
555 | +#endif |
556 | |
557 | === added directory 'gtk/window-decorator/local-menus/tests' |
558 | === added file 'gtk/window-decorator/local-menus/tests/CMakeLists.txt' |
559 | --- gtk/window-decorator/local-menus/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
560 | +++ gtk/window-decorator/local-menus/tests/CMakeLists.txt 2012-02-02 17:13:31 +0000 |
561 | @@ -0,0 +1,3 @@ |
562 | +include_directories (${CMAKE_CURRENT_SOURCE_DIR}) |
563 | +add_subdirectory (check_local_menu_on_off) |
564 | +add_subdirectory (force_local_menu_on) |
565 | |
566 | === added directory 'gtk/window-decorator/local-menus/tests/check_local_menu_on_off' |
567 | === added file 'gtk/window-decorator/local-menus/tests/check_local_menu_on_off/CMakeLists.txt' |
568 | --- gtk/window-decorator/local-menus/tests/check_local_menu_on_off/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
569 | +++ gtk/window-decorator/local-menus/tests/check_local_menu_on_off/CMakeLists.txt 2012-02-02 17:13:31 +0000 |
570 | @@ -0,0 +1,21 @@ |
571 | +include_directories (${CMAKE_CURRENT_SOURCE_DIR} |
572 | + ${compiz_SOURCE_DIR}/gtk/window-decorator/local-menus/tests |
573 | + ${compiz_SOURCE_DIR}/gtk/window-decorator |
574 | + ${compiz_SOURCE_DIR}/gtk/window-decorator/local-menus/src) |
575 | + |
576 | +add_executable( |
577 | + gtk_window_decorator_check_local_menu_on_off_test |
578 | + |
579 | + ${CMAKE_CURRENT_SOURCE_DIR}/test-local-menu-on-off.cpp |
580 | +) |
581 | + |
582 | +target_link_libraries( |
583 | + gtk_window_decorator_check_local_menu_on_off_test |
584 | + |
585 | + gtk_window_decorator_local_menus |
586 | + |
587 | + ${GTEST_BOTH_LIBRARIES} |
588 | + ${CMAKE_THREAD_LIBS_INIT} # Link in pthread. |
589 | +) |
590 | + |
591 | +add_test (gtk_window_decorator_local_menus_on_off gtk_window_decorator_check_local_menu_on_off_test) |
592 | |
593 | === added directory 'gtk/window-decorator/local-menus/tests/check_local_menu_on_off/check_local_menu_on_off' |
594 | === added directory 'gtk/window-decorator/local-menus/tests/check_local_menu_on_off/check_local_menu_on_off/CMakeFiles' |
595 | === added file 'gtk/window-decorator/local-menus/tests/check_local_menu_on_off/test-local-menu-on-off.cpp' |
596 | --- gtk/window-decorator/local-menus/tests/check_local_menu_on_off/test-local-menu-on-off.cpp 1970-01-01 00:00:00 +0000 |
597 | +++ gtk/window-decorator/local-menus/tests/check_local_menu_on_off/test-local-menu-on-off.cpp 2012-02-02 17:13:31 +0000 |
598 | @@ -0,0 +1,17 @@ |
599 | +#include "test-local-menu.h" |
600 | + |
601 | +TEST_F (GtkWindowDecoratorTestLocalMenu, TestOn) |
602 | +{ |
603 | + g_settings_set_boolean (getSettings (), "force-local-menus", TRUE); |
604 | + gboolean result = gwd_window_should_have_local_menu (getWindow ()); |
605 | + |
606 | + EXPECT_TRUE (result); |
607 | +} |
608 | + |
609 | +TEST_F (GtkWindowDecoratorTestLocalMenu, TestOff) |
610 | +{ |
611 | + g_settings_set_boolean (getSettings (), "force-local-menus", FALSE); |
612 | + gboolean result = gwd_window_should_have_local_menu (getWindow ()); |
613 | + |
614 | + EXPECT_FALSE (result); |
615 | +} |
616 | |
617 | === added directory 'gtk/window-decorator/local-menus/tests/force_local_menu_on' |
618 | === added file 'gtk/window-decorator/local-menus/tests/force_local_menu_on/CMakeLists.txt' |
619 | --- gtk/window-decorator/local-menus/tests/force_local_menu_on/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
620 | +++ gtk/window-decorator/local-menus/tests/force_local_menu_on/CMakeLists.txt 2012-02-02 17:13:31 +0000 |
621 | @@ -0,0 +1,21 @@ |
622 | +include_directories (${CMAKE_CURRENT_SOURCE_DIR} |
623 | + ${compiz_SOURCE_DIR}/gtk/window-decorator/local-menus/tests |
624 | + ${compiz_SOURCE_DIR}/gtk/window-decorator |
625 | + ${compiz_SOURCE_DIR}/gtk/window-decorator/local-menus/src) |
626 | + |
627 | +add_executable( |
628 | + gtk_window_decorator_force_local_menu_on_test |
629 | + |
630 | + ${CMAKE_CURRENT_SOURCE_DIR}/test-force-local-menu-on.cpp |
631 | +) |
632 | + |
633 | +target_link_libraries( |
634 | + gtk_window_decorator_force_local_menu_on_test |
635 | + |
636 | + gtk_window_decorator_local_menus |
637 | + |
638 | + ${GTEST_BOTH_LIBRARIES} |
639 | + ${CMAKE_THREAD_LIBS_INIT} # Link in pthread. |
640 | +) |
641 | + |
642 | +add_test (gtk_window_decorator_force_local_menu_on gtk_window_decorator_force_local_menu_on_test) |
643 | |
644 | === added file 'gtk/window-decorator/local-menus/tests/force_local_menu_on/test-force-local-menu-on.cpp' |
645 | --- gtk/window-decorator/local-menus/tests/force_local_menu_on/test-force-local-menu-on.cpp 1970-01-01 00:00:00 +0000 |
646 | +++ gtk/window-decorator/local-menus/tests/force_local_menu_on/test-force-local-menu-on.cpp 2012-02-02 17:13:31 +0000 |
647 | @@ -0,0 +1,67 @@ |
648 | +#include "test-local-menu.h" |
649 | +#include <cstring> |
650 | + |
651 | +namespace |
652 | +{ |
653 | + void initializeMetaButtonLayout (MetaButtonLayout *layout) |
654 | + { |
655 | + memset (layout, 0, sizeof (MetaButtonLayout)); |
656 | + |
657 | + unsigned int i; |
658 | + |
659 | + for (i = 0; i < MAX_BUTTONS_PER_CORNER; i++) |
660 | + { |
661 | + layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST; |
662 | + layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST; |
663 | + } |
664 | + } |
665 | +} |
666 | + |
667 | +class GtkWindowDecoratorTestLocalMenuLayout : |
668 | + public GtkWindowDecoratorTestLocalMenu |
669 | +{ |
670 | + public: |
671 | + |
672 | + MetaButtonLayout * getLayout () { return &mLayout; } |
673 | + |
674 | + virtual void SetUp () |
675 | + { |
676 | + GtkWindowDecoratorTestLocalMenu::SetUp (); |
677 | + ::initializeMetaButtonLayout (&mLayout); |
678 | + g_settings_set_boolean (getSettings (), "force-local-menus", TRUE); |
679 | + } |
680 | + |
681 | + private: |
682 | + |
683 | + MetaButtonLayout mLayout; |
684 | +}; |
685 | + |
686 | +TEST_F (GtkWindowDecoratorTestLocalMenuLayout, TestForceNoButtonsSet) |
687 | +{ |
688 | + force_local_menus_on (getWindow (), getLayout ()); |
689 | + |
690 | + EXPECT_EQ (getLayout ()->right_buttons[0], META_BUTTON_FUNCTION_LAST); |
691 | + EXPECT_EQ (getLayout ()->left_buttons[0], META_BUTTON_FUNCTION_LAST); |
692 | +} |
693 | + |
694 | +TEST_F (GtkWindowDecoratorTestLocalMenuLayout, TestForceNoCloseButtonSet) |
695 | +{ |
696 | + getLayout ()->right_buttons[0] = META_BUTTON_FUNCTION_CLOSE; |
697 | + |
698 | + force_local_menus_on (getWindow (), getLayout ()); |
699 | + |
700 | + EXPECT_EQ (getLayout ()->right_buttons[1], META_BUTTON_FUNCTION_WINDOW_MENU); |
701 | + EXPECT_EQ (getLayout ()->left_buttons[0], META_BUTTON_FUNCTION_LAST); |
702 | +} |
703 | + |
704 | +TEST_F (GtkWindowDecoratorTestLocalMenuLayout, TestForceNoCloseMinimizeMaximizeButtonSet) |
705 | +{ |
706 | + getLayout ()->left_buttons[0] = META_BUTTON_FUNCTION_CLOSE; |
707 | + getLayout ()->left_buttons[1] = META_BUTTON_FUNCTION_CLOSE; |
708 | + getLayout ()->left_buttons[2] = META_BUTTON_FUNCTION_CLOSE; |
709 | + |
710 | + force_local_menus_on (getWindow (), getLayout ()); |
711 | + |
712 | + EXPECT_EQ (getLayout ()->right_buttons[0], META_BUTTON_FUNCTION_LAST); |
713 | + EXPECT_EQ (getLayout ()->left_buttons[3], META_BUTTON_FUNCTION_WINDOW_MENU); |
714 | +} |
715 | |
716 | === added directory 'gtk/window-decorator/local-menus/tests/show_hide_menu' |
717 | === added file 'gtk/window-decorator/local-menus/tests/test-local-menu.h' |
718 | --- gtk/window-decorator/local-menus/tests/test-local-menu.h 1970-01-01 00:00:00 +0000 |
719 | +++ gtk/window-decorator/local-menus/tests/test-local-menu.h 2012-02-02 17:13:31 +0000 |
720 | @@ -0,0 +1,48 @@ |
721 | +#include <gtest/gtest.h> |
722 | +#include <gmock/gmock.h> |
723 | +#include "local-menus.h" |
724 | +#include <X11/Xlib.h> |
725 | +#include <gio/gio.h> |
726 | + |
727 | +class GtkWindowDecoratorTestLocalMenu : |
728 | + public ::testing::Test |
729 | +{ |
730 | + public: |
731 | + |
732 | + WnckWindow * getWindow () { return mWindow; } |
733 | + GSettings * getSettings () { return mSettings; } |
734 | + |
735 | + virtual void SetUp () |
736 | + { |
737 | + gtk_init (NULL, NULL); |
738 | + |
739 | + mXDisplay = XOpenDisplay (NULL); |
740 | + mXWindow = XCreateSimpleWindow (mXDisplay, DefaultRootWindow (mXDisplay), 0, 0, 100, 100, 0, 0, 0); |
741 | + |
742 | + XMapRaised (mXDisplay, mXWindow); |
743 | + |
744 | + XFlush (mXDisplay); |
745 | + |
746 | + while (g_main_context_iteration (g_main_context_default (), FALSE)); |
747 | + |
748 | + mWindow = wnck_window_get (mXWindow); |
749 | + |
750 | + g_setenv("GSETTINGS_BACKEND", "memory", true); |
751 | + mSettings = g_settings_new ("com.canonical.Unity.Menus"); |
752 | + } |
753 | + |
754 | + virtual void TearDown () |
755 | + { |
756 | + XDestroyWindow (mXDisplay, mXWindow); |
757 | + XCloseDisplay (mXDisplay); |
758 | + |
759 | + g_object_unref (mSettings); |
760 | + } |
761 | + |
762 | + private: |
763 | + |
764 | + WnckWindow *mWindow; |
765 | + Window mXWindow; |
766 | + Display *mXDisplay; |
767 | + GSettings *mSettings; |
768 | +}; |
769 | |
770 | === modified file 'gtk/window-decorator/metacity.c' |
771 | --- gtk/window-decorator/metacity.c 2012-01-12 06:48:58 +0000 |
772 | +++ gtk/window-decorator/metacity.c 2012-02-02 17:13:31 +0000 |
773 | @@ -24,6 +24,7 @@ |
774 | */ |
775 | |
776 | #include "gtk-window-decorator.h" |
777 | +#include "local-menus.h" |
778 | |
779 | #ifdef USE_METACITY |
780 | |
781 | @@ -488,6 +489,8 @@ |
782 | button_layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST; |
783 | } |
784 | |
785 | + force_local_menus_on (d->win, button_layout); |
786 | + |
787 | *flags = 0; |
788 | |
789 | if (d->actions & WNCK_WINDOW_ACTION_CLOSE) |
790 | @@ -601,6 +604,11 @@ |
791 | GdkColor bg_color; |
792 | double bg_alpha; |
793 | |
794 | + memset (&button_layout, 0, sizeof (MetaButtonLayout)); |
795 | + |
796 | + for (i = 0; i < MAX_BUTTONS_PER_CORNER; i++) |
797 | + button_layout.left_buttons[i] = button_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST; |
798 | + |
799 | if (!d->pixmap || !d->picture) |
800 | return; |
801 | |
802 | @@ -1078,6 +1086,15 @@ |
803 | break; |
804 | #endif |
805 | |
806 | +#ifdef META_HAS_LOCAL_MENUS |
807 | + case BUTTON_WINDOW_MENU: |
808 | + if (!meta_button_present (&button_layout, META_BUTTON_FUNCTION_WINDOW_MENU)) |
809 | + return FALSE; |
810 | + |
811 | + space = &fgeom.window_menu_rect; |
812 | + break; |
813 | +#endif |
814 | + |
815 | default: |
816 | return FALSE; |
817 | } |
818 | @@ -1490,6 +1507,11 @@ |
819 | return META_BUTTON_FUNCTION_UNSTICK; |
820 | #endif |
821 | |
822 | +#ifdef META_HAS_LOCAL_MENUS |
823 | + else if (strcmp (str, "window_menu") == 0) |
824 | + return META_BUTTON_FUNCTION_WINDOW_MENU; |
825 | +#endif |
826 | + |
827 | else |
828 | return META_BUTTON_FUNCTION_LAST; |
829 | } |
830 | |
831 | === modified file 'gtk/window-decorator/wnck.c' |
832 | --- gtk/window-decorator/wnck.c 2011-10-13 09:53:38 +0000 |
833 | +++ gtk/window-decorator/wnck.c 2012-02-02 17:13:31 +0000 |
834 | @@ -727,7 +727,8 @@ |
835 | stick_button_event, |
836 | unshade_button_event, |
837 | unabove_button_event, |
838 | - unstick_button_event |
839 | + unstick_button_event, |
840 | + window_menu_button_event |
841 | }; |
842 | |
843 | d = calloc (1, sizeof (decor_t)); |
8 +#define GWD_SHOW_LOCAL_MENU (WNCK_WINDOW_ ACTION_ BELOW << 1)
No plausible reason for using a macro. In C++ constants (enum or unsigned int) are better as they respect scope rules. Also, should this be inside "#ifdef META_HAS_ LOCAL_MENUS" conditional?
296 button_ layout- >right_ buttons[ 2] = META_BUTTON_ FUNCTION_ CLOSE; PER_CORNER; i++) PER_CORNER; i++) layout- >right_ buttons[ i] = META_BUTTON_ FUNCTION_ LAST;
297
298 - for (i = 3; i < MAX_BUTTONS_
299 + for (i = 4; i < MAX_BUTTONS_
300 button_
301 }
I'm not sure what the magic number "3"->"4" is. But we now seem to miss 3 entirely. Is that correct?