kranewm

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

client.cc (5388B)


      1 #include "client.hh"
      2 
      3 #include <iostream>
      4 
      5 Client::Client(
      6     winsys::Window window,
      7     winsys::Window frame,
      8     std::string name,
      9     std::string class_,
     10     std::string instance,
     11     Partition_ptr partition,
     12     Context_ptr context,
     13     Workspace_ptr workspace,
     14     std::optional<winsys::Pid> pid,
     15     std::optional<winsys::Pid> ppid
     16 )
     17     : window(window),
     18       frame(frame),
     19       name(name),
     20       class_(class_),
     21       instance(instance),
     22       partition(partition),
     23       context(context),
     24       workspace(workspace),
     25       free_region({}),
     26       tile_region({}),
     27       active_region({}),
     28       previous_region({}),
     29       inner_region({}),
     30       tile_decoration(winsys::Decoration::FREE_DECORATION),
     31       free_decoration(winsys::Decoration::FREE_DECORATION),
     32       active_decoration(winsys::Decoration::FREE_DECORATION),
     33       size_hints(std::nullopt),
     34       warp_pos(std::nullopt),
     35       leader(std::nullopt),
     36       parent(nullptr),
     37       children({}),
     38       producer(nullptr),
     39       consumers({}),
     40       focused(false),
     41       mapped(false),
     42       managed(true),
     43       urgent(false),
     44       floating(false),
     45       fullscreen(false),
     46       contained(false),
     47       invincible(false),
     48       sticky(false),
     49       iconifyable(true),
     50       iconified(false),
     51       disowned(false),
     52       producing(true),
     53       attaching(false),
     54       pid(pid),
     55       ppid(ppid),
     56       last_touched(std::chrono::steady_clock::now()),
     57       last_focused(std::chrono::steady_clock::now()),
     58       managed_since(std::chrono::steady_clock::now()),
     59       expected_unmap_count(0),
     60       m_outside_state(OutsideState::Unfocused)
     61 {}
     62 
     63 Client::~Client()
     64 {}
     65 
     66 Client::OutsideState
     67 Client::get_outside_state() const
     68 {
     69     if (urgent)
     70         return Client::OutsideState::Urgent;
     71 
     72     return m_outside_state;
     73 }
     74 
     75 void
     76 Client::touch()
     77 {
     78     last_touched = std::chrono::steady_clock::now();
     79 }
     80 
     81 void
     82 Client::focus()
     83 {
     84     focused = true;
     85 
     86     auto now = std::chrono::steady_clock::now();
     87     last_touched = now;
     88     last_focused = now;
     89 
     90     switch (m_outside_state) {
     91     case OutsideState::Unfocused:         m_outside_state = OutsideState::Focused;         return;
     92     case OutsideState::UnfocusedDisowned: m_outside_state = OutsideState::FocusedDisowned; return;
     93     case OutsideState::UnfocusedSticky:   m_outside_state = OutsideState::FocusedSticky;   return;
     94     default: return;
     95     }
     96 }
     97 
     98 void
     99 Client::unfocus()
    100 {
    101     focused = false;
    102 
    103     switch (m_outside_state) {
    104     case OutsideState::Focused:         m_outside_state = OutsideState::Unfocused;         return;
    105     case OutsideState::FocusedDisowned: m_outside_state = OutsideState::UnfocusedDisowned; return;
    106     case OutsideState::FocusedSticky:   m_outside_state = OutsideState::UnfocusedSticky;   return;
    107     default: return;
    108     }
    109 }
    110 
    111 void
    112 Client::stick()
    113 {
    114     sticky = true;
    115 
    116     switch (m_outside_state) {
    117     case OutsideState::Focused:   m_outside_state = OutsideState::FocusedSticky;   return;
    118     case OutsideState::Unfocused: m_outside_state = OutsideState::UnfocusedSticky; return;
    119     default: return;
    120     }
    121 }
    122 
    123 void
    124 Client::unstick()
    125 {
    126     sticky = false;
    127 
    128     switch (m_outside_state) {
    129     case OutsideState::FocusedSticky:   m_outside_state = OutsideState::Focused;   return;
    130     case OutsideState::UnfocusedSticky: m_outside_state = OutsideState::Unfocused; return;
    131     default: return;
    132     }
    133 }
    134 
    135 void
    136 Client::disown()
    137 {
    138     disowned = true;
    139 
    140     switch (m_outside_state) {
    141     case OutsideState::Focused:   m_outside_state = OutsideState::FocusedDisowned;   return;
    142     case OutsideState::Unfocused: m_outside_state = OutsideState::UnfocusedDisowned; return;
    143     default: return;
    144     }
    145 }
    146 
    147 void
    148 Client::reclaim()
    149 {
    150     disowned = false;
    151 
    152     switch (m_outside_state) {
    153     case OutsideState::FocusedDisowned:   m_outside_state = OutsideState::Focused;   return;
    154     case OutsideState::UnfocusedDisowned: m_outside_state = OutsideState::Unfocused; return;
    155     default: return;
    156     }
    157 }
    158 
    159 void
    160 Client::expect_unmap()
    161 {
    162     expected_unmap_count += 1;
    163 }
    164 
    165 bool
    166 Client::consume_unmap_if_expecting()
    167 {
    168     bool expecting = expected_unmap_count > 0;
    169 
    170     if (expecting)
    171         expected_unmap_count -= 1;
    172 
    173     return expecting;
    174 }
    175 
    176 void
    177 Client::set_tile_region(winsys::Region& region)
    178 {
    179     tile_region = region;
    180     set_active_region(region);
    181 }
    182 
    183 void
    184 Client::set_free_region(winsys::Region& region)
    185 {
    186     free_region = region;
    187     set_active_region(region);
    188 }
    189 
    190 void
    191 Client::set_active_region(winsys::Region& region)
    192 {
    193     previous_region = active_region;
    194     set_inner_region(region);
    195     active_region = region;
    196 }
    197 
    198 
    199 void
    200 Client::set_tile_decoration(winsys::Decoration const& decoration)
    201 {
    202     tile_decoration = decoration;
    203     active_decoration = decoration;
    204 }
    205 
    206 void
    207 Client::set_free_decoration(winsys::Decoration const& decoration)
    208 {
    209     free_decoration = decoration;
    210     active_decoration = decoration;
    211 }
    212 
    213 void
    214 Client::set_inner_region(winsys::Region& region)
    215 {
    216     if (active_decoration.frame) {
    217         winsys::Frame& frame = *active_decoration.frame;
    218 
    219         inner_region.pos.x = frame.extents.left;
    220         inner_region.pos.y = frame.extents.top;
    221         inner_region.dim.w = region.dim.w - frame.extents.left - frame.extents.right;
    222         inner_region.dim.h = region.dim.h - frame.extents.top - frame.extents.bottom;
    223     } else {
    224         inner_region.pos.x = 0;
    225         inner_region.pos.y = 0;
    226         inner_region.dim = region.dim;
    227     }
    228 }