Skip to main content

lattice_config/
window_options.rs

1// `linkme`'s distributed slices use `link_section` to aggregate
2// items at link time. The `options!` macro expansion in this file
3// emits such a declaration; allow the workspace's `unsafe_code =
4// "deny"` lint locally with the same safety rationale documented in
5// `option_decl.rs`, `group.rs`, and `core_options.rs`.
6#![allow(unsafe_code)]
7
8//! GPUI window options (`ui.window.*`). GPUI peer only; the TUI never reads
9//! these. `decorations` is applied at window creation; `start-maximized`
10//! drives a one-shot maximize on launch. See
11//! `docs/dev/architecture/gpui-window-chrome.md`.
12
13use crate::Decorations;
14
15crate::options! {
16    group = crate::Window;
17
18    /// OS window chrome (GPUI only; ignored by the terminal UI). One of:
19    ///   `full` (default) — system titlebar + window controls.
20    ///   `none` — borderless: no titlebar or controls, like alacritty
21    ///     `decorations = none` / kitty / emacs `undecorated`. On macOS a
22    ///     `none` window is non-resizable by any means — even Raycast/yabai
23    ///     can't move or resize it; it opens at a fixed size.
24    ///   `transparent` — frameless-looking but still resizable: a transparent
25    ///     titlebar with the traffic-light buttons hidden. Edge-resize works and
26    ///     window managers (Raycast/yabai) can drive it; rounded corners + shadow
27    ///     remain. The macOS-friendly frameless option.
28    /// Applied at window creation; a change takes effect on the next launch.
29    #[name("ui.window.decorations")]
30    pub WindowDecorationsOption: Decorations = Decorations::Full;
31
32    /// Maximize the window on launch (fill the work area, keep the menu
33    /// bar — not native fullscreen). GPUI peer only; ignored by the TUI.
34    #[name("ui.window.start-maximized")]
35    pub StartMaximized: bool = false;
36}
37
38#[cfg(test)]
39mod tests {
40    #![allow(clippy::unwrap_used, clippy::panic)]
41    use crate::{ConfigRegistry, Decorations, StartMaximized, WindowDecorationsOption};
42
43    fn reg() -> ConfigRegistry {
44        let r = ConfigRegistry::new();
45        r.init_from_linkme();
46        r
47    }
48
49    #[test]
50    fn defaults_match_spec() {
51        let r = reg();
52        assert_eq!(
53            *r.get_typed::<WindowDecorationsOption>().unwrap(),
54            Decorations::Full
55        );
56        assert!(!*r.get_typed::<StartMaximized>().unwrap());
57    }
58
59    #[test]
60    fn set_decorations_none_parses() {
61        let r = reg();
62        r.parse_and_set_command("ui.window.decorations=none")
63            .unwrap();
64        assert_eq!(
65            *r.get_typed::<WindowDecorationsOption>().unwrap(),
66            Decorations::None_
67        );
68    }
69
70    #[test]
71    fn set_start_maximized_true_parses() {
72        let r = reg();
73        r.parse_and_set_command("ui.window.start-maximized=true")
74            .unwrap();
75        assert!(*r.get_typed::<StartMaximized>().unwrap());
76    }
77
78    #[test]
79    fn bad_decorations_value_errors() {
80        let r = reg();
81        assert!(
82            r.parse_and_set_command("ui.window.decorations=wat")
83                .is_err()
84        );
85    }
86
87    // Regression: the `ui.window.*` options must resolve through the real TOML
88    // FILE path (load_file -> walk_table -> apply_scalar), not just the `:set`
89    // path — a `[ui.window]` table with hyphenated leaf keys must apply. This is
90    // the boundary a maximize-on-launch bug report pointed at (the read was fine;
91    // the bug was the apply mechanism).
92    #[test]
93    fn toml_file_path_applies_ui_window_table() {
94        let r = reg();
95        let dir = std::env::temp_dir();
96        let path = dir.join(format!("lattice_probe_{}.toml", std::process::id()));
97        std::fs::write(
98            &path,
99            "[ui.window]\ndecorations = \"none\"\nstart-maximized = true\n",
100        )
101        .unwrap();
102        let out = crate::load_file(&r, &path, &[]);
103        std::fs::remove_file(&path).ok();
104        assert!(out.messages.is_empty(), "load messages: {:?}", out.messages);
105        assert_eq!(
106            *r.get_typed::<WindowDecorationsOption>().unwrap(),
107            Decorations::None_,
108            "decorations from file"
109        );
110        assert!(
111            *r.get_typed::<StartMaximized>().unwrap(),
112            "start-maximized from file"
113        );
114    }
115}