use bern_protocol::Value;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Presentation {
Native,
Virtual,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Visibility {
Visible,
Minimized,
Hidden,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SizeState {
Normal,
Maximized,
FullScreen,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum WindowAction {
Activate,
Close,
Minimize,
Restore,
Maximize,
Move,
Resize,
}
impl WindowAction {
pub const ALL: [WindowAction; 7] = [
WindowAction::Activate,
WindowAction::Close,
WindowAction::Minimize,
WindowAction::Restore,
WindowAction::Maximize,
WindowAction::Move,
WindowAction::Resize,
];
pub fn index(self) -> u32 {
Self::ALL.iter().position(|action| *action == self).unwrap() as u32
}
pub fn name(self) -> &'static str {
match self {
WindowAction::Activate => "activate",
WindowAction::Close => "close",
WindowAction::Minimize => "minimize",
WindowAction::Restore => "restore",
WindowAction::Maximize => "maximize",
WindowAction::Move => "move",
WindowAction::Resize => "resize",
}
}
pub fn from_bits(bits: u32) -> Vec<WindowAction> {
Self::ALL
.into_iter()
.filter(|action| bits & (1 << action.index()) != 0)
.collect()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FactSource {
Command,
System,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Frame {
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64,
}
#[derive(Clone, Debug, PartialEq)]
pub struct WindowFacts {
pub visibility: Visibility,
pub size: SizeState,
pub frame: Frame,
pub focused: bool,
pub actions: Vec<WindowAction>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Lifecycle {
Opening,
Open,
Closing,
}
#[derive(Clone, Debug, PartialEq)]
pub struct WindowInfo {
pub window: String,
pub kind: String,
pub presentation: Presentation,
pub lifecycle: Lifecycle,
pub facts: Option<WindowFacts>,
pub version: u64,
pub changed_by: Option<FactSource>,
}
impl WindowInfo {
pub fn to_value(&self) -> Value {
let variant = |index: usize| Value::unit_variant(index as u32);
let facts = self.facts.as_ref();
Value::Record(vec![
Value::Text(self.window.clone()),
Value::Text(self.kind.clone()),
variant(self.presentation as usize),
variant(self.lifecycle as usize),
variant(facts.map_or(Visibility::Hidden, |facts| facts.visibility) as usize),
variant(facts.map_or(SizeState::Normal, |facts| facts.size) as usize),
match facts {
Some(facts) => Value::some(Value::Record(vec![
Value::Float(facts.frame.x),
Value::Float(facts.frame.y),
Value::Float(facts.frame.width),
Value::Float(facts.frame.height),
])),
None => Value::none(),
},
Value::Bool(facts.is_some_and(|facts| facts.focused)),
Value::List(
facts
.map(|facts| facts.actions.as_slice())
.unwrap_or_default()
.iter()
.map(|action| variant(action.index() as usize))
.collect(),
),
Value::Int(self.version as i64),
match self.changed_by {
Some(source) => Value::some(variant(source as usize)),
None => Value::none(),
},
])
}
}