1 /********************************************************************
2 Copyright © 2020 Roman Gilg <subdiff@gmail.com>
3 
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), which shall
10 act as a proxy defined in Section 6 of version 3 of the license.
11 
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library.  If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
20 #pragma once
21 
22 #include "plasma_window.h"
23 
24 #include "wayland/global.h"
25 #include "wayland/resource.h"
26 
27 #include <QIcon>
28 #include <QObject>
29 
30 #include <wayland-plasma-window-management-server-protocol.h>
31 
32 class QSize;
33 
34 namespace Wrapland::Server
35 {
36 
37 class Display;
38 class PlasmaWindow;
39 class Surface;
40 class PlasmaVirtualDesktopManager;
41 class PlasmaWindowRes;
42 
43 constexpr uint32_t PlasmaWindowManagerVersion = 10;
44 using PlasmaWindowManagerGlobal = Wayland::Global<PlasmaWindowManager, PlasmaWindowManagerVersion>;
45 using PlasmaWindowManagerBind = Wayland::Bind<PlasmaWindowManagerGlobal>;
46 
47 class PlasmaWindowManager::Private : public PlasmaWindowManagerGlobal
48 {
49 public:
50     Private(Display* display, PlasmaWindowManager* qptr);
51     void sendShowingDesktopState();
52 
53     void bindInit(PlasmaWindowManagerBind* bind) override;
54 
55     ShowingDesktopState desktopState = ShowingDesktopState::Disabled;
56     QList<PlasmaWindow*> windows;
57     PlasmaVirtualDesktopManager* virtualDesktopManager = nullptr;
58     uint32_t windowIdCounter = 0;
59 
60 private:
61     static void
62     showDesktopCallback(wl_client* client, wl_resource* resource, uint32_t desktopState);
63     static void getWindowCallback(wl_client* client,
64                                   wl_resource* resource,
65                                   uint32_t id,
66                                   uint32_t internalWindowId);
67 
68     static const struct org_kde_plasma_window_management_interface s_interface;
69 };
70 
71 class PlasmaWindow::Private
72 {
73 public:
74     Private(PlasmaWindowManager* manager, PlasmaWindow* q);
75     ~Private();
76 
77     void createResource(uint32_t version, uint32_t id, Wayland::Client* client, bool temporary);
78     void setTitle(const QString& title);
79     void setAppId(const QString& appId);
80     void setPid(uint32_t pid);
81     void setThemedIconName(const QString& iconName);
82     void setIcon(const QIcon& icon);
83     void unmap() const;
84     void setState(org_kde_plasma_window_management_state flag, bool set);
85     void setParentWindow(PlasmaWindow* window);
86     void setGeometry(const QRect& geometry);
87     void setApplicationMenuPaths(QString const& serviceName, QString const& objectPath);
88 
89     // TODO(romangg): Might make sense to have this as a non-static member function instead.
90     static PlasmaWindowRes* getResourceOfParent(PlasmaWindow* parent, PlasmaWindowRes* childRes);
91 
92     QVector<PlasmaWindowRes*> resources;
93     uint32_t windowId = 0;
94     QHash<Surface*, QRect> minimizedGeometries;
95     PlasmaWindowManager* manager;
96 
97     PlasmaWindow* parentWindow = nullptr;
98     QMetaObject::Connection parentWindowDestroyConnection;
99     QStringList plasmaVirtualDesktops;
100     QRect geometry;
101 
102 private:
103     friend class PlasmaWindowRes;
104 
105     PlasmaWindow* q_ptr;
106     QString m_title;
107     QString m_appId;
108     uint32_t m_pid = 0;
109     QString m_themedIconName;
110     QIcon m_icon;
111     uint32_t m_virtualDesktop = 0;
112     uint32_t m_desktopState = 0;
113     struct {
114         QString serviceName;
115         QString objectPath;
116     } m_applicationMenu;
117     wl_listener listener;
118 };
119 
120 class PlasmaWindowRes : public QObject
121 {
122     Q_OBJECT
123 public:
124     PlasmaWindowRes(Wayland::Client* client, uint32_t version, uint32_t id, PlasmaWindow* window);
125 
126     void unmap();
127 
128 Q_SIGNALS:
129     void resourceDestroyed();
130 
131 private:
132     friend class PlasmaWindow;
133     class Private;
134     Private* d_ptr;
135 };
136 
137 class PlasmaWindowRes::Private : public Wayland::Resource<PlasmaWindowRes>
138 {
139 public:
140     Private(Wayland::Client* client,
141             uint32_t version,
142             uint32_t id,
143             PlasmaWindow* window,
144             PlasmaWindowRes* q);
145 
146     void unmap();
147 
148 private:
149     static void setStateCallback(wl_client* client,
150                                  wl_resource* resource,
151                                  uint32_t flags,
152                                  uint32_t desktopState);
153     static void
154     setVirtualDesktopCallback(wl_client* client, wl_resource* resource, uint32_t number);
155     static void closeCallback(wl_client* client, wl_resource* resource);
156     static void requestMoveCallback(wl_client* client, wl_resource* resource);
157     static void requestResizeCallback(wl_client* client, wl_resource* resource);
158     static void setMinimizedGeometryCallback(wl_client* client,
159                                              wl_resource* resource,
160                                              wl_resource* wlPanel,
161                                              uint32_t x,
162                                              uint32_t y,
163                                              uint32_t width,
164                                              uint32_t height);
165     static void
166     unsetMinimizedGeometryCallback(wl_client* client, wl_resource* resource, wl_resource* wlPanel);
167     static void getIconCallback(wl_client* client, wl_resource* resource, int32_t fd);
168     static void
169     requestEnterVirtualDesktopCallback(wl_client* client, wl_resource* resource, const char* id);
170     static void requestEnterNewVirtualDesktopCallback(wl_client* client, wl_resource* resource);
171     static void
172     requestLeaveVirtualDesktopCallback(wl_client* client, wl_resource* resource, const char* id);
173 
174     PlasmaWindow* window;
175     static const struct org_kde_plasma_window_interface s_interface;
176 };
177 
178 }
179