diff options
-rw-r--r-- | include/sway/input/cursor.h | 5 | ||||
-rw-r--r-- | meson.build | 1 | ||||
-rw-r--r-- | sway/commands/bind.c | 25 | ||||
-rw-r--r-- | sway/input/cursor.c | 59 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/sway.5.scd | 7 |
6 files changed, 89 insertions, 9 deletions
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index 50ac453b..f7e82721 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h | |||
@@ -5,6 +5,11 @@ | |||
5 | 5 | ||
6 | #define SWAY_CURSOR_PRESSED_BUTTONS_CAP 32 | 6 | #define SWAY_CURSOR_PRESSED_BUTTONS_CAP 32 |
7 | 7 | ||
8 | #define SWAY_SCROLL_UP KEY_MAX + 1 | ||
9 | #define SWAY_SCROLL_DOWN KEY_MAX + 2 | ||
10 | #define SWAY_SCROLL_LEFT KEY_MAX + 3 | ||
11 | #define SWAY_SCROLL_RIGHT KEY_MAX + 4 | ||
12 | |||
8 | struct sway_cursor { | 13 | struct sway_cursor { |
9 | struct sway_seat *seat; | 14 | struct sway_seat *seat; |
10 | struct wlr_cursor *cursor; | 15 | struct wlr_cursor *cursor; |
diff --git a/meson.build b/meson.build index 6dc5bd8d..e1e0fc2d 100644 --- a/meson.build +++ b/meson.build | |||
@@ -46,6 +46,7 @@ pango = dependency('pango') | |||
46 | pangocairo = dependency('pangocairo') | 46 | pangocairo = dependency('pangocairo') |
47 | gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: false) | 47 | gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: false) |
48 | pixman = dependency('pixman-1') | 48 | pixman = dependency('pixman-1') |
49 | libevdev = dependency('libevdev') | ||
49 | libinput = dependency('libinput', version: '>=1.6.0') | 50 | libinput = dependency('libinput', version: '>=1.6.0') |
50 | libpam = cc.find_library('pam', required: false) | 51 | libpam = cc.find_library('pam', required: false) |
51 | crypt = cc.find_library('crypt', required: false) | 52 | crypt = cc.find_library('crypt', required: false) |
diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 01a35cf2..5990166a 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <libevdev/libevdev.h> | ||
2 | #ifdef __linux__ | 3 | #ifdef __linux__ |
3 | #include <linux/input-event-codes.h> | 4 | #include <linux/input-event-codes.h> |
4 | #elif __FreeBSD__ | 5 | #elif __FreeBSD__ |
@@ -10,6 +11,7 @@ | |||
10 | #include <strings.h> | 11 | #include <strings.h> |
11 | #include "sway/commands.h" | 12 | #include "sway/commands.h" |
12 | #include "sway/config.h" | 13 | #include "sway/config.h" |
14 | #include "sway/input/cursor.h" | ||
13 | #include "sway/ipc-server.h" | 15 | #include "sway/ipc-server.h" |
14 | #include "list.h" | 16 | #include "list.h" |
15 | #include "log.h" | 17 | #include "log.h" |
@@ -102,9 +104,26 @@ static struct cmd_results *identify_key(const char* name, bool first_key, | |||
102 | 104 | ||
103 | // Check for mouse binding | 105 | // Check for mouse binding |
104 | uint32_t button = 0; | 106 | uint32_t button = 0; |
105 | if (strncasecmp(name, "button", strlen("button")) == 0 && | 107 | if (strncasecmp(name, "button", strlen("button")) == 0) { |
106 | strlen(name) == strlen("button0")) { | 108 | // Map to x11 mouse buttons |
107 | button = name[strlen("button")] - '1' + BTN_LEFT; | 109 | button = name[strlen("button")] - '0'; |
110 | if (button < 1 || button > 9 || strlen(name) > strlen("button0")) { | ||
111 | return cmd_results_new(CMD_INVALID, "bindsym", | ||
112 | "Only buttons 1-9 are supported. For other mouse " | ||
113 | "buttons, use the name of the event code."); | ||
114 | } | ||
115 | uint32_t buttons[] = {BTN_LEFT, BTN_MIDDLE, BTN_RIGHT, | ||
116 | SWAY_SCROLL_UP, SWAY_SCROLL_DOWN, SWAY_SCROLL_LEFT, | ||
117 | SWAY_SCROLL_RIGHT, BTN_SIDE, BTN_EXTRA}; | ||
118 | button = buttons[button - 1]; | ||
119 | } else if (strncmp(name, "BTN_", strlen("BTN_")) == 0) { | ||
120 | // Get event code | ||
121 | int code = libevdev_event_code_from_name(EV_KEY, name); | ||
122 | if (code == -1) { | ||
123 | return cmd_results_new(CMD_INVALID, "bindsym", | ||
124 | "Invalid event code name %s", name); | ||
125 | } | ||
126 | button = code; | ||
108 | } | 127 | } |
109 | 128 | ||
110 | if (*type == BINDING_KEYSYM) { | 129 | if (*type == BINDING_KEYSYM) { |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index ad9b9835..444fe81d 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <math.h> | 2 | #include <math.h> |
3 | #include <libevdev/libevdev.h> | ||
3 | #ifdef __linux__ | 4 | #ifdef __linux__ |
4 | #include <linux/input-event-codes.h> | 5 | #include <linux/input-event-codes.h> |
5 | #elif __FreeBSD__ | 6 | #elif __FreeBSD__ |
@@ -982,6 +983,18 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { | |||
982 | transaction_commit_dirty(); | 983 | transaction_commit_dirty(); |
983 | } | 984 | } |
984 | 985 | ||
986 | static uint32_t wl_axis_to_button(struct wlr_event_pointer_axis *event) { | ||
987 | switch (event->orientation) { | ||
988 | case WLR_AXIS_ORIENTATION_VERTICAL: | ||
989 | return event->delta < 0 ? SWAY_SCROLL_UP : SWAY_SCROLL_DOWN; | ||
990 | case WLR_AXIS_ORIENTATION_HORIZONTAL: | ||
991 | return event->delta < 0 ? SWAY_SCROLL_LEFT : SWAY_SCROLL_RIGHT; | ||
992 | default: | ||
993 | wlr_log(WLR_DEBUG, "Unknown axis orientation"); | ||
994 | return 0; | ||
995 | } | ||
996 | } | ||
997 | |||
985 | static void dispatch_cursor_axis(struct sway_cursor *cursor, | 998 | static void dispatch_cursor_axis(struct sway_cursor *cursor, |
986 | struct wlr_event_pointer_axis *event) { | 999 | struct wlr_event_pointer_axis *event) { |
987 | struct sway_seat *seat = cursor->seat; | 1000 | struct sway_seat *seat = cursor->seat; |
@@ -998,11 +1011,32 @@ static void dispatch_cursor_axis(struct sway_cursor *cursor, | |||
998 | enum wlr_edges edge = cont ? find_edge(cont, cursor) : WLR_EDGE_NONE; | 1011 | enum wlr_edges edge = cont ? find_edge(cont, cursor) : WLR_EDGE_NONE; |
999 | bool on_border = edge != WLR_EDGE_NONE; | 1012 | bool on_border = edge != WLR_EDGE_NONE; |
1000 | bool on_titlebar = cont && !on_border && !surface; | 1013 | bool on_titlebar = cont && !on_border && !surface; |
1014 | bool on_contents = cont && !on_border && surface; | ||
1001 | float scroll_factor = | 1015 | float scroll_factor = |
1002 | (ic == NULL || ic->scroll_factor == FLT_MIN) ? 1.0f : ic->scroll_factor; | 1016 | (ic == NULL || ic->scroll_factor == FLT_MIN) ? 1.0f : ic->scroll_factor; |
1003 | 1017 | ||
1004 | // Scrolling on a tabbed or stacked title bar | 1018 | bool handled = false; |
1005 | if (on_titlebar) { | 1019 | |
1020 | // Gather information needed for mouse bindings | ||
1021 | struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); | ||
1022 | uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; | ||
1023 | struct wlr_input_device *device = input_device->wlr_device; | ||
1024 | char *dev_id = device ? input_device_get_identifier(device) : strdup("*"); | ||
1025 | uint32_t button = wl_axis_to_button(event); | ||
1026 | |||
1027 | // Handle mouse bindings - x11 mouse buttons 4-7 - press event | ||
1028 | struct sway_binding *binding = NULL; | ||
1029 | state_add_button(cursor, button); | ||
1030 | binding = get_active_mouse_binding(cursor, | ||
1031 | config->current_mode->mouse_bindings, modifiers, false, | ||
1032 | on_titlebar, on_border, on_contents, dev_id); | ||
1033 | if (binding) { | ||
1034 | seat_execute_command(seat, binding); | ||
1035 | handled = true; | ||
1036 | } | ||
1037 | |||
1038 | // Scrolling on a tabbed or stacked title bar (handled as press event) | ||
1039 | if (!handled && on_titlebar) { | ||
1006 | enum sway_container_layout layout = container_parent_layout(cont); | 1040 | enum sway_container_layout layout = container_parent_layout(cont); |
1007 | if (layout == L_TABBED || layout == L_STACKED) { | 1041 | if (layout == L_TABBED || layout == L_STACKED) { |
1008 | struct sway_node *tabcontainer = node_get_parent(node); | 1042 | struct sway_node *tabcontainer = node_get_parent(node); |
@@ -1029,13 +1063,26 @@ static void dispatch_cursor_axis(struct sway_cursor *cursor, | |||
1029 | seat_set_raw_focus(seat, new_focus); | 1063 | seat_set_raw_focus(seat, new_focus); |
1030 | seat_set_raw_focus(seat, old_focus); | 1064 | seat_set_raw_focus(seat, old_focus); |
1031 | } | 1065 | } |
1032 | return; | 1066 | handled = true; |
1033 | } | 1067 | } |
1034 | } | 1068 | } |
1035 | 1069 | ||
1036 | wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec, | 1070 | // Handle mouse bindings - x11 mouse buttons 4-7 - release event |
1037 | event->orientation, scroll_factor * event->delta, | 1071 | binding = get_active_mouse_binding(cursor, |
1038 | round(scroll_factor * event->delta_discrete), event->source); | 1072 | config->current_mode->mouse_bindings, modifiers, true, |
1073 | on_titlebar, on_border, on_contents, dev_id); | ||
1074 | state_erase_button(cursor, button); | ||
1075 | if (binding) { | ||
1076 | seat_execute_command(seat, binding); | ||
1077 | handled = true; | ||
1078 | } | ||
1079 | free(dev_id); | ||
1080 | |||
1081 | if (!handled) { | ||
1082 | wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec, | ||
1083 | event->orientation, scroll_factor * event->delta, | ||
1084 | round(scroll_factor * event->delta_discrete), event->source); | ||
1085 | } | ||
1039 | } | 1086 | } |
1040 | 1087 | ||
1041 | static void handle_cursor_axis(struct wl_listener *listener, void *data) { | 1088 | static void handle_cursor_axis(struct wl_listener *listener, void *data) { |
diff --git a/sway/meson.build b/sway/meson.build index 51b40020..2f977fd2 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -174,6 +174,7 @@ sway_deps = [ | |||
174 | cairo, | 174 | cairo, |
175 | gdk_pixbuf, | 175 | gdk_pixbuf, |
176 | jsonc, | 176 | jsonc, |
177 | libevdev, | ||
177 | libinput, | 178 | libinput, |
178 | math, | 179 | math, |
179 | pango, | 180 | pango, |
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 2fe4e372..e6abef56 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -288,6 +288,13 @@ runtime. | |||
288 | overwrite a binding, swaynag will give you a warning. To silence this, use | 288 | overwrite a binding, swaynag will give you a warning. To silence this, use |
289 | the _--no-warn_ flag. | 289 | the _--no-warn_ flag. |
290 | 290 | ||
291 | Mouse buttons can either be specified in the form _button[1-9]_ or by using | ||
292 | the name of the event code (ex _BTN\_LEFT_ or _BTN\_RIGHT_). For the former | ||
293 | option, the buttons will be mapped to their values in X11 (1=left, 2=middle, | ||
294 | 3=right, 4=scroll up, 5=scroll down, 6=scroll left, 7=scroll right, 8=back, | ||
295 | 9=forward). For the latter option, you can find the event names using | ||
296 | _libinput debug-events_. | ||
297 | |||
291 | Example: | 298 | Example: |
292 | ``` | 299 | ``` |
293 | # Execute firefox when alt, shift, and f are pressed together | 300 | # Execute firefox when alt, shift, and f are pressed together |