aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar David96 <david@hameipe.de>2020-04-18 13:29:20 +0200
committerLibravatar Tudor Brindus <me@tbrindus.ca>2020-05-13 14:29:15 -0400
commit2473cac32c9a062ddaee9d5495a72317bdd1f9ff (patch)
treeb22f06986323cc5af17a48c7de65013e66be26a8
parentReally fix floating window border resize problems (diff)
downloadsway-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.h2
-rw-r--r--sway/input/cursor.c74
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
406static void handle_touch_down(struct wl_listener *listener, void *data) { 406static 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
441static void handle_touch_up(struct wl_listener *listener, void *data) { 453static 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
450static void handle_touch_motion(struct wl_listener *listener, void *data) { 473static 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 }