Skip to content

Incorrect focus events for windows created without focus #2102

@swooster

Description

@swooster

On Windows 10, I've noticed that if cargo run takes a while to build my executable and I switch focus to another application, then the focus events sent to my executable are incorrect, preventing it from determining whether it's currently focused.

Here's a minimal reproducible example:

use std::{thread, time};

use winit::{
    event::{Event, WindowEvent},
    event_loop::{ControlFlow, EventLoop},
    window::Window,
};

fn main() {
    println!("Select another window within 5 seconds.");
    thread::sleep(time::Duration::from_secs(5));

    let event_loop = EventLoop::new();
    let window = Window::new(&event_loop).unwrap();

    event_loop.run(move |event, _event_loop_target, control_flow| match event {
        Event::WindowEvent {
            event: WindowEvent::CloseRequested,
            window_id,
        } if window_id == window.id() => {
            *control_flow = ControlFlow::Exit;
        }
        Event::WindowEvent {
            event: WindowEvent::Focused(focused),
            window_id,
        } if window_id == window.id() => {
            println!("Focused: {}", focused);
            // window.set_cursor_grab(focused).unwrap();
            // window.set_cursor_visible(!focused);
        }
        _ => (),
    });
}

The behavior I'd expect is at least one (ideally both) of the following:

  • The winit window receives a Focused(true) event if it's created in a focused state.
  • The winit window receives a Focused(false) event if it's created in an unfocused state.

With winit 0.26.0, if you run this and focus another application during the 5 second wait, then the winit window will be created in the background, yet the application will receive a Focused(true) event. If the application tries to act on this by grabbing the cursor (uncomment the lines near the end), then you end up with a strange situation where the cursor is constrained to the bounds of the winit window, despite another application having focus and being in front.

With winit 0.20.0 through 0.25.0, if you follow the above steps, then the winit window receives no event, even when focused for the first time.

I haven't tested with versions of winit older than 0.20.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    B - bugDang, that shouldn't have happenedC - needs investigationIssue must be confirmed and researchedDS - win32Affects the Win32/Windows backend

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions