kranewm

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

xconnection.hh (14608B)


      1 #ifndef __WINSYS_XDATA_XCONNECTION_H_GUARD__
      2 #define __WINSYS_XDATA_XCONNECTION_H_GUARD__
      3 
      4 #include "../connection.hh"
      5 #include "../event.hh"
      6 #include "../input.hh"
      7 
      8 #include <cstddef>
      9 #include <functional>
     10 #include <iostream>
     11 #include <string>
     12 #include <unordered_map>
     13 #include <variant>
     14 
     15 extern "C" {
     16 #include <X11/Xatom.h>
     17 #include <X11/Xlib.h>
     18 #include <X11/Xmd.h>
     19 #include <X11/cursorfont.h>
     20 #include <sys/un.h>
     21 }
     22 
     23 class XConnection final: public winsys::Connection
     24 {
     25 public:
     26     XConnection(const std::string_view);
     27     ~XConnection();
     28 
     29     virtual void init_wm_ipc() override;
     30     virtual bool flush() override;
     31     virtual winsys::Event step() override;
     32     virtual bool check_progress() override;
     33     virtual void process_events(std::function<void(winsys::Event)>) override;
     34     virtual void process_messages(std::function<void(winsys::Message)>) override;
     35     virtual std::vector<winsys::Screen> connected_outputs() override;
     36     virtual std::vector<winsys::Window> top_level_windows() override;
     37     virtual winsys::Pos get_pointer_position() override;
     38     virtual void warp_pointer_center_of_window_or_root(std::optional<winsys::Window>, winsys::Screen&) override;
     39     virtual void warp_pointer(winsys::Pos) override;
     40     virtual void warp_pointer_rpos(winsys::Window, winsys::Pos) override;
     41     virtual void confine_pointer(winsys::Window) override;
     42     virtual bool release_pointer() override;
     43     virtual void call_external_command(std::string&) override;
     44     virtual void cleanup() override;
     45 
     46     // window manipulation
     47     virtual winsys::Window create_frame(winsys::Region) override;
     48     virtual void init_window(winsys::Window) override;
     49     virtual void init_frame(winsys::Window, bool) override;
     50     virtual void init_unmanaged(winsys::Window) override;
     51     virtual void init_move(winsys::Window) override;
     52     virtual void init_resize(winsys::Window) override;
     53     virtual void cleanup_window(winsys::Window) override;
     54     virtual void map_window(winsys::Window) override;
     55     virtual void unmap_window(winsys::Window) override;
     56     virtual void reparent_window(winsys::Window, winsys::Window, winsys::Pos) override;
     57     virtual void unparent_window(winsys::Window, winsys::Pos) override;
     58     virtual void destroy_window(winsys::Window) override;
     59     virtual bool close_window(winsys::Window) override;
     60     virtual bool kill_window(winsys::Window) override;
     61     virtual void place_window(winsys::Window, winsys::Region&) override;
     62     virtual void move_window(winsys::Window, winsys::Pos) override;
     63     virtual void resize_window(winsys::Window, winsys::Dim) override;
     64     virtual void focus_window(winsys::Window) override;
     65     virtual void stack_window_above(winsys::Window, std::optional<winsys::Window>) override;
     66     virtual void stack_window_below(winsys::Window, std::optional<winsys::Window>) override;
     67     virtual void insert_window_in_save_set(winsys::Window) override;
     68     virtual void grab_bindings(std::vector<winsys::KeyInput>&, std::vector<winsys::MouseInput>&) override;
     69     virtual void regrab_buttons(winsys::Window) override;
     70     virtual void ungrab_buttons(winsys::Window) override;
     71     virtual void unfocus() override;
     72     virtual void set_window_border_width(winsys::Window, unsigned) override;
     73     virtual void set_window_border_color(winsys::Window, unsigned) override;
     74     virtual void set_window_background_color(winsys::Window, unsigned) override;
     75     virtual void set_window_notify_enter(Window, bool) override;
     76     virtual void update_window_offset(winsys::Window, winsys::Window) override;
     77     virtual winsys::Window get_focused_window() override;
     78     virtual std::optional<winsys::Region> get_window_geometry(winsys::Window) override;
     79     virtual std::optional<winsys::Pid> get_window_pid(winsys::Window) override;
     80     virtual std::optional<winsys::Pid> get_ppid(std::optional<winsys::Pid>) override;
     81     virtual bool must_manage_window(winsys::Window) override;
     82     virtual bool must_free_window(winsys::Window) override;
     83     virtual bool window_is_mappable(winsys::Window) override;
     84 
     85     // ICCCM
     86     virtual void set_icccm_window_state(winsys::Window, winsys::IcccmWindowState) override;
     87     virtual void set_icccm_window_hints(winsys::Window, winsys::Hints) override;
     88     virtual std::string get_icccm_window_name(winsys::Window) override;
     89     virtual std::string get_icccm_window_class(winsys::Window) override;
     90     virtual std::string get_icccm_window_instance(winsys::Window) override;
     91     virtual std::optional<winsys::Window> get_icccm_window_transient_for(winsys::Window) override;
     92     virtual std::optional<winsys::Window> get_icccm_window_client_leader(winsys::Window) override;
     93     virtual std::optional<winsys::Hints> get_icccm_window_hints(winsys::Window) override;
     94     virtual std::optional<winsys::SizeHints> get_icccm_window_size_hints(winsys::Window, std::optional<winsys::Dim>) override;
     95 
     96     // EWMH
     97     virtual void init_for_wm(std::vector<std::string> const&) override;
     98     virtual void set_current_desktop(Index) override;
     99     virtual void set_root_window_name(std::string const&) override;
    100     virtual void set_window_desktop(winsys::Window, Index) override;
    101     virtual void set_window_state(winsys::Window, winsys::WindowState, bool) override;
    102     virtual void set_window_frame_extents(winsys::Window, winsys::Extents) override;
    103     virtual void set_desktop_geometry(std::vector<winsys::Region> const&) override;
    104     virtual void set_desktop_viewport(std::vector<winsys::Region> const&) override;
    105     virtual void set_workarea(std::vector<winsys::Region> const&) override;
    106     virtual void update_desktops(std::vector<std::string> const&) override;
    107     virtual void update_client_list(std::vector<winsys::Window> const&) override;
    108     virtual void update_client_list_stacking(std::vector<winsys::Window> const&) override;
    109     virtual std::optional<std::vector<std::optional<winsys::Strut>>> get_window_strut(winsys::Window) override;
    110     virtual std::optional<std::vector<std::optional<winsys::Strut>>> get_window_strut_partial(winsys::Window) override;
    111     virtual std::optional<Index> get_window_desktop(winsys::Window) override;
    112     virtual std::unordered_set<winsys::WindowType> get_window_types(winsys::Window) override;
    113     virtual std::unordered_set<winsys::WindowState> get_window_states(winsys::Window) override;
    114     virtual bool window_is_fullscreen(winsys::Window) override;
    115     virtual bool window_is_above(winsys::Window) override;
    116     virtual bool window_is_below(winsys::Window) override;
    117     virtual bool window_is_sticky(winsys::Window) override;
    118 
    119     // IPC client
    120     virtual void init_for_client() override;
    121 
    122 private:
    123     static int s_otherwm_error_handler(Display*, XErrorEvent*);
    124     static int s_passthrough_error_handler(Display*, XErrorEvent*);
    125     static int s_default_error_handler(Display*, XErrorEvent*);
    126 
    127     enum NetWMID : int
    128     { // NetWM atom identifiers
    129         NetSupported = 0, NetFirst = NetSupported,
    130         NetClientList,
    131         NetNumberOfDesktops,
    132         NetCurrentDesktop,
    133         NetDesktopNames,
    134         NetDesktopGeometry,
    135         NetDesktopViewport,
    136         NetWorkarea,
    137         NetActiveWindow,
    138         NetWMName,
    139         NetWMDesktop,
    140         NetWMStrut,
    141         NetWMStrutPartial,
    142         NetWMFrameExtents,
    143         NetSupportingWMCheck,
    144         NetWMState,
    145         NetWMWindowType,
    146         // root messages
    147         NetWMCloseWindow, NetWMRootFirst = NetWMCloseWindow,
    148         NetWMMoveResize,
    149         NetRequestFrameExtents,
    150         NetMoveResizeWindow, NetWMRootLast = NetMoveResizeWindow,
    151         // window states
    152         NetWMStateFullscreen, NetWMStateFirst = NetWMStateFullscreen,
    153         NetWMStateAbove,
    154         NetWMStateBelow,
    155         NetWMStateDemandsAttention,
    156         NetWMStateHidden, NetWMStateLast = NetWMStateHidden,
    157         // window types
    158         NetWMWindowTypeDesktop, NetWMWindowTypeFirst = NetWMWindowTypeDesktop,
    159         NetWMWindowTypeDock,
    160         NetWMWindowTypeToolbar,
    161         NetWMWindowTypeMenu,
    162         NetWMWindowTypeUtility,
    163         NetWMWindowTypeSplash,
    164         NetWMWindowTypeDialog,
    165         NetWMWindowTypeDropdownMenu,
    166         NetWMWindowTypePopupMenu,
    167         NetWMWindowTypeTooltip,
    168         NetWMWindowTypeNotification,
    169         NetWMWindowTypeNormal, NetWMwindowtypelast = NetWMWindowTypeNormal,
    170         NetLast
    171     };
    172 
    173     enum class NetWMAction
    174     {
    175         NetRemove   = 0,
    176         NetAdd      = 1,
    177         NetToggle   = 2,
    178         NetNoAction
    179     };
    180 
    181     friend inline XConnection::NetWMID&
    182     operator++(XConnection::NetWMID& id)
    183     {
    184         return id = static_cast<XConnection::NetWMID>(static_cast<int>(id) + 1);
    185     }
    186 
    187     Display* mp_dpy;
    188     winsys::Window m_root;
    189     winsys::Window m_check_window;
    190 
    191     int m_dpy_fd;
    192     int m_sock_fd;
    193     int m_client_fd;
    194     int m_max_fd;
    195 
    196 	fd_set m_descr;
    197 	char m_sock_path[256];
    198 	char m_state_path[256] = {};
    199 	struct sockaddr_un m_sock_addr;
    200 
    201     std::string m_wm_name;
    202 
    203     XEvent m_current_event;
    204 
    205     int m_substructure_level = 0;
    206     long m_prev_root_mask = 0;
    207 
    208     Status m_property_status = 0;
    209 
    210     std::optional<winsys::Window> m_confined_to;
    211 
    212     std::unordered_map<std::string, Atom> m_interned_atoms;
    213     std::unordered_map<Atom, std::string> m_atom_names;
    214 
    215     std::unordered_map<std::size_t, winsys::Key> m_keys;
    216     std::unordered_map<winsys::Key, std::size_t> m_keycodes;
    217 
    218     std::unordered_map<NetWMID, Atom> m_netwm_atoms;
    219 
    220     int (*m_checkwm_error_handler)(Display*, XErrorEvent*);
    221 
    222     template <class T>
    223     XEvent
    224     create_event(winsys::Window window, Atom type, T data)
    225     {
    226         XEvent event;
    227         event.type = ClientMessage;
    228         event.xclient.window = window;
    229         event.xclient.message_type = type;
    230         event.xclient.format = 32;
    231         event.xclient.data.l[0] = data;
    232         event.xclient.data.l[1] = CurrentTime;
    233         return event;
    234     }
    235 
    236     void enable_substructure_events();
    237     void disable_substructure_events();
    238 
    239     void next_event(XEvent&);
    240     bool typed_event(XEvent&, int);
    241     void last_typed_event(XEvent&, int);
    242 
    243     void sync(bool);
    244     int pending();
    245 
    246     winsys::Window create_handle();
    247 
    248     Atom get_atom(std::string const&);
    249     Atom get_netwm_atom(NetWMID const&);
    250     void intern_atom(std::string const&, Atom);
    251 
    252     winsys::Key get_key(const std::size_t);
    253     std::size_t get_keycode(const winsys::Key);
    254     void intern_key(const unsigned, const winsys::Key);
    255     winsys::Button get_button(const unsigned) const;
    256     unsigned get_buttoncode(const winsys::Button) const;
    257 
    258     winsys::WindowState get_window_state_from_atom(Atom);
    259     winsys::WindowType get_window_type_from_atom(Atom);
    260     Atom get_atom_from_window_state(winsys::WindowState);
    261     Atom get_atom_from_window_type(winsys::WindowType);
    262 
    263     bool property_status_ok();
    264 
    265     bool has_atom_property(winsys::Window, Atom);
    266     bool has_atomlist_property(winsys::Window, Atom);
    267     bool has_window_property(winsys::Window, Atom);
    268     bool has_windowlist_property(winsys::Window, Atom);
    269     bool has_string_property(winsys::Window, Atom);
    270     bool has_stringlist_property(winsys::Window, Atom);
    271     bool has_card_property(winsys::Window, Atom);
    272     bool has_cardlist_property(winsys::Window, Atom);
    273 
    274     Atom get_atom_property(winsys::Window, std::string const&);
    275     std::vector<Atom> get_atomlist_property(winsys::Window, std::string const&);
    276     winsys::Window get_window_property(winsys::Window, std::string const&);
    277     std::vector<winsys::Window> get_windowlist_property(winsys::Window, std::string const&);
    278     std::string get_string_property(winsys::Window, std::string const&);
    279     std::vector<std::string> get_stringlist_property(winsys::Window, std::string const&);
    280     unsigned long get_card_property(winsys::Window, std::string const&);
    281     std::vector<unsigned long> get_cardlist_property(winsys::Window, std::string const&);
    282 
    283     bool get_text_property(winsys::Window, Atom, char*, unsigned);
    284 
    285     void replace_atom_property(winsys::Window, std::string const&, Atom);
    286     void replace_atomlist_property(winsys::Window, std::string const&, std::vector<Atom> const&);
    287     void replace_window_property(winsys::Window, std::string const&, winsys::Window);
    288     void replace_windowlist_property(winsys::Window, std::string const&, std::vector<winsys::Window> const&);
    289     void replace_string_property(winsys::Window, std::string const&, std::string const&);
    290     void replace_stringlist_property(winsys::Window, std::string const&, std::vector<std::string> const&);
    291     void replace_card_property(winsys::Window, std::string const&, const unsigned long);
    292     void replace_cardlist_property(winsys::Window, std::string const&, std::vector<unsigned long> const&);
    293 
    294     void append_atomlist_property(winsys::Window, std::string const&, Atom);
    295     void append_windowlist_property(winsys::Window, std::string const&, winsys::Window);
    296     void append_stringlist_property(winsys::Window, std::string const&, std::string const&);
    297     void append_cardlist_property(winsys::Window, std::string const&, const unsigned long);
    298 
    299     void unset_atom_property(winsys::Window, std::string const&);
    300     void unset_atomlist_property(winsys::Window, std::string const&);
    301     void unset_window_property(winsys::Window, std::string const&);
    302     void unset_windowlist_property(winsys::Window, std::string const&);
    303     void unset_string_property(winsys::Window, std::string const&);
    304     void unset_stringlist_property(winsys::Window, std::string const&);
    305     void unset_card_property(winsys::Window, std::string const&);
    306     void unset_cardlist_property(winsys::Window, std::string const&);
    307 
    308     bool window_is_any_of_states(winsys::Window, std::vector<winsys::WindowState> const&);
    309     bool window_is_any_of_types(winsys::Window, std::vector<winsys::WindowType> const&);
    310 
    311     void check_otherwm();
    312 
    313     // event dispatching logic
    314     winsys::Event (XConnection::*m_event_dispatcher[LASTEvent])();
    315 
    316     winsys::Event on_button_press();
    317     winsys::Event on_button_release();
    318     winsys::Event on_circulate_request();
    319     winsys::Event on_client_message();
    320     winsys::Event on_configure_notify();
    321     winsys::Event on_configure_request();
    322     winsys::Event on_destroy_notify();
    323     winsys::Event on_expose();
    324     winsys::Event on_focus_in();
    325     winsys::Event on_enter_notify();
    326     winsys::Event on_key_press();
    327     winsys::Event on_map_notify();
    328     winsys::Event on_map_request();
    329     winsys::Event on_mapping_notify();
    330     winsys::Event on_motion_notify();
    331     winsys::Event on_property_notify();
    332     winsys::Event on_screen_change();
    333     winsys::Event on_unmap_notify();
    334 
    335     winsys::Event on_unimplemented();
    336 };
    337 
    338 #endif//__WINSYS_XDATA_XCONNECTION_H_GUARD__