Blame SOURCES/qtwayland-client-expose-toplevel-window-state.patch

0cfe39
From d533901938a996367d7b6f87b0214f5a17098aed Mon Sep 17 00:00:00 2001
0cfe39
From: Jan Grulich <jgrulich@redhat.com>
0cfe39
Date: Tue, 23 Mar 2021 16:03:22 +0100
0cfe39
Subject: [PATCH] Client: expose toplevel window state
0cfe39
0cfe39
QWaylandWindow has only basic information about window state, like if
0cfe39
it's active or maximized, but it has no information about tiling, which
0cfe39
can be useful for client-side decorations. We also need to bump version
0cfe39
of xdg-shell protocol we support, because additional states are not in
0cfe39
the version currently supported by QtWayland. It shouldn't be a problem
0cfe39
to increase the version as the new version adds just these additional
0cfe39
window states.
0cfe39
0cfe39
Change-Id: I4c46516d9c7296c69ea51a022b3bdb4ca06bef8d
0cfe39
Reviewed-by: David Edmundson <davidedmundson@kde.org>
0cfe39
---
0cfe39
 src/client/qwaylandwindow.cpp                    | 15 +++++++++++++++
0cfe39
 src/client/qwaylandwindow_p.h                    | 16 ++++++++++++++++
0cfe39
 .../xdg-shell/qwaylandxdgshell.cpp               | 16 +++++++++++++++-
0cfe39
 .../xdg-shell/qwaylandxdgshell_p.h               |  3 ++-
0cfe39
 4 files changed, 48 insertions(+), 2 deletions(-)
0cfe39
0cfe39
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
0cfe39
index c35ccab15..65a914976 100644
0cfe39
--- a/src/client/qwaylandwindow.cpp
0cfe39
+++ b/src/client/qwaylandwindow.cpp
0cfe39
@@ -1107,6 +1107,21 @@ bool QWaylandWindow::setMouseGrabEnabled(bool grab)
0cfe39
     return true;
0cfe39
 }
0cfe39
0cfe39
+QWaylandWindow::ToplevelWindowTilingStates QWaylandWindow::toplevelWindowTilingStates() const
0cfe39
+{
0cfe39
+    return mLastReportedToplevelWindowTilingStates;
0cfe39
+}
0cfe39
+
0cfe39
+void QWaylandWindow::handleToplevelWindowTilingStatesChanged(ToplevelWindowTilingStates states)
0cfe39
+{
0cfe39
+    mLastReportedToplevelWindowTilingStates = states;
0cfe39
+}
0cfe39
+
0cfe39
+Qt::WindowStates QWaylandWindow::windowStates() const
0cfe39
+{
0cfe39
+    return mLastReportedWindowStates;
0cfe39
+}
0cfe39
+
0cfe39
 void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
0cfe39
 {
0cfe39
     createDecoration();
0cfe39
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
0cfe39
index 5f134568b..1d743f4e4 100644
0cfe39
--- a/src/client/qwaylandwindow_p.h
0cfe39
+++ b/src/client/qwaylandwindow_p.h
0cfe39
@@ -95,6 +95,15 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformW
0cfe39
         Vulkan
0cfe39
     };
0cfe39
0cfe39
+    enum ToplevelWindowTilingState {
0cfe39
+        WindowNoState = 0,
0cfe39
+        WindowTiledLeft = 1,
0cfe39
+        WindowTiledRight = 2,
0cfe39
+        WindowTiledTop = 4,
0cfe39
+        WindowTiledBottom = 8
0cfe39
+    };
0cfe39
+    Q_DECLARE_FLAGS(ToplevelWindowTilingStates, ToplevelWindowTilingState)
0cfe39
+
0cfe39
     QWaylandWindow(QWindow *window, QWaylandDisplay *display);
0cfe39
     ~QWaylandWindow() override;
0cfe39
0cfe39
@@ -145,6 +154,10 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandWindow : public QObject, public QPlatformW
0cfe39
     void handleContentOrientationChange(Qt::ScreenOrientation orientation) override;
0cfe39
     void setOrientationMask(Qt::ScreenOrientations mask);
0cfe39
0cfe39
+    ToplevelWindowTilingStates toplevelWindowTilingStates() const;
0cfe39
+    void handleToplevelWindowTilingStatesChanged(ToplevelWindowTilingStates states);
0cfe39
+
0cfe39
+    Qt::WindowStates windowStates() const;
0cfe39
     void setWindowState(Qt::WindowStates states) override;
0cfe39
     void setWindowFlags(Qt::WindowFlags flags) override;
0cfe39
     void handleWindowStatesChanged(Qt::WindowStates states);
0cfe39
@@ -260,6 +273,7 @@ public slots:
0cfe39
     QRegion mMask;
0cfe39
     QRegion mOpaqueArea;
0cfe39
     Qt::WindowStates mLastReportedWindowStates = Qt::WindowNoState;
