From 0808adefafde263dcf6d8414b8b91d44b1bf950d Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 20 Mar 2014 15:16:57 -0400 Subject: [PATCH] Move focus to be a vfunc --- src/core/window-private.h | 2 ++ src/core/window.c | 64 +-------------------------------- src/wayland/window-wayland.c | 11 ++++++ src/x11/window-x11.c | 70 ++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 63 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index c6e4adc8c..56d902d6a 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -476,6 +476,8 @@ struct _MetaWindowClass void (*delete) (MetaWindow *window, guint32 timestamp); void (*kill) (MetaWindow *window); + void (*focus) (MetaWindow *window, + guint32 timestamp); void (*move_resize_internal) (MetaWindow *window, int gravity, MetaRectangle requested_rect, diff --git a/src/core/window.c b/src/core/window.c index 3c4c53966..12a3f2aec 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -5090,69 +5090,7 @@ meta_window_focus (MetaWindow *window, return; } - /* For output-only or shaded windows, focus the frame. - * This seems to result in the client window getting key events - * though, so I don't know if it's icccm-compliant. - * - * Still, we have to do this or keynav breaks for these windows. - */ - if (window->frame && - (window->shaded || - !(window->input || window->take_focus))) - { - if (window->frame) - { - meta_topic (META_DEBUG_FOCUS, - "Focusing frame of %s\n", window->desc); - meta_display_set_input_focus_window (window->display, - window, - TRUE, - timestamp); - } - } - else - { - if (window->input) - { - meta_topic (META_DEBUG_FOCUS, - "Setting input focus on %s since input = true\n", - window->desc); - meta_display_set_input_focus_window (window->display, - window, - FALSE, - timestamp); - } - - if (window->take_focus) - { - meta_topic (META_DEBUG_FOCUS, - "Sending WM_TAKE_FOCUS to %s since take_focus = true\n", - window->desc); - - if (!window->input) - { - /* The "Globally Active Input" window case, where the window - * doesn't want us to call XSetInputFocus on it, but does - * want us to send a WM_TAKE_FOCUS. - * - * Normally, we want to just leave the focus undisturbed until - * the window respnds to WM_TAKE_FOCUS, but if we're unmanaging - * the current focus window we *need* to move the focus away, so - * we focus the no_focus_window now (and set - * display->focus_window to that) before sending WM_TAKE_FOCUS. - */ - if (window->display->focus_window != NULL && - window->display->focus_window->unmanaging) - meta_display_focus_the_no_focus_window (window->display, - window->screen, - timestamp); - } - - meta_display_request_take_focus (window->display, - window, - timestamp); - } - } + META_WINDOW_GET_CLASS (window)->focus (window, timestamp); if (window->wm_state_demands_attention) meta_window_unset_demands_attention(window); diff --git a/src/wayland/window-wayland.c b/src/wayland/window-wayland.c index 32c511e40..2eaaf017f 100644 --- a/src/wayland/window-wayland.c +++ b/src/wayland/window-wayland.c @@ -95,6 +95,16 @@ meta_window_wayland_kill (MetaWindow *window) /* TODO */ } +static void +meta_window_wayland_focus (MetaWindow *window, + guint32 timestamp) +{ + meta_display_set_input_focus_window (window->display, + window, + FALSE, + timestamp); +} + static void meta_window_wayland_move_resize_internal (MetaWindow *window, int gravity, @@ -199,5 +209,6 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass) window_class->ping = meta_window_wayland_ping; window_class->delete = meta_window_wayland_delete; window_class->kill = meta_window_wayland_kill; + window_class->focus = meta_window_wayland_focus; window_class->move_resize_internal = meta_window_wayland_move_resize_internal; } diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index a7e438145..aae590609 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -386,6 +386,75 @@ meta_window_x11_kill (MetaWindow *window) meta_error_trap_pop (window->display); } +static void +meta_window_x11_focus (MetaWindow *window, + guint32 timestamp) +{ + /* For output-only or shaded windows, focus the frame. + * This seems to result in the client window getting key events + * though, so I don't know if it's icccm-compliant. + * + * Still, we have to do this or keynav breaks for these windows. + */ + if (window->frame && + (window->shaded || + !(window->input || window->take_focus))) + { + if (window->frame) + { + meta_topic (META_DEBUG_FOCUS, + "Focusing frame of %s\n", window->desc); + meta_display_set_input_focus_window (window->display, + window, + TRUE, + timestamp); + } + } + else + { + if (window->input) + { + meta_topic (META_DEBUG_FOCUS, + "Setting input focus on %s since input = true\n", + window->desc); + meta_display_set_input_focus_window (window->display, + window, + FALSE, + timestamp); + } + + if (window->take_focus) + { + meta_topic (META_DEBUG_FOCUS, + "Sending WM_TAKE_FOCUS to %s since take_focus = true\n", + window->desc); + + if (!window->input) + { + /* The "Globally Active Input" window case, where the window + * doesn't want us to call XSetInputFocus on it, but does + * want us to send a WM_TAKE_FOCUS. + * + * Normally, we want to just leave the focus undisturbed until + * the window respnds to WM_TAKE_FOCUS, but if we're unmanaging + * the current focus window we *need* to move the focus away, so + * we focus the no_focus_window now (and set + * display->focus_window to that) before sending WM_TAKE_FOCUS. + */ + if (window->display->focus_window != NULL && + window->display->focus_window->unmanaging) + meta_display_focus_the_no_focus_window (window->display, + window->screen, + timestamp); + } + + meta_display_request_take_focus (window->display, + window, + timestamp); + } + } +} + static void update_net_frame_extents (MetaWindow *window) { @@ -811,6 +880,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) window_class->ping = meta_window_x11_ping; window_class->delete = meta_window_x11_delete; window_class->kill = meta_window_x11_kill; + window_class->focus = meta_window_x11_focus; window_class->move_resize_internal = meta_window_x11_move_resize_internal; window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints; }