From 08f8d16a884fe67576d9a48103a5cd5d23d36f31 Mon Sep 17 00:00:00 2001 From: thomas Date: Fri, 24 Jul 2026 15:51:25 +0800 Subject: [PATCH] fix(settings): the theme panel's close button did nothing on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The settings overlay covers the real title bar, so it lays its own drag band across the top 40px -- absolute, full width, tagged `WindowControlArea::Drag`. The theme panel docks to the window's top edge beside it, which puts its header's `×` inside that band. On Windows the band is `HTCAPTION`. gpui resolves the control area in `Window::hit_test` by walking hitboxes top-down and stopping only at a `HitboxBehavior::BlockMouse`; a plain `Button` isn't one, so the band's hitbox stayed in `mouse_hit_test.ids`, the hit-test callback answered `Drag`, and the OS took every press on the `×` as a window-drag. The button's `on_click` never fired. `occlude()` on the button ends the walk there, which is the same fix the tab-strip chips carry and the one the page's own `×` has had since it was written. Scoped to the button so the rest of the header still drags the window. No-op on macOS and Linux. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/ui/settings.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/ui/settings.rs b/src/ui/settings.rs index 849dab67..6ee32d7f 100644 --- a/src/ui/settings.rs +++ b/src/ui/settings.rs @@ -3557,11 +3557,22 @@ impl Tty7App { .child("Themes"), ) .child( - Button::new("theme-panel-close") - .icon(IconName::Close) - .ghost() - .small() - .on_click(cx.listener(|this, _, _w, cx| this.close_theme_panel(cx))), + // The panel is docked to the window's top edge, so this `×` sits + // inside the settings overlay's stand-in title-bar strip — an + // absolute `WindowControlArea::Drag` band across the top 40px + // (see `root` below). On Windows that band is `HTCAPTION`, and + // unless something on top registers a mouse-blocking hitbox the + // OS takes the press as a window-drag and the button's `on_click` + // never fires. `occlude()` stops hit-testing here, the same way + // the tab-strip chips and the page's own `×` do. No-op elsewhere; + // the rest of the header still drags the window. + div().occlude().child( + Button::new("theme-panel-close") + .icon(IconName::Close) + .ghost() + .small() + .on_click(cx.listener(|this, _, _w, cx| this.close_theme_panel(cx))), + ), ); let subtitle = div()