cranpose 0.1.162

Cranpose runtime and UI facade
Documentation
use cranpose_services::{LifecycleState, window_lifecycle_state};
use winit::{event::WindowEvent, window::WindowId};

pub(crate) struct WindowPresence {
    primary: WindowId,
    focused: Vec<WindowId>,
    occluded: bool,
    minimized: bool,
    published: LifecycleState,
}

impl WindowPresence {
    pub(crate) fn shown(primary: WindowId) -> Self {
        Self {
            primary,
            focused: vec![primary],
            occluded: false,
            minimized: false,
            published: LifecycleState::Resumed,
        }
    }

    pub(crate) fn observe(&mut self, window: WindowId, event: &WindowEvent) {
        let primary = window == self.primary;
        match event {
            WindowEvent::Focused(true) if !self.focused.contains(&window) => {
                self.focused.push(window);
            }
            WindowEvent::Focused(false) | WindowEvent::Destroyed => {
                self.focused.retain(|focused| *focused != window);
            }
            WindowEvent::Occluded(occluded) if primary => self.occluded = *occluded,
            WindowEvent::SurfaceResized(size) if primary => {
                self.minimized = size.width == 0 || size.height == 0;
            }
            _ => {}
        }
    }

    pub(crate) fn settled(&mut self) -> Option<LifecycleState> {
        let visible = !self.occluded && !self.minimized;
        let state = window_lifecycle_state(visible, !self.focused.is_empty());
        if state == self.published {
            return None;
        }
        self.published = state;
        Some(state)
    }
}

#[cfg(test)]
#[path = "tests/desktop_lifecycle.rs"]
mod tests;