Repository navigation
gtk: fix context menu hiding quick-terminal - #12843
Conversation
…settle. Depending on the backend a window might temporarily become inactive. Fixes an issue where quick-terminal would disappear when opening the surface context menu.
| quick_terminal: bool = false, | ||
|
|
||
| /// Timeout source to react to this window becoming (in)active. | ||
| timeout: ?c_uint = null, |
There was a problem hiding this comment.
This variable should be more descriptive of it's purpose so you don't have to refer back to the docstring to see what it does.
| } | ||
| } | ||
|
|
||
| fn onTimeout(ud: ?*anyopaque) callconv(.c) c_int { |
There was a problem hiding this comment.
This function name should be more descriptive of what it does. Should also have a short docstring describing it's function.
| // become inactive and immediately active again. This happens | ||
| // e.g. on Wayland when opening a context menu. | ||
| if (priv.timeout == null) priv.timeout = glib.timeoutAdd( | ||
| 100, |
There was a problem hiding this comment.
Did you experiment at all with shorter timeouts? We should probably document the source of this magic number.
There was a problem hiding this comment.
Thank you for the review! I already did a bunch of experimenting and some more today. On my own setup with Hyprland even a small delay like 1ms or just an idle callback works reliably. In a Nix VM with KDE Plasma6 anything lower than 25ms only works some of the time, just an idle callback actually works most of the time there, but also not always.
I think a smaller timeout like 50ms together with the priority of an idle callback strikes a good balance. Since an idle callback is already enough most of the time, this should be reliable. For now there is probably also no harm in being safe and choosing a higher value, 50ms delay in hiding the quick-terminal should barely be noticeable.
|
|
||
| if (priv.timeout) |v| { | ||
| if (glib.Source.remove(v) == 0) { | ||
| log.warn("unable to remove timeout source", .{}); |
There was a problem hiding this comment.
Warning should be more descriptive of what timeout can't be removed.
Fixes #12783 where opening the context menu (with right click) inside the quick-terminal will hide the quick-terminal if autohide is enabled.
The cause of this issue is the quick-terminal window becoming inactive and immediately active again when you open the context-menu. When the window becomes inactive, the autohide feature hides the quick-terminal. The temporary focus loss in GTK is triggered by GDK focus change events, which probably originate from the windowing backend treating the context menu as its own window. Whereas in GTK the context menu is not a separate window but instead part of the widget tree of the window it was opened from, so even when the context menu has focus that window is still the active one in GTK.
As a fix
Window.propIsActive, which implements the autohide logic, will now do its work from a timeout callback, since there is probably no reliable way to distinguish a temporary focus loss from a real one from inside GTK and I'm not sure we can make any assumptions about the timing of things happening in the windowing backend. A 100ms delay should be long enough for the focus state to settle while still hiding the quick-terminal quickly.I reproduced the bug and verified the fix on Wayland with both Hyprland and KDE. Temporary focus loss happens on X11+KDE as well, although it doesn't matter there because there is no quick-terminal.
AI Disclosure
No AI was used, code and comments were written by myself.