1use bern_protocol::Value;
11
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub enum Presentation {
15 Native,
17 Virtual,
19}
20
21#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23pub enum Visibility {
24 Visible,
25 Minimized,
26 Hidden,
28}
29
30#[derive(Clone, Copy, Debug, PartialEq, Eq)]
31pub enum SizeState {
32 Normal,
33 Maximized,
34 FullScreen,
35}
36
37#[derive(Clone, Copy, Debug, PartialEq, Eq)]
39pub enum WindowAction {
40 Activate,
41 Close,
42 Minimize,
43 Restore,
44 Maximize,
45 Move,
46 Resize,
47}
48
49impl WindowAction {
50 pub const ALL: [WindowAction; 7] = [
51 WindowAction::Activate,
52 WindowAction::Close,
53 WindowAction::Minimize,
54 WindowAction::Restore,
55 WindowAction::Maximize,
56 WindowAction::Move,
57 WindowAction::Resize,
58 ];
59
60 pub fn index(self) -> u32 {
61 Self::ALL.iter().position(|action| *action == self).unwrap() as u32
62 }
63
64 pub fn name(self) -> &'static str {
65 match self {
66 WindowAction::Activate => "activate",
67 WindowAction::Close => "close",
68 WindowAction::Minimize => "minimize",
69 WindowAction::Restore => "restore",
70 WindowAction::Maximize => "maximize",
71 WindowAction::Move => "move",
72 WindowAction::Resize => "resize",
73 }
74 }
75
76 pub fn from_bits(bits: u32) -> Vec<WindowAction> {
78 Self::ALL
79 .into_iter()
80 .filter(|action| bits & (1 << action.index()) != 0)
81 .collect()
82 }
83}
84
85#[derive(Clone, Copy, Debug, PartialEq, Eq)]
87pub enum FactSource {
88 Command,
90 System,
92}
93
94#[derive(Clone, Copy, Debug, PartialEq)]
97pub struct Frame {
98 pub x: f64,
99 pub y: f64,
100 pub width: f64,
101 pub height: f64,
102}
103
104#[derive(Clone, Debug, PartialEq)]
106pub struct WindowFacts {
107 pub visibility: Visibility,
108 pub size: SizeState,
109 pub frame: Frame,
110 pub focused: bool,
111 pub actions: Vec<WindowAction>,
112}
113
114#[derive(Clone, Copy, Debug, PartialEq, Eq)]
116pub enum Lifecycle {
117 Opening,
119 Open,
120 Closing,
122}
123
124#[derive(Clone, Debug, PartialEq)]
126pub struct WindowInfo {
127 pub window: String,
128 pub kind: String,
129 pub presentation: Presentation,
130 pub lifecycle: Lifecycle,
131 pub facts: Option<WindowFacts>,
133 pub version: u64,
135 pub changed_by: Option<FactSource>,
136}
137
138impl WindowInfo {
139 pub fn to_value(&self) -> Value {
142 let variant = |index: usize| Value::unit_variant(index as u32);
143 let facts = self.facts.as_ref();
144 Value::Record(vec![
145 Value::Text(self.window.clone()),
146 Value::Text(self.kind.clone()),
147 variant(self.presentation as usize),
148 variant(self.lifecycle as usize),
149 variant(facts.map_or(Visibility::Hidden, |facts| facts.visibility) as usize),
150 variant(facts.map_or(SizeState::Normal, |facts| facts.size) as usize),
151 match facts {
152 Some(facts) => Value::some(Value::Record(vec![
153 Value::Float(facts.frame.x),
154 Value::Float(facts.frame.y),
155 Value::Float(facts.frame.width),
156 Value::Float(facts.frame.height),
157 ])),
158 None => Value::none(),
159 },
160 Value::Bool(facts.is_some_and(|facts| facts.focused)),
161 Value::List(
162 facts
163 .map(|facts| facts.actions.as_slice())
164 .unwrap_or_default()
165 .iter()
166 .map(|action| variant(action.index() as usize))
167 .collect(),
168 ),
169 Value::Int(self.version as i64),
170 match self.changed_by {
171 Some(source) => Value::some(variant(source as usize)),
172 None => Value::none(),
173 },
174 ])
175 }
176}