1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
use std::fmt::Debug; pub mod grid; pub mod monocle; pub mod spiral; pub mod stack; /// A screen area size to be accounted for when arranging windows. /// /// Describes the area used for tiling windows. This allows to leave an open /// spot for desktop windows, bars and whatever else you might want. #[derive(Clone, Debug, Default)] pub struct TilingArea { /// x offset of tiling area pub offset_x: u32, /// y offset of tiling area pub offset_y: u32, /// width of tiling area pub width: u32, /// height of tiling area pub height: u32, } impl TilingArea { /// Create a new `TilingArea` object. /// /// Uses a `TilingArea` that represents the user's wishes to get something /// that is actually possible. Offsets, however are honored. pub fn new(old: &TilingArea, width: u32, height: u32) -> TilingArea { let new_width = if old.width + old.offset_x < width { old.width - old.offset_x } else { width - old.offset_x }; let new_height = if old.height + old.offset_y < height { old.height - old.offset_y } else { height - old.offset_y }; TilingArea { offset_x: old.offset_x, offset_y: old.offset_y, width: new_width, height: new_height, } } } /// A window's geometry. #[derive(Clone, Debug)] pub struct Geometry { /// x coordinate of window pub x: u32, /// y coordinate of window pub y: u32, /// width of window pub width: u32, /// height of window pub height: u32, } impl Geometry { /// Check whether a geometry contains a point. pub fn match_coords(&self, x: u32, y: u32) -> bool { self.x <= x && self.x + self.width > x && self.y <= y && self.y + self.height > y } /// Check whether two `Geometry`s overlap. pub fn match_overlap(&self, other: &Geometry) -> bool { self.match_coords(other.x, other.y) || other.match_coords(self.x, self.y) } } /// Types that compute geometries for arbitrary amounts of windows. /// /// The only input such objects get are `TilingArea` and number of windows. /// The trait inherits from `Debug` for purely practical reasons: some types /// we want to output (`WmCommand` in particular) rely on derived `Debug` /// instances and all types implementing `Layout` implement `Debug` anyway. pub trait Layout: Debug { /// Compute window geometries. /// /// If a `None` is returned at a particular position, that window is not /// to be made visible. fn arrange(&self, num_windows: usize, screen: &TilingArea) -> Vec<Option<Geometry>>; /// Get the index of the window to the right of the nth window. fn right_window(&self, index: usize, max: usize) -> Option<usize>; /// Get the index of the window to the left of the nth window. fn left_window(&self, index: usize, max: usize) -> Option<usize>; /// Get the index of the window to the top of the nth window. fn top_window(&self, index: usize, max: usize) -> Option<usize>; /// Get the index of the window to the bottom of the nth window. fn bottom_window(&self, index: usize, max: usize) -> Option<usize>; /// Decide whether to insert new windows as master. fn new_window_as_master(&self) -> bool; /// React to a `LayoutMessage`, returning true on change. fn edit_layout(&mut self, msg: LayoutMessage) -> bool; /// React to the first applicable `LayoutMessage`. /// /// If any reaction is triggered, return `true`, else `false`. fn edit_layout_retry(&mut self, mut msgs: Vec<LayoutMessage>) -> bool { msgs.drain(..).any(|m| self.edit_layout(m)) } } /// A message type being sent to layout objects. /// /// Introduced to allow for type- and implementation-independent layout editing /// from keybindings and other code. Layout implementations can choose to react /// to any subset of the message variants below, or none at all. #[derive(Debug, PartialEq, Eq)] pub enum LayoutMessage { /// Set absolute value of the master factor. MasterFactorAbs(u8), /// Add an offset to the master factor. MasterFactorRel(i8), /// Set `fixed` attribute of layout. FixedAbs(bool), /// Toggle `fixed` attribute of layout. FixedRel, /// Set `inverted` attribute of layout. InvertedAbs(bool), /// Toggle `inverted` attribute of layout. InvertedRel, /// Set absolute value of the x offset. XOffAbs(u32), /// Add an offset to the x offset. XOffRel(i32), /// Set absolute value of the y offset. YOffAbs(u32), /// Add an offset to the y offset. YOffRel(i32), /// Set absolute value of the column amount. ColumnAbs(u8), /// Add an offset to the column amount. ColumnRel(i8), }