Handle zero-time virtual pointer motion
6987955397aca6d432caa77d970e2da925bae368
1 parent
b6e528e0
swm.c
+13 -5
| 4280 | 4280 | } |
|
| 4281 | 4281 | if ((c = focus_top(m))) |
|
| 4282 | 4282 | wlr_scene_node_raise_to_top(&c->scene->node); |
|
| 4283 | 4283 | } |
|
| 4284 | 4284 | ||
| 4285 | + | /* Give zero-timestamp virtual-pointer events a real input timestamp. */ |
|
| 4286 | + | static uint32_t pointer_event_time(uint32_t time) { |
|
| 4287 | + | struct timespec now; |
|
| 4288 | + | ||
| 4289 | + | if (time) |
|
| 4290 | + | return time; |
|
| 4291 | + | clock_gettime(CLOCK_MONOTONIC, &now); |
|
| 4292 | + | time = (uint32_t)((uint64_t)now.tv_sec * 1000 + (uint64_t)now.tv_nsec / 1000000); |
|
| 4293 | + | return time ? time : 1; |
|
| 4294 | + | } |
|
| 4295 | + | ||
| 4285 | 4296 | /* Convert absolute pointer input into movement across the display layout. */ |
|
| 4286 | 4297 | void motion_absolute(struct wl_listener *listener, void *data) { |
|
| 4287 | 4298 | /* Convert absolute pointer coordinates, such as those from a tablet or a |
|
| 4288 | 4299 | * nested compositor, into display-layout coordinates. */ |
|
| 4289 | 4300 | struct wlr_pointer_motion_absolute_event *event = data; |
|
| 4290 | 4301 | double lx, ly, dx, dy; |
|
| 4291 | 4302 | ||
| 4292 | - | if (!event->time_msec) /* Virtual pointers use a zero timestamp. */ |
|
| 4293 | - | wlr_cursor_warp_absolute(cursor, &event->pointer->base, event->x, event->y); |
|
| 4294 | - | ||
| 4295 | 4303 | wlr_cursor_absolute_to_layout_coords( |
|
| 4296 | 4304 | cursor, &event->pointer->base, event->x, event->y, &lx, &ly |
|
| 4297 | 4305 | ); |
|
| 4298 | 4306 | dx = lx - cursor->x; |
|
| 4299 | 4307 | dy = ly - cursor->y; |
|
| 4300 | - | motion_notify(event->time_msec, &event->pointer->base, dx, dy, dx, dy, 1); |
|
| 4308 | + | motion_notify(pointer_event_time(event->time_msec), &event->pointer->base, dx, dy, dx, dy, 1); |
|
| 4301 | 4309 | } |
|
| 4302 | 4310 | ||
| 4303 | 4311 | /* Move the pointer or grabbed window and update the surface under it. */ |
|
| 4304 | 4312 | void motion_notify( |
|
| 4305 | 4313 | uint32_t time, |
| 4405 | 4413 | struct wlr_pointer_motion_event *event = data; |
|
| 4406 | 4414 | ||
| 4407 | 4415 | /* Move the cursor by the reported distance. wlroots applies display bounds |
|
| 4408 | 4416 | * and any settings specific to the input device. */ |
|
| 4409 | 4417 | motion_notify( |
|
| 4410 | - | event->time_msec, |
|
| 4418 | + | pointer_event_time(event->time_msec), |
|
| 4411 | 4419 | &event->pointer->base, |
|
| 4412 | 4420 | event->delta_x, |
|
| 4413 | 4421 | event->delta_y, |
|
| 4414 | 4422 | event->unaccel_dx, |
|
| 4415 | 4423 | event->unaccel_dy, |
test/unit.c
+1 -0
| 676 | 676 | assert(serial_at_least(10, 10)); |
|
| 677 | 677 | assert(serial_at_least(11, 10)); |
|
| 678 | 678 | assert(!serial_at_least(9, 10)); |
|
| 679 | 679 | assert(serial_at_least(1, UINT32_MAX)); |
|
| 680 | 680 | assert(!serial_at_least(UINT32_MAX, 1)); |
|
| 681 | + | assert(pointer_event_time(0) != 0); |
|
| 681 | 682 | seat = &fake_seat; |
|
| 682 | 683 | assert(shortcuts_inhibited() == 0); |
|
| 683 | 684 | assert(focus_close(nullptr) == nullptr); |
|
| 684 | 685 | slot = pool_take(&static_listener_pool); |
|
| 685 | 686 | assert(slot); |