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

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~smspillaz/compiz-core/compiz-core.lim
Merge into: lp:compiz-core
Diff against target: 1152 lines (+873/-11)
15 files modified
gtk/window-decorator/CMakeLists.txt (+6/-0)
gtk/window-decorator/decorator.c (+32/-6)
gtk/window-decorator/events.c (+109/-3)
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 (+331/-0)
gtk/window-decorator/local-menus/src/local-menus.h (+95/-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 (+20/-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 (+70/-0)
gtk/window-decorator/local-menus/tests/test-local-menu.h (+48/-0)
gtk/window-decorator/metacity.c (+48/-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 Fixing
Alan Griffiths Pending
Review via email: mp+93949@code.launchpad.net

This proposal supersedes a proposal from 2012-02-06.

This proposal has been superseded by a proposal from 2012-02-22.

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 : Posted in a previous version of this proposal

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?

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

> 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

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

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

review: Needs Resubmitting
Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

Looks better

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

(More work needed to adopt to trevino;s changes)

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

Fails to build ifndef META_HAS_LOCAL_MENUS

[ 0%] Building C object gtk/window-decorator/local-menus/CMakeFiles/gtk_window_decorator_local_menus.dir/src/local-menus.c.o
/home/dan/bzr/compiz-core/lim/gtk/window-decorator/local-menus/src/local-menus.c:36:1: error: ‘gwd_menu_mode_changed’ defined but not used [-Werror=unused-function]
/home/dan/bzr/compiz-core/lim/gtk/window-decorator/local-menus/src/local-menus.c:72:1: error: ‘on_local_menu_activated’ defined but not used [-Werror=unused-function]
cc1: all warnings being treated as errors

review: Needs Fixing
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote : Posted in a previous version of this proposal

+ gboolean empty = g_strcmp0 (entry_id, "") == 0;

You can do the same with:
gboolean empty = (!entry_id || entry_id[0] == '\0');

Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

If we're trying to be cryptic...

   gboolean empty = g_strcmp0 (entry_id, "") == 0;

can be written:

   gboolean empty = !entry_id || !*entry_id;

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote : Posted in a previous version of this proposal

Ah, Sam remember to update the "EntryActivated" signal against the new signature s(iiuu).

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

Yep, done

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

Fails to build for a whole new reason now :(

Scanning dependencies of target gtk_window_decorator_force_local_menu_on_test
[ 5%] Building CXX object gtk/window-decorator/local-menus/tests/force_local_menu_on/CMakeFiles/gtk_window_decorator_force_local_menu_on_test.dir/test-force-local-menu-on.cpp.o
/home/dan/bzr/compiz-core/lim/gtk/window-decorator/local-menus/tests/force_local_menu_on/test-force-local-menu-on.cpp: In member function ‘virtual void GtkWindowDecoratorTestLocalMenuLayout_TestForceNoCloseButtonSet_Test::TestBody()’:
/home/dan/bzr/compiz-core/lim/gtk/window-decorator/local-menus/tests/force_local_menu_on/test-force-local-menu-on.cpp:56:5: error: ‘META_BUTTON_FUNCTION_WINDOW_MENU’ was not declared in this scope
/home/dan/bzr/compiz-core/lim/gtk/window-decorator/local-menus/tests/force_local_menu_on/test-force-local-menu-on.cpp: In member function ‘virtual void GtkWindowDecoratorTestLocalMenuLayout_TestForceNoCloseMinimizeMaximizeButtonSet_Test::TestBody()’:
/home/dan/bzr/compiz-core/lim/gtk/window-decorator/local-menus/tests/force_local_menu_on/test-force-local-menu-on.cpp:69:5: error: ‘META_BUTTON_FUNCTION_WINDOW_MENU’ was not declared in this scope
make[2]: *** [gtk/window-decorator/local-menus/tests/force_local_menu_on/CMakeFiles/gtk_window_decorator_force_local_menu_on_test.dir/test-force-local-menu-on.cpp.o] Error 1
make[1]: *** [gtk/window-decorator/local-menus/tests/force_local_menu_on/CMakeFiles/gtk_window_decorator_force_local_menu_on_test.dir/all] Error 2
make: *** [all] Error 2

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'gtk/window-decorator/CMakeLists.txt'
--- gtk/window-decorator/CMakeLists.txt 2011-02-16 17:39:56 +0000
+++ gtk/window-decorator/CMakeLists.txt 2012-02-21 10:38:22 +0000
@@ -4,7 +4,10 @@
4 set (CMAKE_INSTALL_RPATH ${libdir})4 set (CMAKE_INSTALL_RPATH ${libdir})
5 endif (COMPIZ_BUILD_WITH_RPATH)5 endif (COMPIZ_BUILD_WITH_RPATH)
66
7 add_subdirectory (local-menus)
8
7 include_directories (9 include_directories (
10 ${CMAKE_CURRENT_SOURCE_DIR}/local-menus/src
8 ${compiz_SOURCE_DIR}/include11 ${compiz_SOURCE_DIR}/include
9 ${CMAKE_BINARY_DIR}/gtk12 ${CMAKE_BINARY_DIR}/gtk
10 ${GTK_WINDOW_DECORATOR_INCLUDE_DIRS}13 ${GTK_WINDOW_DECORATOR_INCLUDE_DIRS}
@@ -63,6 +66,9 @@
63 target_link_libraries (66 target_link_libraries (
64 gtk-window-decorator67 gtk-window-decorator
65 decoration68 decoration
69
70 gtk_window_decorator_local_menus
71
66 ${GTK_WINDOW_DECORATOR_LIBRARIES}72 ${GTK_WINDOW_DECORATOR_LIBRARIES}
67 ${GCONF_LIBRARIES}73 ${GCONF_LIBRARIES}
68 ${DBUS_GLIB_LIBRARIES}74 ${DBUS_GLIB_LIBRARIES}
6975
=== modified file 'gtk/window-decorator/decorator.c'
--- gtk/window-decorator/decorator.c 2012-02-20 07:42:20 +0000
+++ gtk/window-decorator/decorator.c 2012-02-21 10:38:22 +0000
@@ -24,6 +24,7 @@
24 */24 */
2525
26#include "gtk-window-decorator.h"26#include "gtk-window-decorator.h"
27#include "local-menus.h"
2728
28decor_frame_t *29decor_frame_t *
29create_normal_frame (const gchar *type)30create_normal_frame (const gchar *type)
@@ -230,12 +231,16 @@
230void231void
231update_event_windows (WnckWindow *win)232update_event_windows (WnckWindow *win)
232{233{
234#define GWD_SHOW_LOCAL_MENU (WNCK_WINDOW_ACTION_BELOW << 1)
233 Display *xdisplay;235 Display *xdisplay;
234 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");236 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
235 gint x0, y0, width, height, x, y, w, h;237 gint x0, y0, width, height, x, y, w, h;
236 gint i, j, k, l;238 gint i, j, k, l;
237 gint actions = d->actions;239 gint actions = d->actions;
238240
241 if (gwd_window_should_have_local_menu (win))
242 actions |= GWD_SHOW_LOCAL_MENU;
243
239 xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());244 xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
240245
241 /* Get the geometry of the client */246 /* Get the geometry of the client */
@@ -298,11 +303,19 @@
298 XMapWindow (xdisplay, d->event_windows[i][j].window);303 XMapWindow (xdisplay, d->event_windows[i][j].window);
299 XMoveResizeWindow (xdisplay, d->event_windows[i][j].window,304 XMoveResizeWindow (xdisplay, d->event_windows[i][j].window,
300 x, y, w, h);305 x, y, w, h);
306
307 BoxPtr box = &d->event_windows[i][j].pos;
308 box->x1 = x;
309 box->x2 = x + w;
310 box->y1 = y;
311 box->y2 = y + h;
301 }312 }
302 /* No parent and no geometry - unmap all event windows */313 /* No parent and no geometry - unmap all event windows */
303 else if (!d->frame_window)314 else if (!d->frame_window)
304 {315 {
305 XUnmapWindow (xdisplay, d->event_windows[i][j].window);316 XUnmapWindow (xdisplay, d->event_windows[i][j].window);
317
318 memset (&d->event_windows[i][j].pos, 0, sizeof (Box));
306 }319 }
307 }320 }
308 }321 }
@@ -326,12 +339,18 @@
326 WNCK_WINDOW_ACTION_STICK,339 WNCK_WINDOW_ACTION_STICK,
327 WNCK_WINDOW_ACTION_UNSHADE,340 WNCK_WINDOW_ACTION_UNSHADE,
328 WNCK_WINDOW_ACTION_ABOVE,341 WNCK_WINDOW_ACTION_ABOVE,
329 WNCK_WINDOW_ACTION_UNSTICK342 WNCK_WINDOW_ACTION_UNSTICK,
330#else343#else
331 0,344 0,
332 0,345 0,
333 0,346 0,
334 0,347 0,
348 0,
349#endif
350
351#ifdef META_HAS_LOCAL_MENUS
352 GWD_SHOW_LOCAL_MENU
353#else
335 0354 0
336#endif355#endif
337356
@@ -371,10 +390,17 @@
371 Window win = d->button_windows[i].window;390 Window win = d->button_windows[i].window;
372 XMapWindow (xdisplay, win);391 XMapWindow (xdisplay, win);
373 XMoveResizeWindow (xdisplay, win, x, y, w, h);392 XMoveResizeWindow (xdisplay, win, x, y, w, h);
393
394 BoxPtr box = &d->button_windows[i].pos;
395 box->x1 = x;
396 box->x2 = x + w;
397 box->y1 = y;
398 box->y2 = y + h;
374 }399 }
375 else if (!d->frame_window)400 else if (!d->frame_window)
376 {401 {
377 XUnmapWindow (xdisplay, d->button_windows[i].window);402 XUnmapWindow (xdisplay, d->button_windows[i].window);
403 memset (&d->button_windows[i].pos, 0, sizeof (Box));
378 }404 }
379 }405 }
380406
381407
=== modified file 'gtk/window-decorator/events.c'
--- gtk/window-decorator/events.c 2012-02-20 07:46:35 +0000
+++ gtk/window-decorator/events.c 2012-02-21 10:38:22 +0000
@@ -24,6 +24,16 @@
24 */24 */
2525
26#include "gtk-window-decorator.h" 26#include "gtk-window-decorator.h"
27#include "local-menus.h"
28
29typedef struct _delayed_move_info
30{
31 WnckWindow *win;
32 int x_root;
33 int y_root;
34 unsigned int button;
35 unsigned int time;
36} delayed_move_info;
2737
28void38void
29move_resize_window (WnckWindow *win,39move_resize_window (WnckWindow *win,
@@ -65,8 +75,9 @@
65 ev.xclient.data.l[3] = gtkwd_event->button;75 ev.xclient.data.l[3] = gtkwd_event->button;
66 ev.xclient.data.l[4] = 1;76 ev.xclient.data.l[4] = 1;
6777
68 XUngrabPointer (xdisplay, gtkwd_event->time);78 XAllowEvents (xdisplay, AsyncKeyboard | AsyncPointer, CurrentTime);
69 XUngrabKeyboard (xdisplay, gtkwd_event->time);79 XUngrabPointer (xdisplay, CurrentTime);
80 XUngrabKeyboard (xdisplay, CurrentTime);
7081
71 XSendEvent (xdisplay, xroot, FALSE,82 XSendEvent (xdisplay, xroot, FALSE,
72 SubstructureRedirectMask | SubstructureNotifyMask,83 SubstructureRedirectMask | SubstructureNotifyMask,
@@ -75,6 +86,24 @@
75 XSync (xdisplay, FALSE);86 XSync (xdisplay, FALSE);
76}87}
7788
89static gboolean
90move_resize_window_on_timeout (gpointer user_data)
91{
92 delayed_move_info *info = (delayed_move_info *) user_data;
93
94 decor_event event;
95 event.x = 0;
96 event.y = 0;
97 event.x_root = info->x_root;
98 event.y_root = info->y_root;
99 event.button = info->button;
100 event.window = wnck_window_get_xid (info->win);
101
102 move_resize_window (info->win, WM_MOVERESIZE_MOVE, &event);
103
104 return FALSE;
105}
106
78void107void
79common_button_event (WnckWindow *win,108common_button_event (WnckWindow *win,
80 decor_event *gtkwd_event,109 decor_event *gtkwd_event,
@@ -380,6 +409,73 @@
380}409}
381410
382void411void
412on_local_menu_hidden (gpointer user_data)
413{
414 decor_t *d = (decor_t *) user_data;
415
416 d->button_states[BUTTON_WINDOW_MENU] &= ~PRESSED_EVENT_WINDOW;
417
418 queue_decor_draw (d);
419}
420
421void
422window_menu_button_event (WnckWindow *win,
423 decor_event *gtkwd_event,
424 decor_event_type gtkwd_type)
425{
426 decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
427 guint state = d->button_states[BUTTON_WINDOW_MENU];
428
429 common_button_event (win, gtkwd_event, gtkwd_type,
430 BUTTON_WINDOW_MENU, 1, _("Window Menu"));
431
432 switch (gtkwd_type) {
433 case GButtonPress:
434 if (gtkwd_event->button == 1)
435 {
436 if (d->button_states[BUTTON_WINDOW_MENU] & BUTTON_EVENT_ACTION_STATE)
437 {
438 delayed_move_info *info = g_new0 (delayed_move_info, 1);
439
440 info->button = gtkwd_event->button;
441 info->time = gtkwd_event->time;
442 info->win = win;
443 info->x_root = gtkwd_event->x_root;
444 info->y_root = gtkwd_event->y_root;
445
446 gwd_prepare_show_local_menu ((start_move_window_cb) move_resize_window_on_timeout, (gpointer) info);
447 }
448 }
449 break;
450 case GButtonRelease:
451 if (gtkwd_event->button == 1)
452 if (state)
453 {
454 int win_x, win_y;
455 int box_x = d->button_windows[BUTTON_WINDOW_MENU].pos.x1;
456
457 wnck_window_get_geometry (win, &win_x, &win_y, NULL, NULL);
458
459 int x = win_x + box_x;
460 int y = win_y + d->context->extents.top;
461
462 gwd_show_local_menu (gdk_x11_display_get_xdisplay (gdk_display_get_default ()),
463 wnck_window_get_xid (win),
464 x, y,
465 box_x,
466 d->context->extents.top,
467 gtkwd_event->button,
468 gtkwd_event->time,
469 (show_window_menu_hidden_cb) on_local_menu_hidden,
470 (gpointer) d);
471 }
472 break;
473 default:
474 break;
475 }
476}
477
478void
383handle_title_button_event (WnckWindow *win,479handle_title_button_event (WnckWindow *win,
384 int action,480 int action,
385 decor_event *gtkwd_event)481 decor_event *gtkwd_event)
@@ -485,7 +581,17 @@
485581
486 restack_window (win, Above);582 restack_window (win, Above);
487583
488 move_resize_window (win, WM_MOVERESIZE_MOVE, gtkwd_event);584 delayed_move_info *info = g_new0 (delayed_move_info, 1);
585
586 info->x_root = gtkwd_event->x_root;
587 info->y_root = gtkwd_event->y_root;
588 info->button = gtkwd_event->button;
589 info->time = gtkwd_event->time;
590 info->win = win;
591
592 move_resize_window_on_timeout ((gpointer) info);
593
594 g_free (info);
489 }595 }
490 }596 }
491 else if (gtkwd_event->button == 2)597 else if (gtkwd_event->button == 2)
492598
=== modified file 'gtk/window-decorator/gtk-window-decorator.h'
--- gtk/window-decorator/gtk-window-decorator.h 2011-10-13 12:22:14 +0000
+++ gtk/window-decorator/gtk-window-decorator.h 2012-02-21 10:38:22 +0000
@@ -328,7 +328,8 @@
328#define BUTTON_UNSHADE 7328#define BUTTON_UNSHADE 7
329#define BUTTON_UNABOVE 8329#define BUTTON_UNABOVE 8
330#define BUTTON_UNSTICK 9330#define BUTTON_UNSTICK 9
331#define BUTTON_NUM 10331#define BUTTON_WINDOW_MENU 10
332#define BUTTON_NUM 11
332333
333struct _pos {334struct _pos {
334 int x, y, w, h;335 int x, y, w, h;
@@ -1013,6 +1014,11 @@
1013 decor_event_type gtkwd_type);1014 decor_event_type gtkwd_type);
10141015
1015void1016void
1017window_menu_button_event (WnckWindow *win,
1018 decor_event *gtkwd_event,
1019 decor_event_type gtkwd_type);
1020
1021void
1016handle_title_button_event (WnckWindow *win,1022handle_title_button_event (WnckWindow *win,
1017 int action,1023 int action,
1018 decor_event *gtkwd_event);1024 decor_event *gtkwd_event);
10191025
=== added directory 'gtk/window-decorator/local-menus'
=== added file 'gtk/window-decorator/local-menus/CMakeLists.txt'
--- gtk/window-decorator/local-menus/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/local-menus/CMakeLists.txt 2012-02-21 10:38:22 +0000
@@ -0,0 +1,60 @@
1pkg_check_modules(
2 LOCAL_MENUS
3 REQUIRED
4 glib-2.0 gio-2.0 libwnck-1.0 gtk+-2.0>=2.18.0
5)
6
7INCLUDE_DIRECTORIES(
8 ${CMAKE_CURRENT_SOURCE_DIR}/include
9 ${CMAKE_CURRENT_SOURCE_DIR}/src
10
11 ${compiz_SOURCE_DIR}/gtk/window-decorator
12
13 ${Boost_INCLUDE_DIRS}
14
15 ${LOCAL_MENUS_INCLUDE_DIRS}
16 ${METACITY_INCLUDE_DIRS}
17)
18
19LINK_DIRECTORIES (${LOCAL_MENUS_LIBRARY_DIRS})
20
21SET(
22 PUBLIC_HEADERS
23)
24
25SET(
26 PRIVATE_HEADERS
27 ${CMAKE_CURRENT_SOURCE_DIR}/src/local-menus.h
28)
29
30SET(
31 SRCS
32 ${CMAKE_CURRENT_SOURCE_DIR}/src/local-menus.c
33)
34
35ADD_LIBRARY(
36 gtk_window_decorator_local_menus STATIC
37
38 ${SRCS}
39
40 ${PUBLIC_HEADERS}
41 ${PRIVATE_HEADERS}
42)
43
44IF (COMPIZ_BUILD_TESTING)
45ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
46ENDIF (COMPIZ_BUILD_TESTING)
47
48SET_TARGET_PROPERTIES(
49 gtk_window_decorator_local_menus PROPERTIES
50 PUBLIC_HEADER "${PUBLIC_HEADERS}"
51)
52
53install (FILES ${PUBLIC_HEADERS} DESTINATION ${COMPIZ_CORE_INCLUDE_DIR})
54
55TARGET_LINK_LIBRARIES(
56 gtk_window_decorator_local_menus
57
58 ${LOCAL_MENUS_LIBRARIES}
59)
60
061
=== added directory 'gtk/window-decorator/local-menus/include'
=== added directory 'gtk/window-decorator/local-menus/src'
=== added file 'gtk/window-decorator/local-menus/src/local-menus.c'
--- gtk/window-decorator/local-menus/src/local-menus.c 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/local-menus/src/local-menus.c 2012-02-21 10:38:22 +0000
@@ -0,0 +1,331 @@
1/*
2 * Copyright © 2006 Novell, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * Author: David Reveman <davidr@novell.com>
20 *
21 * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com>
22 * Frames Management: Copright © 2011 Canonical Ltd.
23 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
24 */
25
26#include <string.h>
27#include "local-menus.h"
28#include <gdk/gdk.h>
29#include <gdk/gdkx.h>
30
31#define GLOBAL 0
32#define LOCAL 1
33
34gint menu_mode = GLOBAL;
35
36#ifdef META_HAS_LOCAL_MENUS
37static void
38gwd_menu_mode_changed (GSettings *settings,
39 gchar *key,
40 gpointer user_data)
41{
42 menu_mode = g_settings_get_enum (settings, "menu-mode");
43}
44#endif
45
46active_local_menu *active_menu;
47pending_local_menu *pending_menu;
48
49gboolean
50gwd_window_should_have_local_menu (WnckWindow *win)
51{
52#ifdef META_HAS_LOCAL_MENUS
53 const gchar * const *schemas = g_settings_list_schemas ();
54 static GSettings *lim_settings = NULL;
55 while (*schemas != NULL && !lim_settings)
56 {
57 if (g_str_equal (*schemas, "com.canonical.indicator.appmenu"))
58 {
59 lim_settings = g_settings_new ("com.canonical.indicator.appmenu");
60 menu_mode = g_settings_get_enum (lim_settings, "menu-mode");
61 g_signal_connect (lim_settings, "changed::menu-mode", G_CALLBACK (gwd_menu_mode_changed), NULL);
62 break;
63 }
64 ++schemas;
65 }
66
67 if (lim_settings)
68 return menu_mode == LOCAL;
69#endif
70
71 return FALSE;
72}
73
74gchar *
75gwd_get_entry_id_from_sync_variant (GVariant *args)
76{
77 /* We need to get the indicator data once we've called show */
78
79 GVariantIter* iter = NULL;
80 gchar* name_hint = NULL;
81 gchar* indicator_id = NULL;
82 gchar* entry_id = NULL;
83 gchar* label = NULL;
84 gboolean label_sensitive = FALSE;
85 gboolean label_visible = FALSE;
86 guint32 image_type = 0;
87 gchar* image_data = NULL;
88 gboolean image_sensitive = FALSE;
89 gboolean image_visible = FALSE;
90 gint32 priority = -1;
91
92 g_variant_get (args, "(a(ssssbbusbbi))", &iter);
93 while (g_variant_iter_loop (iter, "(ssssbbusbbi)",
94 &indicator_id,
95 &entry_id,
96 &name_hint,
97 &label,
98 &label_sensitive,
99 &label_visible,
100 &image_type,
101 &image_data,
102 &image_sensitive,
103 &image_visible,
104 &priority))
105 {
106 g_variant_unref (args);
107 return g_strdup (entry_id);
108 }
109
110 g_variant_unref (args);
111 g_assert_not_reached ();
112 return NULL;
113}
114#ifdef META_HAS_LOCAL_MENUS
115static void
116on_local_menu_activated (GDBusProxy *proxy,
117 gchar *sender_name,
118 gchar *signal_name,
119 GVariant *parameters,
120 gpointer user_data)
121{
122
123 if (g_strcmp0 (signal_name, "EntryActivated") == 0)
124 {
125 show_local_menu_data *d = (show_local_menu_data *) user_data;
126 gchar *entry_id = NULL;
127 gint x_out, y_out;
128 guint width, height;
129
130 g_variant_get (parameters, "(s(iiuu))", &entry_id, &x_out, &y_out, &width, &height, NULL);
131
132 if (!d->local_menu_entry_id)
133 {
134 GError *error = NULL;
135 GVariant *params = g_variant_new ("(s)", "libappmenu.so", NULL);
136 GVariant *args = g_dbus_proxy_call_sync (proxy, "SyncOne", params, 0, 500, NULL, &error);
137
138 g_assert_no_error (error);
139 d->local_menu_entry_id = gwd_get_entry_id_from_sync_variant (args);
140 }
141
142 if (g_strcmp0 (entry_id, d->local_menu_entry_id) == 0)
143 {
144 d->rect->x = x_out - d->dx;
145 d->rect->y = y_out - d->dy;
146 d->rect->width = width;
147 d->rect->height = height;
148 }
149 else if (g_strcmp0 (entry_id, "") == 0)
150 {
151 memset (d->rect, 0, sizeof (GdkRectangle));
152 (*d->cb) (d->user_data);
153
154 g_signal_handlers_disconnect_by_func (d->proxy, on_local_menu_activated, d);
155
156 g_object_unref (d->proxy);
157 g_object_unref (d->conn);
158
159 if (active_menu)
160 {
161 g_free (active_menu);
162 active_menu = NULL;
163 }
164
165 g_free (d->local_menu_entry_id);
166 g_free (d);
167 }
168 }
169
170}
171#endif
172gboolean
173gwd_move_window_instead (gpointer user_data)
174{
175 (*pending_menu->cb) (pending_menu->user_data);
176 g_free (pending_menu->user_data);
177 g_free (pending_menu);
178 pending_menu = NULL;
179 return FALSE;
180}
181
182void
183gwd_prepare_show_local_menu (start_move_window_cb start_move_window,
184 gpointer user_data_start_move_window)
185{
186 if (pending_menu)
187 {
188 g_source_remove (pending_menu->move_timeout_id);
189 g_free (pending_menu->user_data);
190 g_free (pending_menu);
191 pending_menu = NULL;
192 }
193
194 pending_menu = g_new0 (pending_local_menu, 1);
195 pending_menu->cb = start_move_window;
196 pending_menu->user_data = user_data_start_move_window;
197 pending_menu->move_timeout_id = g_timeout_add (120, gwd_move_window_instead, pending_menu);
198}
199
200void
201gwd_show_local_menu (Display *xdisplay,
202 Window frame_xwindow,
203 int x,
204 int y,
205 int x_win,
206 int y_win,
207 int button,
208 guint32 timestamp,
209 show_window_menu_hidden_cb cb,
210 gpointer user_data_show_window_menu)
211{
212 if (pending_menu)
213 {
214 g_source_remove (pending_menu->move_timeout_id);
215 g_free (pending_menu->user_data);
216 g_free (pending_menu);
217 pending_menu = NULL;
218 }
219
220#ifdef META_HAS_LOCAL_MENUS
221 GError *error = NULL;
222 GDBusConnection *conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
223
224
225 XUngrabPointer (gdk_x11_display_get_xdisplay (gdk_display_get_default ()), CurrentTime);
226 XUngrabKeyboard (gdk_x11_display_get_xdisplay (gdk_display_get_default ()), CurrentTime);
227 XSync (gdk_x11_display_get_xdisplay (gdk_display_get_default ()), FALSE);
228
229 if (!conn)
230 {
231 g_print ("error getting connection: %s\n", error->message);
232 return;
233 }
234
235 GDBusProxy *proxy = g_dbus_proxy_new_sync (conn, 0, NULL, "com.canonical.Unity.Panel.Service",
236 "/com/canonical/Unity/Panel/Service",
237 "com.canonical.Unity.Panel.Service",
238 NULL, &error);
239
240 if (proxy)
241 {
242 GVariant *message = g_variant_new ("(uiiu)", frame_xwindow, x, y, time);
243 g_dbus_proxy_call_sync (proxy, "ShowAppMenu", message, 0, 500, NULL, &error);
244 if (error)
245 {
246 g_print ("error calling ShowAppMenu: %s\n", error->message);
247 g_object_unref (proxy);
248 g_object_unref (conn);
249 return;
250 }
251
252 show_local_menu_data *data = g_new0 (show_local_menu_data, 1);
253
254 if (active_menu)
255 g_free (active_menu);
256
257 active_menu = g_new0 (active_local_menu, 1);
258
259 data->conn = g_object_ref (conn);
260 data->proxy = g_object_ref (proxy);
261 data->cb = cb;
262 data->user_data = user_data_show_window_menu;
263 data->rect = &active_menu->rect;
264 data->dx = x - x_win;
265 data->dy = y - y_win;
266 data->local_menu_entry_id = NULL;
267
268 g_signal_connect (proxy, "g-signal", G_CALLBACK (on_local_menu_activated), data);
269
270 g_object_unref (conn);
271 g_object_unref (proxy);
272
273 return;
274 }
275 else
276 {
277 g_print ("error getting proxy: %s\n", error->message);
278 }
279
280 g_object_unref (conn);
281#endif
282}
283
284void
285force_local_menus_on (WnckWindow *win,
286 MetaButtonLayout *button_layout)
287{
288#ifdef META_HAS_LOCAL_MENUS
289 if (gwd_window_should_have_local_menu (win))
290 {
291 if (button_layout->left_buttons[0] != META_BUTTON_FUNCTION_LAST)
292 {
293 unsigned int i = 0;
294 for (; i < MAX_BUTTONS_PER_CORNER; i++)
295 {
296 if (button_layout->left_buttons[i] == META_BUTTON_FUNCTION_WINDOW_MENU)
297 break;
298 else if (button_layout->left_buttons[i] == META_BUTTON_FUNCTION_LAST)
299 {
300 if ((i + 1) < MAX_BUTTONS_PER_CORNER)
301 {
302 button_layout->left_buttons[i + 1] = META_BUTTON_FUNCTION_LAST;
303 button_layout->left_buttons[i] = META_BUTTON_FUNCTION_WINDOW_MENU;
304 break;
305 }
306 }
307 }
308 }
309 if (button_layout->right_buttons[0] != META_BUTTON_FUNCTION_LAST)
310 {
311 unsigned int i = 0;
312 for (; i < MAX_BUTTONS_PER_CORNER; i++)
313 {
314 if (button_layout->right_buttons[i] == META_BUTTON_FUNCTION_WINDOW_MENU)
315 break;
316 else if (button_layout->right_buttons[i] == META_BUTTON_FUNCTION_LAST)
317 {
318 if ((i + 1) < MAX_BUTTONS_PER_CORNER)
319 {
320 button_layout->right_buttons[i + 1] = META_BUTTON_FUNCTION_LAST;
321 button_layout->right_buttons[i] = META_BUTTON_FUNCTION_WINDOW_MENU;
322 break;
323 }
324 }
325 }
326 }
327 }
328#endif
329}
330
331
0332
=== added file 'gtk/window-decorator/local-menus/src/local-menus.h'
--- gtk/window-decorator/local-menus/src/local-menus.h 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/local-menus/src/local-menus.h 2012-02-21 10:38:22 +0000
@@ -0,0 +1,95 @@
1/*
2 * Copyright © 2006 Novell, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 *
19 * Author: David Reveman <davidr@novell.com>
20 *
21 * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com>
22 * Frames Management: Copright © 2011 Canonical Ltd.
23 * Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
24 */
25
26#ifdef __cplusplus
27extern "C"
28{
29#endif
30
31#include <glib.h>
32#include <gio/gio.h>
33#ifndef WNCK_I_KNOW_THIS_IS_UNSTABLE
34#define WNCK_I_KNOW_THIS_IS_UNSTABLE
35#endif
36#include <libwnck/libwnck.h>
37#include <libwnck/window-action-menu.h>
38#include <metacity-private/theme.h>
39
40typedef void (*show_window_menu_hidden_cb) (gpointer);
41typedef void (*start_move_window_cb) (gpointer);
42
43typedef struct _pending_local_menu
44{
45 gint move_timeout_id;
46 gpointer user_data;
47 start_move_window_cb cb;
48} pending_local_menu;
49
50typedef struct _active_local_menu
51{
52 GdkRectangle rect;
53} active_local_menu;
54
55extern active_local_menu *active_menu;
56
57typedef struct _show_local_menu_data
58{
59 GDBusConnection *conn;
60 GDBusProxy *proxy;
61 show_window_menu_hidden_cb cb;
62 gpointer user_data;
63 GdkRectangle *rect;
64 gint dx;
65 gint dy;
66 gchar *local_menu_entry_id;
67} show_local_menu_data;
68
69gboolean
70gwd_window_should_have_local_menu (WnckWindow *win);
71
72void
73force_local_menus_on (WnckWindow *win,
74 MetaButtonLayout *layout);
75
76/* Button Down */
77void
78gwd_prepare_show_local_menu (start_move_window_cb start_move_window,
79 gpointer user_data_start_move_window);
80
81/* Button Up */
82void
83gwd_show_local_menu (Display *xdisplay,
84 Window frame_xwindow,
85 int x,
86 int y,
87 int x_win,
88 int y_win,
89 int button,
90 guint32 timestamp,
91 show_window_menu_hidden_cb cb,
92 gpointer user_data_show_window_menu);
93#ifdef __cplusplus
94}
95#endif
096
=== added directory 'gtk/window-decorator/local-menus/tests'
=== added file 'gtk/window-decorator/local-menus/tests/CMakeLists.txt'
--- gtk/window-decorator/local-menus/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/local-menus/tests/CMakeLists.txt 2012-02-21 10:38:22 +0000
@@ -0,0 +1,3 @@
1include_directories (${CMAKE_CURRENT_SOURCE_DIR})
2add_subdirectory (check_local_menu_on_off)
3add_subdirectory (force_local_menu_on)
04
=== added directory 'gtk/window-decorator/local-menus/tests/check_local_menu_on_off'
=== added file 'gtk/window-decorator/local-menus/tests/check_local_menu_on_off/CMakeLists.txt'
--- gtk/window-decorator/local-menus/tests/check_local_menu_on_off/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/local-menus/tests/check_local_menu_on_off/CMakeLists.txt 2012-02-21 10:38:22 +0000
@@ -0,0 +1,21 @@
1include_directories (${CMAKE_CURRENT_SOURCE_DIR}
2 ${compiz_SOURCE_DIR}/gtk/window-decorator/local-menus/tests
3 ${compiz_SOURCE_DIR}/gtk/window-decorator
4 ${compiz_SOURCE_DIR}/gtk/window-decorator/local-menus/src)
5
6add_executable(
7 gtk_window_decorator_check_local_menu_on_off_test
8
9 ${CMAKE_CURRENT_SOURCE_DIR}/test-local-menu-on-off.cpp
10)
11
12target_link_libraries(
13 gtk_window_decorator_check_local_menu_on_off_test
14
15 gtk_window_decorator_local_menus
16
17 ${GTEST_BOTH_LIBRARIES}
18 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
19)
20
21add_test (gtk_window_decorator_local_menus_on_off gtk_window_decorator_check_local_menu_on_off_test)
022
=== added directory 'gtk/window-decorator/local-menus/tests/check_local_menu_on_off/check_local_menu_on_off'
=== added directory 'gtk/window-decorator/local-menus/tests/check_local_menu_on_off/check_local_menu_on_off/CMakeFiles'
=== added file 'gtk/window-decorator/local-menus/tests/check_local_menu_on_off/test-local-menu-on-off.cpp'
--- gtk/window-decorator/local-menus/tests/check_local_menu_on_off/test-local-menu-on-off.cpp 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/local-menus/tests/check_local_menu_on_off/test-local-menu-on-off.cpp 2012-02-21 10:38:22 +0000
@@ -0,0 +1,20 @@
1#include "test-local-menu.h"
2
3#define GLOBAL 0
4#define LOCAL 1
5
6TEST_F (GtkWindowDecoratorTestLocalMenu, TestOn)
7{
8 g_settings_set_enum (getSettings (), "menu-mode", LOCAL);
9 gboolean result = gwd_window_should_have_local_menu (getWindow ());
10
11 EXPECT_TRUE (result);
12}
13
14TEST_F (GtkWindowDecoratorTestLocalMenu, TestOff)
15{
16 g_settings_set_enum (getSettings (), "menu-mode", GLOBAL);
17 gboolean result = gwd_window_should_have_local_menu (getWindow ());
18
19 EXPECT_FALSE (result);
20}
021
=== added directory 'gtk/window-decorator/local-menus/tests/force_local_menu_on'
=== added file 'gtk/window-decorator/local-menus/tests/force_local_menu_on/CMakeLists.txt'
--- gtk/window-decorator/local-menus/tests/force_local_menu_on/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/local-menus/tests/force_local_menu_on/CMakeLists.txt 2012-02-21 10:38:22 +0000
@@ -0,0 +1,21 @@
1include_directories (${CMAKE_CURRENT_SOURCE_DIR}
2 ${compiz_SOURCE_DIR}/gtk/window-decorator/local-menus/tests
3 ${compiz_SOURCE_DIR}/gtk/window-decorator
4 ${compiz_SOURCE_DIR}/gtk/window-decorator/local-menus/src)
5
6add_executable(
7 gtk_window_decorator_force_local_menu_on_test
8
9 ${CMAKE_CURRENT_SOURCE_DIR}/test-force-local-menu-on.cpp
10)
11
12target_link_libraries(
13 gtk_window_decorator_force_local_menu_on_test
14
15 gtk_window_decorator_local_menus
16
17 ${GTEST_BOTH_LIBRARIES}
18 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
19)
20
21add_test (gtk_window_decorator_force_local_menu_on gtk_window_decorator_force_local_menu_on_test)
022
=== added file 'gtk/window-decorator/local-menus/tests/force_local_menu_on/test-force-local-menu-on.cpp'
--- gtk/window-decorator/local-menus/tests/force_local_menu_on/test-force-local-menu-on.cpp 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/local-menus/tests/force_local_menu_on/test-force-local-menu-on.cpp 2012-02-21 10:38:22 +0000
@@ -0,0 +1,70 @@
1#include "test-local-menu.h"
2#include <cstring>
3
4#define GLOBAL 0
5#define LOCAL 1
6
7namespace
8{
9 void initializeMetaButtonLayout (MetaButtonLayout *layout)
10 {
11 memset (layout, 0, sizeof (MetaButtonLayout));
12
13 unsigned int i;
14
15 for (i = 0; i < MAX_BUTTONS_PER_CORNER; i++)
16 {
17 layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
18 layout->left_buttons[i] = META_BUTTON_FUNCTION_LAST;
19 }
20 }
21}
22
23class GtkWindowDecoratorTestLocalMenuLayout :
24 public GtkWindowDecoratorTestLocalMenu
25{
26 public:
27
28 MetaButtonLayout * getLayout () { return &mLayout; }
29
30 virtual void SetUp ()
31 {
32 GtkWindowDecoratorTestLocalMenu::SetUp ();
33 ::initializeMetaButtonLayout (&mLayout);
34 g_settings_set_enum (getSettings (), "menu-mode", LOCAL);
35 }
36
37 private:
38
39 MetaButtonLayout mLayout;
40};
41
42TEST_F (GtkWindowDecoratorTestLocalMenuLayout, TestForceNoButtonsSet)
43{
44 force_local_menus_on (getWindow (), getLayout ());
45
46 EXPECT_EQ (getLayout ()->right_buttons[0], META_BUTTON_FUNCTION_LAST);
47 EXPECT_EQ (getLayout ()->left_buttons[0], META_BUTTON_FUNCTION_LAST);
48}
49
50TEST_F (GtkWindowDecoratorTestLocalMenuLayout, TestForceNoCloseButtonSet)
51{
52 getLayout ()->right_buttons[0] = META_BUTTON_FUNCTION_CLOSE;
53
54 force_local_menus_on (getWindow (), getLayout ());
55
56 EXPECT_EQ (getLayout ()->right_buttons[1], META_BUTTON_FUNCTION_WINDOW_MENU);
57 EXPECT_EQ (getLayout ()->left_buttons[0], META_BUTTON_FUNCTION_LAST);
58}
59
60TEST_F (GtkWindowDecoratorTestLocalMenuLayout, TestForceNoCloseMinimizeMaximizeButtonSet)
61{
62 getLayout ()->left_buttons[0] = META_BUTTON_FUNCTION_CLOSE;
63 getLayout ()->left_buttons[1] = META_BUTTON_FUNCTION_CLOSE;
64 getLayout ()->left_buttons[2] = META_BUTTON_FUNCTION_CLOSE;
65
66 force_local_menus_on (getWindow (), getLayout ());
67
68 EXPECT_EQ (getLayout ()->right_buttons[0], META_BUTTON_FUNCTION_LAST);
69 EXPECT_EQ (getLayout ()->left_buttons[3], META_BUTTON_FUNCTION_WINDOW_MENU);
70}
071
=== added directory 'gtk/window-decorator/local-menus/tests/show_hide_menu'
=== added file 'gtk/window-decorator/local-menus/tests/test-local-menu.h'
--- gtk/window-decorator/local-menus/tests/test-local-menu.h 1970-01-01 00:00:00 +0000
+++ gtk/window-decorator/local-menus/tests/test-local-menu.h 2012-02-21 10:38:22 +0000
@@ -0,0 +1,48 @@
1#include <gtest/gtest.h>
2#include <gmock/gmock.h>
3#include "local-menus.h"
4#include <X11/Xlib.h>
5#include <gio/gio.h>
6
7class GtkWindowDecoratorTestLocalMenu :
8 public ::testing::Test
9{
10 public:
11
12 WnckWindow * getWindow () { return mWindow; }
13 GSettings * getSettings () { return mSettings; }
14
15 virtual void SetUp ()
16 {
17 gtk_init (NULL, NULL);
18
19 mXDisplay = XOpenDisplay (NULL);
20 mXWindow = XCreateSimpleWindow (mXDisplay, DefaultRootWindow (mXDisplay), 0, 0, 100, 100, 0, 0, 0);
21
22 XMapRaised (mXDisplay, mXWindow);
23
24 XFlush (mXDisplay);
25
26 while (g_main_context_iteration (g_main_context_default (), FALSE));
27
28 mWindow = wnck_window_get (mXWindow);
29
30 g_setenv("GSETTINGS_BACKEND", "memory", true);
31 mSettings = g_settings_new ("com.canonical.indicator.appmenu");
32 }
33
34 virtual void TearDown ()
35 {
36 XDestroyWindow (mXDisplay, mXWindow);
37 XCloseDisplay (mXDisplay);
38
39 g_object_unref (mSettings);
40 }
41
42 private:
43
44 WnckWindow *mWindow;
45 Window mXWindow;
46 Display *mXDisplay;
47 GSettings *mSettings;
48};
049
=== modified file 'gtk/window-decorator/metacity.c'
--- gtk/window-decorator/metacity.c 2012-02-16 06:51:37 +0000
+++ gtk/window-decorator/metacity.c 2012-02-21 10:38:22 +0000
@@ -24,6 +24,7 @@
24 */24 */
2525
26#include "gtk-window-decorator.h"26#include "gtk-window-decorator.h"
27#include "local-menus.h"
2728
28#ifdef USE_METACITY29#ifdef USE_METACITY
2930
@@ -488,6 +489,8 @@
488 button_layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;489 button_layout->right_buttons[i] = META_BUTTON_FUNCTION_LAST;
489 }490 }
490491
492 force_local_menus_on (d->win, button_layout);
493
491 *flags = 0;494 *flags = 0;
492495
493 if (d->actions & WNCK_WINDOW_ACTION_CLOSE)496 if (d->actions & WNCK_WINDOW_ACTION_CLOSE)
@@ -558,6 +561,15 @@
558 else561 else
559 clip->height = d->border_layout.left.y2 - d->border_layout.left.y1;562 clip->height = d->border_layout.left.y2 - d->border_layout.left.y1;
560563
564 memset (fgeom, 0, sizeof (MetaFrameGeometry));
565
566#ifdef META_HAS_LOCAL_MENUS
567
568 if (d->layout)
569 fgeom->text_layout = g_object_ref (d->layout);
570
571#endif
572
561 meta_theme_calc_geometry (theme,573 meta_theme_calc_geometry (theme,
562 frame_type,574 frame_type,
563 d->frame->text_height,575 d->frame->text_height,
@@ -567,6 +579,15 @@
567 button_layout,579 button_layout,
568 fgeom);580 fgeom);
569581
582#ifdef META_HAS_LOCAL_MENUS
583
584 if (d->layout)
585 g_object_unref (fgeom->text_layout);
586
587 fgeom->text_layout = NULL;
588
589#endif
590
570 clip->width += left_width + right_width;591 clip->width += left_width + right_width;
571 clip->height += top_height + bottom_height;592 clip->height += top_height + bottom_height;
572}593}
@@ -601,6 +622,11 @@
601 GdkColor bg_color;622 GdkColor bg_color;
602 double bg_alpha;623 double bg_alpha;
603624
625 memset (&button_layout, 0, sizeof (MetaButtonLayout));
626
627 for (i = 0; i < MAX_BUTTONS_PER_CORNER; i++)
628 button_layout.left_buttons[i] = button_layout.right_buttons[i] = META_BUTTON_FUNCTION_LAST;
629
604 if (!d->pixmap || !d->picture)630 if (!d->pixmap || !d->picture)
605 return;631 return;
606632
@@ -675,6 +701,9 @@
675701
676 size = MAX (fgeom.top_height, fgeom.bottom_height);702 size = MAX (fgeom.top_height, fgeom.bottom_height);
677703
704 if (active_menu)
705 g_object_set_data (G_OBJECT (style_window), "local_menu_rect", &active_menu->rect);
706
678 if (rect.width && size)707 if (rect.width && size)
679 {708 {
680 XRenderPictFormat *format;709 XRenderPictFormat *format;
@@ -899,6 +928,9 @@
899 XRenderFreePicture (xdisplay, src);928 XRenderFreePicture (xdisplay, src);
900 }929 }
901930
931 if (active_menu)
932 g_object_set_data (G_OBJECT (style_window), "local_menu_rect", NULL);
933
902 copy_to_front_buffer (d);934 copy_to_front_buffer (d);
903935
904 if (d->frame_window)936 if (d->frame_window)
@@ -1078,6 +1110,15 @@
1078 break;1110 break;
1079#endif1111#endif
10801112
1113#ifdef META_HAS_LOCAL_MENUS
1114 case BUTTON_WINDOW_MENU:
1115 if (!meta_button_present (&button_layout, META_BUTTON_FUNCTION_WINDOW_MENU))
1116 return FALSE;
1117
1118 space = &fgeom.window_menu_rect;
1119 break;
1120#endif
1121
1081 default:1122 default:
1082 return FALSE;1123 return FALSE;
1083 }1124 }
@@ -1266,6 +1307,8 @@
1266 MetaTheme *theme;1307 MetaTheme *theme;
1267 GdkRectangle clip;1308 GdkRectangle clip;
12681309
1310 memset (&fgeom, 0, sizeof (MetaFrameGeometry));
1311
1269 theme = meta_theme_get_current ();1312 theme = meta_theme_get_current ();
12701313
1271 meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,1314 meta_get_decoration_geometry (d, theme, &flags, &fgeom, &button_layout,
@@ -1490,6 +1533,11 @@
1490 return META_BUTTON_FUNCTION_UNSTICK;1533 return META_BUTTON_FUNCTION_UNSTICK;
1491#endif1534#endif
14921535
1536#ifdef META_HAS_LOCAL_MENUS
1537 else if (strcmp (str, "window_menu") == 0)
1538 return META_BUTTON_FUNCTION_WINDOW_MENU;
1539#endif
1540
1493 else1541 else
1494 return META_BUTTON_FUNCTION_LAST;1542 return META_BUTTON_FUNCTION_LAST;
1495}1543}
14961544
=== modified file 'gtk/window-decorator/wnck.c'
--- gtk/window-decorator/wnck.c 2012-02-10 10:23:27 +0000
+++ gtk/window-decorator/wnck.c 2012-02-21 10:38:22 +0000
@@ -738,7 +738,8 @@
738 stick_button_event,738 stick_button_event,
739 unshade_button_event,739 unshade_button_event,
740 unabove_button_event,740 unabove_button_event,
741 unstick_button_event741 unstick_button_event,
742 window_menu_button_event
742 };743 };
743744
744 d = calloc (1, sizeof (decor_t));745 d = calloc (1, sizeof (decor_t));

Subscribers

People subscribed via source and target branches