mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-05-24 05:40:15 +00:00
gtk: fix quick terminal breaking when manually toggled off while auto-hide is enabled (#12471)
Fixes quick terminal breaking when auto-hide is enabled and quick terminal is manually toggled off (#11679). `quick-terminal-autohide` is implemented by the `Window.propIsActive` function in `apprt/gtk/class/window.zig` which calls `Window.toggleVisibility` when the quick terminal window becomes inactive (loses focus). However `Window.propIsActive` is also triggered when you manually hide the quick terminal because hiding it causes the window to become inactive. Normally that should just toggle the quick terminal off and immediately back on, but there is also a re-entrancy issue. Manually toggling off the terminal causes the `Application.toggleQuickTerminal` (in `apprt/gtk/class/application.zig`) to run which sets off the call chain `Window.toggleVisibility -> gtk_widget_set_visible -> ... GTK signal/event handling ... -> Window.propIsActive -> Window.toggleVisibility -> gtk_widget_set_visible`. The nested calls to `gtk_widget_set_visible` cause the GTK window state to become corrupted. The window is marked visible, but is not actually visible or just shows a placeholder. What exactly happens depends on the compositor and how it handles moving window focus. Reproduced the bug on KDE and hyprland and verified the fix on both. ### Changes `apprt/gtk/class/window.zig`: added check to `Window.propIsActive` to only toggle quick-terminal if it is inactive **and** visible. ### AI Disclosure Found the bug without AI using "printf debugging" then traced it through GTK with valgrind. Used GPT5.4 in setting up valgrind and researching how signals/events move through GTK internally.
This commit is contained in:
@@ -1079,7 +1079,10 @@ pub const Window = extern struct {
|
||||
// Hide quick-terminal if set to autohide
|
||||
if (self.isQuickTerminal()) {
|
||||
if (self.getConfig()) |cfg| {
|
||||
if (cfg.get().@"quick-terminal-autohide" and self.as(gtk.Window).isActive() == 0) {
|
||||
if (cfg.get().@"quick-terminal-autohide" and
|
||||
self.as(gtk.Window).isActive() == 0 and
|
||||
self.as(gtk.Widget).isVisible() == 1)
|
||||
{
|
||||
self.toggleVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user