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
69 struct wl_egl_window;
70
71 QT_BEGIN_NAMESPACE
72
73 namespace QtWaylandClient {
74
75 Q_DECLARE_LOGGING_CATEGORY(lcWaylandBackingstore)
76
77 class QWaylandDisplay;
78 class QWaylandBuffer;
79 class QWaylandShellSurface;
80 class QWaylandSubSurface;
81 class QWaylandAbstractDecoration;
82 class QWaylandInputDevice;
83 class QWaylandScreen;
84 class QWaylandShmBackingStore;
85 class QWaylandPointerEvent;
86 class QWaylandSurface;
87
88 class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformWindow
89 {
90 Q_OBJECT
91 public:
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 ®ion);
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
waylandSurface()136 QWaylandSurface *waylandSurface() const { return mSurface.data(); }
137 ::wl_surface *wlSurface();
138 static QWaylandWindow *fromWlSurface(::wl_surface *surface);
139
display()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 Qt::WindowStates windowStates() const;
152
153 void raise() override;
154 void lower() override;
155
156 void setMask(const QRegion ®ion) override;
157
158 int scale() const;
159 qreal devicePixelRatio() const override;
160
161 void requestActivateWindow() override;
162 bool isExposed() const override;
163 bool isActive() const override;
164
165 QWaylandAbstractDecoration *decoration() const;
166
167 void handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
168
169 bool touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
170 Qt::TouchPointState state, Qt::KeyboardModifiers mods);
171
172 bool createDecoration();
173
174 #if QT_CONFIG(cursor)
175 void setMouseCursor(QWaylandInputDevice *device, const QCursor &cursor);
176 void restoreMouseCursor(QWaylandInputDevice *device);
177 #endif
178
179 QWaylandWindow *transientParent() const;
180
resizeMutex()181 QMutex *resizeMutex() { return &mResizeLock; }
182 void doApplyConfigure();
183 void setCanResize(bool canResize);
184
185 bool setMouseGrabEnabled(bool grab) override;
mouseGrab()186 static QWaylandWindow *mouseGrab() { return mMouseGrab; }
187
188 void sendProperty(const QString &name, const QVariant &value);
189 void setProperty(const QString &name, const QVariant &value);
190
191 QVariantMap properties() const;
192 QVariant property(const QString &name);
193 QVariant property(const QString &name, const QVariant &defaultValue);
194
setBackingStore(QWaylandShmBackingStore * backingStore)195 void setBackingStore(QWaylandShmBackingStore *backingStore) { mBackingStore = backingStore; }
backingStore()196 QWaylandShmBackingStore *backingStore() const { return mBackingStore; }
197
setKeyboardGrabEnabled(bool)198 bool setKeyboardGrabEnabled(bool) override { return false; }
199 void propagateSizeHints() override;
200 void addAttachOffset(const QPoint point);
201
202 bool startSystemResize(Qt::Edges edges) override;
203 bool startSystemMove() override;
204
205 void timerEvent(QTimerEvent *event) override;
206 void requestUpdate() override;
207 void handleUpdate();
208 void deliverUpdateRequest() override;
209
210 public slots:
211 void applyConfigure();
212
213 signals:
214 void wlSurfaceCreated();
215 void wlSurfaceDestroyed();
216
217 protected:
218 QWaylandDisplay *mDisplay = nullptr;
219 QScopedPointer<QWaylandSurface> mSurface;
220 QWaylandShellSurface *mShellSurface = nullptr;
221 QWaylandSubSurface *mSubSurfaceWindow = nullptr;
222 QVector<QWaylandSubSurface *> mChildren;
223
224 QWaylandAbstractDecoration *mWindowDecoration = nullptr;
225 bool mMouseEventsInContentArea = false;
226 Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
227
228 WId mWindowId;
229 bool mWaitingForFrameCallback = false;
230 bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
231 bool mWaitingForUpdateDelivery = false;
232 int mFrameCallbackCheckIntervalTimerId = -1;
233 QElapsedTimer mFrameCallbackElapsedTimer;
234 struct ::wl_callback *mFrameCallback = nullptr;
235 QWaylandDisplay::FrameQueue mFrameQueue;
236 QWaitCondition mFrameSyncWait;
237
238 // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
239 bool mWaitingForUpdate = false;
240
241 QMutex mResizeLock;
242 bool mWaitingToApplyConfigure = false;
243 bool mCanResize = true;
244 bool mResizeDirty = false;
245 bool mResizeAfterSwap;
246 int mFrameCallbackTimeout = 100;
247 QVariantMap m_properties;
248
249 bool mSentInitialResize = false;
250 QPoint mOffset;
251 int mScale = 1;
252 QPlatformScreen *mLastReportedScreen = nullptr;
253
254 QIcon mWindowIcon;
255
256 Qt::WindowFlags mFlags;
257 QRegion mMask;
258 QRegion mOpaqueArea;
259 Qt::WindowStates mLastReportedWindowStates = Qt::WindowNoState;
260
261 QWaylandShmBackingStore *mBackingStore = nullptr;
262 QWaylandBuffer *mQueuedBuffer = nullptr;
263 QRegion mQueuedBufferDamage;
264
265 private:
266 void setGeometry_helper(const QRect &rect);
267 void initWindow();
268 void initializeWlSurface();
269 bool shouldCreateShellSurface() const;
270 bool shouldCreateSubSurface() const;
271 void reset();
272 void sendExposeEvent(const QRect &rect);
273 static void closePopups(QWaylandWindow *parent);
274 QPlatformScreen *calculateScreenFromSurfaceEvents() const;
275 void setOpaqueArea(const QRegion &opaqueArea);
276 bool isOpaque() const;
277
278 void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
279 void handleScreensChanged();
280 void sendRecursiveExposeEvent();
281
282 bool mInResizeFromApplyConfigure = false;
283 bool lastVisible = false;
284 QRect mLastExposeGeometry;
285
286 static const wl_callback_listener callbackListener;
287 void handleFrameCallback();
288
289 static QWaylandWindow *mMouseGrab;
290
291 QReadWriteLock mSurfaceLock;
292
293 friend class QWaylandSubSurface;
294 };
295
windowIcon()296 inline QIcon QWaylandWindow::windowIcon() const
297 {
298 return mWindowIcon;
299 }
300
attachOffset()301 inline QPoint QWaylandWindow::attachOffset() const
302 {
303 return mOffset;
304 }
305
306 }
307
308 QT_END_NAMESPACE
309
310 #endif // QWAYLANDWINDOW_H
311