feat: improved dropdown menus - #328
Conversation
|
Sounds like this would also close #173 |
Yep it does, I missed that one. Added it to the description. |
0b685db to
009a7f8
Compare
# Conflicts: # crates/wayle-shell/src/shell/bar/modules/systray/item/methods.rs # crates/wayle-shell/src/shell/bar/modules/systray/item/mod.rs
|
Still in the process of reviewing, this is quite a chonker so I need to understand the intent, architecture and code - may take a bit. Though one regression I noticed is that, on multi-monitor setups previously, the dropdown would hide if we clicked somewhere on another monitor. Here's an example scenario in which you have 2 monitors DP-1, DP-2:
Now, that dropdown remains open unless you click somewhere on the monitor in which the dropdown is open. Which is a behavioral regression. Is there some way to tackle this, perhaps with cross monitor shims? We do have to be aware of not adding more complexity to satisfy this though. We'll have to make that tradeoff and whether this regression is worth the one click dropdown switching. |
Of course, take your time! Thanks for the review.
My choice to change this behavior was actually intentional. The things that made me lean toward the per-monitor dropdown design were
If you would like a global click-to-dismiss I do think it can be implemented without too much additional complexity. A few follow-up questions:
|
#285 was caused by GtkPopoverMenu not being able to scroll: so, a menu/submenu that was too tall would simply overflow the screen and become unusable. In the process of rewriting this, I ran into some issues with autohide popovers.
GTK's autohide popover is, on Wayland, a xdg_popup grab (captures pointer + keyboard). On Hyprland/wlroots that grab is inherently buggy in ways that seem to be unavoidable:
My solution is to introduce a scrim, a transparent full-screen window that intercepts mouse and keyboard input whenever a popover is open. This is similar to and inspired by the approach used by eww/AGS/Astal, which draw their popup menus as a child widget inside a transparent fullscreen window (for the same reasons, to avoid buggy autohide behavior). However, I wanted to allow users to quickly switch between dropdowns with a single click, similar to the behavior of the bar on MacOS. The eww/AGS/Astal approach would layer the scrim above the bar, making other bar buttons non-functional when a popup was open (clicking them would just close the currently open popup).
My approach keeps dropdowns as real GTK popovers parented to bar buttons (their own surfaces), and the scrim is only a dismiss catcher, never a content host. That gives GTK-native popover positioning/flip/scroll. and one-click dropdown switching is achieved by keeping the bar layered above the scrim.
Additionally, whenever a popup is open the bar (and popup) will now be layered above even full-screen applications (again matching the behavior of MacOS). This allows CLI dispatchers (keep reading) to function even when a full-screen app is open.
Finally, in implementing the scrim-based approach I ran into several focus-grabbing race conditions. The cleanest solution to these turned out to be centralizing dropdown dispatch into a single dropdown coordinator. This made it straightforward to implement a CLI to open/close/toggle dropdowns, which I also implemented. This can be used by:
which lists available dropdown menus; these can be opened and closed with
wayle dropdown open <name>orwayle dropdown toggle <name>. By default dropdowns are opened/closed on the currently active monitor (which is determined using compositor-specific features), but as a fallback they will open/close on all monitors. The monitor can be overridden by passing--monitor=<name>or--monitor=all. Similar CLI bindings can control systray icons (wayle systray openandwayle systray toggle), with the same--monitorsemantics.Closes #62, closes #285, closes #173.
Note the merge conflicts with my existing PRs; see merge commit here.
Extensively tested on Hyprland, but needs additional testing on other compositors (Sway, Niri, Mango, etc.).