summaryrefslogtreecommitdiff
path: root/src/xwayland/XSurface.hpp
blob: 6c00f915f531335557098906b7657a8dfad06cca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#pragma once

#include "../helpers/signal/Signal.hpp"
#include "../helpers/memory/Memory.hpp"
#include "../helpers/math/Math.hpp"
#include <vector>

class CWLSurfaceResource;
class CXWaylandSurfaceResource;

#ifdef NO_XWAYLAND
using xcb_pixmap_t         = uint32_t;
using xcb_window_t         = uint32_t;
using xcb_atom_t           = uint32_t;
using xcb_icccm_wm_hints_t = struct {
    int32_t      flags;
    uint32_t     input;
    int32_t      initial_state;
    xcb_pixmap_t icon_pixmap;
    xcb_window_t icon_window;
    int32_t      icon_x, icon_y;
    xcb_pixmap_t icon_mask;
    xcb_window_t window_group;
};
using xcb_size_hints_t = struct {
    uint32_t flags;
    int32_t  x, y;
    int32_t  width, height;
    int32_t  min_width, min_height;
    int32_t  max_width, max_height;
    int32_t  width_inc, height_inc;
    int32_t  min_aspect_num, min_aspect_den;
    int32_t  max_aspect_num, max_aspect_den;
    int32_t  base_width, base_height;
    uint32_t win_gravity;
};
#else
#include <xcb/xcb_icccm.h>
#endif

class CXWaylandSurface {
  public:
    WP<CWLSurfaceResource>       m_surface;
    WP<CXWaylandSurfaceResource> m_resource;

    struct {
        CSignalT<>     stateChanged;    // maximized, fs, minimized, etc.
        CSignalT<>     metadataChanged; // title, appid
        CSignalT<>     destroy;

        CSignalT<>     resourceChange; // associated / dissociated

        CSignalT<>     setGeometry;
        CSignalT<CBox> configureRequest;

        CSignalT<>     map;
        CSignalT<>     unmap;
        CSignalT<>     commit;

        CSignalT<>     activate;
    } m_events;

    struct {
        std::string title;
        std::string appid;

        // volatile state: is reset after the stateChanged signal fires
        std::optional<bool> requestsMaximize;
        std::optional<bool> requestsFullscreen;
        std::optional<bool> requestsMinimize;
    } m_state;

    uint32_t                          m_xID         = 0;
    uint64_t                          m_wlID        = 0;
    uint64_t                          m_wlSerial    = 0;
    uint32_t                          m_lastPingSeq = 0;
    pid_t                             m_pid         = 0;
    CBox                              m_geometry;
    bool                              m_overrideRedirect = false;
    bool                              m_withdrawn        = false;
    bool                              m_fullscreen       = false;
    bool                              m_maximized        = false;
    bool                              m_minimized        = false;
    bool                              m_mapped           = false;
    bool                              m_modal            = false;

    WP<CXWaylandSurface>              m_parent;
    WP<CXWaylandSurface>              m_self;
    std::vector<WP<CXWaylandSurface>> m_children;

    UP<xcb_icccm_wm_hints_t>          m_hints;
    UP<xcb_size_hints_t>              m_sizeHints;
    std::vector<uint32_t>             m_atoms;
    std::vector<uint32_t>             m_protocols;
    std::string                       m_role      = "";
    bool                              m_transient = false;

    bool                              wantsFocus();
    void                              configure(const CBox& box);
    void                              activate(bool activate);
    void                              setFullscreen(bool fs);
    void                              setMinimized(bool mz);
    void                              restackToTop();
    void                              close();
    void                              ping();

  private:
    CXWaylandSurface(uint32_t xID, CBox geometry, bool OR);

    void ensureListeners();
    void map();
    void unmap();
    void considerMap();
    void setWithdrawn(bool withdrawn);

    struct {
        CHyprSignalListener destroyResource;
        CHyprSignalListener destroySurface;
        CHyprSignalListener commitSurface;
    } m_listeners;

    std::unordered_map<xcb_atom_t, bool> m_supportedProps;

    friend class CXWM;
};