winit icon indicating copy to clipboard operation
winit copied to clipboard

On MacOS dragging window lags if rendering continuously with Magnet utility enabled and VSync enabled

Open kettle11 opened this issue 4 years ago • 7 comments

Previously I opened this issue over on Glutin (https://github.com/rust-windowing/winit/issues/2468) but it may be more relevant here.

This is a copy-paste of that issue and my follow up comments:


When rerendering continuously on MacOS 10.15.6 (with VSync enabled) if I try to drag the titlebar to move the window there is an approximately half second to a second delay before the window snaps to the mouse cursor and moves smoothly again.

This small example program reproduces the issue:

(the below code can also be downloaded as a crate from this repository: https://github.com/kettle11/glutin_bug_test)

use glow::*;
use glutin::event::Event;
use glutin::event_loop::{ControlFlow, EventLoop};
use glutin::window::WindowBuilder;
use glutin::ContextBuilder;
fn main() {
    let event_loop = EventLoop::new();
    let wb = WindowBuilder::new().with_title("A fantastic window!");

    let windowed_context = ContextBuilder::new()
        .with_vsync(true)
        .build_windowed(wb, &event_loop)
        .unwrap();

    let windowed_context = unsafe { windowed_context.make_current().unwrap() };

    let gl =
        glow::Context::from_loader_function(|s| windowed_context.get_proc_address(s) as *const _);
    unsafe {
        gl.clear_color(0.1, 0.2, 0.3, 1.0);
    }

    event_loop.run(move |event, _, control_flow| {
        *control_flow = ControlFlow::Poll;
        match event {
            Event::RedrawRequested(_) => {
                unsafe {
                    gl.clear(glow::COLOR_BUFFER_BIT);
                }
                windowed_context.swap_buffers().unwrap();
                windowed_context.window().request_redraw();
            }
            Event::LoopDestroyed => {
                return;
            }
            _ => (),
        }
    });
}

Some additional interesting details:

This bug also occurs if the line: windowed_context.swap_buffers().unwrap();

is replaced with:

std::thread::sleep(std::time::Duration::from_millis(16));

which indicates to me that perhaps "RedrawRequested" is issued in a call that MacOS does not expect to take long.

I managed to reproduce the same behavior for SDL as well, and for the Unity game RimWorld (I don't know how Unity handles windowing internally). It did not occur for Factorio and some other games I tested. It does not seem to occur for most apps that don't rerender continuously.

Oddly when I record a fullscreen video what I see and what the video records are different. In the video the mouse cursor always appears to be snapped to the window titlebar even though the window itself clearly lags, but what I see is the mouse moving ahead of the window and then the window eventually catching up.

This also seems like it may be an issue for Metal windows as well, which I have been trying to get working on a crate I've been working on.

I'm very curious if other people run into this issue as well.


For easier access I've made a small repository with the above code that reproduces the bug: https://github.com/kettle11/glutin_bug_test


To add more info: this appears to be a consequence of sending the "RedrawRequested" event here: https://github.com/rust-windowing/winit/blob/68100102be588aea3dd42cb64647e1f8624615b2/src/platform_impl/macos/app_state.rs#L333

Perhaps something about having a delay at the end of the update loop throws MacOS off?

I was able to fix this in my own library (similar to Winit, but for a narrower use case) by calling setNeedsDisplay: YES and allowing drawRect to issue the equivalent of RedrawRequested. However this "fix" will make it impossible to disable VSync as far as I can tell.

That's OK for now for my library, but not an acceptable fix for Winit / Glutin.

kettle11 avatar Oct 10 '20 00:10 kettle11

Well, I just figured this out and I'm frustrated I didn't think to check this earlier. I had installed an extremely popular MacOS utility program called Magnet that allows windows to snap to the edges of the screen like on Windows. If I turn Magnet off the issue no longer reproduces.

Of course, I should have tried this earlier but it's good to figure out what the issue is now!

I can reproduce this on two different MacBooks on different versions of MacOS. Both reliably reproduce the issue with Magnet enabled and do not reproduce the issue when Magnet is disabled.

kettle11 avatar Mar 19 '21 21:03 kettle11

Well, I just figured this out and I'm frustrated I didn't think to check this earlier. I had installed an extremely popular MacOS utility program called Magnet that allows windows to snap to the edges of the screen like on Windows. If I turn Magnet off the issue no longer reproduces.

Of course, I should have tried this earlier but it's good to figure out what the issue is now!

I can reproduce this on two different MacBooks on different versions of MacOS. Both reliably reproduce the issue with Magnet enabled and do not reproduce the issue when Magnet is disabled.

Thank you for helping me find the source of the issue. Magnet is definitely causing problems with winit. I am on M1 Air and I spent all day trying to find an answer. I originally thought it was bevy, or wgpu.

But why does magnet cause this problem for winit and not other applications?

ZebTheWizard avatar Aug 30 '22 19:08 ZebTheWizard

Any update on fixing this? I am also a Magnet user having issues.

frederickjjoubert avatar Nov 28 '22 16:11 frederickjjoubert

Just for the record, this is also an issue when Better Touch Tool is running

natebrunette avatar Sep 07 '23 17:09 natebrunette

I'm having the same issue with Magnet enabled

maxall41 avatar Oct 15 '23 20:10 maxall41

Can confirm issues with both Magnet and BetterTouchTool. With BetterTouchTool the lag goes away if I disable Snap Areas.

geirsagberg avatar Dec 16 '23 17:12 geirsagberg

Interestingly, Rectangle doesn't seem to cause the same problem.

geirsagberg avatar Dec 16 '23 17:12 geirsagberg