Skip to main content

ferroui_controls/platform/
x11_properties.rs

1use super::{IX11OptionsToplevelImplFeature, X11NetWmWindowType};
2use crate::{TopLevel, Window};
3use ferroui_base::platform::IOptionalFeatureProvider;
4use ferroui_base::{
5    ferro_properties, ferro_static_type, AttachedProperty, FerroProperty, FerroPropertyChangedEventArgs,
6};
7use std::rc::Rc;
8
9/// Set of X11 specific attached properties that allow deeper customization
10/// of the application per platform.
11pub struct X11Properties;
12
13ferro_static_type!(X11Properties);
14
15ferro_properties! {
16    impl X11Properties {
17        /// Defines the `NetWmWindowType` attached property: the window type
18        /// hint of the window.
19        pub fn net_wm_window_type_property() -> AttachedProperty<X11NetWmWindowType> {
20            FerroProperty::register_attached::<X11Properties, Window, _>("NetWmWindowType", X11NetWmWindowType::default())
21        }
22
23        /// Defines the `WmClass` attached property: the window class of
24        /// the window.
25        pub fn wm_class_property() -> AttachedProperty<Option<String>> {
26            FerroProperty::register_attached::<X11Properties, Window, _>("WmClass", None)
27        }
28    }
29}
30
31impl X11Properties {
32    fn static_constructor() {
33        Self::net_wm_window_type_property().changed().add_class_handler::<TopLevel>(Self::on_net_wm_window_type_changed);
34        Self::wm_class_property().changed().add_class_handler::<TopLevel>(Self::on_wm_class_changed);
35    }
36
37    pub fn set_net_wm_window_type(obj: &Window, value: X11NetWmWindowType) {
38        obj.set_value(Self::net_wm_window_type_property(), value)
39    }
40
41    pub fn get_net_wm_window_type(obj: &Window) -> X11NetWmWindowType {
42        obj.get_value(Self::net_wm_window_type_property())
43    }
44
45    pub fn set_wm_class(obj: &Window, value: Option<String>) {
46        obj.set_value(Self::wm_class_property(), value)
47    }
48
49    pub fn get_wm_class(obj: &Window) -> Option<String> {
50        obj.get_value(Self::wm_class_property())
51    }
52
53    fn try_get_feature(sender: &TopLevel) -> Option<Rc<dyn IX11OptionsToplevelImplFeature>> {
54        let platform_impl = sender.platform_impl()?;
55        let provider: &dyn IOptionalFeatureProvider = &*platform_impl;
56        provider.try_get::<dyn IX11OptionsToplevelImplFeature>()
57    }
58
59    fn on_wm_class_changed(sender: &TopLevel, e: &FerroPropertyChangedEventArgs<'_>) {
60        if let Some(feature) = Self::try_get_feature(sender) {
61            feature.set_wm_class(e.get_new_value::<Option<String>>().as_deref());
62        }
63    }
64
65    fn on_net_wm_window_type_changed(sender: &TopLevel, e: &FerroPropertyChangedEventArgs<'_>) {
66        if let Some(feature) = Self::try_get_feature(sender) {
67            feature.set_net_wm_window_type(e.get_new_value::<X11NetWmWindowType>());
68        }
69    }
70}