1 | // Copyright (C) 2017 The Qt Company Ltd. |
2 | // Copyright (C) 2017 Eurogiciel, author: <philippe.coval@eurogiciel.fr> |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | #ifndef QWAYLANDXDGSHELL_H |
6 | #define QWAYLANDXDGSHELL_H |
7 | |
8 | // |
9 | // W A R N I N G |
10 | // ------------- |
11 | // |
12 | // This file is not part of the Qt API. It exists purely as an |
13 | // implementation detail. This header file may change from version to |
14 | // version without notice, or even be removed. |
15 | // |
16 | // We mean it. |
17 | // |
18 | |
19 | #include "qwayland-xdg-shell.h" |
20 | |
21 | #include "qwaylandxdgdecorationv1_p.h" |
22 | #include "qwaylandxdgactivationv1_p.h" |
23 | |
24 | #include <QtWaylandClient/qtwaylandclientglobal.h> |
25 | #include <QtWaylandClient/private/qwaylandshellsurface_p.h> |
26 | #include <QtWaylandClient/private/qwaylandwindow_p.h> |
27 | |
28 | #include <QtCore/QSize> |
29 | #include <QtGui/QRegion> |
30 | |
31 | QT_BEGIN_NAMESPACE |
32 | |
33 | class QWindow; |
34 | |
35 | namespace QtWaylandClient { |
36 | |
37 | class QWaylandDisplay; |
38 | class QWaylandInputDevice; |
39 | class QWaylandXdgShell; |
40 | class QWaylandXdgExportedV2; |
41 | class QWaylandXdgExporterV2; |
42 | |
43 | class Q_WAYLANDCLIENT_EXPORT QWaylandXdgSurface : public QWaylandShellSurface, public QtWayland::xdg_surface |
44 | { |
45 | Q_OBJECT |
46 | public: |
47 | QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *surface, QWaylandWindow *window); |
48 | ~QWaylandXdgSurface() override; |
49 | |
50 | bool resize(QWaylandInputDevice *inputDevice, Qt::Edges edges) override; |
51 | bool move(QWaylandInputDevice *inputDevice) override; |
52 | bool showWindowMenu(QWaylandInputDevice *seat) override; |
53 | void setTitle(const QString &title) override; |
54 | void setAppId(const QString &appId) override; |
55 | void setWindowFlags(Qt::WindowFlags flags) override; |
56 | |
57 | bool isExposed() const override; |
58 | bool handleExpose(const QRegion &) override; |
59 | bool handlesActiveState() const { return m_toplevel; } |
60 | void applyConfigure() override; |
61 | bool wantsDecorations() const override; |
62 | void propagateSizeHints() override; |
63 | void setWindowGeometry(const QRect &rect) override; |
64 | bool requestActivate() override; |
65 | void setXdgActivationToken(const QString &token) override; |
66 | void requestXdgActivationToken(quint32 serial) override; |
67 | void setAlertState(bool enabled) override; |
68 | bool isAlertState() const override { return m_alertState; } |
69 | QString externWindowHandle() override; |
70 | |
71 | void setSizeHints(); |
72 | |
73 | void *nativeResource(const QByteArray &resource); |
74 | |
75 | std::any surfaceRole() const override; |
76 | |
77 | protected: |
78 | void requestWindowStates(Qt::WindowStates states) override; |
79 | void xdg_surface_configure(uint32_t serial) override; |
80 | |
81 | private: |
82 | class Toplevel: public QtWayland::xdg_toplevel |
83 | { |
84 | public: |
85 | Toplevel(QWaylandXdgSurface *xdgSurface); |
86 | ~Toplevel() override; |
87 | |
88 | void applyConfigure(); |
89 | bool wantsDecorations(); |
90 | |
91 | void xdg_toplevel_configure(int32_t width, int32_t height, wl_array *states) override; |
92 | void xdg_toplevel_close() override; |
93 | void xdg_toplevel_configure_bounds(int32_t width, int32_t height) override; |
94 | |
95 | void requestWindowFlags(Qt::WindowFlags flags); |
96 | void requestWindowStates(Qt::WindowStates states); |
97 | |
98 | static resize_edge convertToResizeEdges(Qt::Edges edges); |
99 | |
100 | struct { |
101 | QSize bounds = {0, 0}; |
102 | QSize size = {0, 0}; |
103 | Qt::WindowStates states = Qt::WindowNoState; |
104 | } m_pending, m_applied; |
105 | QWaylandWindow::ToplevelWindowTilingStates m_toplevelStates = QWaylandWindow::WindowNoState; |
106 | QSize m_normalSize; |
107 | |
108 | QWaylandXdgSurface *m_xdgSurface = nullptr; |
109 | QWaylandXdgToplevelDecorationV1 *m_decoration = nullptr; |
110 | QScopedPointer<QWaylandXdgExportedV2> m_exported; |
111 | }; |
112 | |
113 | class Popup : public QtWayland::xdg_popup { |
114 | public: |
115 | Popup(QWaylandXdgSurface *xdgSurface, QWaylandWindow *parent, QtWayland::xdg_positioner *positioner); |
116 | ~Popup() override; |
117 | |
118 | void applyConfigure(); |
119 | void resetConfiguration(); |
120 | |
121 | void grab(QWaylandInputDevice *seat, uint serial); |
122 | void xdg_popup_configure(int32_t x, int32_t y, int32_t width, int32_t height) override; |
123 | void xdg_popup_popup_done() override; |
124 | |
125 | QWaylandXdgSurface *m_xdgSurface = nullptr; |
126 | QWaylandXdgSurface *m_parentXdgSurface = nullptr; |
127 | QWaylandWindow *m_parent = nullptr; |
128 | bool m_grabbing = false; |
129 | |
130 | QRect m_pendingGeometry; |
131 | }; |
132 | |
133 | void setToplevel(); |
134 | void setPopup(QWaylandWindow *parent); |
135 | void setGrabPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial); |
136 | |
137 | QWaylandXdgShell *m_shell = nullptr; |
138 | QWaylandWindow *m_window = nullptr; |
139 | Toplevel *m_toplevel = nullptr; |
140 | Popup *m_popup = nullptr; |
141 | bool m_configured = false; |
142 | QRegion m_exposeRegion; |
143 | uint m_pendingConfigureSerial = 0; |
144 | uint m_appliedConfigureSerial = 0; |
145 | QString m_activationToken; |
146 | QString m_appId; |
147 | bool m_alertState = false; |
148 | |
149 | friend class QWaylandXdgShell; |
150 | }; |
151 | |
152 | class Q_WAYLANDCLIENT_EXPORT QWaylandXdgShell |
153 | { |
154 | public: |
155 | QWaylandXdgShell(QWaylandDisplay *display, QtWayland::xdg_wm_base *xdg_wm_base); |
156 | ~QWaylandXdgShell(); |
157 | |
158 | QWaylandDisplay *display() const { return m_display; } |
159 | |
160 | QWaylandXdgDecorationManagerV1 *decorationManager() { return m_xdgDecorationManager.data(); } |
161 | QWaylandXdgActivationV1 *activation() const { return m_xdgActivation.data(); } |
162 | QWaylandXdgExporterV2 *exporter() const { return m_xdgExporter.data(); } |
163 | QWaylandXdgSurface *getXdgSurface(QWaylandWindow *window); |
164 | |
165 | private: |
166 | static void handleRegistryGlobal(void *data, ::wl_registry *registry, uint id, |
167 | const QString &interface, uint version); |
168 | |
169 | QWaylandDisplay *m_display = nullptr; |
170 | QtWayland::xdg_wm_base *m_xdgWmBase = nullptr; |
171 | QScopedPointer<QWaylandXdgDecorationManagerV1> m_xdgDecorationManager; |
172 | QScopedPointer<QWaylandXdgActivationV1> m_xdgActivation; |
173 | QScopedPointer<QWaylandXdgExporterV2> m_xdgExporter; |
174 | QWaylandXdgSurface::Popup *m_topmostGrabbingPopup = nullptr; |
175 | |
176 | friend class QWaylandXdgSurface; |
177 | }; |
178 | |
179 | QT_END_NAMESPACE |
180 | |
181 | } |
182 | |
183 | #endif // QWAYLANDXDGSHELL_H |
184 | |