0cfe39
+    ToplevelWindowTilingStates mLastReportedToplevelWindowTilingStates = WindowNoState;
0cfe39
0cfe39
     QWaylandShmBackingStore *mBackingStore = nullptr;
0cfe39
     QWaylandBuffer *mQueuedBuffer = nullptr;
0cfe39
@@ -295,6 +309,8 @@ public slots:
0cfe39
     friend class QWaylandSubSurface;
0cfe39
 };
0cfe39
0cfe39
+Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandWindow::ToplevelWindowTilingStates)
0cfe39
+
0cfe39
 inline QIcon QWaylandWindow::windowIcon() const
0cfe39
 {
0cfe39
     return mWindowIcon;
0cfe39
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
0cfe39
index 965bc261d..5d9a21f81 100644
0cfe39
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
0cfe39
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
0cfe39
@@ -94,6 +94,7 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
0cfe39
     // TODO: none of the other plugins send WindowActive either, but is it on purpose?
0cfe39
     Qt::WindowStates statesWithoutActive = m_pending.states & ~Qt::WindowActive;
0cfe39
0cfe39
+    m_xdgSurface->m_window->handleToplevelWindowTilingStatesChanged(m_toplevelStates);
0cfe39
     m_xdgSurface->m_window->handleWindowStatesChanged(statesWithoutActive);
0cfe39
0cfe39
     if (m_pending.size.isEmpty()) {
0cfe39
@@ -126,6 +127,7 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t
0cfe39
     size_t numStates = states->size / sizeof(uint32_t);
0cfe39
0cfe39
     m_pending.states = Qt::WindowNoState;
0cfe39
+    m_toplevelStates = QWaylandWindow::WindowNoState;
0cfe39
0cfe39
     for (size_t i = 0; i < numStates; i++) {
0cfe39
         switch (xdgStates[i]) {
0cfe39
@@ -138,6 +140,18 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t
0cfe39
         case XDG_TOPLEVEL_STATE_FULLSCREEN:
0cfe39
             m_pending.states |= Qt::WindowFullScreen;
0cfe39
             break;
0cfe39
+        case XDG_TOPLEVEL_STATE_TILED_LEFT:
0cfe39
+            m_toplevelStates |= QWaylandWindow::WindowTiledLeft;
0cfe39
+            break;
0cfe39
+        case XDG_TOPLEVEL_STATE_TILED_RIGHT:
0cfe39
+            m_toplevelStates |= QWaylandWindow::WindowTiledRight;
0cfe39
+            break;
0cfe39
+        case XDG_TOPLEVEL_STATE_TILED_TOP:
0cfe39
+            m_toplevelStates |= QWaylandWindow::WindowTiledTop;
0cfe39
+            break;
0cfe39
+        case XDG_TOPLEVEL_STATE_TILED_BOTTOM:
0cfe39
+            m_toplevelStates |= QWaylandWindow::WindowTiledBottom;
0cfe39
+            break;
0cfe39
         default:
0cfe39
             break;
0cfe39
         }
0cfe39
@@ -469,7 +483,7 @@ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
0cfe39
 }
0cfe39
0cfe39
 QWaylandXdgShell::QWaylandXdgShell(QWaylandDisplay *display, uint32_t id, uint32_t availableVersion)
0cfe39
-    : QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 1u))
0cfe39
+    : QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 2u))
0cfe39
     , m_display(display)
0cfe39
 {
0cfe39
     display->addRegistryListener(&QWaylandXdgShell::handleRegistryGlobal, this);
0cfe39
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
0cfe39
index 5aeec2eb9..e3a90c547 100644
0cfe39
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
0cfe39
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
0cfe39
@@ -58,6 +58,7 @@
0cfe39
0cfe39
 #include <QtWaylandClient/qtwaylandclientglobal.h>
0cfe39
 #include <QtWaylandClient/private/qwaylandshellsurface_p.h>
0cfe39
+#include <QtWaylandClient/private/qwaylandwindow_p.h>
0cfe39
0cfe39
 #include <QtCore/QSize>
0cfe39
 #include <QtGui/QRegion>
0cfe39
@@ -69,7 +70,6 @@ class QWindow;
0cfe39
 namespace QtWaylandClient {
0cfe39
0cfe39
 class QWaylandDisplay;
0cfe39
-class QWaylandWindow;
0cfe39
 class QWaylandInputDevice;
0cfe39
 class QWaylandXdgShell;
0cfe39
0cfe39
@@ -125,6 +125,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgSurface : public QWaylandShellSurface,
0cfe39
             QSize size = {0, 0};
0cfe39
             Qt::WindowStates states = Qt::WindowNoState;
0cfe39
         }  m_pending, m_applied;
0cfe39
+        QWaylandWindow::ToplevelWindowTilingStates m_toplevelStates = QWaylandWindow::WindowNoState;
0cfe39
         QSize m_normalSize;
0cfe39
0cfe39
         QWaylandXdgSurface *m_xdgSurface = nullptr;