egui icon indicating copy to clipboard operation
egui copied to clipboard

`with_always_on_top` causes window to display incorrectly when window size is equal to screen size

Open lopo12123 opened this issue 1 year ago • 12 comments

When I create a window with a size equal to the screen and use always_on_top, the window displays incorrectly and transparency becomes invalid

I tried using screen recording software, but I couldn’t see this in the recorded video, so I used my mobile phone to shoot. Please bear with me. First time, I didn't use with_always_on_top, the window was created normally (size 1920*1080, position 10, 10). The second time, I used with_always_on_top, and I could see that a black window appeared covering the full screen (actually its upper left corner should be (10,10)). When I clicked outside the window, the window became Displayed normally. (This situation seems to be that when the window has focus, it will display abnormally, and when it is out of focus, it will display normally.) I don’t know if this is a problem with the implementation of always_on_top on Windows.

https://github.com/emilk/egui/assets/59609929/1e1734e0-1784-482e-ae69-5206d267bac9

~%HYMY46R5954IS1@NQ7OXC The versions of egui and eframe are both 0.27.2

my option and updateFn of app:

// option
let option = eframe::NativeOptions {
  viewport: ViewportBuilder::default()
      .with_position([10.0, 10.0])
      .with_inner_size([1920.0, 1080.0])
      .with_decorations(false)
      .with_always_on_top()
      .with_transparent(true),
  ..Default::default()
};

// app
impl eframe::App for MyApp {
    fn update(&mut self, ctx: &Context, frame: &mut eframe::Frame) {
        egui::CentralPanel::default()
            .frame(Frame::none().fill(Color32::from_black_alpha(128)))
            .show(ctx, |ui| {
                if ctx.input(|i| i.key_pressed(Key::Escape)) {
                    ctx.send_viewport_cmd(ViewportCommand::Close);
                }

                if ui.button("close").clicked() {
                    ctx.send_viewport_cmd(ViewportCommand::Close);
                }
            });
    }
}

lopo12123 avatar May 04 '24 14:05 lopo12123

This situation should indeed be related to whether it is focused or not. When I use with_active(false), the window is initially normal. When I use the mouse to click on the window so that it has focus, the strange full-screen window appears again.

lopo12123 avatar May 04 '24 15:05 lopo12123

Please provide a complete example without any omissions. Please refer to the information below to solve the problem.

  • Related #4451
  • Related #4453

rustbasic avatar May 05 '24 07:05 rustbasic

Please provide a complete example without any omissions. Please refer to the information below to solve the problem.

to reproduce

fn main() {
    use eframe::epaint::Color32;
    use egui::{Frame, Key, ViewportBuilder, ViewportCommand};

    let option = eframe::NativeOptions {
        viewport: ViewportBuilder::default()
            .with_taskbar(false)
            .with_decorations(false)
            // .with_always_on_top()  // <= uncomment this line to reproduce the bug
            .with_position([10.0, 10.0])
            // replace with the screen size for the actual use
            .with_inner_size([1920.0, 1080.0]),
        ..Default::default()
    };

    eframe::run_simple_native(
        "my-app",
        option,
        |ctx, _frame| {
            egui::CentralPanel::default()
                .frame(Frame::none().fill(Color32::WHITE))
                .show(ctx, |ui| {
                    if ui.button("close").clicked() {
                        ctx.send_viewport_cmd(ViewportCommand::Close);
                    }

                    if ctx.input(|i| i.key_pressed(Key::Escape)) {
                        ctx.send_viewport_cmd(ViewportCommand::Close);
                    }
                });
        },
    ).unwrap();
}

This only occurs when the window size is equal(or larger) to the screen size, so changing the window size defeats my purpose. And transparency does not matter here.

lopo12123 avatar May 05 '24 12:05 lopo12123

I didn't find any abnormalities with the above example in Windows 10.

If there is no Decoration in Windows, you may need to set the size again with ViewportCommand::InnerSize(). This may not be relevant. Still, it can be helpful to watch for changes.

            if ui.button("Maximized").clicked() {                                   
                ui.ctx()                                                              
                    .send_viewport_cmd(egui::ViewportCommand::Maximized(true));    
            }                                                                         
                                                                                      
            if ui.button("innersize").clicked() {                                     
                ui.ctx()                                                              
                    .send_viewport_cmd(egui::ViewportCommand::InnerSize(egui::Vec2::new(500.0, 500.0)));
            }                                                                         

rustbasic avatar May 05 '24 14:05 rustbasic

After uncommenting the with_always_on_top line and setting the window size to the screen size (it can also be set to a large value, such as 9999), is there the set 10 pixels of space on the left and top of the window that appears?

X)HX4@1{AT 02AVVL)KIQ70

  1. Run and check if there is a 10 pixel gap between the left and top edges
  2. If not, move the mouse to the top or left side and click. A 10-pixel spacing should appear at this time (the window at this time is the expected position)
  3. Click the window again to give it focus, and the window will cover the entire screen again.

I asked my friend to test it, and it also happened on win11.

lopo12123 avatar May 05 '24 14:05 lopo12123

I have two screens and each is enlarged, so I didn't adjust the window size to fit the screen size. No abnormalities were found.

If you reduce the window size, check if there are any problems. If there is no Decoration in Windows, you may need to set the size again with ViewportCommand::InnerSize().

rustbasic avatar May 05 '24 15:05 rustbasic

When the window size is smaller than the screen size, there are no problems and everything works as expected. This problem only occurs when the window size is greater than or equal to the screen size.

The problem I described should be visible in the case of a single monitor. I only have one monitor at home. I need to go to the company tomorrow to see the multi-monitor situation.

lopo12123 avatar May 05 '24 15:05 lopo12123

@lopo12123

Try removing .with_decorations(false).

Use ViewportCommand temporarily.

  • Related #4451

rustbasic avatar May 05 '24 17:05 rustbasic

I tested it on another computer and this problem did not occur. I don't know what's causing it (os, cpu or something else)

GSBXKBCVQ~GV1 _)IM}Y@BA

lopo12123 avatar May 06 '24 05:05 lopo12123

This may be a problem that occurs when using .with_decorations(false) in Windows 10. (It may not be a problem with egui itself, but a problem with winit that egui uses.)

Check if there is no problem if you do not use one of .with_always_on_top() and .with_decorations(false).

rustbasic avatar May 06 '24 06:05 rustbasic

This bug will appear whether with_decorations is true or false. This problem will occur as long as with_always_on_top is used.

When with_always_on_top is used and with_decorations is true.

  • When not focused, the window is normal.
  • When focused, it still covers the full screen and no decoration appears.

https://github.com/emilk/egui/assets/59609929/27505816-bd06-4c87-8461-f66a5bce38db

lopo12123 avatar May 06 '24 13:05 lopo12123

Thank you so much! I used https://github.com/emilk/egui/pull/4467 for testing and the issue discussed here no longer occurs.


But it seems like flickering is newly introduced. The moment the application is started, part of the window is white first, and then all of it is white.

like this 👇

image

lopo12123 avatar May 06 '24 15:05 lopo12123