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

e1c9ed
From d533901938a996367d7b6f87b0214f5a17098aed Mon Sep 17 00:00:00 2001
e1c9ed
From: Jan Grulich <jgrulich@redhat.com>
e1c9ed
Date: Tue, 23 Mar 2021 16:03:22 +0100
e1c9ed
Subject: [PATCH] Client: expose toplevel window state
e1c9ed
e1c9ed
QWaylandWindow has only basic information about window state, like if
e1c9ed
it's active or maximized, but it has no information about tiling, which
e1c9ed
can be useful for client-side decorations. We also need to bump version
e1c9ed
of xdg-shell protocol we support, because additional states are not in
e1c9ed
the version currently supported by QtWayland. It shouldn't be a problem
e1c9ed
to increase the version as the new version adds just these additional
e1c9ed
window states.
e1c9ed
e1c9ed
Change-Id: I4c46516d9c7296c69ea51a022b3bdb4ca06bef8d
e1c9ed
Reviewed-by: David Edmundson <davidedmundson@kde.org>
e1c9ed
---
e1c9ed
 src/client/qwaylandwindow.cpp                    | 15 +++++++++++++++
e1c9ed
 src/client/qwaylandwindow_p.h                    | 16 ++++++++++++++++
e1c9ed
 .../xdg-shell/qwaylandxdgshell.cpp               | 16 +++++++++++++++-
e1c9ed
 .../xdg-shell/qwaylandxdgshell_p.h               |  3 ++-
e1c9ed
 4 files changed, 48 insertions(+), 2 deletions(-)
e1c9ed
e1c9ed
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
e1c9ed
index ba881cb..a1e891d 100644
e1c9ed
--- a/src/client/qwaylandwindow.cpp
e1c9ed
+++ b/src/client/qwaylandwindow.cpp
e1c9ed
@@ -1089,6 +1089,16 @@ Qt::WindowStates QWaylandWindow::windowStates() const
e1c9ed
     return mLastReportedWindowStates;
e1c9ed
 }
e1c9ed
e1c9ed
+QWaylandWindow::ToplevelWindowTilingStates QWaylandWindow::toplevelWindowTilingStates() const
e1c9ed
+{
e1c9ed
+    return mLastReportedToplevelWindowTilingStates;
e1c9ed
+}
e1c9ed
+
e1c9ed
+void QWaylandWindow::handleToplevelWindowTilingStatesChanged(ToplevelWindowTilingStates states)
e1c9ed
+{
e1c9ed
+    mLastReportedToplevelWindowTilingStates = states;
e1c9ed
+}
e1c9ed
+
e1c9ed
 void QWaylandWindow::handleWindowStatesChanged(Qt::WindowStates states)
e1c9ed
 {
e1c9ed
     createDecoration();
e1c9ed
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
e1c9ed
index e068796..f4e5d3d 100644
e1c9ed
--- a/src/client/qwaylandwindow_p.h
e1c9ed
+++ b/src/client/qwaylandwindow_p.h
e1c9ed
@@ -95,6 +95,15 @@ public:
e1c9ed
         Vulkan
e1c9ed
     };
e1c9ed
e1c9ed
+    enum ToplevelWindowTilingState {
e1c9ed
+        WindowNoState = 0,
e1c9ed
+        WindowTiledLeft = 1,
e1c9ed
+        WindowTiledRight = 2,
e1c9ed
+        WindowTiledTop = 4,
e1c9ed
+        WindowTiledBottom = 8
e1c9ed
+    };
e1c9ed
+    Q_DECLARE_FLAGS(ToplevelWindowTilingStates, ToplevelWindowTilingState)
e1c9ed
+
e1c9ed
     QWaylandWindow(QWindow *window, QWaylandDisplay *display);
e1c9ed
     ~QWaylandWindow() override;
e1c9ed
e1c9ed
@@ -145,6 +154,9 @@ public:
e1c9ed
     void handleContentOrientationChange(Qt::ScreenOrientation orientation) override;
e1c9ed
     void setOrientationMask(Qt::ScreenOrientations mask);
e1c9ed
e1c9ed
+    ToplevelWindowTilingStates toplevelWindowTilingStates() const;
e1c9ed
+    void handleToplevelWindowTilingStatesChanged(ToplevelWindowTilingStates states);
e1c9ed
+
e1c9ed
     void setWindowState(Qt::WindowStates states) override;
e1c9ed
     void setWindowFlags(Qt::WindowFlags flags) override;
e1c9ed
     void handleWindowStatesChanged(Qt::WindowStates states);
e1c9ed
@@ -257,6 +269,7 @@ protected:
e1c9ed
     QRegion mMask;
e1c9ed
     QRegion mOpaqueArea;
e1c9ed
     Qt::WindowStates mLastReportedWindowStates = Qt::WindowNoState;
e1c9ed
+    ToplevelWindowTilingStates mLastReportedToplevelWindowTilingStates = WindowNoState;
e1c9ed
e1c9ed
     QWaylandShmBackingStore *mBackingStore = nullptr;
