diff options
Diffstat (limited to 'sway/input/cursor.c')
-rw-r--r-- | sway/input/cursor.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 688fc230..7ac5013d 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -727,19 +727,23 @@ static void state_add_button(struct sway_cursor *cursor, uint32_t button) { | |||
727 | * Return the mouse binding which matches modifier, click location, release, | 727 | * Return the mouse binding which matches modifier, click location, release, |
728 | * and pressed button state, otherwise return null. | 728 | * and pressed button state, otherwise return null. |
729 | */ | 729 | */ |
730 | static struct sway_binding* get_active_mouse_binding(const struct sway_cursor *cursor, | 730 | static struct sway_binding* get_active_mouse_binding( |
731 | list_t *bindings, uint32_t modifiers, bool release, bool on_titlebar, | 731 | const struct sway_cursor *cursor, list_t *bindings, uint32_t modifiers, |
732 | bool on_border, bool on_content) { | 732 | bool release, bool on_titlebar, bool on_border, bool on_content, |
733 | const char *identifier) { | ||
733 | uint32_t click_region = (on_titlebar ? BINDING_TITLEBAR : 0) | | 734 | uint32_t click_region = (on_titlebar ? BINDING_TITLEBAR : 0) | |
734 | (on_border ? BINDING_BORDER : 0) | | 735 | (on_border ? BINDING_BORDER : 0) | |
735 | (on_content ? BINDING_CONTENTS : 0); | 736 | (on_content ? BINDING_CONTENTS : 0); |
736 | 737 | ||
738 | struct sway_binding *current = NULL; | ||
737 | for (int i = 0; i < bindings->length; ++i) { | 739 | for (int i = 0; i < bindings->length; ++i) { |
738 | struct sway_binding *binding = bindings->items[i]; | 740 | struct sway_binding *binding = bindings->items[i]; |
739 | if (modifiers ^ binding->modifiers || | 741 | if (modifiers ^ binding->modifiers || |
740 | cursor->pressed_button_count != (size_t)binding->keys->length || | 742 | cursor->pressed_button_count != (size_t)binding->keys->length || |
741 | release != (binding->flags & BINDING_RELEASE) || | 743 | release != (binding->flags & BINDING_RELEASE) || |
742 | !(click_region & binding->flags)) { | 744 | !(click_region & binding->flags) || |
745 | (strcmp(binding->input, identifier) != 0 && | ||
746 | strcmp(binding->input, "*") != 0)) { | ||
743 | continue; | 747 | continue; |
744 | } | 748 | } |
745 | 749 | ||
@@ -755,13 +759,20 @@ static struct sway_binding* get_active_mouse_binding(const struct sway_cursor *c | |||
755 | continue; | 759 | continue; |
756 | } | 760 | } |
757 | 761 | ||
758 | return binding; | 762 | if (!current || strcmp(current->input, "*") == 0) { |
763 | current = binding; | ||
764 | if (strcmp(current->input, identifier) == 0) { | ||
765 | // If a binding is found for the exact input, quit searching | ||
766 | break; | ||
767 | } | ||
768 | } | ||
759 | } | 769 | } |
760 | return NULL; | 770 | return current; |
761 | } | 771 | } |
762 | 772 | ||
763 | void dispatch_cursor_button(struct sway_cursor *cursor, | 773 | void dispatch_cursor_button(struct sway_cursor *cursor, |
764 | uint32_t time_msec, uint32_t button, enum wlr_button_state state) { | 774 | struct wlr_input_device *device, uint32_t time_msec, uint32_t button, |
775 | enum wlr_button_state state) { | ||
765 | if (time_msec == 0) { | 776 | if (time_msec == 0) { |
766 | time_msec = get_current_time_msec(); | 777 | time_msec = get_current_time_msec(); |
767 | } | 778 | } |
@@ -797,18 +808,21 @@ void dispatch_cursor_button(struct sway_cursor *cursor, | |||
797 | struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); | 808 | struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); |
798 | uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; | 809 | uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; |
799 | 810 | ||
811 | char *device_identifier = device ? input_device_get_identifier(device) | ||
812 | : strdup("*"); | ||
800 | struct sway_binding *binding = NULL; | 813 | struct sway_binding *binding = NULL; |
801 | if (state == WLR_BUTTON_PRESSED) { | 814 | if (state == WLR_BUTTON_PRESSED) { |
802 | state_add_button(cursor, button); | 815 | state_add_button(cursor, button); |
803 | binding = get_active_mouse_binding(cursor, | 816 | binding = get_active_mouse_binding(cursor, |
804 | config->current_mode->mouse_bindings, modifiers, false, | 817 | config->current_mode->mouse_bindings, modifiers, false, |
805 | on_titlebar, on_border, on_contents); | 818 | on_titlebar, on_border, on_contents, device_identifier); |
806 | } else { | 819 | } else { |
807 | binding = get_active_mouse_binding(cursor, | 820 | binding = get_active_mouse_binding(cursor, |
808 | config->current_mode->mouse_bindings, modifiers, true, | 821 | config->current_mode->mouse_bindings, modifiers, true, |
809 | on_titlebar, on_border, on_contents); | 822 | on_titlebar, on_border, on_contents, device_identifier); |
810 | state_erase_button(cursor, button); | 823 | state_erase_button(cursor, button); |
811 | } | 824 | } |
825 | free(device_identifier); | ||
812 | if (binding) { | 826 | if (binding) { |
813 | seat_execute_command(seat, binding); | 827 | seat_execute_command(seat, binding); |
814 | return; | 828 | return; |
@@ -942,7 +956,7 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { | |||
942 | struct sway_cursor *cursor = wl_container_of(listener, cursor, button); | 956 | struct sway_cursor *cursor = wl_container_of(listener, cursor, button); |
943 | wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat); | 957 | wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat); |
944 | struct wlr_event_pointer_button *event = data; | 958 | struct wlr_event_pointer_button *event = data; |
945 | dispatch_cursor_button(cursor, | 959 | dispatch_cursor_button(cursor, event->device, |
946 | event->time_msec, event->button, event->state); | 960 | event->time_msec, event->button, event->state); |
947 | transaction_commit_dirty(); | 961 | transaction_commit_dirty(); |
948 | } | 962 | } |
@@ -1128,7 +1142,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) { | |||
1128 | struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip); | 1142 | struct sway_cursor *cursor = wl_container_of(listener, cursor, tool_tip); |
1129 | wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat); | 1143 | wlr_idle_notify_activity(cursor->seat->input->server->idle, cursor->seat->wlr_seat); |
1130 | struct wlr_event_tablet_tool_tip *event = data; | 1144 | struct wlr_event_tablet_tool_tip *event = data; |
1131 | dispatch_cursor_button(cursor, event->time_msec, | 1145 | dispatch_cursor_button(cursor, event->device, event->time_msec, |
1132 | BTN_LEFT, event->state == WLR_TABLET_TOOL_TIP_DOWN ? | 1146 | BTN_LEFT, event->state == WLR_TABLET_TOOL_TIP_DOWN ? |
1133 | WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED); | 1147 | WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED); |
1134 | transaction_commit_dirty(); | 1148 | transaction_commit_dirty(); |
@@ -1143,14 +1157,14 @@ static void handle_tool_button(struct wl_listener *listener, void *data) { | |||
1143 | switch (event->state) { | 1157 | switch (event->state) { |
1144 | case WLR_BUTTON_PRESSED: | 1158 | case WLR_BUTTON_PRESSED: |
1145 | if (cursor->tool_buttons == 0) { | 1159 | if (cursor->tool_buttons == 0) { |
1146 | dispatch_cursor_button(cursor, | 1160 | dispatch_cursor_button(cursor, event->device, |
1147 | event->time_msec, BTN_RIGHT, event->state); | 1161 | event->time_msec, BTN_RIGHT, event->state); |
1148 | } | 1162 | } |
1149 | cursor->tool_buttons++; | 1163 | cursor->tool_buttons++; |
1150 | break; | 1164 | break; |
1151 | case WLR_BUTTON_RELEASED: | 1165 | case WLR_BUTTON_RELEASED: |
1152 | if (cursor->tool_buttons == 1) { | 1166 | if (cursor->tool_buttons == 1) { |
1153 | dispatch_cursor_button(cursor, | 1167 | dispatch_cursor_button(cursor, event->device, |
1154 | event->time_msec, BTN_RIGHT, event->state); | 1168 | event->time_msec, BTN_RIGHT, event->state); |
1155 | } | 1169 | } |
1156 | cursor->tool_buttons--; | 1170 | cursor->tool_buttons--; |