rust-windowing / winit

Window handling library in pure Rust

Home Page:https://docs.rs/winit/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Wayland metabug

elinorbgr opened this issue · comments

There are several issues with wayland. Most of them come from the fact that wayland does things differently than other platforms. I open this issue to list know issues and hopefully get discussion going about them.

Common problems

Resize/move do not work with Gnome

This is a bug in gnome that have been fixed now, you need at least gnome version 3.24.3, 3.25.3 or 3.26 (or newer) to have the fix.

The decorations are ugly / not native

Well, that's how wayland works. Clients are supposed to draw their own decorations. Winit uses wayland-window to draw them. I know they are ugly, and if you want to contribute to make them less ugly, please do! See the issue tracker of wayland-window for details.

The borders of my windows are not drawn the right size

This is perhaps the most regular issue, caused by several wayland particularities:

  • wayland clients are expected to draw their own borders
  • The dimensions of a wayland window is defined by the dimensions of its contents (with glutin, the EGL surface).

This means that winit know about the size of borders but not of the contents. Meaning the user needs to keep the two in sync by calling window.set_inner_size() appropriately. Hopefully at some point glutin will be able to handle it directly.

When your app receives a Resized event, winit has already changed the border size according to what you receive, so you don't need to manually resize the borders (unless you want an other size). Though you'll still need to resize your contents (your egl surface for example) to this new size.

My app crashes at startup with a message about a surface not being configured

See https://docs.rs/winit/0.8.2/winit/os/unix/trait.WindowExt.html#tymethod.is_ready

Note that depending on the wayland environment, this issue can manifest itself differently

#309 should help with that

Missing features to be implemented

These are known missing features with some hints about what needs to be done, if you want to help with some of it, please don't hesitate to ask on this issue for details or explanations.

Touch events

Currently touch event are completely ignored by winit, but it should be fairly straightforward to implement them in a similar way pointer events are.

The relevant implementation struct is here: https://docs.rs/wayland-client/0.11.3/wayland_client/protocol/wl_touch/struct.Implementation.html

Repeat keys

On wayland, key repeats are completely handled client-side. We need to figure out how to handle them, given the server sends us the delay before starting a delay and the repeat period. This might need some adapting of wayland-kbd.

Drag&drop / copy-paste

Both are handled by the same logic on wayland, from the wl_data_device_manager global. I'm in the process of figuring out how it should be used.

HiDPI handling (partly done)

Currently the backend correctly advertizes the dpi of each monitor as well as the expected drawn dpi for the windows, however it does not correctly translate it when sending the buffer to the server and does not generate HiDPIFactorChanged events.

Cursor image setting

Currently, Window::set_cursor is a stub. Should be implemented using wayland_client::cursor.

Window::set_cursor_state with CursorState::Hide will be handled the same way.

Cursor grabbing

Cursor grabbing is not supported by core wayland protcol, and will need to be implemented using the unstable pointer_constraints and relative_pointer protocol extensions.

Hide/Show the Window

Will likely require implementing it in wayland-window, by mapping/unmapping the shell_surface.

Key repeat: alacritty/alacritty#760

For the record, this is something that needs to be implemented in winit. The wayland server won't do the repeat itself, it only sends use what are the delay and repeat frequency, and we are supposed to handle it ourselves.

Now the big question is: how to we generate this stream of events?

Doesn't the server have some support for timers? Is that something that can be used by the client?

Well, libwayland-server.so does expose some timer API, but it is for internal use of the server only and not exposed by the protocol.

Though, it's just a light wrapper around a timerfd. The cleaner way I see currently to handle the repeating keys would be to use a timerfd ourselves, and hook it and the wayland event queue into a small mio event loop (which is perfectly possible, wayland does expose the required API).

hidpi_factor should actually compute the scale factor rather than hardcode 1.0. Alacritty needs this to properly scale fonts for the user.

Good point. Let's move to #315 to figure out the details.

Actually #105 is already there.

I am using Debian 9 with Gnome 3.22.3 on Wayland. When I launch example from wayland-window I am getting the following result:

Click to expand

1

Also it does not get handled correctly in the overview mode (not sure how it's properly called):
2

Also it looks like with_dimensions, with_fullscreen and with_title methods do not work at all. Example window can not be resized or moved. Not sure if it's winit problem or some bug on Debian side, but I thought it's worth to report it.

@newpavlov Ah, that's interesting.

Would you mind moving this to wayland-window's repository (as this is clearly a wayland-window issue) by opening an issue there, and providing with it the output of running this example with the WAYLAND_DEBUG=1 environment variable?

Let me make sure I understand. These are the current known issues with Wayland and Winit

Wayland Problems

  • Touch Events are not supported
  • Holding down a key does not perform Repeat Keys
  • Drag & Drop/Copy & Paste Doesn't work
  • HiDPI handling is un-implemented
  • Cannot set the cursor

I am uncertain of what Hide/Show the Window and Cursor Grabbing covers.

Hide/Show the window refers to the Window::show and Window::hide methods of winit, which currently have no effect on wayland.

Curso Grabbing is described in the CursorState::Grab

For the record, this is something that needs to be implemented in winit. The wayland server won't do the repeat itself, it only sends use what are the delay and repeat frequency, and we are supposed to handle it ourselves.

Now the big question is: how to we generate this stream of events?

You're right that wayland-server's timers won't help you. The only reason timers are there is because libwayland-server contains a lame event loop; they're not at all exposed over the protocol.

You'd have to hook a timer into the winit event loop and generate key events internally. Note that xkb_keymap_key_repeats will tell you whether or not a particular key-down event should repeat or not.

Have you taken a look at KDE's server side decoration protocol? I belive that wlroots (and by extension sway) and KDE Plasma both support this, so this is a decent solution for now. I think it is not an official protocol in wayland-protocols yet, but GTK has support for it and so does QT.

I could attempt to add this to winit but I have no experience with wayland so I can't really help. It'd take me some time before I could be able to work on this. The best solution for now would be to check whether this protocol is supported and request server side decorations, and if it's not there then just fallback to the decorations that winit itself draws

Yes, this is a known option.

Winit delegates the decoration-handling in wayland to wayland-window, and my goal was to implement this fallback in wayland-window: Smithay/wayland-window#25. It has just not been done yet, because I have a limited bandwidth...

For the record, I've implemented the server-side decoration protocol in SCTK, see Smithay/client-toolkit#20, using the now "standard" xdg-decoration protocol.

I don't know if many wayland compositors already implement it, though.

I noticed a new issue when using Alacritty on GNOME. When I move the cursor from the top of the screen to the bottom and it passes the window decoration they become invisible.
Seems to be some kind of hover-event bug or maybe mutter asks winit to redraw the decorations but it does not.

Is there any bug that matches this description? If not I will open a new one...

seems like a new mutter bug tbqh.

I'll close this bug, since there's no value in keeping it around anymore, especially knowing that mostly everything that was mentioned here was implemented. Specific issues should be reported as separate tickets.