Skip to content

Flickering When Creating Borderless Window on Windows #4116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
dannyHallo opened this issue Feb 5, 2025 · 2 comments
Open

Flickering When Creating Borderless Window on Windows #4116

dannyHallo opened this issue Feb 5, 2025 · 2 comments
Labels
B - bug Dang, that shouldn't have happened DS - windows

Comments

@dannyHallo
Copy link

Description

When creating a borderless window on Windows using the winit library, a noticeable flicker occurs during window creation. This flicker appears when the window is created with the default visible attribute. I was able to observe the flicker (see the attached screenshot) when using the typical window creation flow (see create_window_case_1).

Interestingly, the flicker can be avoided by creating the window with its visibility set to false (see create_window_case_2) and then setting the window to visible after creation. While this workaround eliminates the flicker, it seems more like a trick rather than a proper fix to the window initialization sequence.

Image

use winit::{
    application::ApplicationHandler,
    event::{ElementState, WindowEvent},
    event_loop::{ActiveEventLoop, EventLoop},
    keyboard::KeyCode,
    window::{Fullscreen, Window, WindowId},
};

fn main() {
    let mut app = App::default();
    let event_loop = EventLoop::builder().build().unwrap();
    let result = event_loop.run_app(&mut app);

    match result {
        Ok(_) => println!("Application exited successfully"),
        Err(e) => println!("Application exited with error: {:?}", e),
    }
}

fn create_window_case_1(event_loop: &winit::event_loop::ActiveEventLoop) -> Window {
    // when the window is visible, and borderless mode is selected,
    // a flicker will be observed during the create_window call, the flicker pattern can be seen at ./case_1.png
    let winit_window_attributes = Window::default_attributes()
        .with_fullscreen(Some(Fullscreen::Borderless(event_loop.primary_monitor())));
    let window = event_loop.create_window(winit_window_attributes).unwrap();
    window
}

#[allow(unused)]
fn create_window_case_2(event_loop: &winit::event_loop::ActiveEventLoop) -> Window {
    // here's a method I found to avoid the flicker during window creation, but it is only a trick
    // that is: create the window with the visible attribute set to false, then set it back to true after creation
    let winit_window_attributes = Window::default_attributes()
        .with_visible(false)
        .with_fullscreen(Some(Fullscreen::Borderless(event_loop.primary_monitor())));
    let window = event_loop.create_window(winit_window_attributes).unwrap();
    window.set_visible(true);
    window
}

#[derive(Default)]
pub struct App {
    window: Option<Window>,
}

impl ApplicationHandler for App {
    // initialize resources here
    fn resumed(&mut self, event_loop: &ActiveEventLoop) {
        self.window = Some(create_window_case_1(event_loop));
        // self.window = Some(create_window_case_2(event_loop));
    }

    fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) {
        match event {
            WindowEvent::CloseRequested => {
                event_loop.exit();
            }
            WindowEvent::KeyboardInput { event, .. } => {
                // close the loop when escape key is pressed
                if event.state == ElementState::Pressed && event.physical_key == KeyCode::Escape {
                    event_loop.exit();
                    return;
                }
            }
            _ => {}
        };
    }

    fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) {}
}

Windows version

Microsoft Windows [Version 10.0.19045.5247]

Winit version

0.30.8

@dannyHallo dannyHallo added B - bug Dang, that shouldn't have happened DS - windows labels Feb 5, 2025
@kchibisov
Copy link
Member

I think it's not really uncommon for something to flicker until you have rendered something into it before showing it? Like maybe there's a way around it, but in general, it's rather common and pretty much only Wayland doesn't have this problem, since window visibility is determined there whether it has a buffer attached or not, which means have you drawn or not.

@Long0x0
Copy link

Long0x0 commented Feb 18, 2025

Actually the examples in this repo have the same problem, you can see a white window flash by and then show up with the target size.

I tried to fix this by making the window transparent before rendering anything (see Long0x0@23722ea), but I gave up submitting a PR because I thought that was too hacky, and hiding the window before rendering anything should be a better solution.

So my question is whether we can improve the sample code? When is the right time to render the first frame and show the window?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B - bug Dang, that shouldn't have happened DS - windows
Development

No branches or pull requests

3 participants