Skip to content
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

eframe: Graphical glitches when window has been minimized #3321

Closed
rustbasic opened this issue Sep 8, 2023 · 5 comments · Fixed by #3877
Closed

eframe: Graphical glitches when window has been minimized #3321

rustbasic opened this issue Sep 8, 2023 · 5 comments · Fixed by #3877
Labels
bug Something is broken

Comments

@rustbasic
Copy link
Contributor

rustbasic commented Sep 8, 2023

Title: Regarding severe graphical glitches with egui

Dear emilk,

When continuously running a program that uses the egui library on windows, there is a bug causing severe graphic glitches after about 1 to 6 hours.

Before I explain the circumstances leading to this glitch, I want to highlight another bug.

        frame.set_minimized(true);

When using the above function or the native windows minimize button and then restoring the program to its original size, the frame.info().window_info.minimized remains constantly set to true. Therefore, it's impossible to determine whether the program is in a minimized state. In the minimized state, ui.available_width() slightly decreases, and ui.available_height() becomes 0.0. After restoring from the minimized state, while ui.available_width() returns to normal, sometimes ui.available_height() remains at 0.0.

I've tried to determine the exact conditions that lead to the graphic glitches. The frequency of glitches appears to be higher when restoring the program to its original size after minimizing it for over an hour. The graphical glitches also occur every few hours even without minimizing the program. When these glitches happen, it seems ui.available_height() is at 0.0. It's presumed that the glitches might be linked to the instances when, upon restoring from minimized state, ui.available_height() occasionally remains at 0.0.

Please note that this behavior isn't consistent, as it happens only every few hours. However, these are my observations so far while trying to reproduce and prevent this glitch.

Thanks.


egui Version
egui 0.22.0
egui 0.21.0

[ BUG Capture ]

bug-capture-1

[ No Bug Capture ]

no-bug-capture-1


Dear emilk,

I've been working for over 6 months to reproduce the issue of graphics breaking every few hours in a Windows program using the egui library. Through these efforts, I've roughly identified the reason and found a temporary way to prevent it.

When the program is minimized, the value of ui.available_height() decreases.

In the minimized state, the value of ui.available_height() seems to range between 0.0 to 20.0, depending on where the program was launched.

I tried using the method if ui.available_height() < 100.0 { return; }, but graphics still broke every few hours when restoring from a minimized state.

So,

let mut ui_available_height = ui.available_height();
if ui_available_height < 100.0 {
    ui_available_height = ui_available_height.at_least(100.0);
}

I created the ui_available_height value using the above method and used it, but still, the graphics broke every few hours after restoring from a minimized state.

Lastly, I found a method where graphics didn't break for 2-3 days upon testing.

fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
    ...
    let mut minimized_stop_work = false;
    ...
    egui::CentralPanel::default().frame(panel_frame).show(ctx, |ui| {
        let ui_available_height = ui.available_height();
        if ui_available_height < 100.0 {
            minimized_stop_work = true;
        }
        ...
    });     // CentralPanel()
    ...
    if !minimized_stop_work {
        ctx.request_repaint();
    }
}    // fn update()

By assuming that it's in a minimized state when ui.available_height() is below 100.0, and by not executing ctx.request_repaint(); (RunMode::Continuous mode in egui_demo_app.exe), the screen doesn't break even when restoring from a minimized state in Windows for a prolonged period. I've successfully tested this for 2-3 days.

This method might temporarily prevent the screen from breaking. However, I'm looking forward to a fundamental solution provided by the egui library.

Thanks, emilk.

@rustbasic rustbasic added the bug Something is broken label Sep 8, 2023
@rustbasic
Copy link
Contributor Author

rustbasic commented Sep 23, 2023

Dear emilk,

I've been working for over 6 months to reproduce the issue of graphics breaking every few hours in a Windows program using the egui library. Through these efforts, I've roughly identified the reason and found a temporary way to prevent it.

When the program is minimized, the value of ui.available_height() decreases.

In the minimized state, the value of ui.available_height() seems to range between 0.0 to 20.0, depending on where the program was launched.

I tried using the method if ui.available_height() < 100.0 { return; }, but graphics still broke every few hours when restoring from a minimized state.

So,

let mut ui_available_height = ui.available_height();
if ui_available_height < 100.0 {
    ui_available_height = ui_available_height.at_least(100.0);
}

I created the ui_available_height value using the above method and used it, but still, the graphics broke every few hours after restoring from a minimized state.

Lastly, I found a method where graphics didn't break for 2-3 days upon testing.

fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
    ...
    let mut minimized_stop_work = false;
    ...
    egui::CentralPanel::default().frame(panel_frame).show(ctx, |ui| {
        let ui_available_height = ui.available_height();
        if ui_available_height < 100.0 {
            minimized_stop_work = true;
        }
        ...
    });     // CentralPanel()
    ...
    if !minimized_stop_work {
        ctx.request_repaint();
    }
}    // fn update()

By assuming that it's in a minimized state when ui.available_height() is below 100.0, and by not executing ctx.request_repaint(); (RunMode::Continuous mode in egui_demo_app.exe), the screen doesn't break even when restoring from a minimized state in Windows for a prolonged period. I've successfully tested this for 2-3 days.

This method might temporarily prevent the screen from breaking. However, I'm looking forward to a fundamental solution provided by the egui library.

Thanks, emilk.

@emilk
Copy link
Owner

emilk commented Sep 23, 2023

Thanks for your investigation!

First of all: your posts are easier to read if you add proper markdown code blocks.

You should be able to read the minimized state with frame.info().window_info.minimized instead of checking for the available height.

The question is what eframe should do when an app is minimized. I think it should still call App::update, but giving a very small available_height seems the wrong thing to do, and sounds like a bug in eframe, or perhaps winit.


We should also consider splitting App::update into two: one App::tick and one App::ui. tick would be called even when minimized, while ui only when non minimized (right after the call to tick).

@rustbasic
Copy link
Contributor Author

Dear emilk,

In egui v0.22.0, the value of Frame.info().window_info.minimized seems to be inconsistent, making it unusable.
It (= my program) always calls ctx.request_repaint() in the same manner as RunMode::Continuous.

    if !minimized_stop_work {
        ctx.request_repaint();
    }

Using this approach, I haven't experienced any screen corruption for several days.

Thanks emilk.

@rustbasic
Copy link
Contributor Author

Dear emilk,

I would like to share the results of using egui v0.24.0 ( & v024.1 ) on Windows for the past few days.
I encountered one scene where the screen broke, and the program terminated within 3 seconds.
Instead of the screen breaking, when used in a minimized state for approximately 2 to 6 hours, the program often exits.
However, this is a better outcome than the screen breaking, as when the screen breaks, the program becomes unusable, and it is difficult to terminate.

In versions prior to egui v0.23.0, the screen often remained in a broken state.
With egui v0.24.0, there were no instances where the screen continued to be in a broken state.

I would like to determine if the window is in a minimized state using the winapi::um::winuser::IsIconic() function.
However, as the HWND of the window in egui is in a private state, there is no way to know if it is in a minimized state.

pub fn is_minimized() -> bool {

    let foreground_window: *mut winapi::shared::windef::HWND__ = unsafe { winapi::um::winuser::GetForegroundWindow() };
    let is_minimized: bool = unsafe { winapi::um::winuser::IsIconic(foreground_window) } != 0;

    return is_minimized;
}

Still assuming that the window is in a minimized state if the window size is less than 100.0,
and not requesting repaint during the minimized state, the program works fine.
(I have also made sure not to output other screens of the viewpoint during the minimized state.)

Copy code
let ui_available_height = ui.available_height();
if ui_available_height < 100.0 {
    minimized_stop_work = true;
}

if !minimized_stop_work {
    ctx.request_repaint();
}

This is an update sharing the current usage experience.

Thanks, emilk.

@rustbasic
Copy link
Contributor Author

P.S. I didn't mention one observed point. When the program exits in a minimized state, the screen briefly flickers (within 0.1 seconds), appearing and disappearing, before the program terminates.

rustbasic added a commit to rustbasic/egui that referenced this issue Jan 18, 2024
request_repaint()
if is_minimized return

emilk#3321
rustbasic added a commit to rustbasic/egui that referenced this issue Jan 24, 2024
I work finished, Pull Request.

Regarding severe graphical glitches with egui emilk#3321

Changed :
crates/eframe/src/native/run.rs

The test results are normal.
@emilk emilk changed the title Regarding severe graphical glitches with egui eframe: Graphical glitches when window has been minimized Jan 25, 2024
emilk pushed a commit that referenced this issue Jan 25, 2024
emilk pushed a commit that referenced this issue Sep 1, 2024
Fix: The viewport stops working when the program is minimized.   

Fix: Logically, the weird parts have been normalized.
                                                               
**Issue :**
The viewport stops working when the program is minimized.
                         
* Related #3321
* Related #3877
* Related #3985
* Closes #3972
* Closes #4772
* Related #4832 
* Closes #4892
**Solution :**
When `request_redraw()` is performed in Minimized state, the occasional
screen tearing phenomenon has disappeared.
( Probably expected to be the effect of #4814 )
To address the issue of the `Immediate Viewport` not updating in
Minimized state, we can call `request_redraw()`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is broken
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants