wzrd

An ICCCM & EWMH compliant X11 reparenting, dynamic window manager, written in Rust
git clone git://git.deurzen.net/wzrd
Log | Files | Refs | LICENSE

stack.rs (4630B)


      1 use winsys::window::Window;
      2 
      3 use std::collections::HashMap;
      4 use std::vec::Vec;
      5 
      6 #[derive(Debug)]
      7 pub enum StackLayer {
      8     Desktop,
      9     Below,
     10     Dock,
     11     // Regular,
     12     // Free,
     13     // Transient,
     14     Above,
     15     // Fullscreen,
     16     Notification,
     17 }
     18 
     19 pub struct StackManager {
     20     window_layers: HashMap<Window, StackLayer>,
     21 
     22     desktop_windows: Vec<Window>,
     23     below_windows: Vec<Window>,
     24     dock_windows: Vec<Window>,
     25     above_windows: Vec<Window>,
     26     notification_windows: Vec<Window>,
     27 
     28     // which windows should be stacked directly {above,below} which other windows
     29     above_other: HashMap<Window, Window>,
     30     below_other: HashMap<Window, Window>,
     31 }
     32 
     33 impl StackManager {
     34     pub fn new() -> Self {
     35         Self {
     36             window_layers: HashMap::with_capacity(5),
     37 
     38             desktop_windows: Vec::with_capacity(10),
     39             below_windows: Vec::with_capacity(10),
     40             dock_windows: Vec::with_capacity(10),
     41             above_windows: Vec::with_capacity(10),
     42             notification_windows: Vec::with_capacity(10),
     43 
     44             above_other: HashMap::with_capacity(30),
     45             below_other: HashMap::with_capacity(30),
     46         }
     47     }
     48 
     49     pub fn add_window(
     50         &mut self,
     51         window: Window,
     52         layer: StackLayer,
     53     ) {
     54         if !self.window_layers.contains_key(&window) {
     55             let layer_windows = match layer {
     56                 StackLayer::Desktop => &mut self.desktop_windows,
     57                 StackLayer::Below => &mut self.below_windows,
     58                 StackLayer::Dock => &mut self.dock_windows,
     59                 StackLayer::Above => &mut self.above_windows,
     60                 StackLayer::Notification => &mut self.notification_windows,
     61             };
     62 
     63             layer_windows.push(window);
     64             self.window_layers.insert(window, layer);
     65         }
     66     }
     67 
     68     pub fn add_above_other(
     69         &mut self,
     70         window: Window,
     71         sibling: Window,
     72     ) {
     73         if !self.above_other.contains_key(&window) {
     74             self.above_other.insert(window, sibling);
     75         }
     76     }
     77 
     78     pub fn add_below_other(
     79         &mut self,
     80         window: Window,
     81         sibling: Window,
     82     ) {
     83         if !self.below_other.contains_key(&window) {
     84             self.below_other.insert(window, sibling);
     85         }
     86     }
     87 
     88     pub fn remove_window(
     89         &mut self,
     90         window: Window,
     91     ) {
     92         if let Some(layer) = self.window_layers.get(&window) {
     93             let layer_windows = match layer {
     94                 StackLayer::Desktop => &mut self.desktop_windows,
     95                 StackLayer::Below => &mut self.below_windows,
     96                 StackLayer::Dock => &mut self.dock_windows,
     97                 StackLayer::Above => &mut self.above_windows,
     98                 StackLayer::Notification => &mut self.notification_windows,
     99             };
    100 
    101             let index = layer_windows.iter().position(|&w| w == window).unwrap();
    102 
    103             layer_windows.remove(index);
    104             self.window_layers.remove(&window);
    105         }
    106 
    107         self.above_other.remove(&window);
    108         self.below_other.remove(&window);
    109     }
    110 
    111     pub fn relayer_window(
    112         &mut self,
    113         window: Window,
    114         layer: StackLayer,
    115     ) {
    116         self.remove_window(window);
    117         self.add_window(window, layer);
    118     }
    119 
    120     pub fn raise_window(
    121         &mut self,
    122         window: Window,
    123     ) {
    124         if let Some(layer) = self.window_layers.get(&window) {
    125             let layer_windows = match layer {
    126                 StackLayer::Desktop => &mut self.desktop_windows,
    127                 StackLayer::Below => &mut self.below_windows,
    128                 StackLayer::Dock => &mut self.dock_windows,
    129                 StackLayer::Above => &mut self.above_windows,
    130                 StackLayer::Notification => &mut self.notification_windows,
    131             };
    132 
    133             let index = layer_windows.iter().position(|&w| w == window).unwrap();
    134 
    135             layer_windows.remove(index);
    136             layer_windows.push(window);
    137         }
    138     }
    139 
    140     pub fn layer_windows(
    141         &self,
    142         layer: StackLayer,
    143     ) -> Vec<Window> {
    144         match layer {
    145             StackLayer::Desktop => self.desktop_windows.to_owned(),
    146             StackLayer::Below => self.below_windows.to_owned(),
    147             StackLayer::Dock => self.dock_windows.to_owned(),
    148             StackLayer::Above => self.above_windows.to_owned(),
    149             StackLayer::Notification => self.notification_windows.to_owned(),
    150         }
    151     }
    152 
    153     pub fn above_other(&self) -> &HashMap<Window, Window> {
    154         &self.above_other
    155     }
    156 
    157     pub fn below_other(&self) -> &HashMap<Window, Window> {
    158         &self.below_other
    159     }
    160 }