From e617da03789d5a31abae355a610e6a0884ee518b Mon Sep 17 00:00:00 2001 From: random human Date: Fri, 14 Jun 2019 22:24:03 +0000 Subject: [PATCH] backend, virtual_keyboard: set the time_nsec field of relevant events Backends modified: libinput (with microsecond precision), X11 (with millisecond precision), RDP (with millisecond precision), and Wayland (with nanosecond precision if the host server supports the input-timestamps protocol, otherwise millisecond precision); and virtual-keyboard protocol (with millisecond precision). --- backend/libinput/keyboard.c | 5 +- backend/libinput/pointer.c | 20 +++-- backend/libinput/touch.c | 20 +++-- backend/rdp/peer.c | 12 ++- backend/wayland/backend.c | 9 +++ backend/wayland/wl_seat.c | 134 +++++++++++++++++++++++++++----- backend/x11/input_device.c | 4 + include/backend/wayland.h | 5 ++ types/wlr_virtual_keyboard_v1.c | 1 + 9 files changed, 172 insertions(+), 38 deletions(-) diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index 93605e778..67d6c1774 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -65,8 +65,9 @@ void handle_keyboard_key(struct libinput_event *event, struct libinput_event_keyboard *kbevent = libinput_event_get_keyboard_event(event); struct wlr_event_keyboard_key wlr_event = { 0 }; - wlr_event.time_msec = - usec_to_msec(libinput_event_keyboard_get_time_usec(kbevent)); + uint64_t event_time = libinput_event_keyboard_get_time_usec(kbevent); + wlr_event.time_msec = usec_to_msec(event_time); + wlr_event.time_nsec = event_time * 1000; wlr_event.keycode = libinput_event_keyboard_get_key(kbevent); enum libinput_key_state state = libinput_event_keyboard_get_key_state(kbevent); diff --git a/backend/libinput/pointer.c b/backend/libinput/pointer.c index 2e799df63..b4b46bbb5 100644 --- a/backend/libinput/pointer.c +++ b/backend/libinput/pointer.c @@ -32,8 +32,9 @@ void handle_pointer_motion(struct libinput_event *event, libinput_event_get_pointer_event(event); struct wlr_event_pointer_motion wlr_event = { 0 }; wlr_event.device = wlr_dev; - wlr_event.time_msec = - usec_to_msec(libinput_event_pointer_get_time_usec(pevent)); + uint64_t event_time = libinput_event_pointer_get_time_usec(pevent); + wlr_event.time_msec = usec_to_msec(event_time); + wlr_event.time_nsec = event_time * 1000; wlr_event.delta_x = libinput_event_pointer_get_dx(pevent); wlr_event.delta_y = libinput_event_pointer_get_dy(pevent); wlr_event.unaccel_dx = libinput_event_pointer_get_dx_unaccelerated(pevent); @@ -54,8 +55,9 @@ void handle_pointer_motion_abs(struct libinput_event *event, libinput_event_get_pointer_event(event); struct wlr_event_pointer_motion_absolute wlr_event = { 0 }; wlr_event.device = wlr_dev; - wlr_event.time_msec = - usec_to_msec(libinput_event_pointer_get_time_usec(pevent)); + uint64_t event_time = libinput_event_pointer_get_time_usec(pevent); + wlr_event.time_msec = usec_to_msec(event_time); + wlr_event.time_nsec = event_time * 1000; wlr_event.x = libinput_event_pointer_get_absolute_x_transformed(pevent, 1); wlr_event.y = libinput_event_pointer_get_absolute_y_transformed(pevent, 1); wlr_signal_emit_safe(&wlr_dev->pointer->events.motion_absolute, &wlr_event); @@ -74,8 +76,9 @@ void handle_pointer_button(struct libinput_event *event, libinput_event_get_pointer_event(event); struct wlr_event_pointer_button wlr_event = { 0 }; wlr_event.device = wlr_dev; - wlr_event.time_msec = - usec_to_msec(libinput_event_pointer_get_time_usec(pevent)); + uint64_t event_time = libinput_event_pointer_get_time_usec(pevent); + wlr_event.time_msec = usec_to_msec(event_time); + wlr_event.time_nsec = event_time * 1000; wlr_event.button = libinput_event_pointer_get_button(pevent); switch (libinput_event_pointer_get_button_state(pevent)) { case LIBINPUT_BUTTON_STATE_PRESSED: @@ -101,8 +104,9 @@ void handle_pointer_axis(struct libinput_event *event, libinput_event_get_pointer_event(event); struct wlr_event_pointer_axis wlr_event = { 0 }; wlr_event.device = wlr_dev; - wlr_event.time_msec = - usec_to_msec(libinput_event_pointer_get_time_usec(pevent)); + uint64_t event_time = libinput_event_pointer_get_time_usec(pevent); + wlr_event.time_msec = usec_to_msec(event_time); + wlr_event.time_nsec = event_time * 1000; switch (libinput_event_pointer_get_axis_source(pevent)) { case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: wlr_event.source = WLR_AXIS_SOURCE_WHEEL; diff --git a/backend/libinput/touch.c b/backend/libinput/touch.c index cb9b0e362..a039e49fa 100644 --- a/backend/libinput/touch.c +++ b/backend/libinput/touch.c @@ -32,8 +32,9 @@ void handle_touch_down(struct libinput_event *event, libinput_event_get_touch_event(event); struct wlr_event_touch_down wlr_event = { 0 }; wlr_event.device = wlr_dev; - wlr_event.time_msec = - usec_to_msec(libinput_event_touch_get_time_usec(tevent)); + uint64_t event_time = libinput_event_touch_get_time_usec(tevent); + wlr_event.time_msec = usec_to_msec(event_time); + wlr_event.time_nsec = event_time * 1000; wlr_event.touch_id = libinput_event_touch_get_slot(tevent); wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1); wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1); @@ -52,8 +53,9 @@ void handle_touch_up(struct libinput_event *event, libinput_event_get_touch_event(event); struct wlr_event_touch_up wlr_event = { 0 }; wlr_event.device = wlr_dev; - wlr_event.time_msec = - usec_to_msec(libinput_event_touch_get_time_usec(tevent)); + uint64_t event_time = libinput_event_touch_get_time_usec(tevent); + wlr_event.time_msec = usec_to_msec(event_time); + wlr_event.time_nsec = event_time * 1000; wlr_event.touch_id = libinput_event_touch_get_slot(tevent); wlr_signal_emit_safe(&wlr_dev->touch->events.up, &wlr_event); } @@ -70,8 +72,9 @@ void handle_touch_motion(struct libinput_event *event, libinput_event_get_touch_event(event); struct wlr_event_touch_motion wlr_event = { 0 }; wlr_event.device = wlr_dev; - wlr_event.time_msec = - usec_to_msec(libinput_event_touch_get_time_usec(tevent)); + uint64_t event_time = libinput_event_touch_get_time_usec(tevent); + wlr_event.time_msec = usec_to_msec(event_time); + wlr_event.time_nsec = event_time * 1000; wlr_event.touch_id = libinput_event_touch_get_slot(tevent); wlr_event.x = libinput_event_touch_get_x_transformed(tevent, 1); wlr_event.y = libinput_event_touch_get_y_transformed(tevent, 1); @@ -90,8 +93,9 @@ void handle_touch_cancel(struct libinput_event *event, libinput_event_get_touch_event(event); struct wlr_event_touch_cancel wlr_event = { 0 }; wlr_event.device = wlr_dev; - wlr_event.time_msec = - usec_to_msec(libinput_event_touch_get_time_usec(tevent)); + uint64_t event_time = libinput_event_touch_get_time_usec(tevent); + wlr_event.time_msec = usec_to_msec(event_time); + wlr_event.time_nsec = event_time * 1000; wlr_event.touch_id = libinput_event_touch_get_slot(tevent); wlr_signal_emit_safe(&wlr_dev->touch->events.cancel, &wlr_event); } diff --git a/backend/rdp/peer.c b/backend/rdp/peer.c index 350a4721d..fcbd2e65c 100644 --- a/backend/rdp/peer.c +++ b/backend/rdp/peer.c @@ -87,8 +87,11 @@ static int xf_input_synchronize_event(rdpInput *input, UINT32 flags) { return true; } -static inline int64_t timespec_to_msec(const struct timespec *a) { - return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; +static inline uint32_t timespec_to_msec(const struct timespec *a) { + return (uint32_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; +} +static inline uint64_t timespec_to_nsec(const struct timespec *a) { + return (uint64_t)a->tv_sec * 1000000000 + a->tv_nsec; } static int xf_input_mouse_event(rdpInput *input, @@ -105,6 +108,7 @@ static int xf_input_mouse_event(rdpInput *input, struct wlr_event_pointer_motion_absolute event = { 0 }; event.device = wlr_device; event.time_msec = timespec_to_msec(&now); + event.time_nsec = timespec_to_nsec(&now); event.x = x / (double)context->output->wlr_output.width; event.y = y / (double)context->output->wlr_output.height; wlr_signal_emit_safe(&pointer->events.motion_absolute, &event); @@ -124,6 +128,7 @@ static int xf_input_mouse_event(rdpInput *input, struct wlr_event_pointer_button event = { 0 }; event.device = wlr_device; event.time_msec = timespec_to_msec(&now); + event.time_nsec = timespec_to_nsec(&now); event.button = button; event.state = (flags & PTR_FLAGS_DOWN) ? WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED; @@ -139,6 +144,7 @@ static int xf_input_mouse_event(rdpInput *input, struct wlr_event_pointer_axis event = { 0 }; event.device = &context->pointer->wlr_input_device; event.time_msec = timespec_to_msec(&now); + event.time_nsec = timespec_to_nsec(&now); event.source = WLR_AXIS_SOURCE_WHEEL; event.orientation = WLR_AXIS_ORIENTATION_VERTICAL; event.delta = value; @@ -165,6 +171,7 @@ static int xf_input_extended_mouse_event( struct wlr_event_pointer_motion_absolute event = { 0 }; event.device = wlr_device; event.time_msec = timespec_to_msec(&now); + event.time_nsec = timespec_to_nsec(&now); event.x = x / (double)context->output->wlr_output.width; event.y = y / (double)context->output->wlr_output.height; wlr_signal_emit_safe(&pointer->events.motion_absolute, &event); @@ -207,6 +214,7 @@ static int xf_input_keyboard_event(rdpInput *input, UINT16 flags, UINT16 code) { vk_code, KEYCODE_TYPE_EVDEV); struct wlr_event_keyboard_key event = { 0 }; event.time_msec = timespec_to_msec(&now); + event.time_nsec = timespec_to_nsec(&now); event.keycode = scan_code - 8; event.state = state; event.update_state = true; diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index 25feb6fb6..505aa44da 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -16,6 +16,7 @@ #include "backend/wayland.h" #include "util/signal.h" +#include "input-timestamps-unstable-v1-client-protocol.h" #include "xdg-decoration-unstable-v1-client-protocol.h" #include "pointer-gestures-unstable-v1-client-protocol.h" #include "xdg-shell-client-protocol.h" @@ -81,6 +82,9 @@ static void registry_global(void *data, struct wl_registry *registry, } else if (strcmp(iface, zwp_pointer_gestures_v1_interface.name) == 0) { wl->zwp_pointer_gestures_v1 = wl_registry_bind(registry, name, &zwp_pointer_gestures_v1_interface, 1); + } else if (strcmp(iface, zwp_input_timestamps_manager_v1_interface.name) == 0) { + wl->input_timestamps.manager = wl_registry_bind(registry, name, + &zwp_input_timestamps_manager_v1_interface, 1); } } @@ -227,6 +231,11 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display, goto error_registry; } + if (!wl->input_timestamps.manager) { + wlr_log(WLR_INFO, + "Remote Wayland compositor does not support input-timestamps"); + } + struct wl_event_loop *loop = wl_display_get_event_loop(wl->local_display); int fd = wl_display_get_fd(wl->remote_display); int events = WL_EVENT_READABLE | WL_EVENT_ERROR | WL_EVENT_HANGUP; diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index 96c083edb..6b5f0ac11 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -1,6 +1,7 @@ #define _POSIX_C_SOURCE 200809L #include +#include #include #include #include @@ -18,6 +19,7 @@ #include "pointer-gestures-unstable-v1-client-protocol.h" #include "backend/wayland.h" #include "util/signal.h" +#include "input-timestamps-unstable-v1-client-protocol.h" static struct wlr_wl_pointer *output_get_pointer(struct wlr_wl_output *output) { struct wlr_input_device *wlr_dev; @@ -34,6 +36,15 @@ static struct wlr_wl_pointer *output_get_pointer(struct wlr_wl_output *output) { return NULL; } +static inline uint32_t timespec_to_msec(const struct timespec *a) { + assert((unsigned long)a->tv_sec < UINT32_MAX / 1000 && + "struct timespec value too big"); + return (uint32_t)a->tv_sec * 1000 + a->tv_nsec / 1000000; +} +static inline uint64_t timespec_to_nsec(const struct timespec *a) { + return (uint64_t)a->tv_sec * 1000000000 + a->tv_nsec; +} + static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy) { @@ -78,10 +89,19 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, return; } + uint64_t time_nsec; + if (backend->input_timestamps.manager && + backend->input_timestamps.pointer.tv_sec == time / 1000) { + time_nsec = timespec_to_nsec(&backend->input_timestamps.pointer); + } else { + time_nsec = (time % 1000) * 1000000; + } + struct wlr_output *wlr_output = &pointer->output->wlr_output; struct wlr_event_pointer_motion_absolute event = { .device = &pointer->input_device->wlr_input_device, .time_msec = time, + .time_nsec = time_nsec, .x = wl_fixed_to_double(sx) / wlr_output->width, .y = wl_fixed_to_double(sy) / wlr_output->height, }; @@ -96,11 +116,20 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, return; } + uint64_t time_nsec; + if (backend->input_timestamps.manager && + backend->input_timestamps.pointer.tv_sec == time / 1000) { + time_nsec = timespec_to_nsec(&backend->input_timestamps.pointer); + } else { + time_nsec = (time % 1000) * 1000000; + } + struct wlr_event_pointer_button event = { .device = &pointer->input_device->wlr_input_device, .button = button, .state = state, .time_msec = time, + .time_nsec = time_nsec, }; wlr_signal_emit_safe(&pointer->wlr_pointer.events.button, &event); } @@ -113,12 +142,21 @@ static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, return; } + uint64_t time_nsec; + if (backend->input_timestamps.manager && + backend->input_timestamps.pointer.tv_sec == time / 1000) { + time_nsec = timespec_to_nsec(&backend->input_timestamps.pointer); + } else { + time_nsec = (time % 1000) * 1000000; + } + struct wlr_event_pointer_axis event = { .device = &pointer->input_device->wlr_input_device, .delta = wl_fixed_to_double(value), .delta_discrete = pointer->axis_discrete, .orientation = axis, .time_msec = time, + .time_nsec = time_nsec, .source = pointer->axis_source, }; wlr_signal_emit_safe(&pointer->wlr_pointer.events.axis, &event); @@ -156,12 +194,21 @@ static void pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer, return; } + uint64_t time_nsec; + if (backend->input_timestamps.manager && + backend->input_timestamps.pointer.tv_sec == time / 1000) { + time_nsec = timespec_to_nsec(&backend->input_timestamps.pointer); + } else { + time_nsec = (time % 1000) * 1000000; + } + struct wlr_event_pointer_axis event = { .device = &pointer->input_device->wlr_input_device, .delta = 0, .delta_discrete = 0, .orientation = axis, .time_msec = time, + .time_nsec = time_nsec, .source = pointer->axis_source, }; wlr_signal_emit_safe(&pointer->wlr_pointer.events.axis, &event); @@ -195,24 +242,23 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard, // TODO: set keymap } -static uint32_t get_current_time_msec(void) { - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - return now.tv_nsec / 1000; -} - static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { - struct wlr_input_device *dev = data; + struct wlr_wl_input_device *wl_dev = data; + struct wlr_input_device *dev = &wl_dev->wlr_input_device; - uint32_t time = get_current_time_msec(); + assert(dev && dev->keyboard); + + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); uint32_t *keycode_ptr; wl_array_for_each(keycode_ptr, keys) { struct wlr_event_keyboard_key event = { .keycode = *keycode_ptr, .state = WLR_KEY_PRESSED, - .time_msec = time, + .time_msec = timespec_to_msec(&now), + .time_nsec = timespec_to_nsec(&now), .update_state = false, }; wlr_keyboard_notify_key(dev->keyboard, &event); @@ -221,9 +267,13 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface) { - struct wlr_input_device *dev = data; + struct wlr_wl_input_device *wl_dev = data; + struct wlr_input_device *dev = &wl_dev->wlr_input_device; - uint32_t time = get_current_time_msec(); + assert(dev && dev->keyboard); + + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); uint32_t pressed[dev->keyboard->num_keycodes + 1]; memcpy(pressed, dev->keyboard->keycodes, @@ -235,7 +285,8 @@ static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, struct wlr_event_keyboard_key event = { .keycode = keycode, .state = WLR_KEY_RELEASED, - .time_msec = time, + .time_msec = timespec_to_msec(&now), + .time_nsec = timespec_to_nsec(&now), .update_state = false, }; wlr_keyboard_notify_key(dev->keyboard, &event); @@ -244,13 +295,25 @@ static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { - struct wlr_input_device *dev = data; + struct wlr_wl_input_device *wl_dev = data; + struct wlr_input_device *dev = &wl_dev->wlr_input_device; + assert(dev && dev->keyboard); + uint64_t time_nsec; + if (wl_dev->backend->input_timestamps.manager && + wl_dev->backend->input_timestamps.keyboard.tv_sec == time / 1000) { + time_nsec = + timespec_to_nsec(&wl_dev->backend->input_timestamps.keyboard); + } else { + time_nsec = (time % 1000) * 1000000; + } + struct wlr_event_keyboard_key wlr_event = { .keycode = key, .state = state, .time_msec = time, + .time_nsec = time_nsec, .update_state = false, }; wlr_keyboard_notify_key(dev->keyboard, &wlr_event); @@ -259,15 +322,18 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { - struct wlr_input_device *dev = data; + struct wlr_wl_input_device *wl_dev = data; + struct wlr_input_device *dev = &wl_dev->wlr_input_device; + assert(dev && dev->keyboard); - wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched, - mods_locked, group); + + wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, + mods_latched, mods_locked, group); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay) { - // This space is intentionally left blank + /* This space is intentionally left blank */ } static struct wl_keyboard_listener keyboard_listener = { @@ -521,11 +587,27 @@ void create_wl_keyboard(struct wl_keyboard *wl_keyboard, struct wlr_wl_backend * } wlr_keyboard_init(wlr_dev->keyboard, NULL); - wl_keyboard_add_listener(wl_keyboard, &keyboard_listener, wlr_dev); + wl_keyboard_add_listener(wl_keyboard, &keyboard_listener, dev); dev->resource = wl_keyboard; wlr_signal_emit_safe(&wl->backend.events.new_input, wlr_dev); } +static void input_timestamps_handle_timestamp(void *data, + struct zwp_input_timestamps_v1 *zwp_input_timestamps_v1, + uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec) { + struct timespec *timestamp = data; + + uint64_t tv_sec = ((uint64_t)tv_sec_hi << 32) + tv_sec_lo; + assert(tv_sec < (uint64_t)LONG_MAX && "input-timestamps value is too big"); + + timestamp->tv_sec = tv_sec; + timestamp->tv_nsec = tv_nsec; +} + +static const struct zwp_input_timestamps_v1_listener input_timestamps_listener = { + .timestamp = input_timestamps_handle_timestamp, +}; + static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps) { struct wlr_wl_backend *backend = data; @@ -543,6 +625,14 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, } wl_pointer_add_listener(wl_pointer, &pointer_listener, backend); + + if (backend->input_timestamps.manager) { + struct zwp_input_timestamps_v1 *pointer_input_timestamps = + zwp_input_timestamps_manager_v1_get_pointer_timestamps( + backend->input_timestamps.manager, wl_pointer); + zwp_input_timestamps_v1_add_listener(pointer_input_timestamps, + &input_timestamps_listener, &backend->input_timestamps.pointer); + } } if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { wlr_log(WLR_DEBUG, "seat %p offered keyboard", (void*) wl_seat); @@ -553,6 +643,14 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, if (backend->started) { create_wl_keyboard(wl_keyboard, backend); } + + if (backend->input_timestamps.manager) { + struct zwp_input_timestamps_v1 *keyboard_input_timestamps = + zwp_input_timestamps_manager_v1_get_keyboard_timestamps( + backend->input_timestamps.manager, wl_keyboard); + zwp_input_timestamps_v1_add_listener(keyboard_input_timestamps, + &input_timestamps_listener, &backend->input_timestamps.keyboard); + } } } diff --git a/backend/x11/input_device.c b/backend/x11/input_device.c index 086123660..1845c6f64 100644 --- a/backend/x11/input_device.c +++ b/backend/x11/input_device.c @@ -20,6 +20,7 @@ static void send_key_event(struct wlr_x11_backend *x11, uint32_t key, enum wlr_key_state st, xcb_timestamp_t time) { struct wlr_event_keyboard_key ev = { .time_msec = time, + .time_nsec = time * 1000000, .keycode = key, .state = st, .update_state = true, @@ -32,6 +33,7 @@ static void send_button_event(struct wlr_x11_output *output, uint32_t key, struct wlr_event_pointer_button ev = { .device = &output->pointer_dev, .time_msec = time, + .time_nsec = time * 1000000, .button = key, .state = st, }; @@ -44,6 +46,7 @@ static void send_axis_event(struct wlr_x11_output *output, int32_t delta, struct wlr_event_pointer_axis ev = { .device = &output->pointer_dev, .time_msec = time, + .time_nsec = time * 1000000, .source = WLR_AXIS_SOURCE_WHEEL, .orientation = WLR_AXIS_ORIENTATION_VERTICAL, // 15 is a typical value libinput sends for one scroll @@ -59,6 +62,7 @@ static void send_pointer_position_event(struct wlr_x11_output *output, struct wlr_event_pointer_motion_absolute ev = { .device = &output->pointer_dev, .time_msec = time, + .time_nsec = time * 1000000, .x = (double)x / output->wlr_output.width, .y = (double)y / output->wlr_output.height, }; diff --git a/include/backend/wayland.h b/include/backend/wayland.h index 8f8e1ea6d..80a39270b 100644 --- a/include/backend/wayland.h +++ b/include/backend/wayland.h @@ -39,6 +39,11 @@ struct wlr_wl_backend { struct wl_keyboard *keyboard; struct wlr_wl_pointer *current_pointer; char *seat_name; + struct { + struct zwp_input_timestamps_manager_v1 *manager; + struct timespec keyboard; + struct timespec pointer; + } input_timestamps; }; struct wlr_wl_output { diff --git a/types/wlr_virtual_keyboard_v1.c b/types/wlr_virtual_keyboard_v1.c index fd0d7797b..70f6ab325 100644 --- a/types/wlr_virtual_keyboard_v1.c +++ b/types/wlr_virtual_keyboard_v1.c @@ -85,6 +85,7 @@ static void virtual_keyboard_key(struct wl_client *client, } struct wlr_event_keyboard_key event = { .time_msec = time, + .time_nsec = time * 1000000, .keycode = key, .update_state = false, .state = state,