diff --git a/crates/trawler/src/main.rs b/crates/trawler/src/main.rs --- a/crates/trawler/src/main.rs +++ b/crates/trawler/src/main.rs @@ -3271,9 +3271,13 @@ /// A window caption button (min/max/close) for the client-drawn titlebar. /// The `WindowControlArea` maps its bounds to the platform's native /// non-client hit-test (HTMINBUTTON etc. on Windows), so hover flyouts -/// (Snap Layouts) and clicks are OS-handled there; the `on_click` attached -/// at the call site covers paths that deliver plain clicks instead (e.g. -/// the test platform). +/// (Snap Layouts) and clicks are OS-handled there — including the +/// maximize/restore toggle. Deliberately no `on_click`: GPUI replays +/// non-client mouse events through the scene first, and a click listener +/// would consume them (stop propagation), suppressing the native handling +/// — with no way to restore a maximized window from app code +/// (`Window::zoom_window` only ever maximizes on Windows). A platform +/// that delivers plain clicks instead would need `on_click` fallbacks. fn caption_button( id: &'static str, icon_path: &'static str, @@ -3850,7 +3854,6 @@ .flex() .flex_col() .key_context(APP_CONTEXT) - .track_focus(&self.root_focus) .on_action(cx.listener(Self::navigate_back)) .on_action(cx.listener(Self::navigate_forward)) .on_action(cx.listener(Self::toggle_quick_open)) @@ -3988,10 +3991,7 @@ ) .child( caption_button("caption-min", "icons/minus.svg", WindowControlArea::Min) - .hover(|d| d.bg(rgb(0x2a2a3a))) - .on_click(cx.listener(|_, _: &ClickEvent, window, _| { - window.minimize_window(); - })), + .hover(|d| d.bg(rgb(0x2a2a3a))), ) .child( caption_button( @@ -4003,24 +4003,30 @@ }, WindowControlArea::Max, ) - .hover(|d| d.bg(rgb(0x2a2a3a))) - .on_click(cx.listener( - |_, _: &ClickEvent, window, _| { - window.zoom_window(); - }, - )), + .hover(|d| d.bg(rgb(0x2a2a3a))), ) .child( caption_button("caption-close", "icons/x.svg", WindowControlArea::Close) - .hover(|d| d.bg(rgb(0xc42b1c)).text_color(rgb(0xffffff))) - .on_click(cx.listener(|_, _: &ClickEvent, window, _| { - window.remove_window(); - })), + .hover(|d| d.bg(rgb(0xc42b1c)).text_color(rgb(0xffffff))), ), ) - .children(view_header) - .children(breadcrumb_bar) .child( + // Everything below the titlebar, and the app's click-to- + // focus scope. `track_focus` must NOT cover the titlebar: + // its implicit mouse-down listener prevent-defaults every + // left click, and the Windows backend treats a handled + // synthesized non-client mouse-down as "don't run the + // native handler" — which is what implements caption drag, + // double-click maximize, and the caption buttons. + div() + .flex() + .flex_col() + .flex_1() + .min_h_0() + .track_focus(&self.root_focus) + .children(view_header) + .children(breadcrumb_bar) + .child( // Main content row: the outline column (with its bottom // backlinks dock) fills the remaining width; the sidebar, // when open, sits to its right behind a drag handle. @@ -4551,6 +4557,7 @@ ) .children(sidebar_handle) .children(sidebar_panel), + ), ) .children(quick_open_overlay) .children(search_overlay)