fractal/system_settings/
mod.rs

1use gtk::{glib, prelude::*, subclass::prelude::*};
2use tracing::error;
3
4#[cfg(target_os = "linux")]
5mod linux;
6
7/// The clock format setting.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, glib::Enum)]
9#[repr(u32)]
10#[enum_type(name = "ClockFormat")]
11pub enum ClockFormat {
12    /// The 12h format, i.e. AM/PM.
13    TwelveHours = 0,
14    /// The 24h format.
15    TwentyFourHours = 1,
16}
17
18impl Default for ClockFormat {
19    fn default() -> Self {
20        // Use the locale's default clock format as a fallback.
21        let local_formatted_time = glib::DateTime::now_local()
22            .and_then(|d| d.format("%X"))
23            .map(|s| s.to_ascii_lowercase());
24        match &local_formatted_time {
25            Ok(s) if s.ends_with("am") || s.ends_with("pm") => ClockFormat::TwelveHours,
26            Ok(_) => ClockFormat::TwentyFourHours,
27            Err(error) => {
28                error!("Could not get local formatted time: {error}");
29                ClockFormat::TwelveHours
30            }
31        }
32    }
33}
34
35mod imp {
36    use std::cell::Cell;
37
38    use super::*;
39
40    #[repr(C)]
41    pub struct SystemSettingsClass {
42        pub parent_class: glib::object::Class<glib::Object>,
43    }
44
45    unsafe impl ClassStruct for SystemSettingsClass {
46        type Type = SystemSettings;
47    }
48
49    #[derive(Debug, Default, glib::Properties)]
50    #[properties(wrapper_type = super::SystemSettings)]
51    pub struct SystemSettings {
52        /// The clock format setting.
53        #[property(get, builder(ClockFormat::default()))]
54        pub clock_format: Cell<ClockFormat>,
55    }
56
57    #[glib::object_subclass]
58    impl ObjectSubclass for SystemSettings {
59        const NAME: &'static str = "SystemSettings";
60        type Type = super::SystemSettings;
61        type Class = SystemSettingsClass;
62    }
63
64    #[glib::derived_properties]
65    impl ObjectImpl for SystemSettings {}
66}
67
68glib::wrapper! {
69    /// A sublassable API to access system settings.
70    pub struct SystemSettings(ObjectSubclass<imp::SystemSettings>);
71}
72
73impl SystemSettings {
74    pub fn new() -> Self {
75        #[cfg(target_os = "linux")]
76        let obj = linux::LinuxSystemSettings::new().upcast();
77
78        #[cfg(not(target_os = "linux"))]
79        let obj = glib::Object::new();
80
81        obj
82    }
83
84    /// Set the clock format setting.
85    fn set_clock_format(&self, clock_format: ClockFormat) {
86        if self.clock_format() == clock_format {
87            return;
88        }
89
90        self.imp().clock_format.set(clock_format);
91        self.notify_clock_format();
92    }
93}
94
95impl Default for SystemSettings {
96    fn default() -> Self {
97        Self::new()
98    }
99}
100
101/// Public trait that must be implemented for everything that derives from
102/// `SystemSettings`.
103pub trait SystemSettingsImpl: ObjectImpl {}
104
105unsafe impl<T> IsSubclassable<T> for SystemSettings
106where
107    T: SystemSettingsImpl,
108    T::Type: IsA<SystemSettings>,
109{
110}