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

No way to avoid focus stealing on X11. #1160

Closed
Toqozz opened this issue Sep 13, 2019 · 4 comments · Fixed by #1176
Closed

No way to avoid focus stealing on X11. #1160

Toqozz opened this issue Sep 13, 2019 · 4 comments · Fixed by #1176
Labels
B - bug Dang, that shouldn't have happened C - needs investigation Issue must be confirmed and researched DS - x11

Comments

@Toqozz
Copy link
Contributor

Toqozz commented Sep 13, 2019

There seems to be no way to map a window without focusing it. I've only tested this on X11, but it may be present on other platforms as well given there is no WindowBuilder option to disable the behaviour.

On X11, this code is the culprit:

// Set visibility (map window)
if window_attrs.visible {
unsafe {
(xconn.xlib.XMapRaised)(xconn.display, window.xwindow);
} //.queue();
}

XMapRaised pushes the window to the top of the stack as well as maps the window.

There should be an option to disable this behaviour and map the window normally with XMapWindow().

@goddessfreya goddessfreya added DS - x11 C - needs investigation Issue must be confirmed and researched B - bug Dang, that shouldn't have happened labels Sep 13, 2019
@murarth
Copy link
Contributor

murarth commented Sep 17, 2019

I've run a quick test, changing both instances of XMapRaised (one in Window::new, the other in Window::set_visible) to XMapWindow and the window still steals focus when mapped. I suspect this is due to window manager behavior and likely varies from WM to another and may be affected by WM configuration.

Also, I'm a bit confused about the use case for this. Why would one want to create a window that does not steal focus?

@Toqozz
Copy link
Contributor Author

Toqozz commented Sep 18, 2019

It looks like there's more than one culprit. This code seems to focus the window again after mapping it:

(xconn.xlib.XSetInputFocus)(
xconn.display,
window.xwindow,
ffi::RevertToParent,
ffi::CurrentTime,
);

When I comment that code out, it allows the window to be mapped without stealing focus. (for testing, try with_x11_window_type(XWindowType::Notification) to avoid the window manager focusing it for you.)

Actually, I can't find a difference in behaviour between XMapRaised and XMapWindow on my WM (bspwm); they both either steal focus or don't steal focus depending on window type. I suspect that XMapRaised might actually mean raise window within subwindows, or maybe the behaviour differs between window managers.

The problem is that the code I linked above seems to focus the window regardless of window type.

Also, I'm a bit confused about the use case for this. Why would one want to create a window that does not steal focus?

Some examples include notification windows and tooltips. It's pretty annoying for a notification to steal focus and stop you from being able to type, and similarly tooltip windows could stop you from using shortcuts (not to mention the jankiness of the window getting greyed out every time a tooltip pops up).

@murarth
Copy link
Contributor

murarth commented Sep 18, 2019

Some examples include notification windows and tooltips.

Oh, I didn't realize a tooltip was its own window. It seems so obvious now.

Anyway, I tracked down the commit that introduced the code you referenced and I ended up at this issue: rust-windowing/glutin#509

It seems that the XSetInputFocus call was first introduced to fix an issue with fullscreen windows not receiving any keyboard input. As such, I believe the code could be changed to call XSetInputFocus only when Window::set_fullscreen is called. This way, all applications should experience correct behavior without having to jump through the hoops of explicitly disabling focus stealing.

I'll get started on a PR for this tomorrow.

@OvermindDL1
Copy link

Actually, I can't find a difference in behaviour between XMapRaised and XMapWindow on my WM (bspwm); they both either steal focus or don't steal focus depending on window type. I suspect that XMapRaised might actually mean raise window within subwindows, or maybe the behaviour differs between window managers.

As per the docs:

The XMapRaised() function essentially is similar to XMapWindow() in that it maps the window and all of its subwindows that have had map requests. However, it also raises the specified window to the top of the stack.

So yes, of the group of windows in the stack it also raises it to the top.

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

Successfully merging a pull request may close this issue.

4 participants