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

Setting position on startup does not work reliably on X11 #978

Open
chrisduerr opened this issue Jun 24, 2019 · 11 comments
Open

Setting position on startup does not work reliably on X11 #978

chrisduerr opened this issue Jun 24, 2019 · 11 comments
Labels
B - bug Dang, that shouldn't have happened C - needs investigation Issue must be confirmed and researched DS - x11

Comments

@chrisduerr
Copy link
Contributor

chrisduerr commented Jun 24, 2019

This has been reported to Alacritty in alacritty/alacritty#2561.

On X11, it seems like setting the startup mode after the window is show()n on an originally invisible window has some inconsistent behavior. I've tested this myself on i3.

When the window is created and set to fullscreen on window.get_current_monitor() right at startup, the window is fullscreened on the incorrect monitor.

Additionally, if the position is set right after show() too, the window is fullscreened on the incorrect monitor and when leaving fullscreen mode the position is not what it has been set to.

If set_fullscreen is manually called on a keyboard event at a later point in time, both of these work without any issue.

See #978 (comment).

@chrisduerr
Copy link
Contributor Author

Applying the following diff to glutin makes it possible to reproduce the issue:

diff --git a/glutin_examples/examples/fullscreen.rs b/glutin_examples/examples/fullscreen.rs
index 25cbc72..bdc03d6 100644
--- a/glutin_examples/examples/fullscreen.rs
+++ b/glutin_examples/examples/fullscreen.rs
@@ -9,52 +9,26 @@ use glutin::window::WindowBuilder;
 use std::io::Write;
 
 fn main() {
+    let mut is_fullscreen = true;
     let el = EventLoop::new();
 
     #[cfg(target_os = "macos")]
     let mut macos_use_simple_fullscreen = false;
-
-    let monitor = {
-        // On macOS there are two fullscreen modes "native" and "simple"
-        #[cfg(target_os = "macos")]
-        {
-            print!(
-                "Please choose the fullscreen mode: (1) native, (2) simple: "
-            );
-            std::io::stdout().flush().unwrap();
-
-            let mut num = String::new();
-            std::io::stdin().read_line(&mut num).unwrap();
-            let num = num.trim().parse().ok().expect("Please enter a number");
-            match num {
-                2 => macos_use_simple_fullscreen = true,
-                _ => {}
-            }
-
-            // Prompt for monitor when using native fullscreen
-            if !macos_use_simple_fullscreen {
-                Some(prompt_for_monitor(&el))
-            } else {
-                None
-            }
-        }
-
-        #[cfg(not(target_os = "macos"))]
-        Some(prompt_for_monitor(&el))
-    };
-
-    let mut is_fullscreen = monitor.is_some();
     let mut is_maximized = false;
     let mut decorations = true;
 
     let wb = WindowBuilder::new()
-        .with_title("Hello world!")
-        .with_fullscreen(monitor);
+        .with_visible(false)
+        .with_title("test");
     let windowed_context = glutin::ContextBuilder::new()
         .build_windowed(wb, &el)
         .unwrap();
 
     let windowed_context = unsafe { windowed_context.make_current().unwrap() };
+    windowed_context.window().set_visible(true);
+
+    let current_monitor = windowed_context.window().current_monitor();
+    windowed_context.window().set_fullscreen(Some(current_monitor));
 
     let gl = support::load(&windowed_context.context());

The issue is not present when the window is created as visible from the start.

@goddessfreya
Copy link
Contributor

I can reproduce this if the window is set to be floating by default.

Add for_window [title="test"] floating enable to your ~/.config/i3/config. Then refresh your config (Mod-Shift-C by default).

@goddessfreya
Copy link
Contributor

goddessfreya commented Jun 24, 2019

@murarth You said you wanted to be X11 maintainer, yeah? Seams like a good issue to dip your toes in.

Edit: Also, please add your name to this wiki as a Tester please.

Edit: And maybe also join us here so you can get more interesting oddities.

@murarth
Copy link
Contributor

murarth commented Jun 24, 2019

Investigating issues is quickly making clear to me that I don't know anything about X11.

Nevertheless, I will take a look at this and, at least, see what I can learn.

(Also, I've added myself to the wiki and I am generally available on IRC.)

@murarth
Copy link
Contributor

murarth commented Jun 26, 2019

Okay, I've figured out what's happening:

When a window is created, its initial position is (0, 0) until the window manager updates this with the X server. If the window is visible upon creation, winit calls XMapRaised (and some other functions) during window creation and, by the time WindowBuilder::build returns, the window position typically has been updated.

However, when set_visible is called after window creation and immediately followed by a call to current_monitor, the X server still reports the window position as (0, 0) and winit uses this false position to find the current monitor. As a result, it always returns the leftmost screen.

EDIT: So, as for a way forward, either set_visible can wait for the event updating the window position (not sure how feasible that is) or applications can wait for the first WindowEvent::Moved(_) and set fullscreen at that time.

@felixrabe
Copy link
Contributor

EDIT: So, as for a way forward, either set_visible can wait for the event updating the window position (not sure how feasible that is) or applications can wait for the first WindowEvent::Moved(_) and set fullscreen at that time.

I'd prefer a solution that does not require a specific ordering of API calls on the application side.

@pwnorbitals
Copy link

@murarth is this issue still a problem now ? It has been a long time

@murarth
Copy link
Contributor

murarth commented Oct 7, 2020

I think this issue may have been fixed by #1252, which improved current monitor guessing on window creation.

@chrisduerr Can you confirm whether this issue is resolved?

@chrisduerr
Copy link
Contributor Author

chrisduerr commented Oct 7, 2020

Fullscreen startup is solved, but the positional issue is not.

It works sometimes, but is very inconsistent.

@chrisduerr chrisduerr changed the title Fullscreen at startup inconsistent on X11 Setting position on startup does not work reliably on X11 Oct 7, 2020
@BarePotato
Copy link

I just got done fighting position issues on Arch(5.16.16-arch1-1) with i3-gaps(4.20.1) with X.Org version: 1.21.1.3. For this example I am making a window the size of my full Display and positioning it over top of all. My monitors are laid out like this:
MonitorLayoutImage
When using just the builder and setting .with_position(P) the position is consistently down and to the left. The red square shows relative position:
MonitorLayoutImage
The size is correct, just the position is off.
When I then set the position after the builder using window.set_outer_position(P) the position is set correctly as expected.
This is the code used:

    let display_position = PhysicalPosition::new(0, 0);
    let display_size = PhysicalSize::new(5760, 3240);

    let event_loop = EventLoop::new();
    let window = WindowBuilder::new()
        .with_resizable(false)
        .with_transparent(false)
        .with_decorations(false)
        .with_always_on_top(true)
        .with_position(display_position)
        .with_inner_size(display_size)
        .build(&event_loop)?;

    window.set_outer_position(display_position);

When only setting size and position in builder and none of the other stuff, and then floating the i3 window, it lands in the incorrect position noted above even with the position set after the builder.

@BarePotato
Copy link

This seems to only be happening when setting the position to 0,0. If I set it to 0,1 it is then in the correct position for that coord.

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 C - needs investigation Issue must be confirmed and researched DS - x11
Development

No branches or pull requests

6 participants