aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/input/cursor.h1
-rw-r--r--sway/input/cursor.c54
2 files changed, 48 insertions, 7 deletions
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h
index 8a2898dd..828ac370 100644
--- a/include/sway/input/cursor.h
+++ b/include/sway/input/cursor.h
@@ -64,6 +64,7 @@ struct sway_cursor {
64 struct wl_listener tool_proximity; 64 struct wl_listener tool_proximity;
65 struct wl_listener tool_button; 65 struct wl_listener tool_button;
66 bool simulating_pointer_from_tool_tip; 66 bool simulating_pointer_from_tool_tip;
67 bool simulating_pointer_from_tool_button;
67 uint32_t tool_buttons; 68 uint32_t tool_buttons;
68 69
69 struct wl_listener request_set_cursor; 70 struct wl_listener request_set_cursor;
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index 9d83008f..243eb42c 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -818,7 +818,34 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
818 node_at_coords(cursor->seat, cursor->cursor->x, cursor->cursor->y, 818 node_at_coords(cursor->seat, cursor->cursor->x, cursor->cursor->y,
819 &surface, &sx, &sy); 819 &surface, &sx, &sy);
820 820
821 if (!surface || !wlr_surface_accepts_tablet_v2(tablet_v2, surface)) { 821 // TODO: floating resize should support graphics tablet events
822 struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(cursor->seat->wlr_seat);
823 uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
824 bool mod_pressed = modifiers & config->floating_mod;
825
826 bool surface_supports_tablet_events =
827 surface && wlr_surface_accepts_tablet_v2(tablet_v2, surface);
828
829 // Simulate pointer when:
830 // 1. The modifier key is pressed, OR
831 // 2. The surface under the cursor does not support tablet events.
832 bool should_simulate_pointer = mod_pressed || !surface_supports_tablet_events;
833
834 // Similar to tool tip, we need to selectively simulate mouse events, but we
835 // want to make sure that it is always consistent. Because all tool buttons
836 // currently map to BTN_RIGHT, we need to keep count of how many tool
837 // buttons are currently pressed down so we can send consistent events.
838 //
839 // The logic follows:
840 // - If we are already simulating the pointer, we should continue to do so
841 // until at least no tool button is held down.
842 // - If we should simulate the pointer and no tool button is currently held
843 // down, begin simulating the pointer.
844 // - If neither of the above are true, send the tablet events.
845 if ((cursor->tool_buttons > 0 && cursor->simulating_pointer_from_tool_button)
846 || (cursor->tool_buttons == 0 && should_simulate_pointer)) {
847 cursor->simulating_pointer_from_tool_button = true;
848
822 // TODO: the user may want to configure which tool buttons are mapped to 849 // TODO: the user may want to configure which tool buttons are mapped to
823 // which simulated pointer buttons 850 // which simulated pointer buttons
824 switch (event->state) { 851 switch (event->state) {
@@ -827,22 +854,35 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
827 dispatch_cursor_button(cursor, &event->tablet->base, 854 dispatch_cursor_button(cursor, &event->tablet->base,
828 event->time_msec, BTN_RIGHT, event->state); 855 event->time_msec, BTN_RIGHT, event->state);
829 } 856 }
830 cursor->tool_buttons++;
831 break; 857 break;
832 case WLR_BUTTON_RELEASED: 858 case WLR_BUTTON_RELEASED:
833 if (cursor->tool_buttons == 1) { 859 if (cursor->tool_buttons <= 1) {
834 dispatch_cursor_button(cursor, &event->tablet->base, 860 dispatch_cursor_button(cursor, &event->tablet->base,
835 event->time_msec, BTN_RIGHT, event->state); 861 event->time_msec, BTN_RIGHT, event->state);
836 } 862 }
837 cursor->tool_buttons--;
838 break; 863 break;
839 } 864 }
840 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat); 865 wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
841 return; 866 } else {
867 cursor->simulating_pointer_from_tool_button = false;
868
869 wlr_tablet_v2_tablet_tool_notify_button(sway_tool->tablet_v2_tool,
870 event->button, (enum zwp_tablet_pad_v2_button_state)event->state);
842 } 871 }
843 872
844 wlr_tablet_v2_tablet_tool_notify_button(sway_tool->tablet_v2_tool, 873 // Update tool button count.
845 event->button, (enum zwp_tablet_pad_v2_button_state)event->state); 874 switch (event->state) {
875 case WLR_BUTTON_PRESSED:
876 cursor->tool_buttons++;
877 break;
878 case WLR_BUTTON_RELEASED:
879 if (cursor->tool_buttons == 0) {
880 sway_log(SWAY_ERROR, "inconsistent tablet tool button events");
881 } else {
882 cursor->tool_buttons--;
883 }
884 break;
885 }
846} 886}
847 887
848static void check_constraint_region(struct sway_cursor *cursor) { 888static void check_constraint_region(struct sway_cursor *cursor) {