kranewm

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

workspace.hh (6691B)


      1 #ifndef __WORKSPACE_H_GUARD__
      2 #define __WORKSPACE_H_GUARD__
      3 
      4 #include "../winsys/geometry.hh"
      5 #include "../winsys/input.hh"
      6 #include "../winsys/window.hh"
      7 #include "../winsys/util.hh"
      8 #include "client.hh"
      9 #include "cycle.hh"
     10 #include "cycle.t.hh"
     11 #include "layout.hh"
     12 #include "placement.hh"
     13 
     14 #include <cstdlib>
     15 #include <deque>
     16 #include <string>
     17 #include <vector>
     18 
     19 class Buffer final
     20 {
     21 public:
     22     enum class BufferKind
     23     {
     24         Move, Resize
     25     };
     26 
     27     Buffer(BufferKind kind)
     28         : m_kind(kind),
     29           m_client(nullptr),
     30           m_grip(std::nullopt),
     31           m_grip_pos(std::nullopt),
     32           m_client_region(std::nullopt)
     33     {}
     34 
     35     bool is_occupied() const;
     36 
     37     Client_ptr client() const;
     38     std::optional<winsys::Grip> grip() const;
     39     std::optional<winsys::Pos> grip_pos() const;
     40     std::optional<winsys::Region> client_region() const;
     41 
     42     void set_grip_pos(winsys::Pos);
     43     void set_client_region(winsys::Region);
     44 
     45     void set(Client_ptr, winsys::Grip, winsys::Pos, winsys::Region);
     46     void unset();
     47 
     48 private:
     49     BufferKind m_kind;
     50     Client_ptr m_client;
     51     std::optional<winsys::Grip> m_grip;
     52     std::optional<winsys::Pos> m_grip_pos;
     53     std::optional<winsys::Region> m_client_region;
     54 
     55 };
     56 
     57 class Scratchpad final
     58 {
     59 public:
     60     Scratchpad() {}
     61 
     62 private:
     63 
     64 };
     65 
     66 typedef class Workspace final
     67 {
     68 public:
     69     struct ClientSelector
     70     {
     71         enum class SelectionCriterium {
     72             AtFirst,
     73             AtLast,
     74             AtMain,
     75             AtIndex
     76         };
     77 
     78         ClientSelector(const SelectionCriterium criterium)
     79             : m_index(std::nullopt)
     80         {
     81             switch (criterium) {
     82             case SelectionCriterium::AtFirst: m_tag = ClientSelectorTag::AtFirst; return;
     83             case SelectionCriterium::AtLast:  m_tag = ClientSelectorTag::AtLast;  return;
     84             case SelectionCriterium::AtMain:  m_tag = ClientSelectorTag::AtMain;  return;
     85             default: return;
     86             }
     87         }
     88 
     89         ClientSelector(const std::size_t index)
     90             : m_tag(ClientSelectorTag::AtIndex),
     91               m_index(index)
     92         {}
     93 
     94         ~ClientSelector() = default;
     95 
     96         SelectionCriterium
     97         criterium() const
     98         {
     99             switch (m_tag) {
    100             case ClientSelectorTag::AtFirst: return SelectionCriterium::AtFirst;
    101             case ClientSelectorTag::AtLast:  return SelectionCriterium::AtLast;
    102             case ClientSelectorTag::AtMain:  return SelectionCriterium::AtMain;
    103             case ClientSelectorTag::AtIndex: return SelectionCriterium::AtIndex;
    104             default: Util::die("no associated criterium");
    105             }
    106 
    107             return {};
    108         }
    109 
    110         std::size_t
    111         index() const
    112         {
    113             return *m_index;
    114         }
    115 
    116     private:
    117         enum class ClientSelectorTag {
    118             AtFirst,
    119             AtLast,
    120             AtMain,
    121             AtIndex
    122         };
    123 
    124         ClientSelectorTag m_tag;
    125         std::optional<std::size_t> m_index;
    126 
    127     };
    128 
    129     Workspace(std::size_t index, std::string name, Context_ptr context)
    130         : m_index(index),
    131           m_name(name),
    132           m_layout_handler({}),
    133           mp_context(context),
    134           mp_active(nullptr),
    135           m_clients({}, true),
    136           m_icons({}, true),
    137           m_disowned({}, true),
    138           m_focus_follows_mouse(false)
    139     {}
    140 
    141     bool empty() const;
    142     bool contains(Client_ptr) const;
    143 
    144     bool focus_follows_mouse() const;
    145     void set_focus_follows_mouse(bool);
    146 
    147     bool layout_is_free() const;
    148     bool layout_has_margin() const;
    149     bool layout_has_gap() const;
    150     bool layout_is_persistent() const;
    151     bool layout_is_single() const;
    152     bool layout_wraps() const;
    153 
    154     std::size_t size() const;
    155     std::size_t length() const;
    156     std::size_t main_count() const;
    157 
    158     Context_ptr context() const;
    159 
    160     Index index() const;
    161     std::string const& name() const;
    162     std::string identifier() const;
    163     Client_ptr active() const;
    164 
    165     Cycle<Client_ptr> const& clients() const;
    166     std::vector<Client_ptr> stack_after_focus() const;
    167 
    168     Client_ptr next_client() const;
    169     Client_ptr prev_client() const;
    170 
    171     std::optional<Client_ptr> find_client(ClientSelector const&) const;
    172 
    173     void cycle(winsys::Direction);
    174     void drag(winsys::Direction);
    175     void reverse();
    176     void rotate(winsys::Direction);
    177     void shuffle_main(winsys::Direction);
    178     void shuffle_stack(winsys::Direction);
    179 
    180     void activate_client(Client_ptr);
    181 
    182     void add_client(Client_ptr);
    183     void remove_client(Client_ptr);
    184     void replace_client(Client_ptr, Client_ptr);
    185 
    186     void client_to_icon(Client_ptr);
    187     void icon_to_client(Client_ptr);
    188     void add_icon(Client_ptr);
    189     void remove_icon(Client_ptr);
    190     std::optional<Client_ptr> pop_icon();
    191 
    192     void client_to_disowned(Client_ptr);
    193     void disowned_to_client(Client_ptr);
    194     void add_disowned(Client_ptr);
    195     void remove_disowned(Client_ptr);
    196 
    197     void toggle_layout_data();
    198     void cycle_layout_data(winsys::Direction);
    199     void copy_data_from_prev_layout();
    200 
    201     void change_gap_size(Util::Change<int>);
    202     void change_main_count(Util::Change<int>);
    203     void change_main_factor(Util::Change<float>);
    204     void change_margin(Util::Change<int>);
    205     void change_margin(winsys::Edge, Util::Change<int>);
    206     void reset_gap_size();
    207     void reset_margin();
    208     void reset_layout_data();
    209 
    210     void save_layout(std::size_t) const;
    211     void load_layout(std::size_t);
    212 
    213     void toggle_layout();
    214     void set_layout(LayoutHandler::LayoutKind);
    215     std::vector<Placement> arrange(winsys::Region) const;
    216 
    217     std::deque<Client_ptr>::iterator
    218     begin()
    219     {
    220         return m_clients.begin();
    221     }
    222 
    223     std::deque<Client_ptr>::const_iterator
    224     begin() const
    225     {
    226         return m_clients.begin();
    227     }
    228 
    229     std::deque<Client_ptr>::const_iterator
    230     cbegin() const
    231     {
    232         return m_clients.cbegin();
    233     }
    234 
    235     std::deque<Client_ptr>::iterator
    236     end()
    237     {
    238         return m_clients.end();
    239     }
    240 
    241     std::deque<Client_ptr>::const_iterator
    242     end() const
    243     {
    244         return m_clients.end();
    245     }
    246 
    247     std::deque<Client_ptr>::const_iterator
    248     cend() const
    249     {
    250         return m_clients.cend();
    251     }
    252 
    253     Client_ptr
    254     operator[](std::size_t i)
    255     {
    256         return m_clients[i];
    257     }
    258 
    259     Client_ptr
    260     operator[](std::size_t i) const
    261     {
    262         return m_clients[i];
    263     }
    264 
    265 private:
    266     std::size_t m_index;
    267     std::string m_name;
    268 
    269     LayoutHandler m_layout_handler;
    270 
    271     Context_ptr mp_context;
    272 
    273     Client_ptr mp_active;
    274     Cycle<Client_ptr> m_clients;
    275     Cycle<Client_ptr> m_icons;
    276     Cycle<Client_ptr> m_disowned;
    277 
    278     bool m_focus_follows_mouse;
    279 
    280 }* Workspace_ptr;
    281 
    282 #endif//__WORKSPACE_H_GUARD__