gpui/platform/desktop_preferences.rs
1//! Optional desktop preferences for toolkit-owned window frames.
2
3/// Desktop preferences exposed by the platform, independent of a particular toolkit.
4///
5/// `None` means unavailable or unset, not an instruction to override an app's defaults.
6/// Linux reads Settings portal keys with optional native desktop fallbacks; other
7/// platforms currently return an empty snapshot. Color scheme and button placement
8/// retain their existing separate APIs.
9/// These preferences do not change application styling or behavior automatically.
10#[derive(Clone, Debug, Default, PartialEq)]
11pub struct DesktopPreferences {
12 /// Preferred accent as encoded sRGB components in the inclusive range 0–1.
13 pub accent_color: Option<[f32; 3]>,
14 /// Whether the desktop explicitly requests high contrast.
15 pub high_contrast: Option<bool>,
16 /// Whether the desktop explicitly requests reduced motion.
17 pub reduced_motion: Option<bool>,
18 /// Positive logical text scale, independent of device/display scaling.
19 pub text_scale: Option<f32>,
20 /// Desktop font description, for example `Cantarell 11`; not a font family alone.
21 pub font: Option<String>,
22 /// Preferred title-bar double-click action, when exposed by the desktop.
23 pub titlebar_double_click: Option<TitlebarAction>,
24 /// Preferred title-bar middle-click action, when exposed by the desktop.
25 pub titlebar_middle_click: Option<TitlebarAction>,
26 /// Preferred title-bar right-click action, when exposed by the desktop.
27 pub titlebar_right_click: Option<TitlebarAction>,
28}
29
30/// A supported desktop title-bar action. Unsupported actions remain unavailable.
31#[derive(Clone, Copy, Debug, PartialEq, Eq)]
32pub enum TitlebarAction {
33 /// Intentionally take no action.
34 None,
35 /// Toggle maximization when the window supports it.
36 ToggleMaximize,
37 /// Minimize when the window supports it.
38 Minimize,
39 /// Display the platform window menu when supported.
40 Menu,
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46 use std::{cell::RefCell, rc::Rc};
47
48 #[gpui::test]
49 fn observers_read_the_new_snapshot_and_stop_when_dropped(cx: &mut crate::TestAppContext) {
50 let received = Rc::new(RefCell::new(Vec::new()));
51 let observations = received.clone();
52 let subscription = cx.update(|app| {
53 assert_eq!(app.desktop_preferences(), DesktopPreferences::default());
54 app.observe_desktop_preferences(move |app| {
55 observations.borrow_mut().push(app.desktop_preferences());
56 })
57 });
58 let preferences = DesktopPreferences {
59 high_contrast: Some(true),
60 reduced_motion: Some(false),
61 text_scale: Some(1.5),
62 ..Default::default()
63 };
64 cx.test_platform()
65 .simulate_desktop_preferences(preferences.clone());
66 assert_eq!(*received.borrow(), vec![preferences]);
67 drop(subscription);
68 cx.test_platform()
69 .simulate_desktop_preferences(DesktopPreferences::default());
70 assert_eq!(received.borrow().len(), 1);
71 cx.update(|app| assert_eq!(app.desktop_preferences(), DesktopPreferences::default()));
72 }
73}