e1c9ed
     QWaylandBuffer *mQueuedBuffer = nullptr;
e1c9ed
@@ -293,6 +306,8 @@ private:
e1c9ed
     friend class QWaylandSubSurface;
e1c9ed
 };
e1c9ed
e1c9ed
+Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandWindow::ToplevelWindowTilingStates)
e1c9ed
+
e1c9ed
 inline QIcon QWaylandWindow::windowIcon() const
e1c9ed
 {
e1c9ed
     return mWindowIcon;
e1c9ed
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
e1c9ed
index d7d0ddf..2c6e84b 100644
e1c9ed
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
e1c9ed
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
e1c9ed
@@ -88,6 +88,7 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
e1c9ed
         && !m_xdgSurface->m_window->display()->isKeyboardAvailable())
e1c9ed
         m_xdgSurface->m_window->display()->handleWindowDeactivated(m_xdgSurface->m_window);
e1c9ed
e1c9ed
+    m_xdgSurface->m_window->handleToplevelWindowTilingStatesChanged(m_toplevelStates);
e1c9ed
     m_xdgSurface->m_window->handleWindowStatesChanged(m_pending.states);
e1c9ed
e1c9ed
     if (m_pending.size.isEmpty()) {
e1c9ed
@@ -120,6 +121,7 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t
e1c9ed
     size_t numStates = states->size / sizeof(uint32_t);
e1c9ed
e1c9ed
     m_pending.states = Qt::WindowNoState;
e1c9ed
+    m_toplevelStates = QWaylandWindow::WindowNoState;
e1c9ed
e1c9ed
     for (size_t i = 0; i < numStates; i++) {
e1c9ed
         switch (xdgStates[i]) {
e1c9ed
@@ -132,6 +134,18 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t
e1c9ed
         case XDG_TOPLEVEL_STATE_FULLSCREEN:
e1c9ed
             m_pending.states |= Qt::WindowFullScreen;
e1c9ed
             break;
e1c9ed
+        case XDG_TOPLEVEL_STATE_TILED_LEFT:
e1c9ed
+            m_toplevelStates |= QWaylandWindow::WindowTiledLeft;
e1c9ed
+            break;
e1c9ed
+        case XDG_TOPLEVEL_STATE_TILED_RIGHT:
e1c9ed
+            m_toplevelStates |= QWaylandWindow::WindowTiledRight;
e1c9ed
+            break;
e1c9ed
+        case XDG_TOPLEVEL_STATE_TILED_TOP:
e1c9ed
+            m_toplevelStates |= QWaylandWindow::WindowTiledTop;
e1c9ed
+            break;
e1c9ed
+        case XDG_TOPLEVEL_STATE_TILED_BOTTOM:
e1c9ed
+            m_toplevelStates |= QWaylandWindow::WindowTiledBottom;
e1c9ed
+            break;
e1c9ed
         default:
e1c9ed
             break;
e1c9ed
         }
e1c9ed
@@ -451,7 +465,7 @@ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
e1c9ed
 }
e1c9ed
e1c9ed
 QWaylandXdgShell::QWaylandXdgShell(QWaylandDisplay *display, uint32_t id, uint32_t availableVersion)
e1c9ed
-    : QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 1u))
e1c9ed
+    : QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 2u))
e1c9ed
     , m_display(display)
e1c9ed
 {
e1c9ed
     display->addRegistryListener(&QWaylandXdgShell::handleRegistryGlobal, this);
e1c9ed
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
e1c9ed
index 0c98be3..d791213 100644
e1c9ed
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
e1c9ed
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h
e1c9ed
@@ -58,6 +58,7 @@
e1c9ed
e1c9ed
 #include <QtWaylandClient/qtwaylandclientglobal.h>
e1c9ed
 #include <QtWaylandClient/private/qwaylandshellsurface_p.h>
e1c9ed
+#include <QtWaylandClient/private/qwaylandwindow_p.h>
e1c9ed
e1c9ed
 #include <QtCore/QSize>
e1c9ed
 #include <QtGui/QRegion>
e1c9ed
@@ -69,7 +70,6 @@ class QWindow;
e1c9ed
 namespace QtWaylandClient {
e1c9ed
e1c9ed
 class QWaylandDisplay;
e1c9ed
-class QWaylandWindow;
e1c9ed
 class QWaylandInputDevice;
e1c9ed
 class QWaylandXdgShell;
e1c9ed
e1c9ed
@@ -123,6 +123,7 @@ private:
e1c9ed
             QSize size = {0, 0};
e1c9ed
             Qt::WindowStates states = Qt::WindowNoState;
e1c9ed
         }  m_pending, m_applied;
e1c9ed
+        QWaylandWindow::ToplevelWindowTilingStates m_toplevelStates = QWaylandWindow::WindowNoState;
e1c9ed
         QSize m_normalSize;
e1c9ed
e1c9ed
         QWaylandXdgSurface *m_xdgSurface = nullptr;