Skip to main content

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