Merge lp:~smspillaz/compiz-core/compiz-core.lim into lp:compiz-core/0.9.5

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

Description of the change

Adds support for Ubuntu's "locally integrated menu bars" into gtk-window-decorator.

No tests as of yet, but I'll try and write some for

showing/hiding
forcing them on/off
positions etc

soonish.

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

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;
297
298 - for (i = 3; i < MAX_BUTTONS_PER_CORNER; i++)
299 + for (i = 4; i < MAX_BUTTONS_PER_CORNER; i++)
300 button_layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
301 }

I'm not sure what the magic number "3"->"4" is. But we now seem to miss 3 entirely. Is that correct?

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

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

> 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?
>

Its C

>
> 296 button_layout->right_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
> 297
> 298 - for (i = 3; i < MAX_BUTTONS_PER_CORNER; i++)
> 299 + for (i = 4; i < MAX_BUTTONS_PER_CORNER; i++)
> 300 button_layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
> 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

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Please resubmit for target branch lp:compiz-core (0.9.7)

review: Needs Resubmitting
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

Revision history for this message
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

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

Subscribers

People subscribed via source and target branches