mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-01-08 08:10:14 +01:00
evdev: Keep track of button/key press count per device
Keep track of the number of times a given button or key is pressed on a device. For regular mouse devices or keyboard devices, such a count will never exceed 1, but counting button presses could help when button presses with the same code can originate from different sources. One could for example implement overlapping tap-drags with button presses by having them deal with their own life-time independently, sorting out when the user should receive button presses or not depending on the pressed count. Signed-off-by: Jonas Ådahl <jadahl@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
c8017595fc
commit
3a3d70a3a8
4 changed files with 91 additions and 22 deletions
|
|
@ -607,11 +607,12 @@ tp_post_clickfinger_buttons(struct tp_dispatch *tp, uint64_t time)
|
|||
state = LIBINPUT_BUTTON_STATE_RELEASED;
|
||||
}
|
||||
|
||||
if (button)
|
||||
pointer_notify_button(&tp->device->base,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
if (button) {
|
||||
evdev_pointer_notify_button(tp->device,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -633,10 +634,10 @@ tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time)
|
|||
else
|
||||
state = LIBINPUT_BUTTON_STATE_RELEASED;
|
||||
|
||||
pointer_notify_button(&tp->device->base,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
evdev_pointer_notify_button(tp->device,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
}
|
||||
|
||||
button++;
|
||||
|
|
@ -708,11 +709,12 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time)
|
|||
|
||||
tp->buttons.click_pending = false;
|
||||
|
||||
if (button)
|
||||
pointer_notify_button(&tp->device->base,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
if (button) {
|
||||
evdev_pointer_notify_button(tp->device,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,10 +113,10 @@ tp_tap_notify(struct tp_dispatch *tp,
|
|||
return;
|
||||
}
|
||||
|
||||
pointer_notify_button(&tp->device->base,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
evdev_pointer_notify_button(tp->device,
|
||||
time,
|
||||
button,
|
||||
state);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
60
src/evdev.c
60
src/evdev.c
|
|
@ -59,6 +59,58 @@ is_key_down(struct evdev_device *device, int code)
|
|||
return long_bit_is_set(device->key_mask, code);
|
||||
}
|
||||
|
||||
static int
|
||||
update_key_down_count(struct evdev_device *device, int code, int pressed)
|
||||
{
|
||||
int key_count;
|
||||
assert(code >= 0 && code < KEY_CNT);
|
||||
|
||||
if (pressed) {
|
||||
key_count = ++device->key_count[code];
|
||||
} else {
|
||||
assert(device->key_count[code] > 0);
|
||||
key_count = --device->key_count[code];
|
||||
}
|
||||
|
||||
if (key_count > 32) {
|
||||
log_bug_libinput(device->base.seat->libinput,
|
||||
"Key count for %s reached abnormal values\n",
|
||||
libevdev_event_code_get_name(EV_KEY, code));
|
||||
}
|
||||
|
||||
return key_count;
|
||||
}
|
||||
|
||||
void
|
||||
evdev_keyboard_notify_key(struct evdev_device *device,
|
||||
uint32_t time,
|
||||
int key,
|
||||
enum libinput_key_state state)
|
||||
{
|
||||
int down_count;
|
||||
|
||||
down_count = update_key_down_count(device, key, state);
|
||||
|
||||
if ((state == LIBINPUT_KEY_STATE_PRESSED && down_count == 1) ||
|
||||
(state == LIBINPUT_KEY_STATE_RELEASED && down_count == 0))
|
||||
keyboard_notify_key(&device->base, time, key, state);
|
||||
}
|
||||
|
||||
void
|
||||
evdev_pointer_notify_button(struct evdev_device *device,
|
||||
uint32_t time,
|
||||
int button,
|
||||
enum libinput_button_state state)
|
||||
{
|
||||
int down_count;
|
||||
|
||||
down_count = update_key_down_count(device, button, state);
|
||||
|
||||
if ((state == LIBINPUT_BUTTON_STATE_PRESSED && down_count == 1) ||
|
||||
(state == LIBINPUT_BUTTON_STATE_RELEASED && down_count == 0))
|
||||
pointer_notify_button(&device->base, time, button, state);
|
||||
}
|
||||
|
||||
void
|
||||
evdev_device_led_update(struct evdev_device *device, enum libinput_led leds)
|
||||
{
|
||||
|
|
@ -341,16 +393,16 @@ evdev_process_key(struct evdev_device *device,
|
|||
case EVDEV_KEY_TYPE_NONE:
|
||||
break;
|
||||
case EVDEV_KEY_TYPE_KEY:
|
||||
keyboard_notify_key(
|
||||
&device->base,
|
||||
evdev_keyboard_notify_key(
|
||||
device,
|
||||
time,
|
||||
e->code,
|
||||
e->value ? LIBINPUT_KEY_STATE_PRESSED :
|
||||
LIBINPUT_KEY_STATE_RELEASED);
|
||||
break;
|
||||
case EVDEV_KEY_TYPE_BUTTON:
|
||||
pointer_notify_button(
|
||||
&device->base,
|
||||
evdev_pointer_notify_button(
|
||||
device,
|
||||
time,
|
||||
e->code,
|
||||
e->value ? LIBINPUT_BUTTON_STATE_PRESSED :
|
||||
|
|
|
|||
15
src/evdev.h
15
src/evdev.h
|
|
@ -99,6 +99,9 @@ struct evdev_device {
|
|||
/* Bitmask of pressed keys used to ignore initial release events from
|
||||
* the kernel. */
|
||||
unsigned long key_mask[NLONGS(KEY_CNT)];
|
||||
/* Key counter used for multiplexing button events internally in
|
||||
* libinput. */
|
||||
uint8_t key_count[KEY_CNT];
|
||||
};
|
||||
|
||||
#define EVDEV_UNHANDLED_DEVICE ((struct evdev_device *) 1)
|
||||
|
|
@ -177,6 +180,18 @@ evdev_device_transform_y(struct evdev_device *device,
|
|||
double y,
|
||||
uint32_t height);
|
||||
|
||||
void
|
||||
evdev_keyboard_notify_key(struct evdev_device *device,
|
||||
uint32_t time,
|
||||
int key,
|
||||
enum libinput_key_state state);
|
||||
|
||||
void
|
||||
evdev_pointer_notify_button(struct evdev_device *device,
|
||||
uint32_t time,
|
||||
int button,
|
||||
enum libinput_button_state state);
|
||||
|
||||
void
|
||||
evdev_device_remove(struct evdev_device *device);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue