aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-12-23 10:54:54 -0500
committerLibravatar emersion <contact@emersion.fr>2018-12-25 13:27:08 +0100
commita223030b70c8e360f81b820244705e007e3ac1ec (patch)
tree4e38abb2e27cb567760bab659546ff7176fe49fa
parentsway(5): document tiling_drag (diff)
downloadsway-a223030b70c8e360f81b820244705e007e3ac1ec.tar.gz
sway-a223030b70c8e360f81b820244705e007e3ac1ec.tar.zst
sway-a223030b70c8e360f81b820244705e007e3ac1ec.zip
Change mouse buttons to x11 map and libevdev names
This modifies the way mouse bindings are parsed. Instead of adding to BTN_LEFT, which results in button numbers that may not be expected, buttons will be parsed in one of the following ways: 1. `button[1-9]` will now map to their x11 equivalents. This is already the case for bar bindings. This adds support for binding to axis events, which was not possible in the previous approach. 2. Anything that starts with `BTN_` will be parsed as an event code name using `libevdev_event_code_from_name`. This allows for any button to be mapped to instead of limiting usage to the ones near BTN_LEFT. This also adds a dependency on libevdev, but since libevdev is already a dependency of libinput, this should be fine. If needed, this option can have dependency guards added. Binding changes: - button1: BTN_LEFT -> BTN_LEFT - button2: BTN_RIGHT -> BTN_MIDDLE - button3: BTN_MIDDLE -> BTN_RIGHT - button4: BTN_SIDE -> SWAY_SCROLL_UP - button5: BTN_EXTRA -> SWAY_SCROLL_DOWN - button6: BTN_FORWARD -> SWAY_SCROLL_LEFT - button7: BTN_BACK -> SWAY_SCROLL_RIGHT - button8: BTN_TASK -> BTN_SIDE - button9: BTN_JOYSTICK -> BTN_EXTRA Since the axis events need to be mapped to an event code, this uses the following mappings to avoid any conflicts: - SWAY_SCROLL_UP: KEY_MAX + 1 - SWAY_SCROLL_DOWN: KEY_MAX + 2 - SWAY_SCROLL_LEFT: KEY_MAX + 3 - SWAY_SCROLL_RIGHT: KEY_MAX + 4
-rw-r--r--include/sway/input/cursor.h5
-rw-r--r--meson.build1
-rw-r--r--sway/commands/bind.c25
-rw-r--r--sway/input/cursor.c59
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway.5.scd7
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
8struct sway_cursor { 13struct 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')
46pangocairo = dependency('pangocairo') 46pangocairo = dependency('pangocairo')
47gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: false) 47gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: false)
48pixman = dependency('pixman-1') 48pixman = dependency('pixman-1')
49libevdev = dependency('libevdev')
49libinput = dependency('libinput', version: '>=1.6.0') 50libinput = dependency('libinput', version: '>=1.6.0')
50libpam = cc.find_library('pam', required: false) 51libpam = cc.find_library('pam', required: false)
51crypt = cc.find_library('crypt', required: false) 52crypt = 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
986static 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
985static void dispatch_cursor_axis(struct sway_cursor *cursor, 998static 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
1041static void handle_cursor_axis(struct wl_listener *listener, void *data) { 1088static 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