diff options
-rw-r--r-- | include/sway/input/cursor.h | 1 | ||||
-rw-r--r-- | sway/input/cursor.c | 54 |
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 | ||
848 | static void check_constraint_region(struct sway_cursor *cursor) { | 888 | static void check_constraint_region(struct sway_cursor *cursor) { |