Skip to main content

miracle_plugin/
placement.rs

1use super::bindings;
2use super::container::*;
3use super::core::*;
4use super::window::*;
5use super::workspace::*;
6use glam::Mat4;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
9#[repr(u32)]
10pub enum WindowManagementStrategy {
11    /// Use the system default management strategy.
12    #[default]
13    System = 0,
14    /// Window will be placed in the tiling grid.
15    Tiled = 1,
16    /// Window behavior is entirely determined by the plugin.
17    Freestyle = 2,
18}
19
20impl From<WindowManagementStrategy> for bindings::miracle_window_management_strategy_t {
21    fn from(value: WindowManagementStrategy) -> Self {
22        value as bindings::miracle_window_management_strategy_t
23    }
24}
25
26impl TryFrom<bindings::miracle_window_management_strategy_t> for WindowManagementStrategy {
27    type Error = ();
28
29    fn try_from(
30        value: bindings::miracle_window_management_strategy_t,
31    ) -> Result<Self, Self::Error> {
32        match value {
33            0 => Ok(Self::System),
34            1 => Ok(Self::Tiled),
35            2 => Ok(Self::Freestyle),
36            _ => Err(()),
37        }
38    }
39}
40
41#[derive(Debug, Clone, Default)]
42pub struct TiledPlacement {
43    /// The parent container.
44    pub parent: Option<Container>,
45    /// The index at which to place the container.
46    pub index: u32,
47    /// The requested layout scheme.
48    pub layout_scheme: LayoutScheme,
49}
50
51impl From<TiledPlacement> for bindings::miracle_tiled_placement_t {
52    fn from(value: TiledPlacement) -> Self {
53        Self {
54            parent_internal: value.parent.map_or(0, |c| c.id()),
55            index: value.index,
56            layout_scheme: value.layout_scheme.into(),
57        }
58    }
59}
60
61/// Freestyle placement configuration.
62#[derive(Debug, Clone)]
63pub struct FreestylePlacement {
64    /// The top left position.
65    pub top_left: Point,
66    /// The depth layer.
67    pub depth_layer: DepthLayer,
68    /// The workspace
69    pub workspace: Option<Workspace>,
70    /// The size.
71    pub size: Size,
72    /// The 4x4 transform matrix applied to the window (column-major).
73    ///
74    /// Defaults to the identity matrix.
75    pub transform: Mat4,
76    /// The alpha (opacity) of the window.
77    ///
78    /// Defaults to 1.0 (fully opaque).
79    pub alpha: f32,
80    /// Whether the window can be resized.
81    ///
82    /// Defaults to true.
83    pub resizable: bool,
84    /// Whether the window can be moved.
85    ///
86    /// Defaults to true.
87    pub movable: bool,
88}
89
90impl Default for FreestylePlacement {
91    fn default() -> Self {
92        Self {
93            top_left: Point::default(),
94            depth_layer: DepthLayer::default(),
95            workspace: None,
96            size: Size::default(),
97            transform: Mat4::IDENTITY,
98            alpha: 1.0,
99            resizable: true,
100            movable: true,
101        }
102    }
103}
104
105impl From<FreestylePlacement> for bindings::miracle_freestyle_placement_t {
106    fn from(value: FreestylePlacement) -> Self {
107        Self {
108            top_left: value.top_left.into(),
109            depth_layer: value.depth_layer.into(),
110            workspace_internal: value.workspace.map_or(0, |w| w.id()),
111            size: value.size.into(),
112            transform: mat4_to_f32_array(value.transform),
113            alpha: value.alpha,
114            resizable: value.resizable as i32,
115            movable: value.movable as i32,
116        }
117    }
118}
119
120/// Placement configuration.
121#[derive(Debug, Clone)]
122pub struct Placement {
123    /// The placement strategy.
124    pub strategy: WindowManagementStrategy,
125    /// Freestyle placement (used if strategy is Freestyle).
126    pub freestyle: FreestylePlacement,
127    /// Tiled placement (used if strategy is Tiled).
128    pub tiled: TiledPlacement,
129}
130
131impl Default for Placement {
132    fn default() -> Self {
133        Self {
134            strategy: WindowManagementStrategy::default(),
135            freestyle: FreestylePlacement::default(),
136            tiled: TiledPlacement::default(),
137        }
138    }
139}
140
141impl Placement {
142    /// Set the values of a C placement struct from this Placement.
143    pub fn set_c(&self, out: &mut bindings::miracle_placement_t) {
144        out.strategy = self.strategy.into();
145        out.freestyle_placement = self.freestyle.clone().into();
146        out.tiled_placement = self.tiled.clone().into();
147    }
148}
149
150impl From<Placement> for bindings::miracle_placement_t {
151    fn from(value: Placement) -> Self {
152        Self {
153            strategy: value.strategy.into(),
154            freestyle_placement: value.freestyle.clone().into(),
155            tiled_placement: value.tiled.clone().into(),
156        }
157    }
158}