diff options
| author | Brian Ashworth <bosrsf04@gmail.com> | 2019-05-30 03:30:08 -0400 | 
|---|---|---|
| committer | Simon Ser <contact@emersion.fr> | 2019-05-30 10:47:42 +0300 | 
| commit | 6afb392823d27ec69bedc8fd74263c3d072cca29 (patch) | |
| tree | a1a72a233a2ef8e89240b7702d7c9eabb3444bf0 /sway | |
| parent | 2c6a10c4ba8e1ab97db81677e32ca1580e4f0430 (diff) | |
| download | sway-6afb392823d27ec69bedc8fd74263c3d072cca29.tar.xz | |
bindings: allow unlocked and locked bindings
This changes the behavior of bindings to make the `BINDING_LOCKED` flag
conflicting, which will allow for both unlocked and locked bindings.
If there are two matching bindings and one has `--locked` and the other
does not, the one with `--locked` will be preferred when locked and
the one without will be preferred when unlocked.
If there are two matching bindings and one has both a matching
`--input-device=<input>` and `--locked` and the other has neither, the
former will be preferred for both unlocked and locked.
This also refactors `get_active_binding` in `sway/input/keyboard.c`
to make it easier to read.
Diffstat (limited to 'sway')
| -rw-r--r-- | sway/commands/bind.c | 6 | ||||
| -rw-r--r-- | sway/input/keyboard.c | 43 | ||||
| -rw-r--r-- | sway/input/switch.c | 16 | ||||
| -rw-r--r-- | sway/sway.5.scd | 28 | 
4 files changed, 67 insertions, 26 deletions
| diff --git a/sway/commands/bind.c b/sway/commands/bind.c index ea8179bb..d43c87fb 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c @@ -49,6 +49,10 @@ static bool binding_switch_compare(struct sway_switch_binding *binding_a,  	if (binding_a->state != binding_b->state) {  		return false;  	} +	if ((binding_a->flags & BINDING_LOCKED) != +			(binding_b->flags & BINDING_LOCKED)) { +		return false; +	}  	return true;  } @@ -68,7 +72,7 @@ static bool binding_key_compare(struct sway_binding *binding_a,  	}  	uint32_t conflict_generating_flags = BINDING_RELEASE | BINDING_BORDER -			| BINDING_CONTENTS | BINDING_TITLEBAR; +			| BINDING_CONTENTS | BINDING_TITLEBAR | BINDING_LOCKED;  	if ((binding_a->flags & conflict_generating_flags) !=  			(binding_b->flags & conflict_generating_flags)) {  		return false; diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 78e8fa0c..dcfaa4fa 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -146,7 +146,7 @@ static void get_active_binding(const struct sway_shortcut_state *state,  		uint32_t modifiers, bool release, bool locked, const char *input) {  	for (int i = 0; i < bindings->length; ++i) {  		struct sway_binding *binding = bindings->items[i]; -		bool binding_locked = binding->flags & BINDING_LOCKED; +		bool binding_locked = (binding->flags & BINDING_LOCKED) != 0;  		bool binding_release = binding->flags & BINDING_RELEASE;  		if (modifiers ^ binding->modifiers || @@ -178,18 +178,37 @@ static void get_active_binding(const struct sway_shortcut_state *state,  			continue;  		} -		if (*current_binding && *current_binding != binding && -				strcmp((*current_binding)->input, binding->input) == 0) { -			sway_log(SWAY_DEBUG, "encountered duplicate bindings %d and %d", -					(*current_binding)->order, binding->order); -		} else if (!*current_binding || -				strcmp((*current_binding)->input, "*") == 0) { -			*current_binding = binding; - -			if (strcmp((*current_binding)->input, input) == 0) { -				// If a binding is found for the exact input, quit searching -				return; +		if (*current_binding) { +			if (*current_binding == binding) { +				continue;  			} + +			bool current_locked = +				((*current_binding)->flags & BINDING_LOCKED) != 0; +			bool current_input = strcmp((*current_binding)->input, input) == 0; +			bool binding_input = strcmp(binding->input, input) == 0; + +			if (current_input == binding_input +					&& current_locked == binding_locked) { +				sway_log(SWAY_DEBUG, +						"Encountered conflicting bindings %d and %d", +						(*current_binding)->order, binding->order); +				continue; +			} + +			if (current_input && !binding_input) { +				continue; // Prefer the correct input +			} + +			if (current_input == binding_input && current_locked == locked) { +				continue; // Prefer correct lock state for matching inputs +			} +		} + +		*current_binding = binding; +		if (strcmp((*current_binding)->input, input) == 0 && +				(((*current_binding)->flags & BINDING_LOCKED) == locked)) { +			return; // If a perfect match is found, quit searching  		}  	}  } diff --git a/sway/input/switch.c b/sway/input/switch.c index a8769713..d825c5c3 100644 --- a/sway/input/switch.c +++ b/sway/input/switch.c @@ -38,6 +38,7 @@ static void handle_switch_toggle(struct wl_listener *listener, void *data) {  	sway_log(SWAY_DEBUG, "%s: type %d state %d", device_identifier, type, state);  	list_t *bindings = config->current_mode->switch_bindings; +	struct sway_switch_binding *matched_binding = NULL;  	for (int i = 0; i < bindings->length; ++i) {  		struct sway_switch_binding *binding = bindings->items[i];  		if (binding->type != type) { @@ -52,10 +53,19 @@ static void handle_switch_toggle(struct wl_listener *listener, void *data) {  			continue;  		} -		struct sway_binding *dummy_binding = calloc(1, sizeof(struct sway_binding)); +		matched_binding = binding; + +		if (binding_locked == input_inhibited) { +			break; +		} +	} + +	if (matched_binding) { +		struct sway_binding *dummy_binding = +			calloc(1, sizeof(struct sway_binding));  		dummy_binding->type = BINDING_SWITCH; -		dummy_binding->flags = binding->flags; -		dummy_binding->command = binding->command; +		dummy_binding->flags = matched_binding->flags; +		dummy_binding->command = matched_binding->command;  		seat_execute_command(seat, dummy_binding);  		free(dummy_binding); diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 74963c9d..6d098d94 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -331,12 +331,17 @@ runtime.  	Binds _key combo_ to execute the sway command _command_ when pressed. You  	may use XKB key names here (*xev*(1) is a good tool for discovering these).  	With the flag _--release_, the command is executed when the key combo is -	released. Unless the flag _--locked_ is set, the command will not be run -	when a screen locking program is active. If _input-device_ is given, the -	binding will only be executed for that input device and will be executed -	instead of any binding that is generic to all devices. By default, if you -	overwrite a binding, swaynag will give you a warning. To silence this, use -	the _--no-warn_ flag. +	released. If _input-device_ is given, the binding will only be executed for +	that input device and will be executed instead of any binding that is +	generic to all devices. By default, if you overwrite a binding, swaynag +	will give you a warning. To silence this, use the _--no-warn_ flag. + +	Unless the flag _--locked_ is set, the command will not be run when a +	screen locking program is active. If there is a matching binding with +	and without _--locked_, the one with will be preferred when locked and the +	one without will be preferred when unlocked. If there are matching bindings +	and one has both _--input-device_ and _--locked_ and the other has neither, +	the former will be preferred even when unlocked.  	Bindings to keysyms are layout-dependent. This can be changed with the  	_--to-code_ flag. In this case, the keysyms will be translated into the @@ -380,10 +385,13 @@ runtime.  	respectively. _toggle_ is also supported to run a command both when the  	switch is toggled on or off. -	Unless the flag _--locked_ is set, the command will not be run -	when a screen locking program is active. By default, if you -	overwrite a binding, swaynag will give you a warning. To silence this, use -	the _--no-warn_ flag. +	Unless the flag _--locked_ is set, the command will not be run when a +	screen locking program is active. If there is a matching binding with +	and without _--locked_, the one with will be preferred when locked and the +	one without will be preferred when unlocked. + +	By default, if you overwrite a binding, swaynag will give you a warning. To +	silence this, use the _--no-warn_ flag.  	Example:  ``` | 
