mirror of
https://github.com/swaywm/sway.git
synced 2024-11-23 00:11:28 +00:00
Implement bindsym --release
This is a "simple" version of --release (same as i3) that only supports a binding that contain one normal key. e.g.: bindsym --release $mod+x exec somthing-fun I didn't bother implementing it for a combination like `$mod+x+z` since it is a bit tricky to get right and also a bit weird to actually do on a keyboard.
This commit is contained in:
parent
8f5de70c93
commit
55f63935ab
|
@ -22,6 +22,7 @@ struct sway_variable {
|
||||||
*/
|
*/
|
||||||
struct sway_binding {
|
struct sway_binding {
|
||||||
int order;
|
int order;
|
||||||
|
bool release;
|
||||||
list_t *keys;
|
list_t *keys;
|
||||||
uint32_t modifiers;
|
uint32_t modifiers;
|
||||||
char *command;
|
char *command;
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
// returns true if key has been pressed, otherwise false
|
// returns true if key has been pressed, otherwise false
|
||||||
bool check_key(uint32_t key_sym, uint32_t key_code);
|
bool check_key(uint32_t key_sym, uint32_t key_code);
|
||||||
|
|
||||||
|
// returns true if key_sym matches latest released key.
|
||||||
|
bool check_released_key(uint32_t key_sym);
|
||||||
|
|
||||||
// sets a key as pressed
|
// sets a key as pressed
|
||||||
void press_key(uint32_t key_sym, uint32_t key_code);
|
void press_key(uint32_t key_sym, uint32_t key_code);
|
||||||
|
|
||||||
|
|
|
@ -163,9 +163,25 @@ static struct cmd_results *cmd_bindsym(int argc, char **argv) {
|
||||||
return cmd_results_new(CMD_FAILURE, "bindsym", "Can only be used in config file.");
|
return cmd_results_new(CMD_FAILURE, "bindsym", "Can only be used in config file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct sway_binding *binding = malloc(sizeof(struct sway_binding));
|
struct sway_binding *binding = malloc(sizeof(struct sway_binding));
|
||||||
binding->keys = create_list();
|
binding->keys = create_list();
|
||||||
binding->modifiers = 0;
|
binding->modifiers = 0;
|
||||||
|
binding->release = false;
|
||||||
|
|
||||||
|
// Handle --release
|
||||||
|
if (strcmp("--release", argv[0]) == 0) {
|
||||||
|
if (argc >= 3) {
|
||||||
|
binding->release = true;
|
||||||
|
argv++;
|
||||||
|
argc--;
|
||||||
|
} else {
|
||||||
|
return cmd_results_new(CMD_FAILURE, "bindsym",
|
||||||
|
"Invalid bindsym command"
|
||||||
|
"(expected more than 2 arguments, got %d)", argc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
binding->command = join_args(argv + 1, argc - 1);
|
binding->command = join_args(argv + 1, argc - 1);
|
||||||
|
|
||||||
list_t *split = split_string(argv[0], "+");
|
list_t *split = split_string(argv[0], "+");
|
||||||
|
|
|
@ -336,6 +336,43 @@ static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit s
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool handle_bindsym(struct sway_binding *binding) {
|
||||||
|
bool match = false;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < binding->keys->length; ++i) {
|
||||||
|
xkb_keysym_t *key = binding->keys->items[i];
|
||||||
|
if ((match = check_key(*key, 0)) == false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
struct cmd_results *res = handle_command(binding->command);
|
||||||
|
if (res->status != CMD_SUCCESS) {
|
||||||
|
sway_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error);
|
||||||
|
}
|
||||||
|
free_cmd_results(res);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handle_bindsym_release(struct sway_binding *binding) {
|
||||||
|
if (binding->keys->length == 1) {
|
||||||
|
xkb_keysym_t *key = binding->keys->items[0];
|
||||||
|
if (check_released_key(*key)) {
|
||||||
|
struct cmd_results *res = handle_command(binding->command);
|
||||||
|
if (res->status != CMD_SUCCESS) {
|
||||||
|
sway_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error);
|
||||||
|
}
|
||||||
|
free_cmd_results(res);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers,
|
static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers,
|
||||||
uint32_t key, enum wlc_key_state state) {
|
uint32_t key, enum wlc_key_state state) {
|
||||||
|
@ -366,33 +403,6 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
|
||||||
release_key(sym, key);
|
release_key(sym, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < mode->bindings->length; ++i) {
|
|
||||||
struct sway_binding *binding = mode->bindings->items[i];
|
|
||||||
|
|
||||||
if ((modifiers->mods ^ binding->modifiers) == 0) {
|
|
||||||
bool match = false;
|
|
||||||
int j;
|
|
||||||
for (j = 0; j < binding->keys->length; ++j) {
|
|
||||||
xkb_keysym_t *key = binding->keys->items[j];
|
|
||||||
if ((match = check_key(*key, 0)) == false) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (match) {
|
|
||||||
if (state == WLC_KEY_STATE_PRESSED) {
|
|
||||||
struct cmd_results *res = handle_command(binding->command);
|
|
||||||
if (res->status != CMD_SUCCESS) {
|
|
||||||
sway_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error);
|
|
||||||
}
|
|
||||||
free_cmd_results(res);
|
|
||||||
return EVENT_HANDLED;
|
|
||||||
} else if (state == WLC_KEY_STATE_RELEASED) {
|
|
||||||
// TODO: --released
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle bar modifiers pressed/released
|
// handle bar modifiers pressed/released
|
||||||
uint32_t modifier;
|
uint32_t modifier;
|
||||||
for (i = 0; i < config->active_bar_modifiers->length; ++i) {
|
for (i = 0; i < config->active_bar_modifiers->length; ++i) {
|
||||||
|
@ -409,6 +419,27 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
|
||||||
}
|
}
|
||||||
// update modifiers state
|
// update modifiers state
|
||||||
modifiers_state_update(modifiers->mods);
|
modifiers_state_update(modifiers->mods);
|
||||||
|
|
||||||
|
// handle bindings
|
||||||
|
for (i = 0; i < mode->bindings->length; ++i) {
|
||||||
|
struct sway_binding *binding = mode->bindings->items[i];
|
||||||
|
if ((modifiers->mods ^ binding->modifiers) == 0) {
|
||||||
|
switch (state) {
|
||||||
|
case WLC_KEY_STATE_PRESSED: {
|
||||||
|
if (!binding->release && handle_bindsym(binding)) {
|
||||||
|
return EVENT_HANDLED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WLC_KEY_STATE_RELEASED:
|
||||||
|
if (binding->release && handle_bindsym_release(binding)) {
|
||||||
|
return EVENT_HANDLED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return EVENT_PASSTHROUGH;
|
return EVENT_PASSTHROUGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ struct key_state {
|
||||||
|
|
||||||
static struct key_state key_state_array[KEY_STATE_MAX_LENGTH];
|
static struct key_state key_state_array[KEY_STATE_MAX_LENGTH];
|
||||||
|
|
||||||
|
static struct key_state last_released;
|
||||||
|
|
||||||
static uint32_t modifiers_state;
|
static uint32_t modifiers_state;
|
||||||
|
|
||||||
void input_init(void) {
|
void input_init(void) {
|
||||||
|
@ -31,6 +33,9 @@ void input_init(void) {
|
||||||
key_state_array[i] = none;
|
key_state_array[i] = none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct key_state none = { 0, 0, 0 };
|
||||||
|
last_released = none;
|
||||||
|
|
||||||
modifiers_state = 0;
|
modifiers_state = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +81,12 @@ bool check_key(uint32_t key_sym, uint32_t key_code) {
|
||||||
return find_key(key_sym, key_code, false) < KEY_STATE_MAX_LENGTH;
|
return find_key(key_sym, key_code, false) < KEY_STATE_MAX_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_released_key(uint32_t key_sym) {
|
||||||
|
return (key_sym != 0
|
||||||
|
&& (last_released.key_sym == key_sym
|
||||||
|
|| last_released.alt_sym == key_sym));
|
||||||
|
}
|
||||||
|
|
||||||
void press_key(uint32_t key_sym, uint32_t key_code) {
|
void press_key(uint32_t key_sym, uint32_t key_code) {
|
||||||
if (key_code == 0) {
|
if (key_code == 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -94,6 +105,9 @@ void press_key(uint32_t key_sym, uint32_t key_code) {
|
||||||
void release_key(uint32_t key_sym, uint32_t key_code) {
|
void release_key(uint32_t key_sym, uint32_t key_code) {
|
||||||
uint8_t index = find_key(key_sym, key_code, true);
|
uint8_t index = find_key(key_sym, key_code, true);
|
||||||
if (index < KEY_STATE_MAX_LENGTH) {
|
if (index < KEY_STATE_MAX_LENGTH) {
|
||||||
|
last_released.key_sym = key_state_array[index].key_sym;
|
||||||
|
last_released.alt_sym = key_state_array[index].alt_sym;
|
||||||
|
last_released.key_code = key_state_array[index].key_code;
|
||||||
struct key_state none = { 0, 0, 0 };
|
struct key_state none = { 0, 0, 0 };
|
||||||
key_state_array[index] = none;
|
key_state_array[index] = none;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue