diff --git a/src/libei-private.h b/src/libei-private.h index 4ad4aa1..bc404b0 100644 --- a/src/libei-private.h +++ b/src/libei-private.h @@ -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; diff --git a/src/libei.c b/src/libei.c index 7892c78..a1a11b8 100644 --- a/src/libei.c +++ b/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); diff --git a/src/libeis-device.c b/src/libeis-device.c index cf10ba5..2960946 100644 --- a/src/libeis-device.c +++ b/src/libeis-device.c @@ -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); } diff --git a/src/libeis-private.h b/src/libeis-private.h index 5e38cb9..94ec6ed 100644 --- a/src/libeis-private.h +++ b/src/libeis-private.h @@ -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; diff --git a/test/test-ei-device.c b/test/test-ei-device.c index 4c47d9d..46ef8fc 100644 --- a/test/test-ei-device.c +++ b/test/test-ei-device.c @@ -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);