summaryrefslogtreecommitdiff
path: root/src/protocols/ExtWorkspace.hpp
blob: ba4aeeae6daa0c882a985b331b5aec8b3593428b (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
#pragma once

#include "WaylandProtocol.hpp"
#include "../desktop/DesktopTypes.hpp"
#include "ext-workspace-v1.hpp"
#include <cstdint>
#include <vector>
#include "../helpers/signal/Signal.hpp"
#include "../helpers/Monitor.hpp"

class CExtWorkspaceManagerResource;

class CExtWorkspaceGroupResource {
  public:
    CExtWorkspaceGroupResource(WP<CExtWorkspaceManagerResource> manager, UP<CExtWorkspaceGroupHandleV1> resource, PHLMONITORREF monitor);

    static WP<CExtWorkspaceGroupResource> fromResource(wl_resource*);

    [[nodiscard]] bool                    good() const;

    void                                  workspaceEnter(const WP<CExtWorkspaceHandleV1>&);
    void                                  workspaceLeave(const WP<CExtWorkspaceHandleV1>&);

    void                                  sendToWorkspaces();

    PHLMONITORREF                         m_monitor;

  private:
    WP<CExtWorkspaceGroupResource>   m_self;
    WP<CExtWorkspaceManagerResource> m_manager;
    UP<CExtWorkspaceGroupHandleV1>   m_resource;

    struct {
        CHyprSignalListener destroyed;
        CHyprSignalListener outputBound;
    } m_listeners;

    friend class CExtWorkspaceManagerResource;
};

class CExtWorkspaceResource {
  public:
    CExtWorkspaceResource(WP<CExtWorkspaceManagerResource> manager, UP<CExtWorkspaceHandleV1> resource, PHLWORKSPACEREF workspace);

    [[nodiscard]] bool good() const;

    void               commit();

  private:
    WP<CExtWorkspaceResource>        m_self;
    WP<CExtWorkspaceManagerResource> m_manager;
    UP<CExtWorkspaceHandleV1>        m_resource;
    WP<CExtWorkspaceGroupResource>   m_group;
    PHLWORKSPACEREF                  m_workspace;

    [[nodiscard]] bool               isActive() const;

    void                             sendState();
    void                             sendCapabilities();
    void                             sendGroup();

    struct {
        bool          activate   = false;
        bool          deactivate = false;
        PHLMONITORREF targetMonitor;
    } m_pendingState;

    struct {
        CHyprSignalListener destroyed;
        CHyprSignalListener activeChanged;
        CHyprSignalListener monitorChanged;
        CHyprSignalListener renamed;
    } m_listeners;

    friend class CExtWorkspaceManagerResource;
};

class CExtWorkspaceManagerResource {
  public:
    CExtWorkspaceManagerResource(UP<CExtWorkspaceManagerV1> resource);
    WP<CExtWorkspaceManagerResource>             m_self;

    void                                         init(WP<CExtWorkspaceManagerResource> self);
    [[nodiscard]] bool                           good() const;

    void                                         onMonitorCreated(const PHLMONITOR& monitor);
    void                                         onWorkspaceCreated(const PHLWORKSPACE& workspace);

    void                                         scheduleDone();
    [[nodiscard]] WP<CExtWorkspaceGroupResource> findGroup(const PHLMONITORREF& monitor) const;
    void                                         sendGroupToWorkspaces(const WP<CExtWorkspaceGroupResource>& group);

    UP<CExtWorkspaceManagerV1>                   m_resource;

  private:
    bool m_doneScheduled = false;
};

class CExtWorkspaceProtocol : public IWaylandProtocol {
  public:
    CExtWorkspaceProtocol(const wl_interface* iface, const int& var, const std::string& name);

    virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);

    void         destroyManager(const WP<CExtWorkspaceManagerResource>& manager);
    void         destroyGroup(const WP<CExtWorkspaceGroupResource>& group);
    void         destroyWorkspace(const WP<CExtWorkspaceResource>& workspace);

  private:
    std::vector<UP<CExtWorkspaceManagerResource>> m_managers;
    std::vector<UP<CExtWorkspaceGroupResource>>   m_groups;
    std::vector<UP<CExtWorkspaceResource>>        m_workspaces;

    friend class CExtWorkspaceManagerResource;
};

namespace PROTO {
    inline UP<CExtWorkspaceProtocol> extWorkspace;
}