diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-05-02 09:00:26 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2018-05-02 09:00:26 -0400 |
commit | 52aa245b246078a20475edce7d4b6e013d1d99e4 (patch) | |
tree | 6ffd7fcc8e249ce00c223c04fbbee1bfe3b314ce /sway/input | |
parent | Fixed #1888 GCC cannot compile due to uninitialized variables (#1889) (diff) | |
download | sway-52aa245b246078a20475edce7d4b6e013d1d99e4.tar.gz sway-52aa245b246078a20475edce7d4b6e013d1d99e4.tar.zst sway-52aa245b246078a20475edce7d4b6e013d1d99e4.zip |
Implement basic touch support
This required changing container_at_cursor to container_at_coords so
that we could get the appropriate surface (and sx/xy) without moving the
cursor.
Future work:
- Simulate a cursor for clients which have not bound to wl_touch
- Keep sending motion events when moving outside the surface (#1892)
- Bind gestures to sway commands
Diffstat (limited to 'sway/input')
-rw-r--r-- | sway/input/cursor.c | 72 | ||||
-rw-r--r-- | sway/input/seat.c | 13 |
2 files changed, 66 insertions, 19 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 64b95e7d..e094bbbe 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -44,7 +44,8 @@ static struct wlr_surface *layer_surface_at(struct sway_output *output, | |||
44 | * Returns the container at the cursor's position. If there is a surface at that | 44 | * Returns the container at the cursor's position. If there is a surface at that |
45 | * location, it is stored in **surface (it may not be a view). | 45 | * location, it is stored in **surface (it may not be a view). |
46 | */ | 46 | */ |
47 | static struct sway_container *container_at_cursor(struct sway_cursor *cursor, | 47 | static struct sway_container *container_at_coords( |
48 | struct sway_seat *seat, double x, double y, | ||
48 | struct wlr_surface **surface, double *sx, double *sy) { | 49 | struct wlr_surface **surface, double *sx, double *sy) { |
49 | // check for unmanaged views first | 50 | // check for unmanaged views first |
50 | struct wl_list *unmanaged = &root_container.sway_root->xwayland_unmanaged; | 51 | struct wl_list *unmanaged = &root_container.sway_root->xwayland_unmanaged; |
@@ -53,8 +54,8 @@ static struct sway_container *container_at_cursor(struct sway_cursor *cursor, | |||
53 | struct wlr_xwayland_surface *xsurface = | 54 | struct wlr_xwayland_surface *xsurface = |
54 | unmanaged_surface->wlr_xwayland_surface; | 55 | unmanaged_surface->wlr_xwayland_surface; |
55 | 56 | ||
56 | double _sx = cursor->cursor->x - unmanaged_surface->lx; | 57 | double _sx = x - unmanaged_surface->lx; |
57 | double _sy = cursor->cursor->y - unmanaged_surface->ly; | 58 | double _sy = y - unmanaged_surface->ly; |
58 | if (wlr_surface_point_accepts_input(xsurface->surface, _sx, _sy)) { | 59 | if (wlr_surface_point_accepts_input(xsurface->surface, _sx, _sy)) { |
59 | *surface = xsurface->surface; | 60 | *surface = xsurface->surface; |
60 | *sx = _sx; | 61 | *sx = _sx; |
@@ -66,18 +67,17 @@ static struct sway_container *container_at_cursor(struct sway_cursor *cursor, | |||
66 | // find the output the cursor is on | 67 | // find the output the cursor is on |
67 | struct wlr_output_layout *output_layout = | 68 | struct wlr_output_layout *output_layout = |
68 | root_container.sway_root->output_layout; | 69 | root_container.sway_root->output_layout; |
69 | struct wlr_output *wlr_output = wlr_output_layout_output_at(output_layout, | 70 | struct wlr_output *wlr_output = wlr_output_layout_output_at( |
70 | cursor->cursor->x, cursor->cursor->y); | 71 | output_layout, x, y); |
71 | if (wlr_output == NULL) { | 72 | if (wlr_output == NULL) { |
72 | return NULL; | 73 | return NULL; |
73 | } | 74 | } |
74 | struct sway_output *output = wlr_output->data; | 75 | struct sway_output *output = wlr_output->data; |
75 | double ox = cursor->cursor->x, oy = cursor->cursor->y; | 76 | double ox = x, oy = y; |
76 | wlr_output_layout_output_coords(output_layout, wlr_output, &ox, &oy); | 77 | wlr_output_layout_output_coords(output_layout, wlr_output, &ox, &oy); |
77 | 78 | ||
78 | // find the focused workspace on the output for this seat | 79 | // find the focused workspace on the output for this seat |
79 | struct sway_container *ws = | 80 | struct sway_container *ws = seat_get_focus_inactive(seat, output->swayc); |
80 | seat_get_focus_inactive(cursor->seat, output->swayc); | ||
81 | if (ws && ws->type != C_WORKSPACE) { | 81 | if (ws && ws->type != C_WORKSPACE) { |
82 | ws = container_parent(ws, C_WORKSPACE); | 82 | ws = container_parent(ws, C_WORKSPACE); |
83 | } | 83 | } |
@@ -107,8 +107,7 @@ static struct sway_container *container_at_cursor(struct sway_cursor *cursor, | |||
107 | } | 107 | } |
108 | 108 | ||
109 | struct sway_container *c; | 109 | struct sway_container *c; |
110 | if ((c = container_at(ws, cursor->cursor->x, cursor->cursor->y, | 110 | if ((c = container_at(ws, x, y, surface, sx, sy))) { |
111 | surface, sx, sy))) { | ||
112 | return c; | 111 | return c; |
113 | } | 112 | } |
114 | 113 | ||
@@ -123,7 +122,7 @@ static struct sway_container *container_at_cursor(struct sway_cursor *cursor, | |||
123 | return ws; | 122 | return ws; |
124 | } | 123 | } |
125 | 124 | ||
126 | c = seat_get_focus_inactive(cursor->seat, output->swayc); | 125 | c = seat_get_focus_inactive(seat, output->swayc); |
127 | if (c) { | 126 | if (c) { |
128 | return c; | 127 | return c; |
129 | } | 128 | } |
@@ -143,7 +142,8 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec) | |||
143 | struct wlr_seat *seat = cursor->seat->wlr_seat; | 142 | struct wlr_seat *seat = cursor->seat->wlr_seat; |
144 | struct wlr_surface *surface = NULL; | 143 | struct wlr_surface *surface = NULL; |
145 | double sx, sy; | 144 | double sx, sy; |
146 | struct sway_container *c = container_at_cursor(cursor, &surface, &sx, &sy); | 145 | struct sway_container *c = container_at_coords(cursor->seat, |
146 | cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); | ||
147 | if (c && config->focus_follows_mouse) { | 147 | if (c && config->focus_follows_mouse) { |
148 | seat_set_focus_warp(cursor->seat, c, false); | 148 | seat_set_focus_warp(cursor->seat, c, false); |
149 | } | 149 | } |
@@ -195,8 +195,8 @@ void dispatch_cursor_button(struct sway_cursor *cursor, | |||
195 | 195 | ||
196 | struct wlr_surface *surface = NULL; | 196 | struct wlr_surface *surface = NULL; |
197 | double sx, sy; | 197 | double sx, sy; |
198 | struct sway_container *cont = | 198 | struct sway_container *cont = container_at_coords(cursor->seat, |
199 | container_at_cursor(cursor, &surface, &sx, &sy); | 199 | cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); |
200 | if (surface && wlr_surface_is_layer_surface(surface)) { | 200 | if (surface && wlr_surface_is_layer_surface(surface)) { |
201 | struct wlr_layer_surface *layer = | 201 | struct wlr_layer_surface *layer = |
202 | wlr_layer_surface_from_wlr_surface(surface); | 202 | wlr_layer_surface_from_wlr_surface(surface); |
@@ -246,20 +246,58 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) { | |||
246 | static void handle_touch_down(struct wl_listener *listener, void *data) { | 246 | static void handle_touch_down(struct wl_listener *listener, void *data) { |
247 | struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down); | 247 | struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down); |
248 | struct wlr_event_touch_down *event = data; | 248 | struct wlr_event_touch_down *event = data; |
249 | wlr_log(L_DEBUG, "TODO: handle touch down event: %p", event); | 249 | |
250 | struct wlr_seat *seat = cursor->seat->wlr_seat; | ||
251 | struct wlr_surface *surface = NULL; | ||
252 | |||
253 | double lx, ly; | ||
254 | wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device, | ||
255 | event->x, event->y, &lx, &ly); | ||
256 | double sx, sy; | ||
257 | container_at_coords(cursor->seat, lx, ly, &surface, &sx, &sy); | ||
258 | |||
259 | if (!surface) { | ||
260 | return; | ||
261 | } | ||
262 | |||
263 | // TODO: fall back to cursor simulation if client has not bound to touch | ||
264 | if (seat_is_input_allowed(cursor->seat, surface)) { | ||
265 | wlr_seat_touch_notify_down(seat, surface, event->time_msec, | ||
266 | event->touch_id, sx, sy); | ||
267 | } | ||
250 | } | 268 | } |
251 | 269 | ||
252 | static void handle_touch_up(struct wl_listener *listener, void *data) { | 270 | static void handle_touch_up(struct wl_listener *listener, void *data) { |
253 | struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_up); | 271 | struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_up); |
254 | struct wlr_event_touch_up *event = data; | 272 | struct wlr_event_touch_up *event = data; |
255 | wlr_log(L_DEBUG, "TODO: handle touch up event: %p", event); | 273 | struct wlr_seat *seat = cursor->seat->wlr_seat; |
274 | // TODO: fall back to cursor simulation if client has not bound to touch | ||
275 | wlr_seat_touch_notify_up(seat, event->time_msec, event->touch_id); | ||
256 | } | 276 | } |
257 | 277 | ||
258 | static void handle_touch_motion(struct wl_listener *listener, void *data) { | 278 | static void handle_touch_motion(struct wl_listener *listener, void *data) { |
259 | struct sway_cursor *cursor = | 279 | struct sway_cursor *cursor = |
260 | wl_container_of(listener, cursor, touch_motion); | 280 | wl_container_of(listener, cursor, touch_motion); |
261 | struct wlr_event_touch_motion *event = data; | 281 | struct wlr_event_touch_motion *event = data; |
262 | wlr_log(L_DEBUG, "TODO: handle touch motion event: %p", event); | 282 | |
283 | struct wlr_seat *seat = cursor->seat->wlr_seat; | ||
284 | struct wlr_surface *surface = NULL; | ||
285 | |||
286 | double lx, ly; | ||
287 | wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device, | ||
288 | event->x, event->y, &lx, &ly); | ||
289 | double sx, sy; | ||
290 | container_at_coords(cursor->seat, lx, ly, &surface, &sx, &sy); | ||
291 | |||
292 | if (!surface) { | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | // TODO: fall back to cursor simulation if client has not bound to touch | ||
297 | if (seat_is_input_allowed(cursor->seat, surface)) { | ||
298 | wlr_seat_touch_notify_motion( | ||
299 | seat, event->time_msec, event->touch_id, sx, sy); | ||
300 | } | ||
263 | } | 301 | } |
264 | 302 | ||
265 | static double apply_mapping_from_coord(double low, double high, double value) { | 303 | static double apply_mapping_from_coord(double low, double high, double value) { |
diff --git a/sway/input/seat.c b/sway/input/seat.c index 8b9817da..e8bd6b36 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -315,6 +315,13 @@ static void seat_configure_keyboard(struct sway_seat *seat, | |||
315 | } | 315 | } |
316 | } | 316 | } |
317 | 317 | ||
318 | static void seat_configure_touch(struct sway_seat *seat, | ||
319 | struct sway_seat_device *sway_device) { | ||
320 | wlr_cursor_attach_input_device(seat->cursor->cursor, | ||
321 | sway_device->input_device->wlr_device); | ||
322 | seat_apply_input_config(seat, sway_device); | ||
323 | } | ||
324 | |||
318 | static void seat_configure_tablet_tool(struct sway_seat *seat, | 325 | static void seat_configure_tablet_tool(struct sway_seat *seat, |
319 | struct sway_seat_device *sway_device) { | 326 | struct sway_seat_device *sway_device) { |
320 | wlr_cursor_attach_input_device(seat->cursor->cursor, | 327 | wlr_cursor_attach_input_device(seat->cursor->cursor, |
@@ -349,12 +356,14 @@ void seat_configure_device(struct sway_seat *seat, | |||
349 | case WLR_INPUT_DEVICE_KEYBOARD: | 356 | case WLR_INPUT_DEVICE_KEYBOARD: |
350 | seat_configure_keyboard(seat, seat_device); | 357 | seat_configure_keyboard(seat, seat_device); |
351 | break; | 358 | break; |
359 | case WLR_INPUT_DEVICE_TOUCH: | ||
360 | seat_configure_touch(seat, seat_device); | ||
361 | break; | ||
352 | case WLR_INPUT_DEVICE_TABLET_TOOL: | 362 | case WLR_INPUT_DEVICE_TABLET_TOOL: |
353 | seat_configure_tablet_tool(seat, seat_device); | 363 | seat_configure_tablet_tool(seat, seat_device); |
354 | break; | 364 | break; |
355 | case WLR_INPUT_DEVICE_TABLET_PAD: | 365 | case WLR_INPUT_DEVICE_TABLET_PAD: |
356 | case WLR_INPUT_DEVICE_TOUCH: | 366 | wlr_log(L_DEBUG, "TODO: configure tablet pad"); |
357 | wlr_log(L_DEBUG, "TODO: configure other devices"); | ||
358 | break; | 367 | break; |
359 | } | 368 | } |
360 | } | 369 | } |