diff --git a/src/core/core.c b/src/core/core.c index 0607525c8..0b0d1f67d 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 29c18fcd3..d8dccb74c 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2065,7 +2065,7 @@ event_callback (XEvent *event, if (new_screen != NULL && display->active_screen != new_screen) meta_workspace_focus_default_window (new_screen->active_workspace, - NULL, + device, NULL, evtime); } @@ -2214,6 +2214,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)); } @@ -2226,6 +2227,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)); } @@ -2624,8 +2626,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 510f38b25..2c64eea9a 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -2953,12 +2953,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; @@ -2970,7 +2971,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; @@ -2984,12 +2985,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); @@ -3068,7 +3070,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; } @@ -3086,8 +3088,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 c18efa597..6fef672bf 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -184,6 +184,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 (MetaScreen *screen, diff --git a/src/core/screen.c b/src/core/screen.c index 61987155b..432ac7be0 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -2041,28 +2041,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 030395824..5b168e984 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1631,11 +1631,20 @@ meta_window_unmanage (MetaWindow *window, * invariants. */ if (meta_window_appears_focused (window)) - meta_window_propagate_focus_appearance (window, - window->focus_keyboard, - FALSE); + meta_window_propagate_focus_appearance (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) { @@ -1650,6 +1659,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); } @@ -3240,7 +3250,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); @@ -3258,6 +3268,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 f1391d0c8..dae265a99 100644 --- a/src/core/workspace-private.h +++ b/src/core/workspace-private.h @@ -85,6 +85,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 8bc64d561..7497f8e4b 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 */ @@ -1205,6 +1210,7 @@ meta_workspace_get_name (MetaWorkspace *workspace) void meta_workspace_focus_default_window (MetaWorkspace *workspace, + MetaDevice *pointer, MetaWindow *not_this_one, guint32 timestamp) { @@ -1221,7 +1227,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 3149b21f4..bbac9e3d3 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -1293,10 +1293,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 META_ACTION_TITLEBAR_TOGGLE_SHADE: @@ -1378,6 +1380,7 @@ meta_frame_titlebar_event (MetaUIFrame *frame, case META_ACTION_TITLEBAR_LOWER: meta_core_user_lower_and_unfocus (display, frame->xwindow, + gdk_x11_device_get_id (pointer), event->time); break;