mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-01-11 00:20:16 +01:00
eis: quietly ignore double key presses and releases
This is only implemented on the EIS side of things because that side is mostly what we want to protect (read: the compositors). The duplicates are still sent on the protocol. Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/368>
This commit is contained in:
parent
65c0b39c3e
commit
84c23989e9
3 changed files with 58 additions and 0 deletions
|
|
@ -428,6 +428,13 @@ client_msg_button(struct eis_button *button, uint32_t btn, uint32_t state)
|
|||
"Button event for non-button device");
|
||||
}
|
||||
|
||||
if (btn >= KEY_CNT)
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Button event for invalid button %x (KEY_CNT is %#x)", btn, KEY_CNT);
|
||||
|
||||
if (!eis_device_update_key_button_state(device, btn, state))
|
||||
return NULL;
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
eis_queue_pointer_button_event(device, btn, !!state);
|
||||
return NULL;
|
||||
|
|
@ -598,6 +605,13 @@ client_msg_keyboard_key(struct eis_keyboard *keyboard, uint32_t key, uint32_t st
|
|||
"Key event for non-keyboard device");
|
||||
}
|
||||
|
||||
if (key >= KEY_CNT)
|
||||
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Key event for invalid key %x (KEY_CNT is %#x)", key, KEY_CNT);
|
||||
|
||||
if (!eis_device_update_key_button_state(device, key, state))
|
||||
return NULL;
|
||||
|
||||
if (device->state == EIS_DEVICE_STATE_EMULATING) {
|
||||
eis_queue_keyboard_key_event(device, key, !!state);
|
||||
return NULL;
|
||||
|
|
@ -1447,6 +1461,8 @@ eis_device_pause(struct eis_device *device)
|
|||
|
||||
device->state = EIS_DEVICE_STATE_PAUSED;
|
||||
eis_device_event_paused(device, eis_client_get_next_serial(client));
|
||||
|
||||
memset(device->key_button_state.down, 0, sizeof(device->key_button_state.down));
|
||||
}
|
||||
|
||||
_public_ void
|
||||
|
|
|
|||
|
|
@ -26,10 +26,14 @@
|
|||
|
||||
#include "libeis.h"
|
||||
|
||||
#include "util-bits.h"
|
||||
#include "util-object.h"
|
||||
#include "util-list.h"
|
||||
#include "brei-shared.h"
|
||||
|
||||
#define KEY_MAX 0x2ffU
|
||||
#define KEY_CNT (KEY_MAX + 1)
|
||||
|
||||
enum eis_device_state {
|
||||
EIS_DEVICE_STATE_NEW,
|
||||
EIS_DEVICE_STATE_AWAITING_READY,
|
||||
|
|
@ -75,6 +79,9 @@ struct eis_device {
|
|||
bool x_is_cancelled, y_is_cancelled;
|
||||
} scroll_state;
|
||||
|
||||
struct {
|
||||
unsigned char down[NCHARS(KEY_CNT)];
|
||||
} key_button_state;
|
||||
};
|
||||
|
||||
struct eis_touch {
|
||||
|
|
@ -118,6 +125,21 @@ OBJECT_DECLARE_GETTER(eis_device, button_interface, const struct eis_button_inte
|
|||
OBJECT_DECLARE_GETTER(eis_device, keyboard_interface, const struct eis_keyboard_interface *);
|
||||
OBJECT_DECLARE_GETTER(eis_device, touchscreen_interface, const struct eis_touchscreen_interface *);
|
||||
|
||||
static inline bool
|
||||
eis_device_update_key_button_state(struct eis_device *device, uint32_t key_btn, uint32_t state)
|
||||
{
|
||||
if (state) {
|
||||
if (bit_is_set(device->key_button_state.down, key_btn))
|
||||
return false;
|
||||
set_bit(device->key_button_state.down, key_btn);
|
||||
} else {
|
||||
if (!bit_is_set(device->key_button_state.down, key_btn))
|
||||
return false;
|
||||
clear_bit(device->key_button_state.down, key_btn);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
eis_device_set_client_keymap(struct eis_device *device,
|
||||
enum eis_keymap_type type,
|
||||
|
|
|
|||
|
|
@ -390,10 +390,20 @@ MUNIT_TEST(test_ei_device_button_button)
|
|||
struct ei_device *device = peck_ei_get_default_pointer(peck);
|
||||
ei_device_button_button(device, BTN_LEFT, true);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
/* double press is quietly ignored */
|
||||
ei_device_button_button(device, BTN_LEFT, true);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
ei_device_button_button(device, BTN_RIGHT, true);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
ei_device_button_button(device, BTN_RIGHT, false);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
/* double release is quietly ignored */
|
||||
ei_device_button_button(device, BTN_RIGHT, false);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
ei_device_button_button(device, BTN_LEFT, false);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
|
@ -421,6 +431,7 @@ MUNIT_TEST(test_ei_device_button_button)
|
|||
munit_assert_int(eis_event_button_get_button(lu), ==, BTN_LEFT);
|
||||
munit_assert_false(eis_event_button_get_is_press(lu));
|
||||
|
||||
peck_assert_no_eis_events(eis);
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
|
|
@ -439,6 +450,15 @@ MUNIT_TEST(test_ei_device_keyboard_key)
|
|||
struct ei_device *device = peck_ei_get_default_keyboard(peck);
|
||||
ei_device_keyboard_key(device, KEY_Q, true);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
/* Double press is quietly ignored */
|
||||
ei_device_keyboard_key(device, KEY_Q, true);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
ei_device_keyboard_key(device, KEY_Q, false);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
|
||||
/* Double release is quietly ignored */
|
||||
ei_device_keyboard_key(device, KEY_Q, false);
|
||||
ei_device_frame(device, peck_ei_now(peck));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue