diff options
author | David96 <david@hameipe.de> | 2020-04-18 13:29:20 +0200 |
---|---|---|
committer | Tudor Brindus <me@tbrindus.ca> | 2020-05-13 14:29:15 -0400 |
commit | 2473cac32c9a062ddaee9d5495a72317bdd1f9ff (patch) | |
tree | b22f06986323cc5af17a48c7de65013e66be26a8 | |
parent | Really fix floating window border resize problems (diff) | |
download | sway-2473cac32c9a062ddaee9d5495a72317bdd1f9ff.tar.gz sway-2473cac32c9a062ddaee9d5495a72317bdd1f9ff.tar.zst sway-2473cac32c9a062ddaee9d5495a72317bdd1f9ff.zip |
Implement pointer simulation if client hasn't bound to touch
-rw-r--r-- | include/sway/input/cursor.h | 2 | ||||
-rw-r--r-- | sway/input/cursor.c | 74 |
2 files changed, 52 insertions, 24 deletions
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index 1b31143d..8f9f84d0 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h | |||
@@ -50,6 +50,8 @@ struct sway_cursor { | |||
50 | struct wl_listener touch_down; | 50 | struct wl_listener touch_down; |
51 | struct wl_listener touch_up; | 51 | struct wl_listener touch_up; |
52 | struct wl_listener touch_motion; | 52 | struct wl_listener touch_motion; |
53 | bool simulating_pointer_from_touch; | ||
54 | int32_t pointer_touch_id; | ||
53 | 55 | ||
54 | struct wl_listener tool_axis; | 56 | struct wl_listener tool_axis; |
55 | struct wl_listener tool_tip; | 57 | struct wl_listener tool_tip; |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index f3f056d1..646c61b3 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -405,7 +405,6 @@ static void handle_pointer_frame(struct wl_listener *listener, void *data) { | |||
405 | 405 | ||
406 | static void handle_touch_down(struct wl_listener *listener, void *data) { | 406 | static void handle_touch_down(struct wl_listener *listener, void *data) { |
407 | struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down); | 407 | struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_down); |
408 | cursor_handle_activity(cursor, IDLE_SOURCE_TOUCH); | ||
409 | struct wlr_event_touch_down *event = data; | 408 | struct wlr_event_touch_down *event = data; |
410 | 409 | ||
411 | struct sway_seat *seat = cursor->seat; | 410 | struct sway_seat *seat = cursor->seat; |
@@ -422,35 +421,58 @@ static void handle_touch_down(struct wl_listener *listener, void *data) { | |||
422 | seat->touch_x = lx; | 421 | seat->touch_x = lx; |
423 | seat->touch_y = ly; | 422 | seat->touch_y = ly; |
424 | 423 | ||
425 | if (!surface) { | 424 | if (surface && wlr_surface_accepts_touch(wlr_seat, surface)) { |
426 | return; | 425 | if (seat_is_input_allowed(seat, surface)) { |
427 | } | 426 | cursor_hide(cursor); |
428 | 427 | cursor_handle_activity(cursor, IDLE_SOURCE_TOUCH); | |
429 | // TODO: fall back to cursor simulation if client has not bound to touch | 428 | wlr_seat_touch_notify_down(wlr_seat, surface, event->time_msec, |
430 | if (seat_is_input_allowed(seat, surface)) { | 429 | event->touch_id, sx, sy); |
431 | cursor_hide(cursor); | ||
432 | wlr_seat_touch_notify_down(wlr_seat, surface, event->time_msec, | ||
433 | event->touch_id, sx, sy); | ||
434 | } | ||
435 | 430 | ||
436 | if (focused_node) { | 431 | if (focused_node) { |
437 | seat_set_focus(seat, focused_node); | 432 | seat_set_focus(seat, focused_node); |
433 | } | ||
434 | } | ||
435 | } else if (!cursor->simulating_pointer_from_touch && | ||
436 | (!surface || seat_is_input_allowed(seat, surface))) { | ||
437 | // Fallback to cursor simulation. | ||
438 | // The pointer_touch_id state is needed, so drags are not aborted when over | ||
439 | // a surface supporting touch and multi touch events don't interfere. | ||
440 | cursor->simulating_pointer_from_touch = true; | ||
441 | cursor->pointer_touch_id = seat->touch_id; | ||
442 | double dx, dy; | ||
443 | dx = lx - cursor->cursor->x; | ||
444 | dy = ly - cursor->cursor->y; | ||
445 | pointer_motion(cursor, event->time_msec, event->device, dx, dy, dx, dy); | ||
446 | dispatch_cursor_button(cursor, event->device, event->time_msec, | ||
447 | BTN_LEFT, WLR_BUTTON_PRESSED); | ||
448 | wlr_seat_pointer_notify_frame(wlr_seat); | ||
449 | transaction_commit_dirty(); | ||
438 | } | 450 | } |
439 | } | 451 | } |
440 | 452 | ||
441 | static void handle_touch_up(struct wl_listener *listener, void *data) { | 453 | static void handle_touch_up(struct wl_listener *listener, void *data) { |
442 | struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_up); | 454 | struct sway_cursor *cursor = wl_container_of(listener, cursor, touch_up); |
443 | cursor_handle_activity(cursor, IDLE_SOURCE_TOUCH); | ||
444 | struct wlr_event_touch_up *event = data; | 455 | struct wlr_event_touch_up *event = data; |
445 | struct wlr_seat *seat = cursor->seat->wlr_seat; | 456 | struct wlr_seat *wlr_seat = cursor->seat->wlr_seat; |
446 | // TODO: fall back to cursor simulation if client has not bound to touch | 457 | |
447 | wlr_seat_touch_notify_up(seat, event->time_msec, event->touch_id); | 458 | if (cursor->simulating_pointer_from_touch) { |
459 | if (cursor->pointer_touch_id == cursor->seat->touch_id) { | ||
460 | cursor->simulating_pointer_from_touch = false; | ||
461 | cursor_handle_activity(cursor, IDLE_SOURCE_POINTER); | ||
462 | dispatch_cursor_button(cursor, event->device, event->time_msec, | ||
463 | BTN_LEFT, WLR_BUTTON_RELEASED); | ||
464 | wlr_seat_pointer_notify_frame(wlr_seat); | ||
465 | transaction_commit_dirty(); | ||
466 | } | ||
467 | } else { | ||
468 | cursor_handle_activity(cursor, IDLE_SOURCE_TOUCH); | ||
469 | wlr_seat_touch_notify_up(wlr_seat, event->time_msec, event->touch_id); | ||
470 | } | ||
448 | } | 471 | } |
449 | 472 | ||
450 | static void handle_touch_motion(struct wl_listener *listener, void *data) { | 473 | static void handle_touch_motion(struct wl_listener *listener, void *data) { |
451 | struct sway_cursor *cursor = | 474 | struct sway_cursor *cursor = |
452 | wl_container_of(listener, cursor, touch_motion); | 475 | wl_container_of(listener, cursor, touch_motion); |
453 | cursor_handle_activity(cursor, IDLE_SOURCE_TOUCH); | ||
454 | struct wlr_event_touch_motion *event = data; | 476 | struct wlr_event_touch_motion *event = data; |
455 | 477 | ||
456 | struct sway_seat *seat = cursor->seat; | 478 | struct sway_seat *seat = cursor->seat; |
@@ -475,12 +497,16 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) { | |||
475 | } | 497 | } |
476 | } | 498 | } |
477 | 499 | ||
478 | if (!surface) { | 500 | if (cursor->simulating_pointer_from_touch) { |
479 | return; | 501 | if (seat->touch_id == cursor->pointer_touch_id) { |
480 | } | 502 | double dx, dy; |
481 | 503 | dx = lx - cursor->cursor->x; | |
482 | // TODO: fall back to cursor simulation if client has not bound to touch | 504 | dy = ly - cursor->cursor->y; |
483 | if (seat_is_input_allowed(cursor->seat, surface)) { | 505 | pointer_motion(cursor, event->time_msec, event->device, dx, dy, dx, dy); |
506 | transaction_commit_dirty(); | ||
507 | } | ||
508 | } else if (surface) { | ||
509 | cursor_handle_activity(cursor, IDLE_SOURCE_TOUCH); | ||
484 | wlr_seat_touch_notify_motion(wlr_seat, event->time_msec, | 510 | wlr_seat_touch_notify_motion(wlr_seat, event->time_msec, |
485 | event->touch_id, sx, sy); | 511 | event->touch_id, sx, sy); |
486 | } | 512 | } |