Skip to main content

incular_platform/
capabilities.rs

1//! Runtime platform capability snapshots.
2//!
3//! Capabilities describe the operations the active backend/session can
4//! actually honor. They are intentionally grouped by domain rather than
5//! flattened into one global bitset: a Wayland session, for example, can have
6//! excellent window/input support while deliberately lacking global placement.
7
8use crate::FileDialogCapabilities;
9use incular_config::TransientRole;
10
11/// Whether a portable platform capability is known to be available.
12#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
13pub enum CapabilitySupport {
14    /// No native backend has published a capability snapshot yet.
15    #[default]
16    Unknown,
17    /// The active backend/session can honor the operation.
18    Supported,
19    /// Incular or the active backend/session cannot honor the operation.
20    Unsupported,
21}
22
23impl CapabilitySupport {
24    #[must_use]
25    pub const fn is_supported(self) -> bool {
26        matches!(self, Self::Supported)
27    }
28
29    #[must_use]
30    pub const fn from_supported(supported: bool) -> Self {
31        if supported {
32            Self::Supported
33        } else {
34            Self::Unsupported
35        }
36    }
37}
38
39/// Portable operations performed on an already-created native window.
40#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
41pub struct WindowControlCapabilities {
42    pub set_title: CapabilitySupport,
43    pub set_visibility: CapabilitySupport,
44    pub set_logical_size: CapabilitySupport,
45    pub begin_move_drag: CapabilitySupport,
46    pub begin_resize_drag: CapabilitySupport,
47    pub minimize: CapabilitySupport,
48    pub maximize: CapabilitySupport,
49    pub fullscreen: CapabilitySupport,
50    pub set_resizable: CapabilitySupport,
51    pub set_decorations: CapabilitySupport,
52    pub set_size_limits: CapabilitySupport,
53    pub set_window_level: CapabilitySupport,
54    pub set_window_icon: CapabilitySupport,
55    pub request_user_attention: CapabilitySupport,
56    pub content_sensitivity: CapabilitySupport,
57    pub request_focus: CapabilitySupport,
58    pub request_redraw: CapabilitySupport,
59    pub close: CapabilitySupport,
60}
61
62/// Display discovery and top-level placement capabilities.
63#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
64pub struct DisplayPlacementCapabilities {
65    pub enumerate_displays: CapabilitySupport,
66    pub query_current_display: CapabilitySupport,
67    pub display_bounds: CapabilitySupport,
68    pub work_area: CapabilitySupport,
69    pub query_window_position: CapabilitySupport,
70    pub set_window_position: CapabilitySupport,
71}
72
73/// Native surface hosting for transient UI such as menus and popovers.
74#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
75pub struct TransientSurfaceCapabilities {
76    pub native_surface: CapabilitySupport,
77    pub popover: CapabilitySupport,
78    pub menu: CapabilitySupport,
79    pub context_menu: CapabilitySupport,
80    pub combo_box: CapabilitySupport,
81    pub tooltip: CapabilitySupport,
82}
83
84impl TransientSurfaceCapabilities {
85    #[must_use]
86    pub const fn support(self, role: TransientRole) -> CapabilitySupport {
87        match role {
88            TransientRole::Popover => self.popover,
89            TransientRole::Menu => self.menu,
90            TransientRole::ContextMenu => self.context_menu,
91            TransientRole::ComboBox => self.combo_box,
92            TransientRole::Tooltip => self.tooltip,
93        }
94    }
95}
96
97/// Operating-system application-menu integration.
98#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
99pub struct NativeMenuCapabilities {
100    pub application_menu: CapabilitySupport,
101}
102
103/// Data exchange with the operating system and other applications.
104#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
105pub struct DataTransferCapabilities {
106    pub clipboard_text: CapabilitySupport,
107    pub clipboard_rich: CapabilitySupport,
108    pub clipboard_custom: CapabilitySupport,
109    pub external_drag_drop: CapabilitySupport,
110    pub external_drag_drop_files: CapabilitySupport,
111    pub external_drag_drop_rich: CapabilitySupport,
112}
113
114/// Application-level desktop services that live outside ordinary widgets.
115#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
116pub struct ApplicationServiceCapabilities {
117    pub file_dialogs: FileDialogCapabilities,
118    pub global_shortcuts: CapabilitySupport,
119    pub single_instance_activation: CapabilitySupport,
120    pub tray_or_status_item: CapabilitySupport,
121    pub notifications: CapabilitySupport,
122    pub notification_actions: CapabilitySupport,
123    pub notification_update: CapabilitySupport,
124    pub notification_dismiss: CapabilitySupport,
125    pub taskbar_progress: CapabilitySupport,
126    pub application_badge: CapabilitySupport,
127    pub taskbar_overlay_icon: CapabilitySupport,
128}
129
130/// Device-rich input and native cursor facilities beyond basic pointer input.
131#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
132pub struct AdvancedInputCapabilities {
133    pub pointer_metadata: CapabilitySupport,
134    pub cursor_icons: CapabilitySupport,
135    pub cursor_visibility: CapabilitySupport,
136    pub cursor_position: CapabilitySupport,
137    pub cursor_confine: CapabilitySupport,
138    pub cursor_lock: CapabilitySupport,
139    pub stylus: CapabilitySupport,
140    pub trackpad_gestures: CapabilitySupport,
141}
142
143/// Complete capability snapshot published by a platform backend.
144///
145/// `Default` means "not discovered yet", not unsupported. Headless/custom
146/// embedders that intentionally provide no native services should publish
147/// [`Self::unsupported`] so callers can distinguish those states.
148#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
149pub struct PlatformCapabilities {
150    pub window: WindowControlCapabilities,
151    pub display: DisplayPlacementCapabilities,
152    pub transients: TransientSurfaceCapabilities,
153    pub menus: NativeMenuCapabilities,
154    pub data_transfer: DataTransferCapabilities,
155    pub application_services: ApplicationServiceCapabilities,
156    pub advanced_input: AdvancedInputCapabilities,
157}
158
159impl PlatformCapabilities {
160    /// A deterministic capability snapshot for a backend that intentionally
161    /// implements none of the native facilities represented here.
162    #[must_use]
163    pub const fn unsupported() -> Self {
164        let unsupported = CapabilitySupport::Unsupported;
165        Self {
166            window: WindowControlCapabilities {
167                set_title: unsupported,
168                set_visibility: unsupported,
169                set_logical_size: unsupported,
170                begin_move_drag: unsupported,
171                begin_resize_drag: unsupported,
172                minimize: unsupported,
173                maximize: unsupported,
174                fullscreen: unsupported,
175                set_resizable: unsupported,
176                set_decorations: unsupported,
177                set_size_limits: unsupported,
178                set_window_level: unsupported,
179                set_window_icon: unsupported,
180                request_user_attention: unsupported,
181                content_sensitivity: unsupported,
182                request_focus: unsupported,
183                request_redraw: unsupported,
184                close: unsupported,
185            },
186            display: DisplayPlacementCapabilities {
187                enumerate_displays: unsupported,
188                query_current_display: unsupported,
189                display_bounds: unsupported,
190                work_area: unsupported,
191                query_window_position: unsupported,
192                set_window_position: unsupported,
193            },
194            transients: TransientSurfaceCapabilities {
195                native_surface: unsupported,
196                popover: unsupported,
197                menu: unsupported,
198                context_menu: unsupported,
199                combo_box: unsupported,
200                tooltip: unsupported,
201            },
202            menus: NativeMenuCapabilities {
203                application_menu: unsupported,
204            },
205            data_transfer: DataTransferCapabilities {
206                clipboard_text: unsupported,
207                clipboard_rich: unsupported,
208                clipboard_custom: unsupported,
209                external_drag_drop: unsupported,
210                external_drag_drop_files: unsupported,
211                external_drag_drop_rich: unsupported,
212            },
213            application_services: ApplicationServiceCapabilities {
214                file_dialogs: FileDialogCapabilities::all(unsupported),
215                global_shortcuts: unsupported,
216                single_instance_activation: unsupported,
217                tray_or_status_item: unsupported,
218                notifications: unsupported,
219                notification_actions: unsupported,
220                notification_update: unsupported,
221                notification_dismiss: unsupported,
222                taskbar_progress: unsupported,
223                application_badge: unsupported,
224                taskbar_overlay_icon: unsupported,
225            },
226            advanced_input: AdvancedInputCapabilities {
227                pointer_metadata: unsupported,
228                cursor_icons: unsupported,
229                cursor_visibility: unsupported,
230                cursor_position: unsupported,
231                cursor_confine: unsupported,
232                cursor_lock: unsupported,
233                stylus: unsupported,
234                trackpad_gestures: unsupported,
235            },
236        }
237    }
238}