From 04cbdb4e23e1baddff2c93b4aabe0f74375181bf Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 4 Jul 2011 01:55:09 +0200 Subject: [PATCH] workspace: use triggering device to focus the default window on workspace switch --- src/core/core.c | 11 +++++++++++ src/core/core.h | 1 + src/core/display.c | 15 ++++++++++++--- src/core/keybindings.c | 21 ++++++++++++++------- src/core/screen-private.h | 1 + src/core/screen.c | 21 ++++++++------------- src/core/window.c | 15 ++++++++++++++- src/core/workspace-private.h | 1 + src/core/workspace.c | 11 +++++++++-- src/ui/frames.c | 5 ++++- 10 files changed, 75 insertions(+), 27 deletions(-) diff --git a/src/core/core.c b/src/core/core.c index b00cb58c2..cd8ebec2a 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -250,9 +250,19 @@ lower_window_and_transients (MetaWindow *window, void meta_core_user_lower_and_unfocus (Display *xdisplay, Window frame_xwindow, + int device_id, guint32 timestamp) { MetaWindow *window = get_window (xdisplay, frame_xwindow); + MetaDevice *pointer; + + pointer = meta_device_map_lookup (window->display->device_map, device_id); + + if (pointer == NULL) + return; + + if (!META_IS_DEVICE_POINTER (pointer)) + pointer = meta_device_get_paired_device (pointer); lower_window_and_transients (window, NULL); @@ -261,6 +271,7 @@ meta_core_user_lower_and_unfocus (Display *xdisplay, * this will be invoked via keyboard action or by a mouse action; * in either case the window or a modal child will have been focused.) */ meta_workspace_focus_default_window (window->screen->active_workspace, + pointer, NULL, timestamp); } diff --git a/src/core/core.h b/src/core/core.h index ba269672a..48171a701 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -110,6 +110,7 @@ void meta_core_user_raise (Display *xdisplay, Window frame_xwindow); void meta_core_user_lower_and_unfocus (Display *xdisplay, Window frame_xwindow, + int device_id, guint32 timestamp); void meta_core_user_focus (Display *xdisplay, diff --git a/src/core/display.c b/src/core/display.c index 6e534b07d..27e30daea 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2294,8 +2294,8 @@ event_callback (XEvent *event, meta_display_screen_for_root (display, xroot); if (new_screen != NULL && display->active_screen != new_screen) - meta_workspace_focus_default_window (new_screen->active_workspace, - NULL, + meta_workspace_focus_default_window (new_screen->active_workspace, + device, NULL, evtime); } @@ -2417,6 +2417,7 @@ event_callback (XEvent *event, "brain-damage in the X protocol (see bug " "125492). Setting the default focus window.\n"); meta_workspace_focus_default_window (screen->active_workspace, + meta_device_get_paired_device (device), NULL, meta_display_get_current_time_roundtrip (display)); } @@ -2429,6 +2430,7 @@ event_callback (XEvent *event, "gnome-session logout dialog usage (see bug " "153220). Setting the default focus window.\n"); meta_workspace_focus_default_window (screen->active_workspace, + meta_device_get_paired_device (device), NULL, meta_display_get_current_time_roundtrip (display)); } @@ -2829,8 +2831,15 @@ event_callback (XEvent *event, meta_screen_show_desktop (screen, timestamp); else { + MetaDevice *pointer; + + pointer = meta_device_map_lookup (screen->display->device_map, + META_CORE_POINTER_ID); + meta_screen_unshow_desktop (screen); - meta_workspace_focus_default_window (screen->active_workspace, NULL, timestamp); + meta_workspace_focus_default_window (screen->active_workspace, + pointer, + NULL, timestamp); } } else if (event->xclient.message_type == diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 6f7d60e2f..c93e23665 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -2906,12 +2906,13 @@ process_workspace_switch_grab (MetaDisplay *display, { MetaWorkspace *workspace; guint evtype, keycode; - MetaDevice *device; + MetaDevice *pointer, *keyboard; MetaGrabInfo *grab_info; Time evtime; - device = meta_input_event_get_device (display, event); - grab_info = meta_display_get_grab_info (display, device); + keyboard = meta_input_event_get_device (display, event); + pointer = meta_device_get_paired_device (keyboard); + grab_info = meta_display_get_grab_info (display, pointer); if (screen != grab_info->grab_screen || !screen->ws_popup) return FALSE; @@ -2923,7 +2924,7 @@ process_workspace_switch_grab (MetaDisplay *display, evtime = meta_input_event_get_time (display, event); if (evtype == KeyRelease && - end_keyboard_grab (display, device, keycode)) + end_keyboard_grab (display, keyboard, keycode)) { /* We're done, move to the new workspace. */ MetaWorkspace *target_workspace; @@ -2937,12 +2938,13 @@ process_workspace_switch_grab (MetaDisplay *display, { meta_topic (META_DEBUG_KEYBINDINGS, "Ending grab so we can focus on the target workspace\n"); - meta_display_end_grab_op (display, device, evtime); + meta_display_end_grab_op (display, pointer, evtime); meta_topic (META_DEBUG_KEYBINDINGS, "Focusing default window on target workspace\n"); - meta_workspace_focus_default_window (target_workspace, + meta_workspace_focus_default_window (target_workspace, + pointer, NULL, evtime); @@ -3021,7 +3023,7 @@ process_workspace_switch_grab (MetaDisplay *display, meta_topic (META_DEBUG_KEYBINDINGS, "Ending workspace tabbing & focusing default window; uninteresting key pressed\n"); workspace = meta_screen_workspace_popup_get_selected (screen); - meta_workspace_focus_default_window (workspace, NULL, evtime); + meta_workspace_focus_default_window (workspace, pointer, NULL, evtime); return FALSE; } @@ -3039,8 +3041,13 @@ handle_show_desktop (MetaDisplay *display, if (screen->active_workspace->showing_desktop) { + MetaDevice *keyboard; + + keyboard = meta_input_event_get_device (display, event); + meta_screen_unshow_desktop (screen); meta_workspace_focus_default_window (screen->active_workspace, + meta_device_get_paired_device (keyboard), NULL, evtime); } else diff --git a/src/core/screen-private.h b/src/core/screen-private.h index fe6cd3fa8..31a246977 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -182,6 +182,7 @@ void meta_screen_tile_preview_update (MetaScreen *screen, void meta_screen_tile_preview_hide (MetaScreen *screen); MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen, + MetaDevice *pointer, MetaWindow *not_this_one); const MetaMonitorInfo* meta_screen_get_current_monitor_info (MetaScreen *screen, diff --git a/src/core/screen.c b/src/core/screen.c index 0860e92ba..7b5df82a7 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -1955,28 +1955,23 @@ meta_screen_tile_preview_hide (MetaScreen *screen) MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen, + MetaDevice *pointer, MetaWindow *not_this_one) { MetaWindow *window; - Window root_return, child_return; int root_x_return, root_y_return; - int win_x_return, win_y_return; - unsigned int mask_return; - + if (not_this_one) meta_topic (META_DEBUG_FOCUS, "Focusing mouse window excluding %s\n", not_this_one->desc); meta_error_trap_push (screen->display); - XQueryPointer (screen->display->xdisplay, - screen->xroot, - &root_return, - &child_return, - &root_x_return, - &root_y_return, - &win_x_return, - &win_y_return, - &mask_return); + meta_device_pointer_query_position (META_DEVICE_POINTER (pointer), + screen->xroot, + NULL, NULL, + &root_x_return, + &root_y_return, + NULL, NULL, NULL); meta_error_trap_pop (screen->display); window = meta_stack_get_default_focus_window_at_point (screen->stack, diff --git a/src/core/window.c b/src/core/window.c index 84317b2c3..5def815e8 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1740,6 +1740,17 @@ meta_window_unmanage (MetaWindow *window, FALSE); if (window->focus_keyboard) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing default window since we're unmanaging %s\n", + window->desc); + meta_workspace_focus_default_window (window->screen->active_workspace, + meta_device_get_paired_device (window->focus_keyboard), + window, + timestamp); + } + else if (window->focus_keyboard && + window->expecting_focus_in) { if (window->expecting_focus_in) { @@ -1754,6 +1765,7 @@ meta_window_unmanage (MetaWindow *window, window->desc); meta_workspace_focus_default_window (window->screen->active_workspace, + meta_device_get_paired_device (window->focus_keyboard), window, timestamp); } @@ -3334,7 +3346,7 @@ meta_window_hide (MetaWindow *window) * gotten FocusIn/FocusOut events. A more complete comprehensive * fix for these type of issues is described in the bug. */ - if (window->has_focus && window->expecting_focus_in) + if (window->focus_keyboard && window->expecting_focus_in) { MetaWindow *not_this_one = NULL; MetaWorkspace *my_workspace = meta_window_get_workspace (window); @@ -3355,6 +3367,7 @@ meta_window_hide (MetaWindow *window) not_this_one = window; meta_workspace_focus_default_window (window->screen->active_workspace, + meta_device_get_paired_device (window->focus_keyboard), not_this_one, timestamp); } diff --git a/src/core/workspace-private.h b/src/core/workspace-private.h index 78c900b04..fa2362163 100644 --- a/src/core/workspace-private.h +++ b/src/core/workspace-private.h @@ -95,6 +95,7 @@ GList* meta_workspace_get_onmonitor_region (MetaWorkspace *workspace, int which_monitor); void meta_workspace_focus_default_window (MetaWorkspace *workspace, + MetaDevice *pointer, MetaWindow *not_this_one, guint32 timestamp); diff --git a/src/core/workspace.c b/src/core/workspace.c index 06b7dadc5..043bf84dd 100644 --- a/src/core/workspace.c +++ b/src/core/workspace.c @@ -687,8 +687,13 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, } else { + MetaDevice *pointer; + + pointer = meta_device_map_lookup (screen->display->device_map, + META_CORE_POINTER_ID); meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n"); - meta_workspace_focus_default_window (workspace, NULL, timestamp); + meta_workspace_focus_default_window (workspace, pointer, + NULL, timestamp); } /* Emit switched signal from screen.c */ @@ -1212,6 +1217,7 @@ meta_workspace_get_name (MetaWorkspace *workspace) void meta_workspace_focus_default_window (MetaWorkspace *workspace, + MetaDevice *pointer, MetaWindow *not_this_one, guint32 timestamp) { @@ -1228,7 +1234,8 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, else { MetaWindow * window; - window = meta_screen_get_mouse_window (workspace->screen, not_this_one); + window = meta_screen_get_mouse_window (workspace->screen, + pointer, not_this_one); if (window && window->type != META_WINDOW_DOCK && window->type != META_WINDOW_DESKTOP) diff --git a/src/ui/frames.c b/src/ui/frames.c index 933108a48..c6d7b439b 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -1046,10 +1046,12 @@ meta_frame_titlebar_event (MetaUIFrame *frame, int action) { MetaFrameFlags flags; + GdkDevice *pointer; Display *display; display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - + pointer = gdk_event_get_device ((GdkEvent *) event); + switch (action) { case G_DESKTOP_TITLEBAR_ACTION_TOGGLE_SHADE: @@ -1131,6 +1133,7 @@ meta_frame_titlebar_event (MetaUIFrame *frame, case G_DESKTOP_TITLEBAR_ACTION_LOWER: meta_core_user_lower_and_unfocus (display, frame->xwindow, + gdk_x11_device_get_id (pointer), event->time); break;