Ensure the server can safely handle client requests for wl_seat resource
that have become inert due to weston_seat object release and subsequent
destruction.
The clean-up involves, among other things, unsetting the destroyed
weston_seat object from the user data of wl_seat resources, and handling
this NULL user data case where required.
The list of sites extracting and using weston_seat object from wl_seat
resources which were audited for this patch are:
Legend:
N/A = Not Applicable (not implemented by weston)
FIXED = Fixed in the commit
OK = Already works correctly
== keyboard_shortcuts_inhibit_unstable_v1 ==
[N/A] zwp_keyboard_shortcuts_inhibit_manager_v1.inhibit_shortcuts
== tablet_input_unstable_v{1,2} ==
[N/A] zwp_tablet_manager_v{1,2}.get_tablet_seat
== text_input_unstable_v1 ==
[FIXED] zwp_text_input_v1.activate
[FIXED] zwp_text_input_v1.deactivate
== wl_data_device ==
[FIXED] wl_data_device_manager.get_data_device
[OK] wl_data_device.start_drag
[FIXED] wl_data_device.set_selection
[OK] wl_data_device.release
== wl_shell ==
[FIXED] wl_shell_surface.move
[FIXED] wl_shell_surface.resize
[FIXED] wl_shell_surface.set_popup
== xdg_shell and xdg_shell_unstable_v6 ==
[FIXED] xdg_toplevel.show_window_menu
[FIXED] xdg_toplevel.move
[FIXED] xdg_toplevel.resize
[FIXED] xdg_popup.grab
== xdg_shell_unstable_v5 ==
[FIXED] xdg_shell.get_xdg_popup
[FIXED] xdg_surface.show_window_menu
[FIXED] xdg_surface.move
[FIXED] xdg_surface.resize
Signed-off-by: Alexandros Frantzis
Reviewed-by: Pekka Paalanen
Reviewed-by: Quentin Glidic
---
Changes in v4:
- Add seat == NULL in assert in weston_desktop_seat_popup_grab_start.
- Move check for NULL seat after checking for toplevel configured in
weston_desktop_xdg_toplevel_protocol_{show_window_menu, move, resize}
Changes in v3:
- Drop xdg_shell v5 changes since support for v5 has been removed.
- Handle inert seats more transparently in libweston-desktop, by ensuring
that the weston_desktop_seat_from_seat,
weston_desktop_seat_popup_grab_get_topmost_surface, and
weston desktop_seat_popup_grab_start functions gracefully handle NULL
seat pointer arguments internally.
Changes in v2:
- Properly create inert resources in seat_get_pointer/touch/keyboard.
- Ensure all sites which have a wl_seat input resource can deal
with inert resources.
compositor/text-backend.c| 8 --
libweston-desktop/seat.c | 18
libweston-desktop/wl-shell.c | 9 +-
libweston-desktop/xdg-shell-v6.c | 24
libweston/data-device.c | 15 ++
libweston/input.c| 61
6 files changed, 103 insertions(+), 32 deletions(-)
diff --git a/compositor/text-backend.c b/compositor/text-backend.c
index e6ee249c..4d8c085b 100644
--- a/compositor/text-backend.c
+++ b/compositor/text-backend.c
@@ -193,10 +193,14 @@ text_input_activate(struct wl_client *client,
{
struct text_input *text_input = wl_resource_get_user_data(resource);
struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
- struct input_method *input_method = weston_seat->input_method;
+ struct input_method *input_method;
struct weston_compositor *ec = text_input->ec;
struct text_input *current;
+ if (!weston_seat)
+ return;
+
+ input_method = weston_seat->input_method;
if (input_method->input == text_input)
return;
@@ -237,7 +241,7 @@ text_input_deactivate(struct wl_client *client,
{
struct weston_seat *weston_seat = wl_resource_get_user_data(seat);
- if (weston_seat->input_method->input)
+ if (weston_seat && weston_seat->input_method->input)
deactivate_input_method(weston_seat->input_method);
}
diff --git a/libweston-desktop/seat.c b/libweston-desktop/seat.c
index 382b9e41..ae1c5e9f 100644
--- a/libweston-desktop/seat.c
+++ b/libweston-desktop/seat.c
@@ -242,6 +242,9 @@ weston_desktop_seat_from_seat(struct weston_seat *wseat)
struct wl_listener *listener;
struct weston_desktop_seat *seat;
+ if (wseat == NULL)
+ return NULL;
+
listener = wl_signal_get(>destroy_signal,
weston_desktop_seat_destroy);
if (listener != NULL)
@@ -270,7 +273,7 @@ weston_desktop_seat_from_seat(struct weston_seat *wseat)
struct weston_desktop_surface *
weston_desktop_seat_popup_grab_get_topmost_surface(struct weston_desktop_seat
*seat)
{
- if (wl_list_empty(>popup_grab.surfaces))
+ if (seat == NULL || wl_list_empty(>popup_grab.surfaces))
return NULL;
struct wl_list *grab_link = seat->popup_grab.surfaces.next;
@@ -282,11 +285,14 @@ bool
weston_desktop_seat_popup_grab_start(struct weston_desktop_seat *seat,
struct wl_client