diff --git a/include/sway/commands.h b/include/sway/commands.h index ddd2f219..599347ef 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -262,6 +262,7 @@ sway_cmd input_cmd_map_to_region; sway_cmd input_cmd_middle_emulation; sway_cmd input_cmd_natural_scroll; sway_cmd input_cmd_pointer_accel; +sway_cmd input_cmd_rotation_angle; sway_cmd input_cmd_scroll_factor; sway_cmd input_cmd_repeat_delay; sway_cmd input_cmd_repeat_rate; diff --git a/include/sway/config.h b/include/sway/config.h index ce2b8502..8415627b 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -155,6 +155,7 @@ struct input_config { int middle_emulation; int natural_scroll; float pointer_accel; + float rotation_angle; float scroll_factor; int repeat_delay; int repeat_rate; diff --git a/sway/commands/input.c b/sway/commands/input.c index ea531659..740124ea 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c @@ -23,6 +23,7 @@ static const struct cmd_handler input_handlers[] = { { "middle_emulation", input_cmd_middle_emulation }, { "natural_scroll", input_cmd_natural_scroll }, { "pointer_accel", input_cmd_pointer_accel }, + { "rotation_angle", input_cmd_rotation_angle }, { "repeat_delay", input_cmd_repeat_delay }, { "repeat_rate", input_cmd_repeat_rate }, { "scroll_button", input_cmd_scroll_button }, diff --git a/sway/commands/input/rotation_angle.c b/sway/commands/input/rotation_angle.c new file mode 100644 index 00000000..5e278fff --- /dev/null +++ b/sway/commands/input/rotation_angle.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include "sway/config.h" +#include "sway/commands.h" +#include "sway/input/input-manager.h" +#include "util.h" + +struct cmd_results *input_cmd_rotation_angle(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "rotation_angle", EXPECTED_AT_LEAST, 1))) { + return error; + } + struct input_config *ic = config->handler_context.input_config; + if (!ic) { + return cmd_results_new(CMD_FAILURE, "No input device defined."); + } + + float rotation_angle = parse_float(argv[0]); + if (isnan(rotation_angle)) { + return cmd_results_new(CMD_INVALID, + "Invalid rotation_angle; expected float."); + } if (rotation_angle < 0 || rotation_angle > 360) { + return cmd_results_new(CMD_INVALID, "Input out of range [0, 360)"); + } + ic->rotation_angle = rotation_angle; + + return cmd_results_new(CMD_SUCCESS, NULL); +} diff --git a/sway/config/input.c b/sway/config/input.c index a98204df..2ee165c9 100644 --- a/sway/config/input.c +++ b/sway/config/input.c @@ -31,6 +31,7 @@ struct input_config *new_input_config(const char* identifier) { input->middle_emulation = INT_MIN; input->natural_scroll = INT_MIN; input->accel_profile = INT_MIN; + input->rotation_angle = FLT_MIN; input->pointer_accel = FLT_MIN; input->scroll_factor = FLT_MIN; input->scroll_button = INT_MIN; @@ -74,6 +75,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src) { if (src->natural_scroll != INT_MIN) { dst->natural_scroll = src->natural_scroll; } + if (src->rotation_angle != FLT_MIN) { + dst->rotation_angle = src->rotation_angle; + } if (src->pointer_accel != FLT_MIN) { dst->pointer_accel = src->pointer_accel; } diff --git a/sway/input/libinput.c b/sway/input/libinput.c index 53019301..10bd0e35 100644 --- a/sway/input/libinput.c +++ b/sway/input/libinput.c @@ -79,6 +79,16 @@ static bool set_accel_speed(struct libinput_device *device, double speed) { return true; } +static bool set_rotation_angle(struct libinput_device *device, double angle) { + if (!libinput_device_config_rotation_is_available(device) || + libinput_device_config_rotation_get_angle(device) == angle) { + return false; + } + sway_log(SWAY_DEBUG, "rotation_set_angle(%f)", angle); + log_status(libinput_device_config_rotation_set_angle(device, angle)); + return true; +} + static bool set_accel_profile(struct libinput_device *device, enum libinput_config_accel_profile profile) { if (!libinput_device_config_accel_is_available(device) || @@ -241,6 +251,9 @@ bool sway_input_configure_libinput_device(struct sway_input_device *input_device if (ic->pointer_accel != FLT_MIN) { changed |= set_accel_speed(device, ic->pointer_accel); } + if (ic->rotation_angle != FLT_MIN) { + changed |= set_rotation_angle(device, ic->rotation_angle); + } if (ic->accel_profile != INT_MIN) { changed |= set_accel_profile(device, ic->accel_profile); } @@ -298,6 +311,8 @@ void sway_input_reset_libinput_device(struct sway_input_device *input_device) { libinput_device_config_tap_get_default_drag_lock_enabled(device)); changed |= set_accel_speed(device, libinput_device_config_accel_get_default_speed(device)); + changed |= set_rotation_angle(device, + libinput_device_config_rotation_get_default_angle(device)); changed |= set_accel_profile(device, libinput_device_config_accel_get_default_profile(device)); changed |= set_natural_scroll(device, diff --git a/sway/meson.build b/sway/meson.build index b2412d5e..c6a27434 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -167,6 +167,7 @@ sway_sources = files( 'commands/input/middle_emulation.c', 'commands/input/natural_scroll.c', 'commands/input/pointer_accel.c', + 'commands/input/rotation_angle.c', 'commands/input/repeat_delay.c', 'commands/input/repeat_rate.c', 'commands/input/scroll_button.c', diff --git a/sway/sway-input.5.scd b/sway/sway-input.5.scd index e073c45d..91c978d6 100644 --- a/sway/sway-input.5.scd +++ b/sway/sway-input.5.scd @@ -175,6 +175,10 @@ The following commands may only be used in the configuration file. *input* pointer_accel [<-1|1>] Changes the pointer acceleration for the specified input device. +*input* rotation_angle + Sets the rotation angle of the device to the given clockwise angle in + degrees. The angle must be between 0.0 (inclusive) and 360.0 (exclusive). + *input* scroll_button disable|button[1-3,8,9]| Sets the button used for scroll_method on_button_down. The button can be given as an event name or code, which can be obtained from *libinput