1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the config.tests of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QWAYLANDWINDOW_H
41#define QWAYLANDWINDOW_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <QtCore/QWaitCondition>
55#include <QtCore/QMutex>
56#include <QtCore/QReadWriteLock>
57
58#include <QtGui/QIcon>
59#include <QtCore/QVariant>
60#include <QtCore/QLoggingCategory>
61#include <QtCore/QElapsedTimer>
62
63#include <qpa/qplatformwindow.h>
64
65#include <QtWaylandClient/private/qwayland-wayland.h>
66#include <QtWaylandClient/private/qwaylanddisplay_p.h>
67#include <QtWaylandClient/qtwaylandclientglobal.h>
68
69struct wl_egl_window;
70
71QT_BEGIN_NAMESPACE
72
73namespace QtWaylandClient {
74
75Q_DECLARE_LOGGING_CATEGORY(lcWaylandBackingstore)
76
77class QWaylandDisplay;
78class QWaylandBuffer;
79class QWaylandShellSurface;
80class QWaylandSubSurface;
81class QWaylandAbstractDecoration;
82class QWaylandInputDevice;
83class QWaylandScreen;
84class QWaylandShmBackingStore;
85class QWaylandPointerEvent;
86class QWaylandSurface;
87
88class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformWindow
89{
90 Q_OBJECT
91public:
92 enum WindowType {
93 Shm,
94 Egl,
95 Vulkan
96 };
97
98 QWaylandWindow(QWindow *window, QWaylandDisplay *display);
99 ~QWaylandWindow() override;
100
101 virtual WindowType windowType() const = 0;
102 virtual void ensureSize();
103 WId winId() const override;
104 void setVisible(bool visible) override;
105 void setParent(const QPlatformWindow *parent) override;
106
107 void setWindowTitle(const QString &title) override;
108
109 inline QIcon windowIcon() const;
110 void setWindowIcon(const QIcon &icon) override;
111
112 void setGeometry(const QRect &rect) override;
113 void resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset = {0, 0});
114
115 void applyConfigureWhenPossible(); //rename to possible?
116
117 void attach(QWaylandBuffer *buffer, int x, int y);
118 void attachOffset(QWaylandBuffer *buffer);
119 QPoint attachOffset() const;
120
121 void damage(const QRect &rect);
122
123 void safeCommit(QWaylandBuffer *buffer, const QRegion &damage);
124 void handleExpose(const QRegion &region);
125 void commit(QWaylandBuffer *buffer, const QRegion &damage);
126
127 void commit();
128
129 bool waitForFrameSync(int timeout);
130
131 QMargins frameMargins() const override;
132 QSize surfaceSize() const;
133 QRect windowContentGeometry() const;
134 QPointF mapFromWlSurface(const QPointF &surfacePosition) const;
135
136 QWaylandSurface *waylandSurface() const { return mSurface.data(); }
137 ::wl_surface *wlSurface();
138 static QWaylandWindow *fromWlSurface(::wl_surface *surface);
139
140 QWaylandDisplay *display() const { return mDisplay; }
141 QWaylandShellSurface *shellSurface() const;
142 QWaylandSubSurface *subSurfaceWindow() const;
143 QWaylandScreen *waylandScreen() const;
144
145 void handleContentOrientationChange(Qt::ScreenOrientation orientation) override;
146 void setOrientationMask(Qt::ScreenOrientations mask);
147
148 void setWindowState(Qt::WindowStates states) override;
149 void setWindowFlags(Qt::WindowFlags flags) override;
150 void handleWindowStatesChanged(Qt::WindowStates states);
151
152 void raise() override;
153 void lower() override;
154
155 void setMask(const QRegion &region) override;
156
157 int scale() const;
158 qreal devicePixelRatio() const override;
159
160 void requestActivateWindow() override;
161 bool isExposed() const override;
162 bool isActive() const override;
163
164 QWaylandAbstractDecoration *decoration() const;
165
166 void handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
167
168 bool touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
169 Qt::TouchPointState state, Qt::KeyboardModifiers mods);
170
171 bool createDecoration();
172
173#if QT_CONFIG(cursor)
174 void setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor);
175 void restoreMouseCursor(QWaylandInputDevice *device);
176#endif
177
178 QWaylandWindow *transientParent() const;
179
180 QMutex *resizeMutex() { return &mResizeLock; }
181 void doApplyConfigure();
182 void setCanResize(bool canResize);
183
184 bool setMouseGrabEnabled(bool grab) override;
185 static QWaylandWindow *mouseGrab() { return mMouseGrab; }
186
187 void sendProperty(const QString &name, const QVariant &value);
188 void setProperty(const QString &name, const QVariant &value);
189
190 QVariantMap properties() const;
191 QVariant property(const QString &name);
192 QVariant property(const QString &name, const QVariant &defaultValue);
193
194 void setBackingStore(QWaylandShmBackingStore *backingStore) { mBackingStore = backingStore; }
195 QWaylandShmBackingStore *backingStore() const { return mBackingStore; }
196
197 bool setKeyboardGrabEnabled(bool) override { return false; }
198 void propagateSizeHints() override;
199 void addAttachOffset(const QPoint point);
200
201 bool startSystemResize(Qt::Edges edges) override;
202 bool startSystemMove() override;
203
204 void timerEvent(QTimerEvent *event) override;
205 void requestUpdate() override;
206 void handleUpdate();
207 void deliverUpdateRequest() override;
208
209public slots:
210 void applyConfigure();
211
212signals:
213 void wlSurfaceCreated();
214 void wlSurfaceDestroyed();
215
216protected:
217 QWaylandDisplay *mDisplay = nullptr;
218 QScopedPointer<QWaylandSurface> mSurface;
219 QWaylandShellSurface *mShellSurface = nullptr;
220 QWaylandSubSurface *mSubSurfaceWindow = nullptr;
221 QVector<QWaylandSubSurface *> mChildren;
222
223 QWaylandAbstractDecoration *mWindowDecoration = nullptr;
224 bool mMouseEventsInContentArea = false;
225 Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
226
227 WId mWindowId;
228 bool mWaitingForFrameCallback = false;
229 bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
230 bool mWaitingForUpdateDelivery = false;
231 int mFrameCallbackCheckIntervalTimerId = -1;
232 QElapsedTimer mFrameCallbackElapsedTimer;
233 struct ::wl_callback *mFrameCallback = nullptr;
234 QWaylandDisplay::FrameQueue mFrameQueue;
235 QWaitCondition mFrameSyncWait;
236
237 // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
238 bool mWaitingForUpdate = false;
239
240 QMutex mResizeLock;
241 bool mWaitingToApplyConfigure = false;
242 bool mCanResize = true;
243 bool mResizeDirty = false;
244 bool mResizeAfterSwap;
245 int mFrameCallbackTimeout = 100;
246 QVariantMap m_properties;
247
248 bool mSentInitialResize = false;
249 QPoint mOffset;
250 int mScale = 1;
251 QPlatformScreen *mLastReportedScreen = nullptr;
252
253 QIcon mWindowIcon;
254
255 Qt::WindowFlags mFlags;
256 QRegion mMask;
257 QRegion mOpaqueArea;
258 Qt::WindowStates mLastReportedWindowStates = Qt::WindowNoState;
259
260 QWaylandShmBackingStore *mBackingStore = nullptr;
261 QWaylandBuffer *mQueuedBuffer = nullptr;
262 QRegion mQueuedBufferDamage;
263
264private:
265 void setGeometry_helper(const QRect &rect);
266 void initWindow();
267 void initializeWlSurface();
268 bool shouldCreateShellSurface() const;
269 bool shouldCreateSubSurface() const;
270 void reset();
271 void sendExposeEvent(const QRect &rect);
272 static void closePopups(QWaylandWindow *parent);
273 QPlatformScreen *calculateScreenFromSurfaceEvents() const;
274 void setOpaqueArea(const QRegion &opaqueArea);
275 bool isOpaque() const;
276
277 void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
278 void handleScreensChanged();
279 void sendRecursiveExposeEvent();
280
281 bool mInResizeFromApplyConfigure = false;
282 bool lastVisible = false;
283 QRect mLastExposeGeometry;
284
285 static const wl_callback_listener callbackListener;
286 void handleFrameCallback();
287
288 static QWaylandWindow *mMouseGrab;
289
290 mutable QReadWriteLock mSurfaceLock;
291
292 friend class QWaylandSubSurface;
293};
294
295inline QIcon QWaylandWindow::windowIcon() const
296{
297 return mWindowIcon;
298}
299
300inline QPoint QWaylandWindow::attachOffset() const
301{
302 return mOffset;
303}
304
305}
306
307QT_END_NAMESPACE
308
309#endif // QWAYLANDWINDOW_H
310

source code of qtwayland/src/client/qwaylandwindow_p.h