From d1cde3c435604c07c9eaf4e4475b3d5ba1f8aa49 Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Fri, 1 Nov 2024 09:11:33 +0100 Subject: [PATCH] input: close xdg-popups on touch down Taken over and now shared from the tablet implementation. --- include/labwc.h | 2 ++ src/input/tablet.c | 27 ++------------------------- src/input/touch.c | 1 + src/seat.c | 22 ++++++++++++++++++++++ 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/include/labwc.h b/include/labwc.h index dc41c74e..730c083a 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -486,6 +486,8 @@ void seat_finish(struct server *server); void seat_reconfigure(struct server *server); void seat_focus_surface(struct seat *seat, struct wlr_surface *surface); +void seat_pointer_end_grab(struct seat *seat, struct wlr_surface *surface); + /** * seat_focus_lock_surface() - ONLY to be called from session-lock.c to * focus lock screen surfaces. Use seat_focus_surface() otherwise. diff --git a/src/input/tablet.c b/src/input/tablet.c index ac94228b..08e52e2f 100644 --- a/src/input/tablet.c +++ b/src/input/tablet.c @@ -458,29 +458,6 @@ to_stylus_button(uint32_t button) } } -static void -seat_pointer_end_grab(struct drawing_tablet_tool *tool, - struct wlr_surface *surface) -{ - if (!surface || !wlr_seat_pointer_has_grab(tool->seat->seat)) { - return; - } - - struct wlr_xdg_surface *xdg_surface = - wlr_xdg_surface_try_from_wlr_surface(surface); - if (!xdg_surface || xdg_surface->role != WLR_XDG_SURFACE_ROLE_POPUP) { - /* - * If we have an active popup grab (an open popup) and we are - * not on the popup itself, end that grab to close the popup. - * Contrary to pointer button notifications, a tablet button - * notification sometimes doesn't end grabs automatically on - * button notifications in another client (observed in GTK4), - * so end the grab manually. - */ - wlr_seat_pointer_end_grab(tool->seat->seat); - } -} - static void handle_tablet_tool_tip(struct wl_listener *listener, void *data) { @@ -519,7 +496,7 @@ handle_tablet_tool_tip(struct wl_listener *listener, void *data) bool notify = cursor_process_button_press(tool->seat, BTN_LEFT, ev->time_msec); if (notify) { - seat_pointer_end_grab(tool, surface); + seat_pointer_end_grab(tool->seat, surface); wlr_tablet_v2_tablet_tool_notify_down(tool->tool_v2); wlr_tablet_tool_v2_start_implicit_grab(tool->tool_v2); } @@ -603,7 +580,7 @@ handle_tablet_tool_button(struct wl_listener *listener, void *data) uint32_t stylus_button = to_stylus_button(button); if (stylus_button && stylus_button != BTN_TOOL_PEN) { if (ev->state == WLR_BUTTON_PRESSED) { - seat_pointer_end_grab(tool, surface); + seat_pointer_end_grab(tool->seat, surface); } wlr_tablet_v2_tablet_tool_notify_button(tool->tool_v2, stylus_button, diff --git a/src/input/touch.c b/src/input/touch.c index d36d9885..e09bb6ae 100644 --- a/src/input/touch.c +++ b/src/input/touch.c @@ -126,6 +126,7 @@ handle_touch_down(struct wl_listener *listener, void *data) int touch_point_count = wl_list_length(&seat->touch_points); if (touch_point->surface) { + seat_pointer_end_grab(seat, touch_point->surface); /* Clear focus to not interfere with touch input */ wlr_seat_pointer_notify_clear_focus(seat->seat); diff --git a/src/seat.c b/src/seat.c index 3aa2e234..bc51c898 100644 --- a/src/seat.c +++ b/src/seat.c @@ -596,6 +596,28 @@ configure_keyboard(struct seat *seat, struct input *input) keyboard_configure(seat, kb, keyboard->is_virtual); } +void +seat_pointer_end_grab(struct seat *seat, struct wlr_surface *surface) +{ + if (!surface || !wlr_seat_pointer_has_grab(seat->seat)) { + return; + } + + struct wlr_xdg_surface *xdg_surface = + wlr_xdg_surface_try_from_wlr_surface(surface); + if (!xdg_surface || xdg_surface->role != WLR_XDG_SURFACE_ROLE_POPUP) { + /* + * If we have an active popup grab (an open popup) and we are + * not on the popup itself, end that grab to close the popup. + * Contrary to pointer button notifications, a tablet/touch + * button notification sometimes doesn't end grabs automatically + * on button notifications in another client (observed in GTK4), + * so end the grab manually. + */ + wlr_seat_pointer_end_grab(seat->seat); + } +} + /* This is called on SIGHUP (generally in response to labwc --reconfigure */ void seat_reconfigure(struct server *server)