mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-05-06 14:08:03 +02:00
Filter empty frame events
We only need frame events after device events (pointer, touch, keyboard). In some cases, the library prevents an event from being written to the wire, e.g. if the coordinates are out of region, but the client will still call ei_device_frame() for that now-filtered event. Keep a boolean to remember if we have sent something that requires a frame event and filter accordingly. Note that this currently filters the *sender* side only, not the receiver side. A sender that gets an empty frame event onto the wire will still get that into the other side. This also doesn't handle the flushing of frame events before other events, ideally we should enforce a frame event before e.g. stop emulating.
This commit is contained in:
parent
35aca1a387
commit
a4dde7c35f
5 changed files with 91 additions and 2 deletions
|
|
@ -129,6 +129,8 @@ struct ei_device {
|
|||
char *name;
|
||||
enum ei_device_type type;
|
||||
|
||||
bool send_frame_event;
|
||||
|
||||
uint32_t width, height;
|
||||
|
||||
struct list regions;
|
||||
|
|
|
|||
27
src/libei.c
27
src/libei.c
|
|
@ -847,6 +847,11 @@ ei_send_frame(struct ei_device *device)
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
if (!device->send_frame_event)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = false;
|
||||
|
||||
int rc = ei->requests->frame(device);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -861,6 +866,8 @@ ei_send_pointer_rel(struct ei_device *device, double x, double y)
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
int rc = ei->requests->rel(device, x, y);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -875,6 +882,8 @@ ei_send_pointer_abs(struct ei_device *device, double x, double y)
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
int rc = ei->requests->abs(device, x, y);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -889,6 +898,8 @@ ei_send_pointer_button(struct ei_device *device, uint32_t button, bool is_press)
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
int rc = ei->requests->button(device, button, is_press);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -902,6 +913,8 @@ int ei_send_pointer_scroll(struct ei_device *device, double x, double y)
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
int rc = ei->requests->scroll(device, x, y);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -915,6 +928,8 @@ int ei_send_pointer_scroll_stop(struct ei_device *device, double x, double y)
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
int rc = ei->requests->scroll_stop(device, x, y);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -928,6 +943,8 @@ int ei_send_pointer_scroll_cancel(struct ei_device *device, double x, double y)
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
int rc = ei->requests->scroll_cancel(device, x, y);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -942,6 +959,8 @@ int ei_send_pointer_scroll_discrete(struct ei_device *device, int32_t x, int32_t
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
int rc = ei->requests->scroll_discrete(device, x, y);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -956,6 +975,8 @@ ei_send_keyboard_key(struct ei_device *device, uint32_t key, bool is_press)
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
int rc = ei->requests->key(device, key, is_press);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -971,6 +992,8 @@ ei_send_touch_down(struct ei_device *device, uint32_t tid,
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
int rc = ei->requests->touch_down(device, tid, x, y);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -986,6 +1009,8 @@ ei_send_touch_motion(struct ei_device *device, uint32_t tid,
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
int rc = ei->requests->touch_motion(device, tid, x, y);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
@ -1000,6 +1025,8 @@ ei_send_touch_up(struct ei_device *device, uint32_t tid)
|
|||
if (ei->state == EI_STATE_NEW || ei->state == EI_STATE_DISCONNECTED)
|
||||
return 0;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
int rc = ei->requests->touch_up(device, tid);
|
||||
if (rc)
|
||||
ei_disconnect(ei);
|
||||
|
|
|
|||
|
|
@ -343,6 +343,8 @@ eis_device_pointer_motion(struct eis_device *device,
|
|||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
handle_request(device, rel, x, y);
|
||||
}
|
||||
|
||||
|
|
@ -366,6 +368,8 @@ eis_device_pointer_motion_absolute(struct eis_device *device,
|
|||
}
|
||||
}
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
handle_request(device, abs, x, y);
|
||||
}
|
||||
|
||||
|
|
@ -390,6 +394,8 @@ eis_device_pointer_button(struct eis_device *device,
|
|||
return;
|
||||
}
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
handle_request(device, button, button, is_press);
|
||||
}
|
||||
|
||||
|
|
@ -421,6 +427,8 @@ eis_device_pointer_scroll(struct eis_device *device,
|
|||
|
||||
eis_device_resume_scrolling(device, x, y);
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
handle_request(device, scroll, x, y);
|
||||
}
|
||||
|
||||
|
|
@ -446,8 +454,10 @@ eis_device_pointer_scroll_stop(struct eis_device *device, bool x, bool y)
|
|||
else
|
||||
y = false;
|
||||
|
||||
if (x || y)
|
||||
if (x || y) {
|
||||
device->send_frame_event = true;
|
||||
handle_request(device, scroll_stop, x, y, false);
|
||||
}
|
||||
}
|
||||
|
||||
_public_ void
|
||||
|
|
@ -476,8 +486,10 @@ eis_device_pointer_scroll_cancel(struct eis_device *device, bool x, bool y)
|
|||
y = false;
|
||||
}
|
||||
|
||||
if (x || y)
|
||||
if (x || y) {
|
||||
device->send_frame_event = true;
|
||||
handle_request(device, scroll_stop, x, y, true);
|
||||
}
|
||||
}
|
||||
|
||||
_public_ void
|
||||
|
|
@ -495,6 +507,8 @@ eis_device_pointer_scroll_discrete(struct eis_device *device,
|
|||
|
||||
eis_device_resume_scrolling(device, x, y);
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
handle_request(device, scroll_discrete, x, y);
|
||||
}
|
||||
|
||||
|
|
@ -511,6 +525,8 @@ eis_device_keyboard_key(struct eis_device *device,
|
|||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return;
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
handle_request(device, key, key, is_press);
|
||||
}
|
||||
|
||||
|
|
@ -578,6 +594,7 @@ eis_touch_down(struct eis_touch *touch, double x, double y)
|
|||
}
|
||||
|
||||
touch->state = TOUCH_IS_DOWN;
|
||||
device->send_frame_event = true;
|
||||
|
||||
handle_request(device, touch_down, touch->tracking_id, x, y);
|
||||
}
|
||||
|
|
@ -599,6 +616,8 @@ eis_touch_motion(struct eis_touch *touch, double x, double y)
|
|||
}
|
||||
}
|
||||
|
||||
device->send_frame_event = true;
|
||||
|
||||
handle_request(device, touch_motion, touch->tracking_id, x, y);
|
||||
}
|
||||
|
||||
|
|
@ -614,6 +633,7 @@ eis_touch_up(struct eis_touch *touch)
|
|||
}
|
||||
|
||||
touch->state = TOUCH_IS_UP;
|
||||
device->send_frame_event = true;
|
||||
|
||||
handle_request(device, touch_up, touch->tracking_id);
|
||||
}
|
||||
|
|
@ -624,6 +644,12 @@ eis_device_frame(struct eis_device *device)
|
|||
if (device->state != EIS_DEVICE_STATE_EMULATING)
|
||||
return;
|
||||
|
||||
if (!device->send_frame_event)
|
||||
return;
|
||||
|
||||
device->send_frame_event = false;
|
||||
|
||||
|
||||
handle_request_noargs(device, frame);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -142,6 +142,8 @@ struct eis_device {
|
|||
|
||||
struct eis_keymap *keymap;
|
||||
|
||||
bool send_frame_event;
|
||||
|
||||
struct {
|
||||
bool x_is_stopped, y_is_stopped;
|
||||
bool x_is_cancelled, y_is_cancelled;
|
||||
|
|
|
|||
|
|
@ -1148,6 +1148,38 @@ MUNIT_TEST(test_ei_keyboard_modifiers)
|
|||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_ei_no_empty_frames)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new();
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_RESUME_DEVICE);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES);
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_client(peck) {
|
||||
struct ei_device *device = peck_ei_get_default_keyboard(peck);
|
||||
ei_device_frame(device); /* Expect to be filtered */
|
||||
ei_device_keyboard_key(device, KEY_Q, true);
|
||||
ei_device_frame(device);
|
||||
ei_device_frame(device); /* Expect to be filtered */
|
||||
}
|
||||
|
||||
peck_dispatch_until_stable(peck);
|
||||
|
||||
with_server(peck) {
|
||||
_unref_(eis_event) *kbd =
|
||||
peck_eis_next_event(eis, EIS_EVENT_KEYBOARD_KEY);
|
||||
_unref_(eis_event) *frame =
|
||||
peck_eis_next_event(eis, EIS_EVENT_FRAME);
|
||||
peck_assert_no_eis_events(eis);
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
MUNIT_TEST(test_passive_ei_device_start_stop_emulating)
|
||||
{
|
||||
_unref_(peck) *peck = peck_new_context(PECK_EI_RECEIVER);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue