wzrd

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

hints.rs (5519B)


      1 use crate::geometry::Dim;
      2 use crate::geometry::Pos;
      3 use crate::geometry::Ratio;
      4 use crate::window::IcccmWindowState;
      5 use crate::window::Window;
      6 
      7 #[derive(Debug, Copy, Clone, PartialOrd)]
      8 pub struct SizeHints {
      9     pub by_user: bool,
     10     pub pos: Option<Pos>,
     11     pub min_width: Option<i32>,
     12     pub min_height: Option<i32>,
     13     pub max_width: Option<i32>,
     14     pub max_height: Option<i32>,
     15     pub base_width: Option<i32>,
     16     pub base_height: Option<i32>,
     17     pub inc_width: Option<i32>,
     18     pub inc_height: Option<i32>,
     19     pub min_ratio: Option<f64>,
     20     pub max_ratio: Option<f64>,
     21     pub min_ratio_vulgar: Option<Ratio>,
     22     pub max_ratio_vulgar: Option<Ratio>,
     23 }
     24 
     25 impl SizeHints {
     26     fn new(
     27         by_user: bool,
     28         pos: Option<Pos>,
     29         min_width: Option<i32>,
     30         min_height: Option<i32>,
     31         max_width: Option<i32>,
     32         max_height: Option<i32>,
     33         base_width: Option<i32>,
     34         base_height: Option<i32>,
     35         inc_width: Option<i32>,
     36         inc_height: Option<i32>,
     37         min_ratio: Option<f64>,
     38         max_ratio: Option<f64>,
     39         min_ratio_vulgar: Option<Ratio>,
     40         max_ratio_vulgar: Option<Ratio>,
     41     ) -> Self {
     42         Self {
     43             by_user,
     44             pos,
     45             min_width,
     46             min_height,
     47             max_width,
     48             max_height,
     49             base_width,
     50             base_height,
     51             inc_width,
     52             inc_height,
     53             min_ratio,
     54             max_ratio,
     55             min_ratio_vulgar,
     56             max_ratio_vulgar,
     57         }
     58     }
     59 
     60     pub fn apply(
     61         &self,
     62         dim: &mut Dim,
     63     ) {
     64         let mut dest_width = dim.w;
     65         let mut dest_height = dim.h;
     66 
     67         if let Some(min_width) = self.min_width {
     68             dest_width = std::cmp::max(dest_width, min_width);
     69         }
     70 
     71         if let Some(min_height) = self.min_height {
     72             dest_height = std::cmp::max(dest_height, min_height);
     73         }
     74 
     75         if let Some(max_width) = self.max_width {
     76             dest_width = std::cmp::min(dest_width, max_width);
     77         }
     78 
     79         if let Some(max_height) = self.max_height {
     80             dest_height = std::cmp::min(dest_height, max_height);
     81         }
     82 
     83         let base_width = if let Some(base_width) = self.base_width {
     84             base_width
     85         } else {
     86             0
     87         };
     88 
     89         let base_height = if let Some(base_height) = self.base_height {
     90             base_height
     91         } else {
     92             0
     93         };
     94 
     95         let mut width = if base_width < dest_width {
     96             dest_width - base_width
     97         } else {
     98             dest_width
     99         };
    100 
    101         let mut height = if base_height < dest_height {
    102             dest_height - base_height
    103         } else {
    104             dest_height
    105         };
    106 
    107         if self.min_ratio.is_some() || self.max_ratio.is_some() {
    108             if height == 0 {
    109                 height = 1;
    110             }
    111 
    112             let current_ratio = width as f64 / height as f64;
    113             let mut new_ratio = None;
    114 
    115             if let Some(min_ratio) = self.min_ratio {
    116                 if current_ratio < min_ratio {
    117                     new_ratio = Some(min_ratio);
    118                 }
    119             }
    120 
    121             if new_ratio.is_none() {
    122                 if let Some(max_ratio) = self.max_ratio {
    123                     if current_ratio > max_ratio {
    124                         new_ratio = Some(max_ratio);
    125                     }
    126                 }
    127             }
    128 
    129             if let Some(new_ratio) = new_ratio {
    130                 height = (width as f64 / new_ratio).round() as i32;
    131                 width = (height as f64 * new_ratio).round() as i32;
    132 
    133                 dest_width = width + base_width;
    134                 dest_height = height + base_height;
    135             }
    136         }
    137 
    138         if let Some(inc_height) = self.inc_height {
    139             if dest_height >= base_height {
    140                 dest_height -= base_height;
    141                 dest_height -= dest_height % inc_height;
    142                 dest_height += base_height;
    143             }
    144         }
    145 
    146         if let Some(inc_width) = self.inc_width {
    147             if dest_width >= base_width {
    148                 dest_width -= base_width;
    149                 dest_width -= dest_width % inc_width;
    150                 dest_width += base_width;
    151             }
    152         }
    153 
    154         dim.w = std::cmp::max(dest_width, 0i32);
    155         dim.h = std::cmp::max(dest_height, 0i32);
    156     }
    157 }
    158 
    159 impl PartialEq for SizeHints {
    160     fn eq(
    161         &self,
    162         other: &Self,
    163     ) -> bool {
    164         self.min_width == other.min_width
    165             && self.min_height == other.min_height
    166             && self.max_width == other.max_width
    167             && self.max_height == other.max_height
    168             && self.base_width == other.base_width
    169             && self.base_height == other.base_height
    170             && self.inc_width == other.inc_width
    171             && self.inc_height == other.inc_height
    172             && self.min_ratio_vulgar == other.min_ratio_vulgar
    173             && self.max_ratio_vulgar == other.max_ratio_vulgar
    174     }
    175 }
    176 
    177 impl Eq for SizeHints {}
    178 
    179 #[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
    180 pub struct Hints {
    181     pub urgent: bool,
    182     pub input: Option<bool>,
    183     pub initial_state: Option<IcccmWindowState>,
    184     pub group: Option<Window>,
    185 }
    186 
    187 impl Hints {
    188     fn new(
    189         urgent: bool,
    190         input: Option<bool>,
    191         initial_state: Option<IcccmWindowState>,
    192         group: Option<Window>,
    193     ) -> Self {
    194         Self {
    195             urgent,
    196             input,
    197             initial_state,
    198             group,
    199         }
    200     }
    201 }