kranewm

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

screen.cc (3230B)


      1 #include "screen.hh"
      2 #include "util.hh"
      3 
      4 using namespace winsys;
      5 
      6 std::vector<Window>
      7 Screen::show_and_get_struts(bool show)
      8 {
      9     m_showing_struts = show;
     10     compute_placeable_region();
     11 
     12     std::vector<Window> windows;
     13     windows.reserve(m_windows.size());
     14 
     15     std::transform(
     16         m_windows.begin(),
     17         m_windows.end(),
     18         std::back_inserter(windows),
     19         [](auto kv) -> Window {
     20             return kv.first;
     21         }
     22     );
     23 
     24     return windows;
     25 }
     26 
     27 void
     28 Screen::add_struts(std::vector<std::optional<Strut>> struts)
     29 {
     30     if (struts.size() > 0 && struts[0])
     31         add_strut(Edge::Left, *struts[0]);
     32 
     33     if (struts.size() > 1 && struts[1])
     34         add_strut(Edge::Right, *struts[1]);
     35 
     36     if (struts.size() > 2 && struts[2])
     37         add_strut(Edge::Top, *struts[2]);
     38 
     39     if (struts.size() > 3 && struts[3])
     40         add_strut(Edge::Bottom, *struts[3]);
     41 }
     42 
     43 void
     44 Screen::add_strut(Edge edge, Strut strut)
     45 {
     46     m_struts.at(edge).insert(strut);
     47 
     48     if (m_windows.count(strut.window) > 0) {
     49         std::vector<Edge>& edges = m_windows.at(strut.window);
     50         edges.push_back(edge);
     51     } else
     52         m_windows[strut.window] = { edge };
     53 }
     54 
     55 void
     56 Screen::add_strut(Edge edge, Window window, int width)
     57 {
     58     m_struts.at(edge).insert(Strut {
     59         window,
     60         width
     61     });
     62 
     63     if (m_windows.count(window) > 0) {
     64         std::vector<Edge>& edges = m_windows.at(window);
     65         edges.push_back(edge);
     66     } else
     67         m_windows[window] = { edge };
     68 }
     69 
     70 void
     71 Screen::update_strut(Edge edge, Window window, int width)
     72 {
     73     remove_strut(window);
     74     add_strut(edge, window, width);
     75 }
     76 
     77 void
     78 Screen::remove_strut(Window window)
     79 {
     80     std::optional<std::vector<Edge>> const& edges
     81         = Util::retrieve(m_windows, window);
     82 
     83     if (edges)
     84         for (auto& edge : *edges) {
     85             std::set<Strut, StrutComparer>& struts = m_struts.at(edge);
     86 
     87             auto iter = std::find_if(
     88                 struts.begin(),
     89                 struts.end(),
     90                 [window](Strut const& strut) -> bool {
     91                     return strut.window == window;
     92                 }
     93             );
     94 
     95             if (iter != struts.end())
     96                 struts.erase(iter);
     97         }
     98 
     99     m_windows.erase(window);
    100 }
    101 
    102 void
    103 Screen::compute_placeable_region()
    104 {
    105     Region region = m_full_region;
    106 
    107     if (m_showing_struts) {
    108         std::set<Strut, StrutComparer>& left = m_struts.at(Edge::Left);
    109         std::set<Strut, StrutComparer>& top = m_struts.at(Edge::Top);
    110         std::set<Strut, StrutComparer>& right = m_struts.at(Edge::Right);
    111         std::set<Strut, StrutComparer>& bottom = m_struts.at(Edge::Bottom);
    112 
    113         if (!left.empty()) {
    114             int width = left.rbegin()->width;
    115             region.pos.x += width;
    116             region.dim.w -= width;
    117         }
    118 
    119         if (!top.empty()) {
    120             int width = top.rbegin()->width;
    121             region.pos.y += width;
    122             region.dim.h -= width;
    123         }
    124 
    125         if (!right.empty()) {
    126             int width = right.rbegin()->width;
    127             region.dim.w -= width;
    128         }
    129 
    130         if (!bottom.empty()) {
    131             int width = bottom.rbegin()->width;
    132             region.dim.h -= width;
    133         }
    134     }
    135 
    136     m_placeable_region = region;
    137 }