Skip to main content

fluent_app/
window_title.rs

1use gpui::{App, Global, SharedString};
2
3/// Global window title/status state for FluentGUI applications.
4///
5/// `FluentApp` initializes this at startup. Views can update it later to keep
6/// platform chrome, custom title bars, and app-owned status surfaces in sync.
7#[derive(Clone, Debug, Default, PartialEq, Eq)]
8pub struct WindowTitle {
9    title: SharedString,
10    status: Option<SharedString>,
11}
12
13impl Global for WindowTitle {}
14
15impl WindowTitle {
16    pub fn new(title: impl Into<SharedString>) -> Self {
17        Self {
18            title: title.into(),
19            status: None,
20        }
21    }
22
23    pub fn with_status(mut self, status: impl Into<SharedString>) -> Self {
24        self.status = Some(status.into());
25        self
26    }
27
28    pub fn title(&self) -> &SharedString {
29        &self.title
30    }
31
32    pub fn status(&self) -> Option<&SharedString> {
33        self.status.as_ref()
34    }
35
36    pub fn init(cx: &mut App, title: impl Into<SharedString>) {
37        cx.set_global(Self::new(title));
38    }
39
40    pub fn set_title(cx: &mut App, title: impl Into<SharedString>) {
41        if cx.has_global::<Self>() {
42            cx.global_mut::<Self>().title = title.into();
43        } else {
44            Self::init(cx, title);
45        }
46    }
47
48    pub fn set_status(cx: &mut App, status: impl Into<SharedString>) {
49        if cx.has_global::<Self>() {
50            cx.global_mut::<Self>().status = Some(status.into());
51        } else {
52            cx.set_global(Self::new("").with_status(status));
53        }
54    }
55
56    pub fn clear_status(cx: &mut App) {
57        if cx.has_global::<Self>() {
58            cx.global_mut::<Self>().status = None;
59        }
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::WindowTitle;
66
67    #[test]
68    fn window_title_stores_title_and_status() {
69        let title = WindowTitle::new("Inbox").with_status("3 unread");
70
71        assert_eq!(title.title().as_ref(), "Inbox");
72        assert_eq!(title.status().map(|s| s.as_ref()), Some("3 unread"));
73    }
74
75    #[test]
76    fn window_title_status_is_optional() {
77        let title = WindowTitle::new("Inbox");
78
79        assert_eq!(title.title().as_ref(), "Inbox");
80        assert_eq!(title.status(), None);
81    }
82}