//! The titlebar duties: traffic-light pads and window controls, asserted per //! platform — macOS draws only pads, Windows/Linux only draw their controls. use gpui::{ AppContext as _, Entity, IntoElement, ParentElement as _, Pixels, Render, Styled as _, TestAppContext, VisualTestContext, Window, div, px, }; use gpui_native_layout::dock::{Dock, DockState, PanelDescriptor}; use gpui_native_layout::window_controls::TRAFFIC_LIGHT_PAD; use gpui_native_theme::Theme; struct Panel { tag: &'static str, } impl Render for Panel { fn render(&mut self, _window: &mut Window, _cx: &mut gpui::Context) -> impl IntoElement { div().size_full().child(self.tag) } } fn descriptor(tag: &'static str) -> PanelDescriptor { PanelDescriptor::new(tag, tag, move |_, cx| cx.new(|_| Panel { tag }).into()) } struct Harness { dock: Entity, window_controls: bool, traffic_light_pad: bool, } impl Render for Harness { fn render(&mut self, _window: &mut Window, _cx: &mut gpui::Context) -> impl IntoElement { div().size_full().child( Dock::new("test-dock", self.dock.clone()) .window_controls(self.window_controls) .traffic_light_pad(self.traffic_light_pad), ) } } fn dock_window( window_controls: bool, traffic_light_pad: bool, cx: &mut TestAppContext, ) -> (Entity, VisualTestContext) { cx.update(Theme::init); let dock = cx.update(DockState::new); let dock_for_window = dock.clone(); let window = cx.add_window(move |_, _| Harness { dock: dock_for_window, window_controls, traffic_light_pad, }); let mut visual = VisualTestContext::from_window(window.into(), cx); visual.update(|window, cx| window.draw(cx).clear(cx)); (dock, visual) } fn bounds(visual: &mut VisualTestContext, selector: &str) -> Option> { visual.debug_bounds(Box::leak(selector.to_string().into_boxed_str())) } fn open(visual: &mut VisualTestContext, dock: &Entity, tag: &'static str) { visual.update(|window, cx| { dock.update(cx, |dock, cx| dock.open_panel(tag, window, cx)); }); visual.update(|window, cx| window.draw(cx).clear(cx)); } #[cfg(target_os = "macos")] #[test] fn the_pill_bar_pads_for_traffic_lights_when_it_leads_the_window() { let mut cx = TestAppContext::single(); let (dock, mut visual) = dock_window(false, false, &mut cx); cx.update(|cx| { dock.update(cx, |dock, cx| { dock.register_panel(descriptor("overview"), cx) }); }); open(&mut visual, &dock, "overview"); let bar = bounds(&mut visual, "test-dock-pane-0-bar").expect("pill bar missing"); let tab = bounds(&mut visual, "test-dock-pane-0-tabs-tab-overview").expect("tab missing"); let bare_inset = tab.left() - bar.left(); let (dock, mut visual) = dock_window(false, true, &mut cx); let _ = &dock; cx.update(|cx| { dock.update(cx, |dock, cx| { dock.register_panel(descriptor("overview"), cx) }); }); open(&mut visual, &dock, "overview"); let padded_bar = bounds(&mut visual, "test-dock-pane-0-bar").expect("padded bar missing"); let padded_tab = bounds(&mut visual, "test-dock-pane-0-tabs-tab-overview").expect("tab missing"); let padded_inset = padded_tab.left() - padded_bar.left(); assert!( padded_inset - bare_inset >= px(TRAFFIC_LIGHT_PAD) - px(1.), "the pad must clear the traffic lights (bare {bare_inset:?}, padded {padded_inset:?})" ); } #[test] fn window_controls_render_only_when_the_flag_is_set() { let mut cx = TestAppContext::single(); let (dock, mut visual) = dock_window(false, false, &mut cx); cx.update(|cx| { dock.update(cx, |dock, cx| { dock.register_panel(descriptor("overview"), cx) }); }); open(&mut visual, &dock, "overview"); // macOS: the system traffic lights own the controls — nothing renders; // the pad test above covers that mode. #[cfg(not(target_os = "macos"))] assert!( bounds(&mut visual, "window-control-close").is_none(), "controls must not render without the flag" ); #[cfg(target_os = "macos")] let _ = (&dock, &mut visual); } #[cfg(not(target_os = "macos"))] #[test] fn the_flag_hosts_the_platform_controls_in_the_bar() { let mut cx = TestAppContext::single(); let (dock, mut visual) = dock_window(true, false, &mut cx); cx.update(|cx| { dock.update(cx, |dock, cx| { dock.register_panel(descriptor("overview"), cx) }); }); open(&mut visual, &dock, "overview"); // The maximize control exists once; its restore flip follows the // window's maximized state, not a separate control. assert!(bounds(&mut visual, "window-control-close").is_some()); assert!(bounds(&mut visual, "window-control-maximize").is_some()); }