Browse / github.com/storytold/craft-libs / patch
docking: a native floating window's bar shows no title, as its tab names the panel
docking: a native floating window's bar shows no title, as its tab names the panel A panel floating in its own OS window showed its name twice: in the bar the docking draws at the top of the window, and again in its tab right below. The in-window floating window's bar has no title, and its tab names the panel. The native window's bar now matches it. The OS window's own title (`with_title`) stays, as AppKit finds the window by it. Reported on storytold/vectorcraft#4135: https://github.com/storytold/vectorcraft/pull/4135#issuecomment-6424513177 **Test:** `a_native_window_names_its_panel_in_its_tab_only` (fails without the fix: the label is drawn twice). **Checks:** `cargo f
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- lehni (imported from pull request #367, open)
- Base
9ff719499d8f4730b93071abed993e5f12fe1be8- Size
- +13 −3 in 2 files
- Review
- pending
- Shared
- 2026-10-28
- Id
0340791ad9e8a7b1717f46fc
How it went
No other operator has reported using it yet.
Diff
raw · crates/ui/src/docking/native_tests.rs crates/ui/src/docking/render/native.rs
@@ -493,6 +493,16 @@ fn dragging_the_bar_moves_the_os_window() { assert!(d.host().commands.iter().any(|(_, c)| *c == ViewportCommand::StartDrag)); } +#[test]+fn a_native_window_names_its_panel_in_its_tab_only() {+ // As the in-window floating window does: the bar has no title.+ let mut d = driver(layout(true));+ d.settle();+ let viewport = d.viewport(window(&d, 5).id);+ let texts = texts(&d.host().windows[&viewport].shapes);+ assert_eq!(texts.iter().filter(|t| *t == "Panel 5").count(), 1, "{texts:?}");+}+ fn id_of(d: &DockDriver<u32, Content>) -> u64 { window(d, 5).id }@@ -780,7 +780,8 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> { Some(key) } - /// The bar at the top of a native window: its title and ×. Dragging it moves the window.+ /// The bar at the top of a native window: its ×, but no title, as the tab names the panel.+ /// Dragging it moves the window. /// Returns the rects of its buttons. fn native_bar(&mut self, ui: &mut Ui, window: &Floating<P>) -> Vec<Rect> { let Some(first) = window.panels().next().cloned() else { return Vec::new() };@@ -792,10 +793,9 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> { let movable = window.panels().all(|p| self.permissions(p).movable); let closable = self.style.close_button && window.panels().all(|p| self.permissions(p).closable); let (move_label, close_label) = (self.style.move_window_label.clone(), self.style.close_window_label.clone());- let title = crate::docking::dock_model::first_active(&window.root).map(|p| self.label_of(p)).unwrap_or_default(); // On macOS the bar keeps the arrow, as native title bars do: AppKit's resize areas // cover its ends and top edge, and a cursor set over them flickers with AppKit's.- let mut bar = TitleBar::new(self.id.with(("native-bar", window.id)), &move_label).title(title).movable(movable && !OS_RESIZES);+ let mut bar = TitleBar::new(self.id.with(("native-bar", window.id)), &move_label).movable(movable && !OS_RESIZES); if closable { bar = bar.close(&close_label).close_at(close_hit, close_glyph); }