slint icon indicating copy to clipboard operation
slint copied to clipboard

Slint apps constantly steal focus on Linux using winit on X11

Open hunger opened this issue 1 year ago • 6 comments

While showing the live preview in VSCode, each keypress in the editor makes the Slint preview window focus. That makes the live preview pretty unusable in combination with VSCode.

This happens on Linux using winit. WAYLAND_DISPLAY is unset, DISPLAY is set, so it should use X11.

It does not happen in these setups:

  • Linux using winit. WAYLAND_DISPLAY is set, so that it should use wayland.
  • Linux using the qt backend

Disabling the accessibility layer in the winit backend does not fix the issue either.

I think this is a upstream bug, but have not found any matching issue in winit.

hunger avatar Feb 23 '24 11:02 hunger

Does commenting out the code in the body of fn input_method_request in winitwindowadapter.rs help?

tronical avatar Feb 23 '24 12:02 tronical

Does this happen with any kind of slint code you're previewing (say just a Rectangle {}) or does this happen in particular when there are focusable elements present?

tronical avatar Feb 23 '24 12:02 tronical

I see the focus stealing with this example:

export component T inherits Rectangle {}

hunger avatar Feb 23 '24 12:02 hunger

Ok, what about fn input_method_request?

Can you reproduce this also with slint-viewer and --auto-reload?

tronical avatar Feb 23 '24 12:02 tronical

I have the feeling this might be related to the recent maximise/minimise feature. We might call too often to winit when the window attributes changes, even if it didn't change

ogoffart avatar Feb 23 '24 13:02 ogoffart

I cannot reproduce the issue on plasma (with the nightly build of our vscode extension). What are the step to reproduce? Does it also happen with the viewer?

ogoffart avatar Feb 26 '24 11:02 ogoffart

I build the slint-lsp and the Slint VSCode extension and start that. I open the preview for anything... and as long as the preview is open, it steals focus from VSCode whenever I type any character into VSCode.

The exact command line I use is this:

cd ~/<SLINT_REPO>/editors/vscode && cargo build -p slint-lsp && npm run build:wasm_lsp && npm run compile && npm run lint && RUST_BACKTRACE=full DISPLAY=:0 WAYLAND_DISPLAY="" SLINT_ENABLE_EXPERIMENTAL_FEATURES=1 code --extensionDevelopmentPath=$PWD ../../examples/

The npm run build:wasm_lsp is not necessary for the native preview, but I keep that around to cover both building native and in WASM mode :-)

I can reproduce this with DISPLAY=:0 WAYLAND_DISPLAY="" cargo run -p slint-viewer -- some.slint --auto-reload: Whenever I edit and save some.slint, the slint-viewer steals focus from the editor.

I am on Linux using Gnome and wayland by default with no Qt being installed on the system. I then set DISPLAY=:0 WAYLAND_DISPLAY="" before starting vscode or the viewer to force the SLint UI into X11 as I can not close the preview window on wayland.

hunger avatar Feb 29 '24 09:02 hunger

I can reproduce the problem. This is only on Gnome Xwayland (wayland compositor, but using X11 from Slint) As I suspected, this is related to minimize, as the problem disappear when commenting this line: https://github.com/slint-ui/slint/blob/3969e09d5bb15f9593ab3e1b9c5cb005c29d078a/internal/backends/winit/winitwindowadapter.rs#L492

Maybe we want to do something like this to workaround:

let value = properties.is_minimized();
if winit_window.is_minimized() != value {
    winit_window.set_minimized(value);
}

And the same for maximized.

This is a shame.

Alternative would be to remember in the winitwindowadapter which value was sent.

ogoffart avatar Feb 29 '24 10:02 ogoffart

This is a shame.

That's true :(

Alternative would be to remember in the winitwindowadapter which value was sent.

I think that we may have to do that.

I noticed two things on the Wayland side here (from reading the winit code):

  1. On wayland, you can't programmatically un-minimize a window.
  2. On wayland, fn is_minimized() always returns None, to indicate that it's not know to the client if the compositor changed the state.

This is also mentioned in the protocol docs at https://wayland.app/protocols/xdg-shell#xdg_toplevel:request:set_minimized:

There is no way to know if the surface is currently minimized, nor is there any way to unset minimization on this surface.

All this leads me to believe that the primary use of the programmatic API for these states is to set them once on startup. After that all bets are off in a cross-platform environment.

tronical avatar Feb 29 '24 10:02 tronical