summaryrefslogtreecommitdiffstats
path: root/src/client/qwaylandwindow_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/qwaylandwindow_p.h')
-rw-r--r--src/client/qwaylandwindow_p.h251
1 files changed, 177 insertions, 74 deletions
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index c47123dc9..b78c8ce4e 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the config.tests of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWAYLANDWINDOW_H
#define QWAYLANDWINDOW_H
@@ -53,14 +17,25 @@
#include <QtCore/QWaitCondition>
#include <QtCore/QMutex>
+#include <QtCore/QReadWriteLock>
+
#include <QtGui/QIcon>
+#include <QtGui/QEventPoint>
#include <QtCore/QVariant>
#include <QtCore/QLoggingCategory>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QList>
+#include <QtCore/QMap> // for QVariantMap
#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformwindow_p.h>
#include <QtWaylandClient/private/qwayland-wayland.h>
+#include <QtWaylandClient/private/qwaylanddisplay_p.h>
#include <QtWaylandClient/qtwaylandclientglobal.h>
+#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
+
+#include <QtCore/qpointer.h>
struct wl_egl_window;
@@ -77,27 +52,48 @@ class QWaylandSubSurface;
class QWaylandAbstractDecoration;
class QWaylandInputDevice;
class QWaylandScreen;
+class QWaylandShellIntegration;
class QWaylandShmBackingStore;
class QWaylandPointerEvent;
-
-class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformWindow, public QtWayland::wl_surface
+class QWaylandPointerGestureSwipeEvent;
+class QWaylandPointerGesturePinchEvent;
+class QWaylandSurface;
+class QWaylandFractionalScale;
+class QWaylandViewport;
+
+class Q_WAYLANDCLIENT_EXPORT QWaylandWindow : public QNativeInterface::Private::QWaylandWindow,
+ public QPlatformWindow
{
Q_OBJECT
public:
enum WindowType {
Shm,
- Egl
+ Egl,
+ Vulkan
+ };
+
+ enum ToplevelWindowTilingState {
+ WindowNoState = 0,
+ WindowTiledLeft = 1,
+ WindowTiledRight = 2,
+ WindowTiledTop = 4,
+ WindowTiledBottom = 8
};
+ Q_DECLARE_FLAGS(ToplevelWindowTilingStates, ToplevelWindowTilingState)
- QWaylandWindow(QWindow *window);
+ QWaylandWindow(QWindow *window, QWaylandDisplay *display);
~QWaylandWindow() override;
+ // Keep Toplevels position on the top left corner of their screen
+ static inline bool fixedToplevelPositions = true;
+
virtual WindowType windowType() const = 0;
virtual void ensureSize();
WId winId() const override;
void setVisible(bool visible) override;
void setParent(const QPlatformWindow *parent) override;
+ QString windowTitle() const;
void setWindowTitle(const QString &title) override;
inline QIcon windowIcon() const;
@@ -105,35 +101,54 @@ public:
void setGeometry(const QRect &rect) override;
void resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset = {0, 0});
+ void repositionFromApplyConfigure(const QPoint &position);
+ void setGeometryFromApplyConfigure(const QPoint &globalPosition, const QSize &sizeWithMargins);
void applyConfigureWhenPossible(); //rename to possible?
- using QtWayland::wl_surface::attach;
void attach(QWaylandBuffer *buffer, int x, int y);
void attachOffset(QWaylandBuffer *buffer);
QPoint attachOffset() const;
- using QtWayland::wl_surface::damage;
void damage(const QRect &rect);
void safeCommit(QWaylandBuffer *buffer, const QRegion &damage);
- void handleExpose(const QRegion &region);
void commit(QWaylandBuffer *buffer, const QRegion &damage);
+ void commit();
+
bool waitForFrameSync(int timeout);
QMargins frameMargins() const override;
-
+ QMargins clientSideMargins() const;
+ void setCustomMargins(const QMargins &margins) override;
+ QSize surfaceSize() const;
+ QMargins windowContentMargins() const;
+ QRect windowContentGeometry() const;
+ QPointF mapFromWlSurface(const QPointF &surfacePosition) const;
+
+ QWaylandSurface *waylandSurface() const { return mSurface.data(); }
+ ::wl_surface *wlSurface() const;
+ ::wl_surface *surface() const override
+ {
+ return wlSurface();
+ }
static QWaylandWindow *fromWlSurface(::wl_surface *surface);
QWaylandDisplay *display() const { return mDisplay; }
QWaylandShellSurface *shellSurface() const;
+ std::any _surfaceRole() const override;
QWaylandSubSurface *subSurfaceWindow() const;
QWaylandScreen *waylandScreen() const;
void handleContentOrientationChange(Qt::ScreenOrientation orientation) override;
+ void updateBufferTransform();
void setOrientationMask(Qt::ScreenOrientations mask);
+ ToplevelWindowTilingStates toplevelWindowTilingStates() const;
+ void handleToplevelWindowTilingStatesChanged(ToplevelWindowTilingStates states);
+
+ Qt::WindowStates windowStates() const;
void setWindowState(Qt::WindowStates states) override;
void setWindowFlags(Qt::WindowFlags flags) override;
void handleWindowStatesChanged(Qt::WindowStates states);
@@ -143,21 +158,28 @@ public:
void setMask(const QRegion &region) override;
- int scale() const;
+ void setAlertState(bool enabled) override;
+ bool isAlertState() const override;
+
+ qreal scale() const;
qreal devicePixelRatio() const override;
void requestActivateWindow() override;
bool isExposed() const override;
bool isActive() const override;
- void unfocus();
QWaylandAbstractDecoration *decoration() const;
void handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
- void handleMouseLeave(QWaylandInputDevice *inputDevice);
+#ifndef QT_NO_GESTURES
+ void handleSwipeGesture(QWaylandInputDevice *inputDevice,
+ const QWaylandPointerGestureSwipeEvent &e);
+ void handlePinchGesture(QWaylandInputDevice *inputDevice,
+ const QWaylandPointerGesturePinchEvent &e);
+#endif
bool touchDragDecoration(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
- Qt::TouchPointState state, Qt::KeyboardModifiers mods);
+ QEventPoint::State state, Qt::KeyboardModifiers mods);
bool createDecoration();
@@ -168,7 +190,6 @@ public:
QWaylandWindow *transientParent() const;
- QMutex *resizeMutex() { return &mResizeLock; }
void doApplyConfigure();
void setCanResize(bool canResize);
@@ -182,72 +203,143 @@ public:
QVariant property(const QString &name);
QVariant property(const QString &name, const QVariant &defaultValue);
+#ifdef QT_PLATFORM_WINDOW_HAS_VIRTUAL_SET_BACKING_STORE
+ void setBackingStore(QPlatformBackingStore *store) override;
+#else
void setBackingStore(QWaylandShmBackingStore *backingStore) { mBackingStore = backingStore; }
+#endif
QWaylandShmBackingStore *backingStore() const { return mBackingStore; }
+ void setShellIntegration(QWaylandShellIntegration *shellIntegration);
+ QWaylandShellIntegration *shellIntegration() const { return mShellIntegration; }
+
bool setKeyboardGrabEnabled(bool) override { return false; }
- void propagateSizeHints() override { }
+ void propagateSizeHints() override;
void addAttachOffset(const QPoint point);
- bool startSystemMove(const QPoint &pos) override;
+ bool startSystemResize(Qt::Edges edges) override;
+ bool startSystemMove() override;
void timerEvent(QTimerEvent *event) override;
void requestUpdate() override;
void handleUpdate();
void deliverUpdateRequest() override;
-public slots:
+ void setXdgActivationToken(const QString &token);
+ void requestXdgActivationToken(uint serial) override;
+
+ void beginFrame();
+ void endFrame();
+
+ void closeChildPopups();
+ void sendRecursiveExposeEvent();
+
+ virtual void reinit();
+ void reset();
+
+ bool windowEvent(QEvent *event) override;
+
+public Q_SLOTS:
void applyConfigure();
+Q_SIGNALS:
+ void wlSurfaceCreated();
+ void wlSurfaceDestroyed();
+
protected:
- void surface_enter(struct ::wl_output *output) override;
- void surface_leave(struct ::wl_output *output) override;
+ virtual void doHandleFrameCallback();
+ virtual QRect defaultGeometry() const;
+ void sendExposeEvent(const QRect &rect);
- QVector<QWaylandScreen *> mScreens; //As seen by wl_surface.enter/leave events. Chronological order.
QWaylandDisplay *mDisplay = nullptr;
+
+ // mSurface can be written by the main thread. Other threads should claim a read lock for access
+ mutable QReadWriteLock mSurfaceLock;
+ QScopedPointer<QWaylandSurface> mSurface;
+ QScopedPointer<QWaylandFractionalScale> mFractionalScale;
+ QScopedPointer<QWaylandViewport> mViewport;
+
+ QWaylandShellIntegration *mShellIntegration = nullptr;
QWaylandShellSurface *mShellSurface = nullptr;
QWaylandSubSurface *mSubSurfaceWindow = nullptr;
- QVector<QWaylandSubSurface *> mChildren;
+ QList<QWaylandSubSurface *> mChildren;
QWaylandAbstractDecoration *mWindowDecoration = nullptr;
+ bool mWindowDecorationEnabled = false;
bool mMouseEventsInContentArea = false;
Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton;
+#ifndef QT_NO_GESTURES
+ enum GestureState {
+ GestureNotActive,
+ GestureActiveInContentArea,
+ GestureActiveInDecoration
+ };
+
+ // We want gestures started in the decoration area to be completely ignored even if the mouse
+ // pointer is later moved to content area. Likewise, gestures started in the content area should
+ // keep sending events even if the mouse pointer is moved over the decoration (consider that
+ // the events for that gesture will be sent to us even if it's moved outside the window).
+ // So we track the gesture state and accept or ignore events based on that. Note that
+ // concurrent gestures of different types are not allowed in the protocol, so single state is
+ // enough
+ GestureState mGestureState = GestureNotActive;
+#endif
+
WId mWindowId;
- bool mWaitingForFrameCallback = false;
bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
- int mFrameCallbackTimerId = -1; // Started on commit, reset on frame callback
- struct ::wl_callback *mFrameCallback = nullptr;
- struct ::wl_event_queue *mFrameQueue = nullptr;
+ int mFrameCallbackCheckIntervalTimerId = -1;
+ QAtomicInt mWaitingForUpdateDelivery = false;
+
+ bool mWaitingForFrameCallback = false; // Protected by mFrameSyncMutex
+ QElapsedTimer mFrameCallbackElapsedTimer; // Protected by mFrameSyncMutex
+ struct ::wl_callback *mFrameCallback = nullptr; // Protected by mFrameSyncMutex
+ QMutex mFrameSyncMutex;
QWaitCondition mFrameSyncWait;
// True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
bool mWaitingForUpdate = false;
- int mFallbackUpdateTimerId = -1; // Started when waiting for app to commit
- QMutex mResizeLock;
+ QRecursiveMutex mResizeLock;
bool mWaitingToApplyConfigure = false;
bool mCanResize = true;
bool mResizeDirty = false;
bool mResizeAfterSwap;
+ int mFrameCallbackTimeout = 100;
QVariantMap m_properties;
bool mSentInitialResize = false;
QPoint mOffset;
- int mScale = 1;
+ qreal mScale = 1;
+ QPlatformScreen *mLastReportedScreen = nullptr;
+ QString mWindowTitle;
QIcon mWindowIcon;
Qt::WindowFlags mFlags;
QRegion mMask;
+
+ // Empty QRegion maps to "infinite" input region, needs a dedicated "deliberately empty" state.
+ QRegion mInputRegion;
+ bool mTransparentInputRegion = false;
+
+ QRegion mOpaqueArea;
Qt::WindowStates mLastReportedWindowStates = Qt::WindowNoState;
+ ToplevelWindowTilingStates mLastReportedToplevelWindowTilingStates = WindowNoState;
QWaylandShmBackingStore *mBackingStore = nullptr;
QWaylandBuffer *mQueuedBuffer = nullptr;
QRegion mQueuedBufferDamage;
-private slots:
- void handleScreenRemoved(QScreen *qScreen);
+ QMargins mCustomMargins;
+
+ QPointer<QWaylandWindow> mTransientParent;
+ QList<QPointer<QWaylandWindow>> mChildPopups;
+
+ Qt::ScreenOrientation mLastReportedContentOrientation = Qt::PrimaryOrientation;
+
+private Q_SLOTS:
+ void doApplyConfigureFromOtherThread();
private:
void setGeometry_helper(const QRect &rect);
@@ -255,25 +347,36 @@ private:
void initializeWlSurface();
bool shouldCreateShellSurface() const;
bool shouldCreateSubSurface() const;
- void reset(bool sendDestroyEvent = true);
- void sendExposeEvent(const QRect &rect);
- static void closePopups(QWaylandWindow *parent);
- QWaylandScreen *calculateScreenFromSurfaceEvents() const;
+ QPlatformScreen *calculateScreenFromSurfaceEvents() const;
+ void setOpaqueArea(const QRegion &opaqueArea);
+ bool isOpaque() const;
+ void updateInputRegion();
+ void updateViewport();
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
- void handleScreenChanged();
+ void handleScreensChanged();
+ void updateScale();
+ void setScale(qreal newScale);
+ QWaylandWindow *guessTransientParent() const;
+ void addChildPopup(QWaylandWindow *child);
+ void removeChildPopup(QWaylandWindow *child);
+
+ bool mInResizeFromApplyConfigure = false;
+ bool lastVisible = false;
QRect mLastExposeGeometry;
static const wl_callback_listener callbackListener;
- void handleFrameCallback();
+ void handleFrameCallback(struct ::wl_callback* callback);
- static QMutex mFrameSyncMutex;
static QWaylandWindow *mMouseGrab;
+ static QWaylandWindow *mTopPopup;
friend class QWaylandSubSurface;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandWindow::ToplevelWindowTilingStates)
+
inline QIcon QWaylandWindow::windowIcon() const
{
return mWindowIcon;