open_sesame/platform/mod.rs
1//! Platform abstraction layer
2//!
3//! Provides traits for window management that can be implemented
4//! by different backends (Wayland, mock for testing).
5//!
6//! Includes COSMIC desktop integration for theming and fonts.
7
8pub mod cosmic_keys;
9pub mod cosmic_theme;
10pub mod fonts;
11pub mod wayland;
12
13use crate::core::window::{Window, WindowId};
14use crate::util::Result;
15
16/// Trait for window management operations
17///
18/// Provides an abstraction layer over platform-specific window management,
19/// enabling mocking in tests and potential support for multiple backends
20/// (Wayland, X11, mock implementations).
21///
22/// # Contract
23///
24/// Implementations must guarantee:
25/// - Window IDs returned by `list_windows()` are valid for `activate_window()`
26/// - Window list is ordered by most-recently-used (MRU), with current window first
27/// - Activation is idempotent (activating an already-focused window succeeds)
28///
29/// # Thread Safety
30///
31/// Implementations are not required to be `Send` or `Sync`. Callers should
32/// assume window manager operations must happen on the main thread.
33pub trait WindowManager {
34 /// List all windows on the desktop
35 ///
36 /// Returns windows in most-recently-used (MRU) order, with the currently
37 /// focused window at index 0. This ordering is critical for Alt+Tab behavior
38 /// (cycling should start from the previous window, not the current one).
39 ///
40 /// # Errors
41 ///
42 /// Returns `Err` if:
43 /// - Unable to connect to the display server (Wayland/X11)
44 /// - Required protocol extensions are unavailable
45 /// - Display server communication times out
46 /// - Insufficient permissions to enumerate windows
47 ///
48 /// # Examples
49 ///
50 /// ```ignore
51 /// let windows = wm.list_windows()?;
52 /// assert!(!windows.is_empty());
53 /// assert!(windows[0].is_focused); // First window should be focused
54 /// ```
55 fn list_windows(&self) -> Result<Vec<Window>>;
56
57 /// Activate (focus) a window by its ID
58 ///
59 /// Raises and focuses the specified window. If the window is already focused,
60 /// this operation succeeds without side effects (idempotent).
61 ///
62 /// # Parameters
63 ///
64 /// - `id`: Window ID obtained from `list_windows()`. Using an ID from a
65 /// different session or backend is undefined behavior.
66 ///
67 /// # Errors
68 ///
69 /// Returns `Err` if:
70 /// - Window ID is invalid or window has been closed
71 /// - Unable to communicate with the display server
72 /// - Compositor denies activation (security policy)
73 /// - Operation times out
74 ///
75 /// # Platform Notes
76 ///
77 /// **Wayland:** Uses `zcosmic_toplevel_manager_v1::activate()` which requires
78 /// COSMIC desktop environment. On other compositors, may fall back to raise-only.
79 ///
80 /// **X11:** Uses `XRaiseWindow()` + `XSetInputFocus()` which may be subject to
81 /// window manager policy (some WMs restrict focus stealing).
82 ///
83 /// # Examples
84 ///
85 /// ```ignore
86 /// let windows = wm.list_windows()?;
87 /// if let Some(prev) = windows.get(1) {
88 /// wm.activate_window(&prev.id)?;
89 /// }
90 /// ```
91 fn activate_window(&self, id: &WindowId) -> Result<()>;
92}
93
94/// Wayland window management implementation
95pub use wayland::{activate_window, enumerate_windows};
96
97/// COSMIC keybinding management functions
98pub use cosmic_keys::{keybinding_status, remove_keybinding, setup_keybinding};
99
100/// COSMIC theme integration
101pub use cosmic_theme::CosmicTheme;
102
103/// Font resolution utilities
104pub use fonts::{fontconfig_available, resolve_font, resolve_sans};