diff options
-rw-r--r-- | common/util.c | 12 | ||||
-rw-r--r-- | include/sway/commands.h | 1 | ||||
-rw-r--r-- | include/sway/config.h | 1 | ||||
-rw-r--r-- | include/util.h | 6 | ||||
-rw-r--r-- | sway/commands/input.c | 1 | ||||
-rw-r--r-- | sway/commands/input/pointer_accel.c | 9 | ||||
-rw-r--r-- | sway/commands/input/scroll_factor.c | 32 | ||||
-rw-r--r-- | sway/config/input.c | 4 | ||||
-rw-r--r-- | sway/input/cursor.c | 10 | ||||
-rw-r--r-- | sway/meson.build | 1 | ||||
-rw-r--r-- | sway/sway-input.5.scd | 10 |
11 files changed, 80 insertions, 7 deletions
diff --git a/common/util.c b/common/util.c index f4588b57..0caafb39 100644 --- a/common/util.c +++ b/common/util.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <sys/types.h> | 3 | #include <sys/types.h> |
4 | #include <sys/stat.h> | 4 | #include <sys/stat.h> |
5 | #include <unistd.h> | 5 | #include <unistd.h> |
6 | #include <float.h> | ||
6 | #include <math.h> | 7 | #include <math.h> |
7 | #include <stdint.h> | 8 | #include <stdint.h> |
8 | #include <stdio.h> | 9 | #include <stdio.h> |
@@ -140,6 +141,17 @@ bool parse_boolean(const char *boolean, bool current) { | |||
140 | return false; | 141 | return false; |
141 | } | 142 | } |
142 | 143 | ||
144 | float parse_float(const char *value) { | ||
145 | errno = 0; | ||
146 | char *end; | ||
147 | float flt = strtof(value, &end); | ||
148 | if (*end || errno) { | ||
149 | wlr_log(WLR_DEBUG, "Invalid float value '%s', defaulting to NAN", value); | ||
150 | return NAN; | ||
151 | } | ||
152 | return flt; | ||
153 | } | ||
154 | |||
143 | enum wlr_direction opposite_direction(enum wlr_direction d) { | 155 | enum wlr_direction opposite_direction(enum wlr_direction d) { |
144 | switch (d) { | 156 | switch (d) { |
145 | case WLR_DIRECTION_UP: | 157 | case WLR_DIRECTION_UP: |
diff --git a/include/sway/commands.h b/include/sway/commands.h index 6606775a..2fe8a631 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h | |||
@@ -229,6 +229,7 @@ sway_cmd input_cmd_map_to_output; | |||
229 | sway_cmd input_cmd_middle_emulation; | 229 | sway_cmd input_cmd_middle_emulation; |
230 | sway_cmd input_cmd_natural_scroll; | 230 | sway_cmd input_cmd_natural_scroll; |
231 | sway_cmd input_cmd_pointer_accel; | 231 | sway_cmd input_cmd_pointer_accel; |
232 | sway_cmd input_cmd_scroll_factor; | ||
232 | sway_cmd input_cmd_repeat_delay; | 233 | sway_cmd input_cmd_repeat_delay; |
233 | sway_cmd input_cmd_repeat_rate; | 234 | sway_cmd input_cmd_repeat_rate; |
234 | sway_cmd input_cmd_scroll_button; | 235 | sway_cmd input_cmd_scroll_button; |
diff --git a/include/sway/config.h b/include/sway/config.h index 79c4359b..658b4a01 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -100,6 +100,7 @@ struct input_config { | |||
100 | int middle_emulation; | 100 | int middle_emulation; |
101 | int natural_scroll; | 101 | int natural_scroll; |
102 | float pointer_accel; | 102 | float pointer_accel; |
103 | float scroll_factor; | ||
103 | int repeat_delay; | 104 | int repeat_delay; |
104 | int repeat_rate; | 105 | int repeat_rate; |
105 | int scroll_button; | 106 | int scroll_button; |
diff --git a/include/util.h b/include/util.h index f143d0c0..84318fe7 100644 --- a/include/util.h +++ b/include/util.h | |||
@@ -59,6 +59,12 @@ uint32_t parse_color(const char *color); | |||
59 | */ | 59 | */ |
60 | bool parse_boolean(const char *boolean, bool current); | 60 | bool parse_boolean(const char *boolean, bool current); |
61 | 61 | ||
62 | /** | ||
63 | * Given a string that represents a floating point value, return a float. | ||
64 | * Returns NAN on error. | ||
65 | */ | ||
66 | float parse_float(const char *value); | ||
67 | |||
62 | enum wlr_direction opposite_direction(enum wlr_direction d); | 68 | enum wlr_direction opposite_direction(enum wlr_direction d); |
63 | 69 | ||
64 | #endif | 70 | #endif |
diff --git a/sway/commands/input.c b/sway/commands/input.c index c50926a8..b5765c38 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c | |||
@@ -22,6 +22,7 @@ static struct cmd_handler input_handlers[] = { | |||
22 | { "repeat_delay", input_cmd_repeat_delay }, | 22 | { "repeat_delay", input_cmd_repeat_delay }, |
23 | { "repeat_rate", input_cmd_repeat_rate }, | 23 | { "repeat_rate", input_cmd_repeat_rate }, |
24 | { "scroll_button", input_cmd_scroll_button }, | 24 | { "scroll_button", input_cmd_scroll_button }, |
25 | { "scroll_factor", input_cmd_scroll_factor }, | ||
25 | { "scroll_method", input_cmd_scroll_method }, | 26 | { "scroll_method", input_cmd_scroll_method }, |
26 | { "tap", input_cmd_tap }, | 27 | { "tap", input_cmd_tap }, |
27 | { "tap_button_map", input_cmd_tap_button_map }, | 28 | { "tap_button_map", input_cmd_tap_button_map }, |
diff --git a/sway/commands/input/pointer_accel.c b/sway/commands/input/pointer_accel.c index df487b1c..efd81ee6 100644 --- a/sway/commands/input/pointer_accel.c +++ b/sway/commands/input/pointer_accel.c | |||
@@ -1,8 +1,10 @@ | |||
1 | #include <math.h> | ||
1 | #include <stdlib.h> | 2 | #include <stdlib.h> |
2 | #include <string.h> | 3 | #include <string.h> |
3 | #include "sway/config.h" | 4 | #include "sway/config.h" |
4 | #include "sway/commands.h" | 5 | #include "sway/commands.h" |
5 | #include "sway/input/input-manager.h" | 6 | #include "sway/input/input-manager.h" |
7 | #include "util.h" | ||
6 | 8 | ||
7 | struct cmd_results *input_cmd_pointer_accel(int argc, char **argv) { | 9 | struct cmd_results *input_cmd_pointer_accel(int argc, char **argv) { |
8 | struct cmd_results *error = NULL; | 10 | struct cmd_results *error = NULL; |
@@ -15,8 +17,11 @@ struct cmd_results *input_cmd_pointer_accel(int argc, char **argv) { | |||
15 | "pointer_accel", "No input device defined."); | 17 | "pointer_accel", "No input device defined."); |
16 | } | 18 | } |
17 | 19 | ||
18 | float pointer_accel = atof(argv[0]); | 20 | float pointer_accel = parse_float(argv[0]); |
19 | if (pointer_accel < -1 || pointer_accel > 1) { | 21 | if (isnan(pointer_accel)) { |
22 | return cmd_results_new(CMD_INVALID, "pointer_accel", | ||
23 | "Invalid pointer accel; expected float."); | ||
24 | } if (pointer_accel < -1 || pointer_accel > 1) { | ||
20 | return cmd_results_new(CMD_INVALID, "pointer_accel", | 25 | return cmd_results_new(CMD_INVALID, "pointer_accel", |
21 | "Input out of range [-1, 1]"); | 26 | "Input out of range [-1, 1]"); |
22 | } | 27 | } |
diff --git a/sway/commands/input/scroll_factor.c b/sway/commands/input/scroll_factor.c new file mode 100644 index 00000000..52d943b0 --- /dev/null +++ b/sway/commands/input/scroll_factor.c | |||
@@ -0,0 +1,32 @@ | |||
1 | #include <errno.h> | ||
2 | #include <math.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <string.h> | ||
5 | #include "sway/config.h" | ||
6 | #include "sway/commands.h" | ||
7 | #include "sway/input/input-manager.h" | ||
8 | #include "util.h" | ||
9 | |||
10 | struct cmd_results *input_cmd_scroll_factor(int argc, char **argv) { | ||
11 | struct cmd_results *error = NULL; | ||
12 | if ((error = checkarg(argc, "scroll_factor", EXPECTED_AT_LEAST, 1))) { | ||
13 | return error; | ||
14 | } | ||
15 | struct input_config *ic = config->handler_context.input_config; | ||
16 | if (!ic) { | ||
17 | return cmd_results_new(CMD_FAILURE, | ||
18 | "scroll_factor", "No input device defined."); | ||
19 | } | ||
20 | |||
21 | float scroll_factor = parse_float(argv[0]); | ||
22 | if (isnan(scroll_factor)) { | ||
23 | return cmd_results_new(CMD_INVALID, "scroll_factor", | ||
24 | "Invalid scroll factor; expected float."); | ||
25 | } else if (scroll_factor < 0) { | ||
26 | return cmd_results_new(CMD_INVALID, "scroll_factor", | ||
27 | "Scroll factor cannot be negative."); | ||
28 | } | ||
29 | ic->scroll_factor = scroll_factor; | ||
30 | |||
31 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
32 | } | ||
diff --git a/sway/config/input.c b/sway/config/input.c index 794d5194..d5d2d90b 100644 --- a/sway/config/input.c +++ b/sway/config/input.c | |||
@@ -29,6 +29,7 @@ struct input_config *new_input_config(const char* identifier) { | |||
29 | input->natural_scroll = INT_MIN; | 29 | input->natural_scroll = INT_MIN; |
30 | input->accel_profile = INT_MIN; | 30 | input->accel_profile = INT_MIN; |
31 | input->pointer_accel = FLT_MIN; | 31 | input->pointer_accel = FLT_MIN; |
32 | input->scroll_factor = FLT_MIN; | ||
32 | input->scroll_button = INT_MIN; | 33 | input->scroll_button = INT_MIN; |
33 | input->scroll_method = INT_MIN; | 34 | input->scroll_method = INT_MIN; |
34 | input->left_handed = INT_MIN; | 35 | input->left_handed = INT_MIN; |
@@ -68,6 +69,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src) { | |||
68 | if (src->pointer_accel != FLT_MIN) { | 69 | if (src->pointer_accel != FLT_MIN) { |
69 | dst->pointer_accel = src->pointer_accel; | 70 | dst->pointer_accel = src->pointer_accel; |
70 | } | 71 | } |
72 | if (src->scroll_factor != FLT_MIN) { | ||
73 | dst->scroll_factor = src->scroll_factor; | ||
74 | } | ||
71 | if (src->repeat_delay != INT_MIN) { | 75 | if (src->repeat_delay != INT_MIN) { |
72 | dst->repeat_delay = src->repeat_delay; | 76 | dst->repeat_delay = src->repeat_delay; |
73 | } | 77 | } |
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index c6b7414c..d89f64d8 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #elif __FreeBSD__ | 5 | #elif __FreeBSD__ |
6 | #include <dev/evdev/input-event-codes.h> | 6 | #include <dev/evdev/input-event-codes.h> |
7 | #endif | 7 | #endif |
8 | #include <float.h> | ||
8 | #include <limits.h> | 9 | #include <limits.h> |
9 | #include <wlr/types/wlr_cursor.h> | 10 | #include <wlr/types/wlr_cursor.h> |
10 | #include <wlr/types/wlr_xcursor_manager.h> | 11 | #include <wlr/types/wlr_xcursor_manager.h> |
@@ -979,6 +980,8 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { | |||
979 | static void dispatch_cursor_axis(struct sway_cursor *cursor, | 980 | static void dispatch_cursor_axis(struct sway_cursor *cursor, |
980 | struct wlr_event_pointer_axis *event) { | 981 | struct wlr_event_pointer_axis *event) { |
981 | struct sway_seat *seat = cursor->seat; | 982 | struct sway_seat *seat = cursor->seat; |
983 | struct sway_input_device *input_device = event->device->data; | ||
984 | struct input_config *ic = input_device_get_config(input_device); | ||
982 | 985 | ||
983 | // Determine what's under the cursor | 986 | // Determine what's under the cursor |
984 | struct wlr_surface *surface = NULL; | 987 | struct wlr_surface *surface = NULL; |
@@ -990,6 +993,8 @@ static void dispatch_cursor_axis(struct sway_cursor *cursor, | |||
990 | enum wlr_edges edge = cont ? find_edge(cont, cursor) : WLR_EDGE_NONE; | 993 | enum wlr_edges edge = cont ? find_edge(cont, cursor) : WLR_EDGE_NONE; |
991 | bool on_border = edge != WLR_EDGE_NONE; | 994 | bool on_border = edge != WLR_EDGE_NONE; |
992 | bool on_titlebar = cont && !on_border && !surface; | 995 | bool on_titlebar = cont && !on_border && !surface; |
996 | float scroll_factor = | ||
997 | (ic == NULL || ic->scroll_factor == FLT_MIN) ? 1.0f : ic->scroll_factor; | ||
993 | 998 | ||
994 | // Scrolling on a tabbed or stacked title bar | 999 | // Scrolling on a tabbed or stacked title bar |
995 | if (on_titlebar) { | 1000 | if (on_titlebar) { |
@@ -1000,7 +1005,7 @@ static void dispatch_cursor_axis(struct sway_cursor *cursor, | |||
1000 | seat_get_active_tiling_child(seat, tabcontainer); | 1005 | seat_get_active_tiling_child(seat, tabcontainer); |
1001 | list_t *siblings = container_get_siblings(cont); | 1006 | list_t *siblings = container_get_siblings(cont); |
1002 | int desired = list_find(siblings, active->sway_container) + | 1007 | int desired = list_find(siblings, active->sway_container) + |
1003 | event->delta_discrete; | 1008 | round(scroll_factor * event->delta_discrete); |
1004 | if (desired < 0) { | 1009 | if (desired < 0) { |
1005 | desired = 0; | 1010 | desired = 0; |
1006 | } else if (desired >= siblings->length) { | 1011 | } else if (desired >= siblings->length) { |
@@ -1024,7 +1029,8 @@ static void dispatch_cursor_axis(struct sway_cursor *cursor, | |||
1024 | } | 1029 | } |
1025 | 1030 | ||
1026 | wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec, | 1031 | wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec, |
1027 | event->orientation, event->delta, event->delta_discrete, event->source); | 1032 | event->orientation, scroll_factor * event->delta, |
1033 | round(scroll_factor * event->delta_discrete), event->source); | ||
1028 | } | 1034 | } |
1029 | 1035 | ||
1030 | static void handle_cursor_axis(struct wl_listener *listener, void *data) { | 1036 | static void handle_cursor_axis(struct wl_listener *listener, void *data) { |
diff --git a/sway/meson.build b/sway/meson.build index cde09a02..d9bc08f3 100644 --- a/sway/meson.build +++ b/sway/meson.build | |||
@@ -135,6 +135,7 @@ sway_sources = files( | |||
135 | 'commands/input/repeat_delay.c', | 135 | 'commands/input/repeat_delay.c', |
136 | 'commands/input/repeat_rate.c', | 136 | 'commands/input/repeat_rate.c', |
137 | 'commands/input/scroll_button.c', | 137 | 'commands/input/scroll_button.c', |
138 | 'commands/input/scroll_factor.c', | ||
138 | 'commands/input/scroll_method.c', | 139 | 'commands/input/scroll_method.c', |
139 | 'commands/input/tap.c', | 140 | 'commands/input/tap.c', |
140 | 'commands/input/tap_button_map.c', | 141 | 'commands/input/tap_button_map.c', |
diff --git a/sway/sway-input.5.scd b/sway/sway-input.5.scd index 82273ef3..45994644 100644 --- a/sway/sway-input.5.scd +++ b/sway/sway-input.5.scd | |||
@@ -105,14 +105,18 @@ The following commands may only be used in the configuration file. | |||
105 | *input* <identifier> repeat\_rate <characters per second> | 105 | *input* <identifier> repeat\_rate <characters per second> |
106 | Sets the frequency of key repeats once the repeat\_delay has passed. | 106 | Sets the frequency of key repeats once the repeat\_delay has passed. |
107 | 107 | ||
108 | *input* <identifier> scroll\_method none|two\_finger|edge|on\_button\_down | ||
109 | Changes the scroll method for the specified input device. | ||
110 | |||
111 | *input* <identifier> scroll\_button <button\_identifier> | 108 | *input* <identifier> scroll\_button <button\_identifier> |
112 | Sets button used for scroll\_method on\_button\_down. The button identifier | 109 | Sets button used for scroll\_method on\_button\_down. The button identifier |
113 | can be obtained from `libinput debug-events`. | 110 | can be obtained from `libinput debug-events`. |
114 | If set to 0, it disables the scroll\_button on\_button\_down. | 111 | If set to 0, it disables the scroll\_button on\_button\_down. |
115 | 112 | ||
113 | *input* <identifier> scroll\_factor <floating point value> | ||
114 | Changes the scroll factor for the specified input device. Scroll speed will | ||
115 | be scaled by the given value, which must be non-negative. | ||
116 | |||
117 | *input* <identifier> scroll\_method none|two\_finger|edge|on\_button\_down | ||
118 | Changes the scroll method for the specified input device. | ||
119 | |||
116 | *input* <identifier> tap enabled|disabled | 120 | *input* <identifier> tap enabled|disabled |
117 | Enables or disables tap for specified input device. | 121 | Enables or disables tap for specified input device. |
118 | 122 | ||