//! Session lock on `Windows`: installing the per-output lock surfaces and
//! entering / leaving the locked view. The lock surfaces themselves live in
//! `View::Lock` (primary) and `extra_locks` (extend screens).

use super::*;

impl Windows {
    pub fn set_lock_surface(
        &mut self,
        surface: LockSurface,
        wl_output: &smithay::reexports::wayland_server::protocol::wl_output::WlOutput,
    ) {
        let transform = self.output.orientation().surface_transform();

        // A lock surface belongs to one wl_output. Extras get their own,
        // painted by their head's scene; anything unmatched lands on the
        // primary, matching the old single-output behaviour.
        if let Some(extra) = self
            .extra_outputs
            .iter()
            .find(|o| o.smithay_output().owns(wl_output))
        {
            let scale = extra.scale();
            let size = extra.size();
            let name = extra.smithay_output().name();
            let mut window = Window::new(surface, scale, transform, None);
            window.set_dimensions(scale, Rectangle::from_size(size));
            // Extra locks sit outside the transaction pipeline, so the rect
            // must be applied here or it stays 0x0 and nothing renders.
            window.apply_transaction();
            self.extra_locks.retain(|(n, _)| *n != name);
            self.extra_locks.push((name, Box::new(window)));
            self.dirty = true;
            return;
        }

        let scale = self.output.scale();
        let size = self.output.size();

        let View::Lock(lock_window) = self.pending_view_mut() else { return };

        let mut window = Window::new(surface, scale, transform, None);
        window.set_dimensions(scale, Rectangle::from_size(size));

        *lock_window = Some(Box::new(window));
    }

    pub fn lock(&mut self) {
        self.extra_locks.clear();
        self.set_view(View::Lock(None));
    }

    pub fn is_locked(&self) -> bool {
        matches!(self.pending_view(), View::Lock(_))
    }

    pub fn unlock(&mut self) {
        self.extra_locks.clear();
        self.start_transaction().view = Some(View::Workspace);
    }
}
