gpui: Allow OS caption/buttons for custom Windows titlebar#48330
gpui: Allow OS caption/buttons for custom Windows titlebar#48330reflectronic merged 1 commit intozed-industries:mainfrom
Conversation
|
Can you explain the behavior you're seeing that you are trying to fix here? We already pass Is this for your own GPUI application? You should be able to make the caption buttons and title bar dragging work using a similar pattern as in the code I linked. |
|
Yes, this is for my own GPUI application. Thank you for pointing me to the Zed caption button implementation — I was able to narrow down the issue further. The problem is reproducible with just In let handled = !result.propagate || result.default_prevented;Since Zed's own titlebar works because Here is a minimal reproduction. Save it as use gpui::{
App, Application, Bounds, Context, FocusHandle, KeyBinding, Window, WindowBounds,
WindowControlArea, WindowOptions, actions, div, prelude::*, px, rgb, size,
};
actions!(custom_titlebar, [Quit]);
struct Demo {
focus_handle: FocusHandle,
}
impl Render for Demo {
fn render(&mut self, window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div()
.id("root")
.track_focus(&self.focus_handle) // <-- causes the bug
.flex()
.flex_col()
.bg(rgb(0x1e1e1e))
.text_color(rgb(0xdddddd))
.size_full()
.child(
div()
.flex()
.flex_row()
.h(px(32.))
.bg(rgb(0x2d2d2d))
.child(
div()
.flex_1()
.h_full()
.flex()
.items_center()
.px_2()
.window_control_area(WindowControlArea::Drag)
.child("Drag here"),
)
.child(
div()
.id("minimize")
.flex().items_center().justify_center()
.w(px(36.)).h_full()
.hover(|s| s.bg(rgb(0x555555)))
.window_control_area(WindowControlArea::Min)
.child("\u{2500}"),
)
.child(
div()
.id("maximize")
.flex().items_center().justify_center()
.w(px(36.)).h_full()
.hover(|s| s.bg(rgb(0x555555)))
.window_control_area(WindowControlArea::Max)
.child(if window.is_maximized() { "\u{25A3}" } else { "\u{25A1}" }),
)
.child(
div()
.id("close")
.flex().items_center().justify_center()
.w(px(36.)).h_full()
.hover(|s| s.bg(rgb(0xe81123)))
.window_control_area(WindowControlArea::Close)
.child("\u{2715}"),
),
)
.child(
div().flex_1().p_4().child(
"Try dragging the titlebar or clicking the caption buttons.",
),
)
}
}
fn main() {
Application::new().run(|cx: &mut App| {
cx.on_action(|_: &Quit, cx| cx.quit());
cx.bind_keys([KeyBinding::new("cmd-q", Quit, None)]);
cx.open_window(
WindowOptions {
titlebar: None,
window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
None, size(px(500.0), px(300.0)), cx,
))),
..Default::default()
},
|_, cx| cx.new(|cx| Demo { focus_handle: cx.focus_handle() }),
)
.unwrap();
cx.activate(true);
});
} |
2784926 to
3d3af76
Compare
|
I think the only change needed here, then, is: - let result = func(input);
- let handled = !result.propagate || result.default_prevented;
+ let handled = !func(input).propagate;I don't understand why |
3d3af76 to
2993d25
Compare
|
Thanks, agreed. I updated let handled = !func(input).propagate; I re-tested with the I also reduced the PR to this minimal behavior change. |
|
This change has introduced a regression (not in zed but in some GPUI apps) on Windows when you have a button in the navbar draggable area. Seems to work fine for MacOS. I've modified the above example to include a button. On Windows, when clicked, the event handler is not called anymore. use gpui::{
App, Application, Bounds, Context, FocusHandle, KeyBinding, Window, WindowBounds,
WindowControlArea, WindowOptions, actions, div, prelude::*, px, rgb, size,
};
actions!(custom_titlebar, [Quit]);
struct Demo {
focus_handle: FocusHandle,
}
impl Render for Demo {
fn render(&mut self, window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
div()
.id("root")
.track_focus(&self.focus_handle)
.flex()
.flex_col()
.bg(rgb(0x1e1e1e))
.text_color(rgb(0xdddddd))
.size_full()
.child(
div()
.flex()
.flex_row()
.h(px(32.))
.bg(rgb(0x2d2d2d))
.child(
div()
.flex_1()
.h_full()
.flex()
.items_center()
.px_2()
.window_control_area(WindowControlArea::Drag)
.child("Drag here")
.child(
div()
.child("Button here")
.id("button")
.cursor_pointer()
.on_click(|_, _, _| {
println!("CLICKED");
}),
),
)
.child(
div()
.id("minimize")
.flex()
.items_center()
.justify_center()
.w(px(36.))
.h_full()
.hover(|s| s.bg(rgb(0x555555)))
.window_control_area(WindowControlArea::Min)
.child("\u{2500}"),
)
.child(
div()
.id("maximize")
.flex()
.items_center()
.justify_center()
.w(px(36.))
.h_full()
.hover(|s| s.bg(rgb(0x555555)))
.window_control_area(WindowControlArea::Max)
.child(if window.is_maximized() {
"\u{25A3}"
} else {
"\u{25A1}"
}),
)
.child(
div()
.id("close")
.flex()
.items_center()
.justify_center()
.w(px(36.))
.h_full()
.hover(|s| s.bg(rgb(0xe81123)))
.window_control_area(WindowControlArea::Close)
.child("\u{2715}"),
),
)
.child(
div()
.flex_1()
.p_4()
.child("Try dragging the titlebar or clicking the caption buttons."),
)
}
}
fn main() {
Application::new().run(|cx: &mut App| {
cx.on_action(|_: &Quit, cx| cx.quit());
cx.bind_keys([KeyBinding::new("cmd-q", Quit, None)]);
cx.open_window(
WindowOptions {
titlebar: None,
window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
None,
size(px(500.0), px(300.0)),
cx,
))),
..Default::default()
},
|_, cx| {
cx.new(|cx| Demo {
focus_handle: cx.focus_handle(),
})
},
)
.unwrap();
cx.activate(true);
});
} |
Key changes: - Side-by-side diff UX improvements (zed-industries#48821) - major diff view polish - Display map refactoring - large cleanup of display_map.rs (~1000 line reduction) - Split editor growth (zed-industries#48753) - significant expansion of split.rs - Multi-char folds fix (zed-industries#48721) - New multi workspace (zed-industries#47795, then reverted zed-industries#48776) - Default view mode setting for SplittableEditor (zed-industries#48440) - macOS drag-drop fix: reset external_files_dragged (zed-industries#48727) - Windows: OS caption/buttons for custom titlebar (zed-industries#48330) - Windows timer resolution guard (zed-industries#48379) - Bedrock Claude Opus 4.6 model (zed-industries#48525) - MCP servers: fix disabled servers disappearing after restart (zed-industries#47758) - Shell command parser extracted to shared crate (zed-industries#48660) - Format-on-save for streaming edit file tool (zed-industries#48663) - Agent: insert images at cursor position (zed-industries#48779) - Project panel: improved file/folder creation in folded paths (zed-industries#46750) - Folding ranges panic fix (zed-industries#48809) - REPL: shutdown all kernels on app quit (zed-industries#48760) - Extension CI improvements - Security updates: time v0.3.47, git2 v0.20.4 Conflict resolution: - collab (Cargo.toml, extensions API, db, tests): deleted - GPUI (8 files): deleted from Glass (handled in Obsydian-HQ/gpui) - Cargo.lock: took upstream Co-Authored-By: Claude Opus 4.6 <[email protected]>
#48330 caused the title bar to start eating input events below these controls. We should find a way to make the title bar handling less busted, but this will do for now. Before you mark this PR as ready for review, make sure that you have: - [X] Added a solid test coverage and/or screenshots from doing manual testing - [X] Done a self-review taking into account security and performance aspects Release Notes: - N/A
#48330 caused the title bar to start eating input events below these controls. We should find a way to make the title bar handling less busted, but this will do for now. Before you mark this PR as ready for review, make sure that you have: - [X] Added a solid test coverage and/or screenshots from doing manual testing - [X] Done a self-review taking into account security and performance aspects Release Notes: - N/A
#48330 caused the title bar to start eating input events below these controls. We should find a way to make the title bar handling less busted, but this will do for now. Before you mark this PR as ready for review, make sure that you have: - [X] Added a solid test coverage and/or screenshots from doing manual testing - [X] Done a self-review taking into account security and performance aspects Release Notes: - N/A
…) (cherry-pick to stable) (#49783) Cherry-pick of #49781 to stable ---- #48330 caused the title bar to start eating input events below these controls. We should find a way to make the title bar handling less busted, but this will do for now. Before you mark this PR as ready for review, make sure that you have: - [X] Added a solid test coverage and/or screenshots from doing manual testing - [X] Done a self-review taking into account security and performance aspects Release Notes: - N/A Co-authored-by: John Tur <[email protected]>
…) (cherry-pick to preview) (#49782) Cherry-pick of #49781 to preview ---- #48330 caused the title bar to start eating input events below these controls. We should find a way to make the title bar handling less busted, but this will do for now. Before you mark this PR as ready for review, make sure that you have: - [X] Added a solid test coverage and/or screenshots from doing manual testing - [X] Done a self-review taking into account security and performance aspects Release Notes: - N/A Co-authored-by: John Tur <[email protected]>
Summary
Fixes an issue where GPUI's handling of
WM_NCLBUTTONDOWNprevented Windows from processing default titlebar interactions (dragging, caption buttons, and border resize).Changes
WM_NCLBUTTONDOWNevents forHTCAPTION, caption button areas, and resize border areas (HTLEFT,HTRIGHT,HTTOP,HTBOTTOM,HTTOPLEFT,HTTOPRIGHT,HTBOTTOMLEFT,HTBOTTOMRIGHT)WM_NCHITTESTfor accurate hit-testingTesting
Release Notes: