diff --git a/include/sway/config.h b/include/sway/config.h index fe06fb9de5..8641054421 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -105,6 +105,7 @@ struct input_config_mapped_from_region { */ struct input_config { char *identifier; + const char *input_type; int accel_profile; int click_method; @@ -418,6 +419,7 @@ struct sway_config { list_t *workspace_configs; list_t *output_configs; list_t *input_configs; + list_t *input_type_configs; list_t *seat_configs; list_t *criteria; list_t *no_focus; diff --git a/sway/config.c b/sway/config.c index 4944ec0242..e14ea83a86 100644 --- a/sway/config.c +++ b/sway/config.c @@ -113,6 +113,12 @@ void free_config(struct sway_config *config) { } list_free(config->input_configs); } + if (config->input_type_configs) { + for (int i = 0; i < config->input_type_configs->length; i++) { + free_input_config(config->input_type_configs->items[i]); + } + list_free(config->input_type_configs); + } if (config->seat_configs) { for (int i = 0; i < config->seat_configs->length; i++) { free_seat_config(config->seat_configs->items[i]); @@ -189,10 +195,12 @@ static void config_defaults(struct sway_config *config) { if (!(config->workspace_configs = create_list())) goto cleanup; if (!(config->criteria = create_list())) goto cleanup; if (!(config->no_focus = create_list())) goto cleanup; - if (!(config->input_configs = create_list())) goto cleanup; if (!(config->seat_configs = create_list())) goto cleanup; if (!(config->output_configs = create_list())) goto cleanup; + if (!(config->input_type_configs = create_list())) goto cleanup; + if (!(config->input_configs = create_list())) goto cleanup; + if (!(config->cmd_queue = create_list())) goto cleanup; if (!(config->current_mode = malloc(sizeof(struct sway_mode)))) diff --git a/sway/config/input.c b/sway/config/input.c index 63c28635b6..aa58143132 100644 --- a/sway/config/input.c +++ b/sway/config/input.c @@ -18,6 +18,7 @@ struct input_config *new_input_config(const char* identifier) { return NULL; } + input->input_type = NULL; input->tap = INT_MIN; input->tap_button_map = INT_MIN; input->drag = INT_MIN; @@ -140,6 +141,30 @@ static void merge_wildcard_on_all(struct input_config *wildcard) { merge_input_config(ic, wildcard); } } + + for (int i = 0; i < config->input_type_configs->length; i++) { + struct input_config *ic = config->input_type_configs->items[i]; + if (strcmp(wildcard->identifier, ic->identifier) != 0) { + sway_log(SWAY_DEBUG, "Merging input * config on %s", ic->identifier); + merge_input_config(ic, wildcard); + } + } +} + +static void merge_type_on_existing(struct input_config *type_wildcard) { + for (int i = 0; i < config->input_configs->length; i++) { + struct input_config *ic = config->input_configs->items[i]; + if (ic->input_type == NULL) { + continue; + } + + if (strcmp(ic->input_type, type_wildcard->identifier + 5) == 0) { + sway_log(SWAY_DEBUG, "Merging %s top of %s", + type_wildcard->identifier, + ic->identifier); + merge_input_config(ic, type_wildcard); + } + } } struct input_config *store_input_config(struct input_config *ic) { @@ -148,11 +173,19 @@ struct input_config *store_input_config(struct input_config *ic) { merge_wildcard_on_all(ic); } - int i = list_seq_find(config->input_configs, input_identifier_cmp, + list_t *config_list = NULL; + if (strncmp(ic->identifier, "type:", 5) == 0) { + config_list = config->input_type_configs; + merge_type_on_existing(ic); + } else { + config_list = config->input_configs; + } + + int i = list_seq_find(config_list, input_identifier_cmp, ic->identifier); if (i >= 0) { sway_log(SWAY_DEBUG, "Merging on top of existing input config"); - struct input_config *current = config->input_configs->items[i]; + struct input_config *current = config_list->items[i]; merge_input_config(current, ic); free_input_config(ic); ic = current; @@ -167,7 +200,7 @@ struct input_config *store_input_config(struct input_config *ic) { free_input_config(ic); ic = current; } - list_add(config->input_configs, ic); + list_add(config_list, ic); } else { // New wildcard config. Just add it sway_log(SWAY_DEBUG, "Adding input * config"); diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index 0c5254bdfc..a2a1e27408 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -105,6 +105,37 @@ const char *input_device_get_type(struct sway_input_device *device) { return "unknown"; } +static void apply_input_type_config(struct sway_input_device *input_device) { + const char *device_type = input_device_get_type(input_device); + struct input_config *type_config = NULL; + for (int i = 0; i < config->input_type_configs->length; i++) { + struct input_config *ic = config->input_type_configs->items[i]; + if (strcmp(ic->identifier + 5, device_type) == 0) { + type_config = ic; + break; + } + } + if (type_config == NULL) { + return; + } + + for (int i = 0; i < config->input_configs->length; i++) { + struct input_config *ic = config->input_configs->items[i]; + if (strcmp(input_device->identifier, ic->identifier) == 0) { + struct input_config *current = new_input_config(ic->identifier); + merge_input_config(current, type_config); + merge_input_config(current, ic); + + current->input_type = device_type; + config->input_configs->items[i] = current; + free_input_config(ic); + ic = NULL; + + break; + } + } +} + static struct sway_input_device *input_sway_device_from_wlr( struct wlr_input_device *device) { struct sway_input_device *input_device = NULL; @@ -541,6 +572,8 @@ static void handle_new_input(struct wl_listener *listener, void *data) { sway_log(SWAY_DEBUG, "adding device: '%s'", input_device->identifier); + apply_input_type_config(input_device); + if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER || input_device->wlr_device->type == WLR_INPUT_DEVICE_TABLET_TOOL) { input_manager_libinput_config_pointer(input_device); @@ -693,9 +726,13 @@ void input_manager_set_focus(struct sway_node *node) { void input_manager_apply_input_config(struct input_config *input_config) { struct sway_input_device *input_device = NULL; bool wildcard = strcmp(input_config->identifier, "*") == 0; + bool type_wildcard = strncmp(input_config->identifier, "type:", 5) == 0; wl_list_for_each(input_device, &server.input->devices, link) { + bool type_matches = type_wildcard && + strcmp(input_device_get_type(input_device), input_config->identifier + 5) == 0; if (strcmp(input_device->identifier, input_config->identifier) == 0 - || wildcard) { + || wildcard + || type_matches) { if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER || input_device->wlr_device->type == WLR_INPUT_DEVICE_TABLET_TOOL) { input_manager_libinput_config_pointer(input_device); @@ -829,5 +866,13 @@ struct input_config *input_device_get_config(struct sway_input_device *device) { } } + const char *device_type = input_device_get_type(device); + for (int i = 0; i < config->input_type_configs->length; ++i) { + input_config = config->input_type_configs->items[i]; + if (strcmp(input_config->identifier + 5, device_type) == 0) { + return input_config; + } + } + return wildcard_config; } diff --git a/sway/sway-input.5.scd b/sway/sway-input.5.scd index 1a8062fb99..efd3d1afcc 100644 --- a/sway/sway-input.5.scd +++ b/sway/sway-input.5.scd @@ -9,13 +9,28 @@ sway-input - input configuration file and commands Sway allows for configuration of devices within the sway configuration file. To obtain a list of available device identifiers, run *swaymsg -t get_inputs*. Settings can also be applied to all input devices by using the wildcard, _\*_, -in place of _\_ in the commands below. +in place of _\_ in the commands below. In addition, the settings +can be applied to a type of device, by using _type:\_ in place +of _\_. Tip: If the configuration settings do not appear to be taking effect, you could try using _\*_ instead of _\_. If it works with the wildcard, try using a different identifier from *swaymsg -t get_inputs* until you find the correct input device. +Current available input types are: + +- touchpad +- pointer +- keyboard +- touch +- tablet_tool +- tablet_pad +- switch + +Note: The type configurations are applied as the devices appear and get applied +on top of the existing device configurations. + # INPUT COMMANDS ## KEYBOARD CONFIGURATION