--- desktop-shell/shell.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 9fbac00..52d82f6 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -176,6 +176,8 @@ struct shell_surface { bool relative; } state, next_state; /* surface states */ bool state_changed; + + int focus_count; }; struct shell_grab { @@ -213,6 +215,7 @@ struct rotate_grab { struct shell_seat { struct weston_seat *seat; struct wl_listener seat_destroy_listener; + struct weston_surface *focused_surface; struct { struct weston_pointer_grab grab; @@ -1854,6 +1857,56 @@ create_pointer_focus_listener(struct weston_seat *seat) } static void +shell_surface_lose_keyboard_focus(struct shell_surface *shsurf) +{ + if (--shsurf->focus_count == 0) + if (shell_surface_is_xdg_surface(shsurf)) + xdg_surface_send_focused_unset(shsurf->resource); +} + +static void +shell_surface_gain_keyboard_focus(struct shell_surface *shsurf) +{ + if (shsurf->focus_count++ == 0) + if (shell_surface_is_xdg_surface(shsurf)) + xdg_surface_send_focused_set(shsurf->resource); +} + +static void +handle_keyboard_focus(struct wl_listener *listener, void *data) +{ + struct weston_keyboard *keyboard = data; + struct shell_seat *seat = get_shell_seat(keyboard->seat); + + if (seat->focused_surface) { + struct shell_surface *shsurf = get_shell_surface(seat->focused_surface); + if (shsurf) + shell_surface_lose_keyboard_focus(shsurf); + } + + seat->focused_surface = keyboard->focus; + + if (seat->focused_surface) { + struct shell_surface *shsurf = get_shell_surface(seat->focused_surface); + if (shsurf) + shell_surface_gain_keyboard_focus(shsurf); + } +} + +static void +create_keyboard_focus_listener(struct weston_seat *seat) +{ + struct wl_listener *listener; + + if (!seat->keyboard) + return; + + listener = malloc(sizeof *listener); + listener->notify = handle_keyboard_focus; + wl_signal_add(&seat->keyboard->focus_signal, listener); +} + +static void xdg_surface_set_transient_for(struct wl_client *client, struct wl_resource *resource, struct wl_resource *parent_resource) @@ -5829,8 +5882,10 @@ module_init(struct weston_compositor *ec, shell->screensaver.timer = wl_event_loop_add_timer(loop, screensaver_timeout, shell); - wl_list_for_each(seat, &ec->seat_list, link) + wl_list_for_each(seat, &ec->seat_list, link) { create_pointer_focus_listener(seat); + create_keyboard_focus_listener(seat); + } shell_add_bindings(ec, shell); -- 1.8.4.2 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel