swc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/swc
Log | Files | Refs | README | LICENSE

commit f39e4fa0db279aa7dde9b527ccfa48d67c16f0d0
parent 892ffcbf9dd568e1d1dfa0c97364cd23225bfc99
Author: Michael Forney <mforney@mforney.org>
Date:   Mon,  4 Aug 2014 23:54:47 -0700

window: Add an unfocus method instead of using focus(NULL)

This makes it easier for the xwm to keep track of the X11 focus, and
allows us to deactivate the window in an xdg_shell_surface
implementation.

Diffstat:
Mlibswc/window.c | 16+++++++---------
Mlibswc/window.h | 1+
Mlibswc/xwm.c | 28+++++++++++++++++++++++++---
3 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/libswc/window.c b/libswc/window.c @@ -74,18 +74,16 @@ void swc_window_focus(struct swc_window * base) struct compositor_view * new_focus = window ? window->view : NULL, * old_focus = swc.seat->keyboard->focus.view; - /* If the keyboard already has a focused window, and we are changing the - * focus to either NULL, or a window with a different implementation, set - * the focus of the previous focus window's implementation to NULL. */ - if (old_focus && old_focus->window - && !(window && window->impl == INTERNAL(old_focus->window)->impl) - && old_focus->window->impl->focus) - { - old_focus->window->impl->focus(NULL); - } + if (new_focus == old_focus) + return; + /* Focus the new window before unfocusing the old one in case both are X11 + * windows so the xwl_window implementation can handle this transition + * correctly. */ if (window && window->impl->focus) window->impl->focus(window); + if (old_focus && old_focus->window && old_focus->window->impl->unfocus) + old_focus->window->impl->unfocus(old_focus->window); keyboard_set_focus(swc.seat->keyboard, new_focus); } diff --git a/libswc/window.h b/libswc/window.h @@ -60,6 +60,7 @@ struct window_impl void (* configure)(struct window * window, const struct swc_rectangle * geometry); void (* focus)(struct window * window); + void (* unfocus)(struct window * window); }; extern struct wl_listener window_enter_listener; diff --git a/libswc/xwm.c b/libswc/xwm.c @@ -62,6 +62,7 @@ static struct xcb_ewmh_connection_t ewmh; xcb_screen_t * screen; xcb_window_t window; + struct xwl_window * focus; struct wl_event_source * source; struct wl_list windows, unpaired_windows; union @@ -145,16 +146,34 @@ static void focus(struct window * window) { struct xwl_window * xwl_window = wl_container_of(window, xwl_window, window); - xcb_window_t id = window ? xwl_window->id : XCB_NONE; xcb_set_input_focus(xwm.connection, XCB_INPUT_FOCUS_NONE, - id, XCB_CURRENT_TIME); + xwl_window->id, XCB_CURRENT_TIME); xcb_flush(xwm.connection); + xwm.focus = xwl_window; +} + +static void unfocus(struct window * window) +{ + struct xwl_window * xwl_window + = wl_container_of(window, xwl_window, window); + + /* If the window we are unfocusing is the latest xwl_window to be focused, + * we know we have transitioned to some other window type, so the X11 focus + * can be set to XCB_NONE. Otherwise, we have transitioned to another X11 + * window, and the X11 focus has already been updated. */ + if (xwl_window == xwm.focus) + { + xcb_set_input_focus(xwm.connection, XCB_INPUT_FOCUS_NONE, XCB_NONE, + XCB_CURRENT_TIME); + xcb_flush(xwm.connection); + } } static const struct window_impl xwl_window_handler = { .configure = &configure, - .focus = &focus + .focus = &focus, + .unfocus = &unfocus, }; static void handle_surface_destroy(struct wl_listener * listener, void * data) @@ -162,6 +181,9 @@ static void handle_surface_destroy(struct wl_listener * listener, void * data) struct xwl_window * xwl_window = wl_container_of(listener, xwl_window, surface_destroy_listener); + if (xwm.focus == xwl_window) + xwm.focus = NULL; + window_finalize(&xwl_window->window); wl_list_remove(&xwl_window->link); wl_list_insert(&xwm.unpaired_windows, &xwl_window->link);