From 3ebc07f7aa62f91ecfab33939bb51c043edd640e Mon Sep 17 00:00:00 2001 From: Simon Long Date: Tue, 5 Mar 2024 20:41:17 +0000 Subject: [PATCH] Handle touch on headerbar (#1550) ...using cursor emulate events. --- src/input/touch.c | 79 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 24 deletions(-) diff --git a/src/input/touch.c b/src/input/touch.c index 9ee11bf7..048aaf2d 100644 --- a/src/input/touch.c +++ b/src/input/touch.c @@ -1,17 +1,22 @@ // SPDX-License-Identifier: GPL-2.0-only #include #include +#include #include "common/mem.h" #include "common/scene-helpers.h" #include "idle.h" #include "input/touch.h" #include "labwc.h" +#include "config/mousebind.h" +#include "action.h" +#include "view.h" /* Holds layout -> surface offsets to report motion events in relative coords */ struct touch_point { int32_t touch_id; uint32_t x_offset; uint32_t y_offset; + struct wlr_surface *surface; struct wl_list link; /* seat.touch_points */ }; @@ -47,20 +52,26 @@ touch_motion(struct wl_listener *listener, void *data) struct wlr_touch_motion_event *event = data; idle_manager_notify_activity(seat->seat); - /* Convert coordinates: first [0, 1] => layout, then apply offsets */ - double lx, ly; - wlr_cursor_absolute_to_layout_coords(seat->cursor, &event->touch->base, - event->x, event->y, &lx, &ly); - /* Find existing touch point to determine initial offsets to subtract */ struct touch_point *touch_point; wl_list_for_each(touch_point, &seat->touch_points, link) { if (touch_point->touch_id == event->touch_id) { - double sx = lx - touch_point->x_offset; - double sy = ly - touch_point->y_offset; - - wlr_seat_touch_notify_motion(seat->seat, event->time_msec, - event->touch_id, sx, sy); + if (touch_point->surface) { + /* Convert coordinates: first [0, 1] => layout */ + double lx, ly; + wlr_cursor_absolute_to_layout_coords(seat->cursor, + &event->touch->base, event->x, event->y, &lx, &ly); + + /* Apply offsets to get surface coords before reporting event */ + double sx = lx - touch_point->x_offset; + double sy = ly - touch_point->y_offset; + + wlr_seat_touch_notify_motion(seat->seat, event->time_msec, + event->touch_id, sx, sy); + } else { + cursor_emulate_move_absolute(seat, &event->touch->base, + event->x, event->y, event->time_msec); + } return; } } @@ -81,28 +92,43 @@ touch_down(struct wl_listener *listener, void *data) struct wlr_touch_down_event *event = data; /* Compute layout => surface offset and save for this touch point */ + struct touch_point *touch_point = znew(*touch_point); double x_offset, y_offset; - struct wlr_surface *surface = touch_get_coords(seat, event->touch, + touch_point->surface = touch_get_coords(seat, event->touch, event->x, event->y, &x_offset, &y_offset); - - struct touch_point *touch_point = znew(*touch_point); touch_point->touch_id = event->touch_id; touch_point->x_offset = x_offset; touch_point->y_offset = y_offset; wl_list_insert(&seat->touch_points, &touch_point->link); - double lx, ly; - wlr_cursor_absolute_to_layout_coords(seat->cursor, &event->touch->base, - event->x, event->y, &lx, &ly); - - /* Apply offsets to get surface coords before reporting event */ - double sx = lx - x_offset; - double sy = ly - y_offset; + if (touch_point->surface) { + /* Convert coordinates: first [0, 1] => layout */ + double lx, ly; + wlr_cursor_absolute_to_layout_coords(seat->cursor, + &event->touch->base, event->x, event->y, &lx, &ly); + + /* Apply offsets to get surface coords before reporting event */ + double sx = lx - x_offset; + double sy = ly - y_offset; + + struct view *view = view_from_wlr_surface(touch_point->surface); + struct mousebind *mousebind; + wl_list_for_each(mousebind, &rc.mousebinds, link) { + if (mousebind->mouse_event == MOUSE_ACTION_PRESS + && mousebind->button == BTN_LEFT + && mousebind->context == LAB_SSD_CLIENT) { + actions_run(view, seat->server, &mousebind->actions, 0); + } + } - if (surface) { - wlr_seat_touch_notify_down(seat->seat, surface, + wlr_seat_touch_notify_down(seat->seat, touch_point->surface, event->time_msec, event->touch_id, sx, sy); + } else { + cursor_emulate_move_absolute(seat, &event->touch->base, + event->x, event->y, event->time_msec); + cursor_emulate_button(seat, BTN_LEFT, WLR_BUTTON_PRESSED, + event->time_msec); } } @@ -116,13 +142,18 @@ touch_up(struct wl_listener *listener, void *data) struct touch_point *touch_point, *tmp; wl_list_for_each_safe(touch_point, tmp, &seat->touch_points, link) { if (touch_point->touch_id == event->touch_id) { + if (touch_point->surface) { + wlr_seat_touch_notify_up(seat->seat, event->time_msec, + event->touch_id); + } else { + cursor_emulate_button(seat, BTN_LEFT, WLR_BUTTON_RELEASED, + event->time_msec); + } wl_list_remove(&touch_point->link); zfree(touch_point); break; } } - - wlr_seat_touch_notify_up(seat->seat, event->time_msec, event->touch_id); } void -- 2.52.0