In order to fix gtk#1895 (closed) there needs to be a way for Wayland native applications to request their window be lowered. This probably requires another gtk_surface1 request like the one added in commit 177b4df2 to support presenting windows.
Designs
Child items
0
Show closed items
No child items are currently assigned. Use child items to break down this issue into smaller parts.
Linked items
0
Link issues together to show that they're related.
Learn more.
Related merge requests
5
When these merge requests are accepted, this issue will be closed automatically.
Opened a merge request that I could not test, don't hesitate to test if you know how to until I can finish this. This is my first time ever contribution to GNOME, so be patient. Thank you.
Merge request !1221 (closed) is opened that should implement this xdg-shell protocol. Is it possible to get guidance on how to move this feature forward now? Thank you.
Also created gtk!1821 (closed) for Gtk support, I don't know how to test with this version of mutter though. If anyone can give me guidance, I would be grateful.
Then, I'm thinking that ideally, it's not the application that should lower itself when middle clicking on the title bar. It's the application that should tell where the title bar is located, and the compositor, when it detects a middle click on this area, should lower the application.
What about other client-side decorated apps outside of the GNOME world. Are they expected to look-up gnome-shell preferences in org.gnome.desktop.wm.preferences.action-middle-click-titlebar? What about Firefox for instance?
If you are extending the private mutter<->gtk protocol, it is kinda expected that the feature does not have universal impact.
What about other client-side decorated apps outside of the GNOME world.
For this to be eventually universal, the protocol changes should happen in the xdg-shell protocol.
I think your concerns about a explicit .lower request put the finger on the reasons why it's not observed there yet.
ideally, it's not the application that should lower itself when middle clicking on the title bar. It's the application that should tell where the title bar is located
IMHO there's no need to forward everything to the compositor. I would also suggest to draw inspiration from how drags/resizes are handled via serial checks.
This could be a generic xdg_surface.titlebar_action(serial, button) request, where the client passes event serials. The compositor may check which device the serial corresponds to, and whether it's in a valid state to trigger a WM action. This leaves apps equally agnostic and compositors equally in control.
Then, I'm thinking that ideally, it's not the application that should lower itself when middle clicking on the title bar. It's the application that should tell where the title bar is located, and the compositor, when it detects a middle click on this area, should lower the application.
This was part of the original vision for Client Side Decorations, so that the user could move/close an application even when it stopped processing events. I don't know why it was forgotten/discarded/deprioritized. Possibly for the usual reasons: it's work and nobody stepped up to do it.
What about other client-side decorated apps outside of the GNOME world. Are they expected to look-up gnome-shell preferences in org.gnome.desktop.wm.preferences.action-middle-click-titlebar? What about Firefox for instance?
Firefox uses actual GTK widgets like HeaderBar, so maybe? I'm not that familiar with the Firefox codebase so I can't tell offhand if it only uses the widgets for rendering, or if it also allows them to handle events.
For this to be eventually universal, the protocol changes should happen in the xdg-shell protocol.
That would be lovely, but I'd hate for this feature to be postponed again in hopes of a better tomorrow.
This was part of the original vision for Client Side Decorations, so that the user could move/close an application even when it stopped processing events. I don't know why it was forgotten/discarded/deprioritized. Possibly for the usual reasons: it's work and nobody stepped up to do it.
Client Side Decorations has many benefits, but I thought that being able to interact with an unresponsive window is explicitly something that does not work when compared with traditional decorations.
I think it would be very interesting to explore a hybrid decorations approach, where clients can draw custom decorations but give enough information to the window manager to know how to manipulate the window, but I don't know of any proposal to do this.
In the mean time, finding an acceptable compromise is worth doing. With the current CSD implementation, even dragging a titlebar to move the window involves a fairly complex interaction between the client and the window manager. I think we can find a solution for middle-click window raise/lower that is no more complex than what is currently in place. The xdg_surface.titlebar_action approach mentioned above looks worthwhile to investigate.
I haven't answered, mostly because I have nothing to add.
For this to be eventually universal, the protocol changes should happen in the xdg-shell protocol.
That would be lovely, but I'd hate for this feature to be postponed again in hopes of a better tomorrow.
I agree with this, and although I suggested that we might find a better approach, I think we should fix this for the meantime as this issue is one of the top issues preventing people to switch to Wayland.
Is there any estimate if or when this could be merged?
I doubt that lowering by middle-click is a serious impediment to Wayland adoption.
Adding a simple lower request is fine, but I don't think we want engineer complicated protocols for communicating reactive areas between the compositor and the client.
xdg_surface.titlebar_action(serial, button) as proposed by @carlosg doesn't look complicated, and has the advantage that all policy is kept in the compositor (with the nice side effect that actions will be consistent between wayland and xwayland clients)
To get something working with the proposal of xdg_surface.titlebar_action(serial, button), I'll need a bit more help. I don't know the codebase and it's a little difficult to get around. I'll especially need help with the Gtk codebase where implementing lower was just implementing a function stub left empty, but implementing something like titlebar_action involves handling of the CSD events way before.
first, to get things working properly, it would be nice not to just implement lower, but to implement all the actions that are possible in frame.chandle_press_event (double-click, left, middle and right mouse click). All the possible actions are in meta_frame_titlebar_event function (shade-unshade, toggle-maximize, toggle-maximize-horizontally/vertically, minimize, lower, menu) of which the share/unshade probably does not makes sense with CSD.
Then, some actions are bound to the double click (maximize, which is implemented by the client currently). Ideally, this should be done by the server so it can force its policy across all windows. Unfortunately the double-click is something that's available in the ClutterEvent and when it gets forwarded to the client (meta-wayland-pointer.cmeta_wayland_pointer_send_button) the click_count of the clutter event is discarded. When the button click will come back to the server using the new protocol, either the double-click logic will have to be recomputed, or the clutter event would have to be saved to get the original click_count.
And the serial seems not to be stored anywhere for the server to check its validity. There is a serial stored in meta-wayland-pointer.c in function handle_button_event but it is for grabbing and it's saved only when implicit_grab is true, which I have no idea when it's triggered.
Knowing all of this, this is what I would do:
In meta_wayland_pointer_send_button, before the event is sent to the client, I would check if the event can trigger a titlebar logic (along the lines of handle_press_event in frame.c when running X11 window manager). If the click event is selected for titlebar action, its information will be saved as last possible titlebar click (serial, timestamp, click_count). Question: where to store this? In _MetaWaylandPointer along the grab_serial?
I would augment a gtk shell (I'd like to leave xdg out of it for now until we have something that can work, it will also help providing feedback to xdg discussions) with a request like following with all the information from the click event.
Handling this request, I would check the last potential titlebar click in the pointer object. In particular the serial, time, button and state must be identical. Depending on configuration, I would execute one of the configured actions (like meta_frame_titlebar_event). Question: How do I access the pointer object from the gtk-shell implementation? I suppose I have to get the seat object, but how do I know the current seat?
And last question: Would saving only the last potential titlebar click event is enough? Can the client request a titlebar click after another event is sent by the server? We can't reasonably store too many events.
Thanks for looking into this. It shines some light into the approach, and where it kind of falls apart IMHO. It's a bit awkward that the compositor would need to record events, and try to produce the gestures the client some how already detected. I discussed this with @carlosg on IRC just now, and have a probably much simpler approach, that will need minimal changes to both mutter and gtk:
The seat and serial is only used to how xdg_popup.grab works, as in, as a race condition mitigation (don't need to make it match).
Gtk would continue discovering "right click" vs "double click" etc, as it already knows how to do, and mutter wouldn't need to know anything of that - it'd just translate the "gesture" to meta_window_*() calls if the serial check passes.
What I regret with this is that the server cannot implement new gestures that the clients didn't implement first. Say in the future we want to implement some feature on triple-click or double-right-click, it will not be possible without the client cooperation. But that's perhaps the part in me preferring server-side decorations that's speaking here.
Else, this idea seems simpler to implement and have less complex runtime requirements. Except that the serial will still have to be saved before a click event is sent to the client so most of the code path that I hinted above still needs to be implemented (there are just less things to save on the server side)
Would we actually expect clients to ever send a value of left_click instead of starting a move operation?
The other values map very nicely to the existing action-right-click-titlebar, action-middle-click-titlebar and action-double-click-titlebar settings in org.gnome.desktop.wm.preferences ...
Would we actually expect clients to ever send a value of left_click instead of starting a move operation?
left_click should not trigger in interactive move. In gtk it's more complex than that - the pointer needs to be moved for a certain amount of pixels before it's turned into a move request. To make that a compositor triggered gesture, we'd have to have a pointer-drag like gesture.
Oh, I'm not suggesting to make "move" a compositor-triggered gesture. I'm questioning the usefulness of left_click
It needs special handling (it can't trigger on button-press like right/middle click because of double_click), and as we've never treated it as a configurable action in mutter, we'll very likely end up ignoring it in the compositor anyway.
Also, I wouldn't mind merging a lower action first to get the issue solved first. And yes, indeed, that's preventing some people from using Wayland (me for instance, and it has been listed as top issue in Wayland Itches, see https://hansdegoede.livejournal.com/21944.html)
Highlights
Middle click on title / header bar to lower the Window does not work for native apps. Multiple people have reported this issue to me. A similar issue was fixed for not being able to raise Windows. It should be easy to apply a similar fix for the lowering problem. There are bugs open for this here, here and here.
His post is the reason I found this bug and decided to dive in mutter code to get this fixed. I never contributed before. I'd really like to get this merged for the next GNOME version at least.