kranewm

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

hints.cc (1996B)


      1 #include "hints.hh"
      2 
      3 #include <algorithm>
      4 #include <cmath>
      5 
      6 using namespace winsys;
      7 
      8 void
      9 SizeHints::apply(Dim& dim)
     10 {
     11     int dest_width = dim.w;
     12     int dest_height = dim.h;
     13 
     14     if (min_width)
     15         dest_width = std::max(dest_width, *min_width);
     16 
     17     if (min_height)
     18         dest_height = std::max(dest_height, *min_height);
     19 
     20     if (max_width)
     21         dest_width = std::min(dest_width, *max_width);
     22 
     23     if (max_height)
     24         dest_height = std::min(dest_height, *max_height);
     25 
     26     int base_width = this->base_width
     27         ? *this->base_width
     28         : 0;
     29 
     30     int base_height = this->base_height
     31         ? *this->base_height
     32         : 0;
     33 
     34     int width = base_width < dest_width
     35         ? dest_width - base_width
     36         : dest_width;
     37 
     38     int height = base_height < dest_height
     39         ? dest_height - base_height
     40         : dest_height;
     41 
     42     if (min_ratio || max_ratio) {
     43         if (height == 0)
     44             height = 1;
     45 
     46         double current_ratio
     47             = static_cast<double>(width) / static_cast<double>(height);
     48 
     49         std::optional<double> new_ratio = std::nullopt;
     50 
     51         if (min_ratio && current_ratio < *min_ratio)
     52             new_ratio = min_ratio;
     53 
     54         if (!new_ratio && max_ratio && current_ratio > *max_ratio)
     55             new_ratio = max_ratio;
     56 
     57         if (new_ratio) {
     58             height = std::round(static_cast<double>(width) / *new_ratio);
     59             width = std::round(static_cast<double>(height) * *new_ratio);
     60 
     61             dest_width = width + base_width;
     62             dest_height = height + base_height;
     63         }
     64     }
     65 
     66     if (inc_height && dest_height >= base_height) {
     67         dest_height -= base_height;
     68         dest_height -= dest_height % *inc_height;
     69         dest_height += base_height;
     70     }
     71 
     72     if (inc_width && dest_width >= base_width) {
     73         dest_width -= base_width;
     74         dest_width -= dest_width % *inc_width;
     75         dest_width += base_width;
     76     }
     77 
     78     dim.h = std::max(dest_height, 0);
     79     dim.w = std::max(dest_width, 0);
     80 }