Handle zero-time virtual pointer motion

6987955397aca6d432caa77d970e2da925bae368
Alexis Sellier committed ago 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);