diff --git a/crates/ui/src/title_bar.rs b/crates/ui/src/title_bar.rs
index c371fa6b..21b1a7fa 100644
--- a/crates/ui/src/title_bar.rs
+++ b/crates/ui/src/title_bar.rs
@@ -1,3 +1,5 @@
+use std::rc::Rc;
+
use crate::{h_flex, theme::ActiveTheme, Icon, IconName, InteractiveElementExt as _, Sizable as _};
use gpui::{
div, prelude::FluentBuilder as _, px, relative, AnyElement, Div, Element, Hsla,
@@ -5,6 +7,12 @@ use gpui::{
StatefulInteractiveElement as _, Style, Styled, WindowContext,
};
+pub const TITLE_BAR_HEIGHT: Pixels = px(35.);
+#[cfg(target_os = "macos")]
+const TITLE_BAR_LEFT_PADDING: Pixels = px(80.);
+#[cfg(not(target_os = "macos"))]
+const TITLE_BAR_LEFT_PADDING: Pixels = px(12.);
+
/// TitleBar used to customize the appearance of the title bar.
///
/// We can put some elements inside the title bar.
@@ -12,35 +20,40 @@ use gpui::{
pub struct TitleBar {
base: Stateful
,
children: Vec
,
+ on_close_window: Option>>,
}
-pub const TITLE_BAR_HEIGHT: Pixels = px(35.);
-
impl TitleBar {
pub fn new() -> Self {
- // Leave more space for the macOS window controls.
- #[cfg(target_os = "macos")]
- let pl = px(80.);
- #[cfg(not(target_os = "macos"))]
- let pl = px(12.);
-
Self {
- base: div().id("title-bar").pl(pl),
+ base: div().id("title-bar").pl(TITLE_BAR_LEFT_PADDING),
children: Vec::new(),
+ on_close_window: None,
}
}
+
+ /// Add custom for close window event, default is None, then click X button will call `cx.remove_window()`.
+ /// Linux only, this will do nothing on other platforms.
+ pub fn on_close_window(mut self, f: impl Fn(&mut WindowContext) + 'static) -> Self {
+ if cfg!(target_os = "linux") {
+ self.on_close_window = Some(Rc::new(Box::new(f)));
+ }
+ self
+ }
}
// The Windows control buttons have a fixed width of 35px.
//
// We don't need implementation the click event for the control buttons.
// If user clicked in the bounds, the window event will be triggered.
-#[derive(IntoElement, Clone, Copy)]
+#[derive(IntoElement, Clone)]
enum ControlIcon {
Minimize,
Restore,
Maximize,
- Close,
+ Close {
+ on_close_window: Option>>,
+ },
}
impl ControlIcon {
@@ -56,8 +69,8 @@ impl ControlIcon {
Self::Maximize
}
- fn close() -> Self {
- Self::Close
+ fn close(on_close_window: Option>>) -> Self {
+ Self::Close { on_close_window }
}
fn id(&self) -> &'static str {
@@ -65,7 +78,7 @@ impl ControlIcon {
Self::Minimize => "minimize",
Self::Restore => "restore",
Self::Maximize => "maximize",
- Self::Close => "close",
+ Self::Close { .. } => "close",
}
}
@@ -74,12 +87,12 @@ impl ControlIcon {
Self::Minimize => IconName::WindowMinimize,
Self::Restore => IconName::WindowRestore,
Self::Maximize => IconName::WindowMaximize,
- Self::Close => IconName::WindowClose,
+ Self::Close { .. } => IconName::WindowClose,
}
}
fn is_close(&self) -> bool {
- matches!(self, Self::Close)
+ matches!(self, Self::Close { .. })
}
fn fg(&self, cx: &WindowContext) -> Hsla {
@@ -118,8 +131,12 @@ impl RenderOnce for ControlIcon {
let fg = self.fg(cx);
let hover_fg = self.hover_fg(cx);
let hover_bg = self.hover_bg(cx);
- let icon = self;
+ let icon = self.clone();
let is_linux = cfg!(target_os = "linux");
+ let on_close_window = match &icon {
+ ControlIcon::Close { on_close_window } => on_close_window.clone(),
+ _ => None,
+ };
div()
.id(self.id())
@@ -136,7 +153,13 @@ impl RenderOnce for ControlIcon {
Self::Minimize => cx.minimize_window(),
Self::Restore => cx.zoom_window(),
Self::Maximize => cx.zoom_window(),
- Self::Close => cx.remove_window(),
+ Self::Close { .. } => {
+ if let Some(f) = on_close_window.clone() {
+ f(cx);
+ } else {
+ cx.remove_window();
+ }
+ }
})
})
.hover(|style| style.bg(hover_bg).text_color(hover_fg))
@@ -146,7 +169,9 @@ impl RenderOnce for ControlIcon {
}
#[derive(IntoElement)]
-struct WindowControls {}
+struct WindowControls {
+ on_close_window: Option>>,
+}
impl RenderOnce for WindowControls {
fn render(self, cx: &mut WindowContext) -> impl IntoElement {
@@ -171,7 +196,7 @@ impl RenderOnce for WindowControls {
ControlIcon::maximize()
}),
)
- .child(ControlIcon::close())
+ .child(ControlIcon::close(self.on_close_window))
}
}
@@ -215,7 +240,9 @@ impl RenderOnce for TitleBar {
.flex_1()
.children(self.children),
)
- .child(WindowControls {}),
+ .child(WindowControls {
+ on_close_window: self.on_close_window,
+ }),
)
.when(is_linux, |this| {
this.child(