Skip to content

Commit 0c3335c

Browse files
committed
input/mouse: add accel_profile custom
Support libinput LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM to define a custom mouse pointer acceleration curve. Implements #8488.
1 parent 71777ee commit 0c3335c

File tree

9 files changed

+87
-3
lines changed

9 files changed

+87
-3
lines changed

include/sway/commands.h

+1
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ sway_cmd input_cmd_map_to_region;
263263
sway_cmd input_cmd_middle_emulation;
264264
sway_cmd input_cmd_natural_scroll;
265265
sway_cmd input_cmd_pointer_accel;
266+
sway_cmd input_cmd_pointer_accel_custom;
266267
sway_cmd input_cmd_rotation_angle;
267268
sway_cmd input_cmd_scroll_factor;
268269
sway_cmd input_cmd_repeat_delay;

include/sway/config.h

+7
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ struct input_config_tool {
139139
enum sway_tablet_tool_mode mode;
140140
};
141141

142+
struct accel_custom {
143+
double step;
144+
size_t npoints;
145+
double points[64]; /* LIBINPUT_ACCEL_NPOINTS_MAX */
146+
};
147+
142148
/**
143149
* options for input devices
144150
*/
@@ -158,6 +164,7 @@ struct input_config {
158164
int middle_emulation;
159165
int natural_scroll;
160166
float pointer_accel;
167+
struct accel_custom pointer_accel_custom;
161168
float rotation_angle;
162169
float scroll_factor;
163170
int repeat_delay;

sway/commands/input.c

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ static const struct cmd_handler input_handlers[] = {
2424
{ "middle_emulation", input_cmd_middle_emulation },
2525
{ "natural_scroll", input_cmd_natural_scroll },
2626
{ "pointer_accel", input_cmd_pointer_accel },
27+
{ "pointer_accel_custom", input_cmd_pointer_accel_custom },
2728
{ "repeat_delay", input_cmd_repeat_delay },
2829
{ "repeat_rate", input_cmd_repeat_rate },
2930
{ "rotation_angle", input_cmd_rotation_angle },

sway/commands/input/accel_profile.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,17 @@ struct cmd_results *input_cmd_accel_profile(int argc, char **argv) {
1818
ic->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
1919
} else if (strcasecmp(argv[0], "flat") == 0) {
2020
ic->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
21+
} else if (strcasecmp(argv[0], "custom") == 0) {
22+
#if HAVE_LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM
23+
ic->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM;
24+
#else
25+
return cmd_results_new(CMD_INVALID,
26+
"Config 'accel_profile custom' not supported (requires libinput >= 1.23.0).");
27+
#endif
2128
} else {
2229
return cmd_results_new(CMD_INVALID,
23-
"Expected 'accel_profile <adaptive|flat>'");
30+
"Expected 'accel_profile <adaptive|flat|custom>'"
31+
);
2432
}
2533

2634
return cmd_results_new(CMD_SUCCESS, NULL);

sway/commands/input/pointer_accel.c

+33
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,36 @@ struct cmd_results *input_cmd_pointer_accel(int argc, char **argv) {
2727

2828
return cmd_results_new(CMD_SUCCESS, NULL);
2929
}
30+
31+
#if HAVE_LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM
32+
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
33+
#define ACCEL_CUSTOM_MAX (1 + ARRAY_SIZE(((struct input_config *)0)->pointer_accel_custom.points))
34+
struct cmd_results *input_cmd_pointer_accel_custom(int argc, char **argv) {
35+
struct cmd_results *error = NULL;
36+
if ((error = checkarg(argc, "pointer_accel_custom", EXPECTED_AT_LEAST, 3))) {
37+
return error;
38+
}
39+
if ((error = checkarg(argc, "pointer_accel_custom", EXPECTED_AT_MOST, ACCEL_CUSTOM_MAX))) {
40+
return error;
41+
}
42+
struct input_config *ic = config->handler_context.input_config;
43+
if (!ic) {
44+
return cmd_results_new(CMD_FAILURE, "No input device defined.");
45+
}
46+
47+
for(int i=0; i<argc; ++i) {
48+
double dbl = parse_double(argv[i]);
49+
if (isnan(dbl) || dbl < 0.0) {
50+
return cmd_results_new(CMD_INVALID,
51+
"Invalid pointer_accel_custom value; expected non-negative double.");
52+
}
53+
if (i == 0) {
54+
ic->pointer_accel_custom.step = dbl;
55+
} else {
56+
ic->pointer_accel_custom.points[i-1] = dbl;
57+
}
58+
}
59+
ic->pointer_accel_custom.npoints = argc - 1;
60+
return cmd_results_new(CMD_SUCCESS, NULL);
61+
}
62+
#endif

sway/config/input.c

+3
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src) {
170170
memcpy(dst->calibration_matrix.matrix, src->calibration_matrix.matrix,
171171
sizeof(src->calibration_matrix.matrix));
172172
}
173+
if (src->pointer_accel_custom.npoints) {
174+
memcpy(&dst->pointer_accel_custom, &src->pointer_accel_custom, sizeof(src->pointer_accel_custom));
175+
}
173176
for (int i = 0; i < src->tools->length; i++) {
174177
struct input_config_tool *src_tool = src->tools->items[i];
175178
for (int j = 0; j < dst->tools->length; j++) {

sway/input/libinput.c

+22
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,23 @@ static bool set_calibration_matrix(struct libinput_device *dev, float mat[6]) {
229229
return changed;
230230
}
231231

232+
#if HAVE_LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM
233+
static bool set_pointer_accel_custom(struct libinput_device *dev, struct accel_custom *custom) {
234+
sway_log(SWAY_DEBUG, "pointer_accel_config(npoints %lu, step %f)", custom->npoints, custom->step);
235+
if (custom->npoints == 0) {
236+
return false;
237+
}
238+
struct libinput_config_accel *accel_config =
239+
libinput_config_accel_create(LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM);
240+
log_status(libinput_config_accel_set_points(accel_config, LIBINPUT_ACCEL_TYPE_MOTION,
241+
custom->step, custom->npoints, custom->points));
242+
log_status(libinput_device_config_accel_apply(dev, accel_config));
243+
libinput_config_accel_destroy(accel_config);
244+
/* there is no way to read back the custom points/step from libinput */
245+
return false;
246+
}
247+
#endif
248+
232249
static bool configure_send_events(struct libinput_device *device,
233250
struct input_config *ic) {
234251
if (ic->mapped_to_output &&
@@ -285,6 +302,11 @@ bool sway_input_configure_libinput_device(struct sway_input_device *input_device
285302
}
286303
if (ic->accel_profile != INT_MIN) {
287304
changed |= set_accel_profile(device, ic->accel_profile);
305+
#if HAVE_LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM
306+
if (ic->accel_profile == LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM) {
307+
set_pointer_accel_custom(device, &ic->pointer_accel_custom);
308+
}
309+
#endif
288310
}
289311
if (ic->natural_scroll != INT_MIN) {
290312
changed |= set_natural_scroll(device, ic->natural_scroll);

sway/sway-input.5.scd

+9-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ The following commands may only be used in the configuration file.
134134

135135
## LIBINPUT CONFIGURATION
136136

137-
*input* <identifier> accel_profile adaptive|flat
137+
*input* <identifier> accel_profile adaptive|flat|custom
138138
Sets the pointer acceleration profile for the specified input device.
139139

140140
*input* <identifier> calibration_matrix <6 space-separated floating point values>
@@ -187,6 +187,14 @@ The following commands may only be used in the configuration file.
187187
*input* <identifier> pointer_accel [<-1|1>]
188188
Changes the pointer acceleration for the specified input device.
189189

190+
*input* <identifier> pointer_accel_custom <step> <point0 point1 ... pointN>
191+
Specifies custom mouse pointer acceleration curve that is used when
192+
accel_profile is set to _custom_. Values are floating point numbers. The
193+
behaviour of the custom acceleration profile is defined by libinput and
194+
described in libinput *doc/user/pointer-acceleration.rst*. For example,
195+
'pointer_accel_custom 1.0 0.0 1.0' means step=1.0 and points=[0.0 1.0], which
196+
is equivalent to the 'flat' profile. Requires libinput >= 1.23.0.
197+
190198
*input* <identifier> rotation_angle <angle>
191199
Sets the rotation angle of the device to the given clockwise angle in
192200
degrees. The angle must be between 0.0 (inclusive) and 360.0 (exclusive).

sway/sway-ipc.7.scd

+2-1
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,8 @@ following properties will be included for devices that support them:
11941194
: The pointer-acceleration in use
11951195
|- accel_profile
11961196
: string
1197-
: The acceleration profile in use. It can be _none_, _flat_, or _adaptive_
1197+
: The acceleration profile in use. It can be _none_, _flat_, _adaptive_, or
1198+
_custom_
11981199
|- natural_scroll
11991200
: string
12001201
: Whether natural scrolling is enabled. It can be _enabled_ or _disabled_

0 commit comments

Comments
 (0)