[PATCH] desktop-shell: Properly handle seat hotplugging
Kristian Høgsberg
hoegsberg at gmail.com
Tue Apr 29 16:52:44 PDT 2014
On Mon, Apr 21, 2014 at 07:42:58PM -0500, Jason Ekstrand wrote:
> Previously, desktop-shell would only create its internal shell_seat object
> for each seat available when the desktop-shell module is loaded. This is a
> problem any time seats are created dynamically. In particular, the Wayland
> and RDP backends create seats on an as-needed basis and they weren't
> getting picked up proprely by desktop-shell.
>
> This fixes bug #77649
Thanks Jason, that's better. Patch committed.
Kristian
> ---
> desktop-shell/shell.c | 84 +++++++++++++++++++++++++++++++--------------------
> desktop-shell/shell.h | 1 +
> 2 files changed, 53 insertions(+), 32 deletions(-)
>
> diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
> index 0e4329b..ac03a15 100644
> --- a/desktop-shell/shell.c
> +++ b/desktop-shell/shell.c
> @@ -211,6 +211,10 @@ struct shell_seat {
> struct wl_listener seat_destroy_listener;
> struct weston_surface *focused_surface;
>
> + struct wl_listener caps_changed_listener;
> + struct wl_listener pointer_focus_listener;
> + struct wl_listener keyboard_focus_listener;
> +
> struct {
> struct weston_pointer_grab grab;
> struct wl_list surfaces_list;
> @@ -1918,19 +1922,6 @@ handle_pointer_focus(struct wl_listener *listener, void *data)
> }
>
> static void
> -create_pointer_focus_listener(struct weston_seat *seat)
> -{
> - struct wl_listener *listener;
> -
> - if (!seat->pointer)
> - return;
> -
> - listener = malloc(sizeof *listener);
> - listener->notify = handle_pointer_focus;
> - wl_signal_add(&seat->pointer->focus_signal, listener);
> -}
> -
> -static void
> shell_surface_lose_keyboard_focus(struct shell_surface *shsurf)
> {
> if (--shsurf->focus_count == 0)
> @@ -1968,19 +1959,6 @@ handle_keyboard_focus(struct wl_listener *listener, void *data)
> }
>
> 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
> shell_client_pong(struct shell_client *sc, uint32_t serial)
> {
> if (sc->ping_serial != serial)
> @@ -2771,6 +2749,30 @@ destroy_shell_seat(struct wl_listener *listener, void *data)
> free(shseat);
> }
>
> +static void
> +shell_seat_caps_changed(struct wl_listener *listener, void *data)
> +{
> + struct shell_seat *seat;
> +
> + seat = container_of(listener, struct shell_seat, caps_changed_listener);
> +
> + if (seat->seat->keyboard &&
> + wl_list_empty(&seat->keyboard_focus_listener.link)) {
> + wl_signal_add(&seat->seat->keyboard->focus_signal,
> + &seat->keyboard_focus_listener);
> + } else if (!seat->seat->keyboard) {
> + wl_list_init(&seat->keyboard_focus_listener.link);
> + }
> +
> + if (seat->seat->pointer &&
> + wl_list_empty(&seat->pointer_focus_listener.link)) {
> + wl_signal_add(&seat->seat->pointer->focus_signal,
> + &seat->pointer_focus_listener);
> + } else if (!seat->seat->pointer) {
> + wl_list_init(&seat->pointer_focus_listener.link);
> + }
> +}
> +
> static struct shell_seat *
> create_shell_seat(struct weston_seat *seat)
> {
> @@ -2789,6 +2791,17 @@ create_shell_seat(struct weston_seat *seat)
> wl_signal_add(&seat->destroy_signal,
> &shseat->seat_destroy_listener);
>
> + shseat->keyboard_focus_listener.notify = handle_keyboard_focus;
> + wl_list_init(&shseat->keyboard_focus_listener.link);
> +
> + shseat->pointer_focus_listener.notify = handle_pointer_focus;
> + wl_list_init(&shseat->pointer_focus_listener.link);
> +
> + shseat->caps_changed_listener.notify = shell_seat_caps_changed;
> + wl_signal_add(&seat->updated_caps_signal,
> + &shseat->caps_changed_listener);
> + shell_seat_caps_changed(&shseat->caps_changed_listener, NULL);
> +
> return shseat;
> }
>
> @@ -2798,8 +2811,7 @@ get_shell_seat(struct weston_seat *seat)
> struct wl_listener *listener;
>
> listener = wl_signal_get(&seat->destroy_signal, destroy_shell_seat);
> - if (listener == NULL)
> - return create_shell_seat(seat);
> + assert(listener != NULL);
>
> return container_of(listener,
> struct shell_seat, seat_destroy_listener);
> @@ -5916,6 +5928,14 @@ shell_add_bindings(struct weston_compositor *ec, struct desktop_shell *shell)
> debug_binding, shell);
> }
>
> +static void
> +handle_seat_created(struct wl_listener *listener, void *data)
> +{
> + struct weston_seat *seat = data;
> +
> + create_shell_seat(seat);
> +}
> +
> WL_EXPORT int
> module_init(struct weston_compositor *ec,
> int *argc, char *argv[])
> @@ -6015,10 +6035,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) {
> - create_pointer_focus_listener(seat);
> - create_keyboard_focus_listener(seat);
> - }
> + wl_list_for_each(seat, &ec->seat_list, link)
> + handle_seat_created(NULL, seat);
> + shell->seat_create_listener.notify = handle_seat_created;
> + wl_signal_add(&ec->seat_created_signal, &shell->seat_create_listener);
>
> screenshooter_create(ec);
>
> diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h
> index 5d127c6..9685cb2 100644
> --- a/desktop-shell/shell.h
> +++ b/desktop-shell/shell.h
> @@ -199,6 +199,7 @@ struct desktop_shell {
>
> struct weston_layer minimized_layer;
>
> + struct wl_listener seat_create_listener;
> struct wl_listener output_create_listener;
> struct wl_listener output_move_listener;
> struct wl_list output_list;
> --
> 1.9.0
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list