From f84637d31e1858cb102581b4881ccad2e8df44f9 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 1 Aug 2011 23:39:37 +0200 Subject: [PATCH] window: Make MetaWindow keep a pointer to the popup menu Multiple windows may now have different popup menus, responding only to the device pair that popped it up. --- src/core/core.c | 8 +++++++- src/core/display.c | 30 +++++++++++++++++++++++++----- src/core/keybindings.c | 3 ++- src/core/window-private.h | 4 ++++ src/core/window.c | 30 ++++++++++++++++-------------- 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/core/core.c b/src/core/core.c index 6c808765c..9ce271b43 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -518,7 +518,13 @@ meta_core_show_window_menu (Display *xdisplay, guint32 timestamp) { MetaWindow *window = get_window (xdisplay, frame_xwindow); - + + /* There is already a menu popped up, + * most likely from another device + */ + if (window->menu) + return; + if (meta_prefs_get_raise_on_click ()) meta_window_raise (window); meta_window_focus (window, timestamp); diff --git a/src/core/display.c b/src/core/display.c index 8d9c6b3ce..b620c6cc4 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -522,9 +522,6 @@ meta_display_open (void) the_display->groups_by_leader = NULL; - the_display->window_with_menu = NULL; - the_display->window_menu = NULL; - the_display->screens = NULL; the_display->active_screen = NULL; @@ -1959,7 +1956,8 @@ event_callback (XEvent *event, ev_root_y); } } - else if (n_button == meta_prefs_get_mouse_button_menu()) + else if (!window->menu && + n_button == meta_prefs_get_mouse_button_menu()) { if (meta_prefs_get_raise_on_click ()) meta_window_raise (window); @@ -3604,7 +3602,29 @@ meta_display_begin_grab_op (MetaDisplay *display, root_x, root_y); grab_info = meta_display_get_grab_info (display, device); - + + if (window && window->cur_grab && + window->cur_grab != grab_info) + { + meta_verbose ("Attempt to perform window operation %u on window %s while" + " operation %u is already in effect on the same window for" + " the device pair %d/%d\n", + op, window->desc, window->cur_grab->grab_op, + meta_device_get_id (window->cur_grab->grab_pointer), + meta_device_get_id (window->cur_grab->grab_keyboard)); + return FALSE; + } + + if (window && window->menu != NULL && + window->menu_device != device) + { + meta_verbose ("Attempt to perform window operation %u on window %s while" + " context menu is opened on that window for pointer %d\n", + op, window->desc, + meta_device_get_id (window->menu_device)); + return FALSE; + } + if (grab_info != NULL && grab_info->grab_op != META_GRAB_OP_NONE) { diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 6634b54d8..aa2bf29c2 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -3120,7 +3120,8 @@ handle_activate_window_menu (MetaDisplay *display, device = meta_input_event_get_device (display, event); focus_info = meta_display_get_focus_info (display, device); - if (focus_info->focus_window) + if (focus_info->focus_window && + !focus_info->focus_window->menu) { Time evtime; int x, y; diff --git a/src/core/window-private.h b/src/core/window-private.h index 676b0416d..6aca9a6bc 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -107,6 +107,10 @@ struct _MetaWindow Window xgroup_leader; Window xclient_leader; + /* window menu if any, and the pointer that popped it up */ + MetaWindowMenu *menu; + MetaDevice *menu_device; + /* Initial workspace property */ int initial_workspace; diff --git a/src/core/window.c b/src/core/window.c index d61ac0b39..88dc14aee 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -197,6 +197,9 @@ meta_window_finalize (GObject *object) if (window->frame_bounds) cairo_region_destroy (window->frame_bounds); + if (window->menu) + meta_ui_window_menu_free (window->menu); + meta_icon_cache_free (&window->icon_cache); g_free (window->sm_client_id); @@ -1497,9 +1500,9 @@ meta_window_unmanage (MetaWindow *window, if (window->display->window_with_menu == window) { - meta_ui_window_menu_free (window->display->window_menu); - window->display->window_menu = NULL; - window->display->window_with_menu = NULL; + meta_ui_window_menu_free (window->menu); + window->menu_device = NULL; + window->menu = NULL; } if (destroying_windows_disallowed > 0) @@ -8030,13 +8033,12 @@ menu_callback (MetaWindowMenu *menu, meta_verbose ("Menu callback on nonexistent window\n"); } - if (display->window_menu == menu) + if (window && window->menu) { - display->window_menu = NULL; - display->window_with_menu = NULL; + meta_ui_window_menu_free (menu); + window->menu_device = NULL; + window->menu = NULL; } - - meta_ui_window_menu_free (menu); } void @@ -8055,11 +8057,11 @@ meta_window_show_menu (MetaWindow *window, g_return_if_fail (!window->override_redirect); - if (window->display->window_menu) + if (window->menu) { - meta_ui_window_menu_free (window->display->window_menu); - window->display->window_menu = NULL; - window->display->window_with_menu = NULL; + meta_ui_window_menu_free (window->menu); + window->menu_device = NULL; + window->menu = NULL; } ops = META_MENU_OP_NONE; @@ -8166,8 +8168,8 @@ meta_window_show_menu (MetaWindow *window, menu_callback, NULL); - window->display->window_menu = menu; - window->display->window_with_menu = window; + window->menu_device = device; + window->menu = menu; meta_verbose ("Popping up window menu for %s\n", window->desc);