mirror of
https://github.com/labwc/labwc.git
synced 2025-11-05 13:29:58 -05:00
<keybind key="W-d">
<action name="Execute">
<command>dmenu_run</command>
</action>
</keybind>
When using the keybind above (in rc.xml), on the first execution of W-d
all is okay, but the second time, a "d" pressed event is sent to dmenu
resulting in a continuous "ddddddd...") which has to be stopped pressing a
key.
This behaviour started in commit 7e57b7f because release events associated
with keybinds are no longer sent to clients (before that commit, the
release event for the “d” would have been passed to dmenu, thus cancelling
the repeat).
Solves issue #176
Helped-by: @spectrum70
71 lines
1.3 KiB
C
71 lines
1.3 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#define MAX_PRESSED_KEYS (16)
|
|
|
|
struct key_array {
|
|
uint32_t keys[MAX_PRESSED_KEYS];
|
|
int nr_keys;
|
|
};
|
|
|
|
static struct key_array pressed, bound;
|
|
|
|
static void
|
|
remove_key(struct key_array *array, uint32_t keycode)
|
|
{
|
|
bool shifting = false;
|
|
|
|
for (int i = 0; i < MAX_PRESSED_KEYS; ++i) {
|
|
if (array->keys[i] == keycode) {
|
|
--array->nr_keys;
|
|
shifting = true;
|
|
}
|
|
if (shifting) {
|
|
array->keys[i] = i < MAX_PRESSED_KEYS - 1
|
|
? array->keys[i + 1] : 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
add_key(struct key_array *array, uint32_t keycode)
|
|
{
|
|
array->keys[array->nr_keys++] = keycode;
|
|
}
|
|
|
|
void
|
|
key_state_set_pressed(uint32_t keycode, bool ispressed)
|
|
{
|
|
if (ispressed) {
|
|
add_key(&pressed, keycode);
|
|
} else {
|
|
remove_key(&pressed, keycode);
|
|
}
|
|
}
|
|
|
|
void
|
|
key_state_store_pressed_keys_as_bound(void)
|
|
{
|
|
memcpy(bound.keys, pressed.keys, MAX_PRESSED_KEYS * sizeof(uint32_t));
|
|
bound.nr_keys = pressed.nr_keys;
|
|
}
|
|
|
|
bool
|
|
key_state_corresponding_press_event_was_bound(uint32_t keycode)
|
|
{
|
|
for (int i = 0; i < bound.nr_keys; ++i) {
|
|
if (bound.keys[i] == keycode) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int
|
|
key_state_bound_key_remove(uint32_t keycode)
|
|
{
|
|
remove_key(&bound, keycode);
|
|
return bound.nr_keys;
|
|
}
|