Winit: [MacOS] Continuous events like MouseMotion and MouseWheel seem laggy in 0.20

Created on 24 Jan 2020  路  13Comments  路  Source: rust-windowing/winit

before 0.20 (pseudocode):

// smooth
loop {
    ev.poll_events(|e| {
        match e {
            DeviceEvent::MouseMotion => {
                // deal with mouse movement
            }
        }
    });
    update();
    render();
}

after 0.20:

// laggy
ev.run(move |e, flow| {
    match e {
        DeviceEvent::MouseMotion => {
            // deal with mouse movement
        },
        RedrawRequested => {
            update();
            render();
        }
        MainEventsCleared => {
            window.request_redraw();
        }
    }
})

Not sure if it's me not setting up correctly. It's pretty obvious in my 3d first person camera example, the example is running at >60fps, movement with keyboard is smooth, but the camera movement which responds to mousemove looks like 20 fps. I have 2 binaries for comparison between 2 versions (I'm using glutin not winit directly, so glutin 0.22 vs glutin 0.21): mousemove_lag_test.zip.

macOS help wanted needs investigation bug

Most helpful comment

My guess is that this started along with this overhaul commit: https://github.com/rust-windowing/winit/commit/d5391686ae98914ba54e30d872d0e42b5ab5800c (I didn't verify this, but it's a huge change and fundamentally changes how events are handled on macOS, so I think it's a good possibility)

Before it looks like events were continuously polled by calling appkit::NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_

Now it relies on receiving callbacks from NSApplication, which calls an extern "C" fn send_event which in turn calls maybe_dispatch_device_event(this, event);

All 13 comments

I am experiencing a similar issue where the mouse events lag behind the cursor, and there is a large amount of lag when you click and hold.

Here's a Gist with a demo: https://gist.github.com/egauderman/e0e3958f9ac4508f4a0e5839107fbd5a

I鈥檝e been seeing this too for a while. I had some notes on it here:

https://github.com/aclysma/skulpin/issues/31

I'm curious if it's possible to investigate the similarities/differences between winit and Reprocessing uses for window events, as I used Reprocessing in the past for graphics programming and it didn't have this mouse lag issue (on the same device).

@egauderman Or just compare changes between 0.20 and 0.19? I didn't have the problem with 0.19, this looks like a problem related to the eventloop refactor

I spent a good amount of time trying to figure this out tonight. The lag is pretty conspicuous when printing out all events. Here's what it looks like just dragging the mouse:

Smoothly moving the mouse

wakeup
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7875    NewEvents(Poll)
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 0.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1268.15625, y: 444.6015625 }, modifiers: (empty) } })
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (0.0, 1.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1267.6640625, y: 445.0859375 }, modifiers: (empty) } })
cleared
ready!
take events
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7875    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7875    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 0.0) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7875    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1268.15625, y: 444.6015625 }, modifiers: (empty) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7875    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7875    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (0.0, 1.0) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7875    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1267.6640625, y: 445.0859375 }, modifiers: (empty) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7875    MainEventsCleared
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7875    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7892    RedrawEventsCleared
wakeup
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7892    NewEvents(Poll)
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 1.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1266.1875, y: 447.0234375 }, modifiers: (empty) } })
cleared
ready!
take events
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7892    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7892    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7892    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 1.0) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7892    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1266.1875, y: 447.0234375 }, modifiers: (empty) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7893    MainEventsCleared
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7893    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7921    RedrawEventsCleared
wakeup
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7921    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7921    MainEventsCleared
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7921    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7939    RedrawEventsCleared
wakeup
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7939    NewEvents(Poll)
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 1.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1262.7421875, y: 450.4140625 }, modifiers: (empty) } })
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 1.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1260.7734375, y: 452.8359375 }, modifiers: (empty) } })
cleared
ready!
take events
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7939    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7939    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7939    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 1.0) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7939    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1262.7421875, y: 450.4140625 }, modifiers: (empty) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7939    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7939    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7940    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 1.0) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7940    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1260.7734375, y: 452.8359375 }, modifiers: (empty) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7940    MainEventsCleared
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7940    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7955    RedrawEventsCleared
wakeup
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7955    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7956    MainEventsCleared
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7956    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7971    RedrawEventsCleared
wakeup
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7971    NewEvents(Poll)
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -2.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 2.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-2.0, 2.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1256.8359375, y: 456.2265625 }, modifiers: (empty) } })
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -2.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-2.0, 1.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1252.8984375, y: 458.6484375 }, modifiers: (empty) } })
cleared
ready!
take events
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7972    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -2.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7972    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 2.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7972    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-2.0, 2.0) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7972    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1256.8359375, y: 456.2265625 }, modifiers: (empty) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7972    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -2.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7972    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7972    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-2.0, 1.0) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7972    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1252.8984375, y: 458.6484375 }, modifiers: (empty) } }
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7972    MainEventsCleared
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7972    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:40Z WARN  skulpin::app::app] EVENT AT 7977    RedrawEventsCleared
wakeup

Smoothly move the mouse but add a left click while moving the mouse

But throw in clicking the mouse while being careful to keep the mouse moving:

wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8194    NewEvents(Poll)
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 1.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1231.15625, y: 478.9921875 }, modifiers: (empty) } })
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8195    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8195    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8195    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 1.0) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8195    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1231.15625, y: 478.9921875 }, modifiers: (empty) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8195    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8195    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8213    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8213    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8214    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8214    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8227    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8227    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8227    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8227    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8245    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8245    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8246    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8246    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8260    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8260    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8260    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8261    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8280    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8280    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8280    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8280    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8292    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8292    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8292    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8292    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8309    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8309    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8309    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8309    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8325    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8325    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8325    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8325    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8342    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8342    NewEvents(Poll)
push back event [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Button { button: 0, state: Pressed } })]
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Button { button: 0, state: Pressed } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: MouseInput { device_id: DeviceId(DeviceId), state: Pressed, button: Left, modifiers: (empty) } })
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 2.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 2.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1228.203125, y: 483.3515625 }, modifiers: (empty) } })
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Button { button: 0, state: Released } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: MouseInput { device_id: DeviceId(DeviceId), state: Released, button: Left, modifiers: (empty) } })
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -19.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 13.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-19.0, 13.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1191.671875, y: 508.3359375 }, modifiers: (empty) } })
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    DeviceEvent { device_id: DeviceId(DeviceId), event: Button { button: 0, state: Pressed } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    WindowEvent { window_id: WindowId(Id(140268456159024)), event: MouseInput { device_id: DeviceId(DeviceId), state: Pressed, button: Left, modifiers: (empty) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 2.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 2.0) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1228.203125, y: 483.3515625 }, modifiers: (empty) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    DeviceEvent { device_id: DeviceId(DeviceId), event: Button { button: 0, state: Released } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    WindowEvent { window_id: WindowId(Id(140268456159024)), event: MouseInput { device_id: DeviceId(DeviceId), state: Released, button: Left, modifiers: (empty) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -19.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 13.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-19.0, 13.0) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1191.671875, y: 508.3359375 }, modifiers: (empty) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    MainEventsCleared
app received mouse down
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8343    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8359    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8359    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8359    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8359    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8377    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8377    NewEvents(Poll)
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 1.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1188.71875, y: 510.2734375 }, modifiers: (empty) } })
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -2.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-2.0, 1.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1184.6953125, y: 512.6953125 }, modifiers: (empty) } })
queue events []
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1184.6953125, y: 513.1796875 }, modifiers: (empty) } })
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8378    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -1.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8378    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8378    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-1.0, 1.0) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8378    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1188.71875, y: 510.2734375 }, modifiers: (empty) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8378    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -2.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8378    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8378    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-2.0, 1.0) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8378    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1184.6953125, y: 512.6953125 }, modifiers: (empty) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8378    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1184.6953125, y: 513.1796875 }, modifiers: (empty) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8378    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8378    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8396    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8396    NewEvents(Poll)
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8396    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8396    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8417    RedrawEventsCleared
wakeup
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8417    NewEvents(Poll)
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -2.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-2.0, 1.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1181.25, y: 515.6015625 }, modifiers: (empty) } })
queue events [StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -2.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 2.0 } }), StaticEvent(DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-2.0, 2.0) } })]
queue event StaticEvent(WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1176.8203125, y: 518.9921875 }, modifiers: (empty) } })
cleared
ready!
take events
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8418    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -2.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8418    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 1.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8418    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-2.0, 1.0) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8418    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1181.25, y: 515.6015625 }, modifiers: (empty) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8418    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 0, value: -2.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8418    DeviceEvent { device_id: DeviceId(DeviceId), event: Motion { axis: 1, value: 2.0 } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8418    DeviceEvent { device_id: DeviceId(DeviceId), event: MouseMotion { delta: (-2.0, 2.0) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8418    WindowEvent { window_id: WindowId(Id(140268456159024)), event: CursorMoved { device_id: DeviceId(DeviceId), position: PhysicalPosition { x: 1176.8203125, y: 518.9921875 }, modifiers: (empty) } }
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8418    MainEventsCleared
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8418    RedrawRequested(WindowId(Id(140268456159024)))
[2020-02-08T09:32:41Z WARN  skulpin::app::app] EVENT AT 8438    RedrawEventsCleared
wakeup

It looks to me like, when clicking, events stop being emitted for about 100ms.

It looks to me like something isn't right with the delivery of events from NSApplication to the registered callback, which makes me suspect something is wrong with the setup for NSApplication or CFRunLoop. But I'm not familiar enough with the platform to know for certain.

My guess is that this started along with this overhaul commit: https://github.com/rust-windowing/winit/commit/d5391686ae98914ba54e30d872d0e42b5ab5800c (I didn't verify this, but it's a huge change and fundamentally changes how events are handled on macOS, so I think it's a good possibility)

Before it looks like events were continuously polled by calling appkit::NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_

Now it relies on receiving callbacks from NSApplication, which calls an extern "C" fn send_event which in turn calls maybe_dispatch_device_event(this, event);

Not sure if this is helpful but I checked the Reason Reprocessing library (which in my experience handles mac touchpad input smoothly as I mentioned in my earlier comment) and found that it depends on SDL and internally it calls SDL_PollEvent. Not sure if this is helpful but putting it out there for reference.

(i.e. Reprocessing depends on Reasongl which depends on a fork of TSDL which is a wrapper around SDL, and specifically SDL_PollEvent (appears as "poll_event" in the Reason code) is what kicks off the mouse move events)

With the disclaimer that I've never written a line of objective C in my life, and that I have no experience working on macOS, I think this is where SDL does their event handling: https://github.com/spurious/SDL-mirror/blob/6b6170caf69b4189c9a9d14fca96e97f09bbcc41/src/video/cocoa/SDL_cocoaevents.m

There is a line here:

NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];

Looking at the 0.19 winit code there was something similar with the comment "Wait for the next event. Note that this function blocks during resize."

                // Wait for the next event. Note that this function blocks during resize.
                let ns_event = appkit::NSApp().nextEventMatchingMask_untilDate_inMode_dequeue_(
                    NSEventMask::NSAnyEventMask.bits() | NSEventMask::NSEventMaskPressure.bits(),
                    foundation::NSDate::distantFuture(cocoa::base::nil),
                    foundation::NSDefaultRunLoopMode,
                    cocoa::base::YES);

The second undtilDate was distantFuture in the rust implementation, perhaps if that were distantPast like in SDL, it wouldn't block.

So maybe manually pumping these events is still an option? (Assuming the only reason for changing the way this was handled before was to avoid blocking.)

Also of note, SDL also has this call [NSApp sendEvent:event]; Not sure if that does anything we'd want to do too.

Using ControlFlow::Poll, performing sleeping manually in MainEventCleared we see a pattern where the MainEventCleared occurs in pairs without any intervening motion events:

Generating mouse event: (8.000, 0.000)
Generating mouse event: (19.000, -5.000)
[DeviceEvent::MouseMotion(8.000, 0.000)] @ 0.193 us, 342.641 us after winit created
[DeviceEvent::MouseMotion(19.000, -5.000)] @ 41.391 us, 178.440 us after winit created
[MainEventCleared] @ 50.862 us
[MainEventCleared] @ 34315.527 us
Generating mouse event: (42.000, -8.000)
Generating mouse event: (83.000, -16.000)
[DeviceEvent::MouseMotion(42.000, -8.000)] @ 70504.492 us, 319.739 us after winit created
[DeviceEvent::MouseMotion(83.000, -16.000)] @ 70528.703 us, 153.272 us after winit created
[MainEventCleared] @ 70541.742 us
[MainEventCleared] @ 106441.617 us
Generating mouse event: (80.000, -11.000)
Generating mouse event: (133.000, -14.000)
[DeviceEvent::MouseMotion(80.000, -11.000)] @ 141973.828 us, 366.537 us after winit created
[DeviceEvent::MouseMotion(133.000, -14.000)] @ 141990.969 us, 123.327 us after winit created
[MainEventCleared] @ 141999.312 us
[MainEventCleared] @ 177216.766 us
Generating mouse event: (110.000, -10.000)
Generating mouse event: (189.000, -2.000)
[DeviceEvent::MouseMotion(110.000, -10.000)] @ 213950.781 us, 390.369 us after winit created
[DeviceEvent::MouseMotion(189.000, -2.000)] @ 213971.625 us, 131.365 us after winit created
[MainEventCleared] @ 213983.016 us
[MainEventCleared] @ 249157.875 us
Generating mouse event: (201.000, -4.000)
Generating mouse event: (316.000, -15.000)
[DeviceEvent::MouseMotion(201.000, -4.000)] @ 285859.250 us, 464.474 us after winit created
[DeviceEvent::MouseMotion(316.000, -15.000)] @ 285882.094 us, 134.143 us after winit created
[MainEventCleared] @ 285893.969 us
[MainEventCleared] @ 321141.406 us
Generating mouse event: (311.000, -13.000)
Generating mouse event: (192.000, -14.000)
[DeviceEvent::MouseMotion(311.000, -13.000)] @ 359207.062 us, 532.341 us after winit created
[DeviceEvent::MouseMotion(192.000, -14.000)] @ 359241.375 us, 186.857 us after winit created
[MainEventCleared] @ 359253.594 us

Code here: https://github.com/Imberflur/winit/blob/04ab898d0939752df709c403c382838c207ea0e4/examples/mouse_test.rs

Polling twice appears to workaround this issue (ie only running update code, sleeping, etc every other MainEventCleared)

@Imberflur That's a valid workaround for now, thanks!

Just chiming in that I am seeing noticeable lag on Windows 10 (nvidia and intel integrated gpus).

In my case at least, I ran my app with Tracy and discovered that due to driver differences between each machine, the time to get the next swapchain texture was "fixed" on one machine to 16ms, but totally unbounded on another. As a result, what I thought was lag was actually just a bug in my handling of input events which causes them to be framerate dependent.

My apologies!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hobogenized picture hobogenized  路  3Comments

e00E picture e00E  路  5Comments

francesca64 picture francesca64  路  4Comments

alexheretic picture alexheretic  路  4Comments

tomaka picture tomaka  路  3Comments