mirror of
https://github.com/labwc/labwc.git
synced 2026-03-31 07:11:19 -04:00
Add onRelease option to <keybind>
...to make keybind actions fire on the release event rather then when the
key is first pressed. This is useful for binding actions to modifier keys
only. The most likely use-case for this is the binding of a Super key to a
menu, for example:
<keybind key="Super_L" onRelease="yes">
<action name="Execute" command="rofi -show drun"/>
</keybind>
If another keybind is issued between the press and release, the on-release
keybind is cancelled.
Co-authored-by: @johanmalm
This commit is contained in:
parent
f6c91c8d13
commit
84c222a84f
6 changed files with 51 additions and 5 deletions
|
|
@ -492,6 +492,23 @@ extending outward from the snapped edge.
|
||||||
If set to "no" (or is absent) the keybind will be layout agnostic.
|
If set to "no" (or is absent) the keybind will be layout agnostic.
|
||||||
Default is no.
|
Default is no.
|
||||||
|
|
||||||
|
*<keyboard><keybind key="" onRelease="yes|no">*
|
||||||
|
*onRelease*, when yes, fires the keybind action when the key or key
|
||||||
|
combination is released, rather than first pressed. This is useful to
|
||||||
|
bind actions to only modifier keys, where the action should fire when
|
||||||
|
the modifier is used without another key. Default is no.
|
||||||
|
|
||||||
|
The example below will trigger the launch of rofi when the super key is
|
||||||
|
pressed & released, without interference from other multi-key
|
||||||
|
combinations that include the super key:
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
<keybind key="Super_L" onRelease="yes">
|
||||||
|
<action name="Execute" command="rofi -show drun"/>
|
||||||
|
</keybind>
|
||||||
|
```
|
||||||
|
|
||||||
*<keyboard><keybind key=""><action name="">*
|
*<keyboard><keybind key=""><action name="">*
|
||||||
Keybind action. See labwc-actions(5).
|
Keybind action. See labwc-actions(5).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ struct keybind {
|
||||||
int keycodes_layout;
|
int keycodes_layout;
|
||||||
struct wl_list actions; /* struct action.link */
|
struct wl_list actions; /* struct action.link */
|
||||||
struct wl_list link; /* struct rcxml.keybinds */
|
struct wl_list link; /* struct rcxml.keybinds */
|
||||||
|
bool on_release;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ struct seat;
|
||||||
struct keyboard;
|
struct keyboard;
|
||||||
struct wlr_keyboard;
|
struct wlr_keyboard;
|
||||||
|
|
||||||
|
void keyboard_reset_current_keybind(void);
|
||||||
void keyboard_configure(struct seat *seat, struct wlr_keyboard *kb,
|
void keyboard_configure(struct seat *seat, struct wlr_keyboard *kb,
|
||||||
bool is_virtual);
|
bool is_virtual);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -403,6 +403,8 @@ fill_keybind(char *nodename, char *content)
|
||||||
} else if (!current_keybind) {
|
} else if (!current_keybind) {
|
||||||
wlr_log(WLR_ERROR, "expect <keybind key=\"\"> element first. "
|
wlr_log(WLR_ERROR, "expect <keybind key=\"\"> element first. "
|
||||||
"nodename: '%s' content: '%s'", nodename, content);
|
"nodename: '%s' content: '%s'", nodename, content);
|
||||||
|
} else if (!strcasecmp(nodename, "onRelease")) {
|
||||||
|
set_bool(content, ¤t_keybind->on_release);
|
||||||
} else if (!strcasecmp(nodename, "layoutDependent")) {
|
} else if (!strcasecmp(nodename, "layoutDependent")) {
|
||||||
set_bool(content, ¤t_keybind->use_syms_only);
|
set_bool(content, ¤t_keybind->use_syms_only);
|
||||||
} else if (!strcmp(nodename, "name.action")) {
|
} else if (!strcmp(nodename, "name.action")) {
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,15 @@ struct keyinfo {
|
||||||
|
|
||||||
static bool should_cancel_cycling_on_next_key_release;
|
static bool should_cancel_cycling_on_next_key_release;
|
||||||
|
|
||||||
|
static struct keybind *cur_keybind;
|
||||||
|
|
||||||
|
/* Called on --reconfigure to prevent segfault when handling release keybinds */
|
||||||
|
void
|
||||||
|
keyboard_reset_current_keybind(void)
|
||||||
|
{
|
||||||
|
cur_keybind = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
change_vt(struct server *server, unsigned int vt)
|
change_vt(struct server *server, unsigned int vt)
|
||||||
{
|
{
|
||||||
|
|
@ -407,7 +416,19 @@ handle_compositor_keybindings(struct keyboard *keyboard,
|
||||||
keyinfo.is_modifier);
|
keyinfo.is_modifier);
|
||||||
|
|
||||||
if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) {
|
||||||
return handle_key_release(server, event->keycode);
|
if (cur_keybind && cur_keybind->on_release) {
|
||||||
|
key_state_bound_key_remove(event->keycode);
|
||||||
|
if (seat->server->session_lock_manager->locked
|
||||||
|
|| seat->active_client_while_inhibited) {
|
||||||
|
cur_keybind = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
actions_run(NULL, server, &cur_keybind->actions, 0);
|
||||||
|
cur_keybind = NULL;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return handle_key_release(server, event->keycode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Catch C-A-F1 to C-A-F12 to change tty */
|
/* Catch C-A-F1 to C-A-F12 to change tty */
|
||||||
|
|
@ -443,16 +464,19 @@ handle_compositor_keybindings(struct keyboard *keyboard,
|
||||||
/*
|
/*
|
||||||
* Handle compositor keybinds
|
* Handle compositor keybinds
|
||||||
*/
|
*/
|
||||||
struct keybind *keybind =
|
cur_keybind = match_keybinding(server, &keyinfo, keyboard->is_virtual);
|
||||||
match_keybinding(server, &keyinfo, keyboard->is_virtual);
|
if (cur_keybind) {
|
||||||
if (keybind) {
|
|
||||||
/*
|
/*
|
||||||
* Update key-state before action_run() because the action
|
* Update key-state before action_run() because the action
|
||||||
* might lead to seat_focus() in which case we pass the
|
* might lead to seat_focus() in which case we pass the
|
||||||
* 'pressed-sent' keys to the new surface.
|
* 'pressed-sent' keys to the new surface.
|
||||||
*/
|
*/
|
||||||
key_state_store_pressed_key_as_bound(event->keycode);
|
key_state_store_pressed_key_as_bound(event->keycode);
|
||||||
actions_run(NULL, server, &keybind->actions, 0);
|
if (!cur_keybind->on_release) {
|
||||||
|
actions_run(NULL, server, &cur_keybind->actions, 0);
|
||||||
|
/* This cancels any pending on-release keybinds */
|
||||||
|
cur_keybind = NULL;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -592,6 +592,7 @@ seat_reconfigure(struct server *server)
|
||||||
struct input *input;
|
struct input *input;
|
||||||
cursor_reload(seat);
|
cursor_reload(seat);
|
||||||
overlay_reconfigure(seat);
|
overlay_reconfigure(seat);
|
||||||
|
keyboard_reset_current_keybind();
|
||||||
wl_list_for_each(input, &seat->inputs, link) {
|
wl_list_for_each(input, &seat->inputs, link) {
|
||||||
switch (input->wlr_input_device->type) {
|
switch (input->wlr_input_device->type) {
|
||||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue