atagen

monolith

public
Star0
Watch0
d9aeb9e28e74d14bc8c35504f26fb3706ba3cf2a
1
ssh://brewery@pls.lobotomise.me:33/atagen/monolith.git

Blame: crates/layout/src/scratchpad.rs

b001ce7817edatagen2026-10-19 09:23 UTC1
use crate::{Layout, Scratchpad, WindowId, centre_in, centred, translate};
4cbf881c67bdatagen2026-10-17 04:56 UTC2
4cbf881c67bdatagen2026-10-17 04:56 UTC3
impl Layout {
4cbf881c67bdatagen2026-10-17 04:56 UTC4
    /// Adds a window to a named scratchpad, creating it. Scratchpad windows
4cbf881c67bdatagen2026-10-17 04:56 UTC5
    /// float and are shown only by summoning.
4cbf881c67bdatagen2026-10-17 04:56 UTC6
    pub fn scratchpad_add(&mut self, w: WindowId, name: &str) {
4cbf881c67bdatagen2026-10-17 04:56 UTC7
        let Some(win) = self.windows.get(w) else {
4cbf881c67bdatagen2026-10-17 04:56 UTC8
            return;
4cbf881c67bdatagen2026-10-17 04:56 UTC9
        };
4cbf881c67bdatagen2026-10-17 04:56 UTC10
        if let Some(s) = win.scratchpad {
4cbf881c67bdatagen2026-10-17 04:56 UTC11
            self.leave_scratchpad(s, w);
4cbf881c67bdatagen2026-10-17 04:56 UTC12
        }
4cbf881c67bdatagen2026-10-17 04:56 UTC13
        self.unplace(w);
4cbf881c67bdatagen2026-10-17 04:56 UTC14
        let s = match self.scratchpads.iter().position(|sp| sp.name == name) {
4cbf881c67bdatagen2026-10-17 04:56 UTC15
            Some(s) => s,
4cbf881c67bdatagen2026-10-17 04:56 UTC16
            None => {
4cbf881c67bdatagen2026-10-17 04:56 UTC17
                self.scratchpads.push(Scratchpad {
4cbf881c67bdatagen2026-10-17 04:56 UTC18
                    name: name.into(),
4cbf881c67bdatagen2026-10-17 04:56 UTC19
                    windows: Vec::new(),
4cbf881c67bdatagen2026-10-17 04:56 UTC20
                    shown: None,
4cbf881c67bdatagen2026-10-17 04:56 UTC21
                    output: None,
4cbf881c67bdatagen2026-10-17 04:56 UTC22
                });
4cbf881c67bdatagen2026-10-17 04:56 UTC23
                self.scratchpads.len() - 1
4cbf881c67bdatagen2026-10-17 04:56 UTC24
            }
4cbf881c67bdatagen2026-10-17 04:56 UTC25
        };
4cbf881c67bdatagen2026-10-17 04:56 UTC26
        self.scratchpads[s].windows.push(w);
243161cd0662atagen2026-10-19 10:41 UTC27
        let area = self.windows[w].output.map(|o| self.outputs[o].usable());
4cbf881c67bdatagen2026-10-17 04:56 UTC28
        let win = &mut self.windows[w];
4cbf881c67bdatagen2026-10-17 04:56 UTC29
        win.scratchpad = Some(s);
4cbf881c67bdatagen2026-10-17 04:56 UTC30
        win.floating = true;
4cbf881c67bdatagen2026-10-17 04:56 UTC31
        if win.float_rect.is_none() {
4cbf881c67bdatagen2026-10-17 04:56 UTC32
            win.float_rect = area.map(|a| centred(a, 0.6));
4cbf881c67bdatagen2026-10-17 04:56 UTC33
        }
4cbf881c67bdatagen2026-10-17 04:56 UTC34
    }
4cbf881c67bdatagen2026-10-17 04:56 UTC35
4cbf881c67bdatagen2026-10-17 04:56 UTC36
    /// Cycles a scratchpad through off, each window, and off again, on the
4cbf881c67bdatagen2026-10-17 04:56 UTC37
    /// active output.
4cbf881c67bdatagen2026-10-17 04:56 UTC38
    pub fn summon(&mut self, name: &str) -> Option<WindowId> {
4cbf881c67bdatagen2026-10-17 04:56 UTC39
        let s = self.scratchpads.iter().position(|sp| sp.name == name)?;
4cbf881c67bdatagen2026-10-17 04:56 UTC40
        let o = self.active?;
4cbf881c67bdatagen2026-10-17 04:56 UTC41
        let sp = &mut self.scratchpads[s];
1c7e3075e57fatagen2026-10-19 10:28 UTC42
        let mut next = sp.shown.map_or(0, |i| i + 1);
cadf3a07a5dcatagen2026-10-19 10:29 UTC43
        while sp
cadf3a07a5dcatagen2026-10-19 10:29 UTC44
            .windows
cadf3a07a5dcatagen2026-10-19 10:29 UTC45
            .get(next)
cadf3a07a5dcatagen2026-10-19 10:29 UTC46
            .is_some_and(|&w| self.windows[w].hidden)
cadf3a07a5dcatagen2026-10-19 10:29 UTC47
        {
1c7e3075e57fatagen2026-10-19 10:28 UTC48
            next += 1;
1c7e3075e57fatagen2026-10-19 10:28 UTC49
        }
4cbf881c67bdatagen2026-10-17 04:56 UTC50
        if next >= sp.windows.len() {
4cbf881c67bdatagen2026-10-17 04:56 UTC51
            sp.shown = None;
4cbf881c67bdatagen2026-10-17 04:56 UTC52
            return None;
4cbf881c67bdatagen2026-10-17 04:56 UTC53
        }
4b73e40af1e3atagen2026-10-19 07:44 UTC54
        let from = sp.output.map(|f| self.outputs[f].usable());
4cbf881c67bdatagen2026-10-17 04:56 UTC55
        sp.shown = Some(next);
4cbf881c67bdatagen2026-10-17 04:56 UTC56
        sp.output = Some(o);
4cbf881c67bdatagen2026-10-17 04:56 UTC57
        let w = sp.windows[next];
4cbf881c67bdatagen2026-10-17 04:56 UTC58
        self.last_scratchpad = Some(s);
4b73e40af1e3atagen2026-10-19 07:44 UTC59
        let usable = self.outputs[o].usable();
4cbf881c67bdatagen2026-10-17 04:56 UTC60
        let win = &mut self.windows[w];
4cbf881c67bdatagen2026-10-17 04:56 UTC61
        if win.output != Some(o) {
4cbf881c67bdatagen2026-10-17 04:56 UTC62
            win.float_rect = match (from, win.float_rect) {
4b73e40af1e3atagen2026-10-19 07:44 UTC63
                (Some(from), Some(r)) => Some(translate(r, from, usable)),
243161cd0662atagen2026-10-19 10:41 UTC64
                _ => Some(centred(usable, 0.6)),
4cbf881c67bdatagen2026-10-17 04:56 UTC65
            };
4cbf881c67bdatagen2026-10-17 04:56 UTC66
            win.output = Some(o);
4cbf881c67bdatagen2026-10-17 04:56 UTC67
        }
b001ce7817edatagen2026-10-19 09:23 UTC68
        win.float_rect = win.float_rect.map(|r| centre_in(usable, r.w, r.h));
1c7e3075e57fatagen2026-10-19 10:28 UTC69
        self.focus_unless_covered(w);
4cbf881c67bdatagen2026-10-17 04:56 UTC70
        Some(w)
4cbf881c67bdatagen2026-10-17 04:56 UTC71
    }
4cbf881c67bdatagen2026-10-17 04:56 UTC72
4cbf881c67bdatagen2026-10-17 04:56 UTC73
    /// Hides a scratchpad, by default the last one summoned.
4cbf881c67bdatagen2026-10-17 04:56 UTC74
    pub fn dismiss(&mut self, name: Option<&str>) {
4cbf881c67bdatagen2026-10-17 04:56 UTC75
        let s = match name {
4cbf881c67bdatagen2026-10-17 04:56 UTC76
            Some(name) => self.scratchpads.iter().position(|sp| sp.name == name),
4cbf881c67bdatagen2026-10-17 04:56 UTC77
            None => self.last_scratchpad,
4cbf881c67bdatagen2026-10-17 04:56 UTC78
        };
4cbf881c67bdatagen2026-10-17 04:56 UTC79
        if let Some(sp) = s.and_then(|s| self.scratchpads.get_mut(s)) {
4cbf881c67bdatagen2026-10-17 04:56 UTC80
            sp.shown = None;
4cbf881c67bdatagen2026-10-17 04:56 UTC81
        }
4cbf881c67bdatagen2026-10-17 04:56 UTC82
    }
4cbf881c67bdatagen2026-10-17 04:56 UTC83
4cbf881c67bdatagen2026-10-17 04:56 UTC84
    pub(crate) fn leave_scratchpad(&mut self, s: usize, w: WindowId) {
4cbf881c67bdatagen2026-10-17 04:56 UTC85
        let sp = &mut self.scratchpads[s];
4cbf881c67bdatagen2026-10-17 04:56 UTC86
        let Some(i) = sp.windows.iter().position(|&x| x == w) else {
4cbf881c67bdatagen2026-10-17 04:56 UTC87
            return;
4cbf881c67bdatagen2026-10-17 04:56 UTC88
        };
4cbf881c67bdatagen2026-10-17 04:56 UTC89
        sp.windows.remove(i);
4cbf881c67bdatagen2026-10-17 04:56 UTC90
        sp.shown = match sp.shown {
4cbf881c67bdatagen2026-10-17 04:56 UTC91
            Some(j) if j == i => None,
4cbf881c67bdatagen2026-10-17 04:56 UTC92
            Some(j) if j > i => Some(j - 1),
4cbf881c67bdatagen2026-10-17 04:56 UTC93
            other => other,
4cbf881c67bdatagen2026-10-17 04:56 UTC94
        };
4cbf881c67bdatagen2026-10-17 04:56 UTC95
        self.windows[w].scratchpad = None;
4cbf881c67bdatagen2026-10-17 04:56 UTC96
    }
4cbf881c67bdatagen2026-10-17 04:56 UTC97
}