From d97f12c1c6bdd3d921f8ba9fe14f94e16392d4dc Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Sun, 23 Aug 2020 14:23:23 +0300 Subject: [PATCH] wayland: Expose tiled state to xdg-shell clients A client-side decorated window could use this information to improve management of edges, for example by providing inset resize handles, etc. --- abstract_client.cpp | 8 +++++++ abstract_client.h | 1 + xdgshellclient.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++ xdgshellclient.h | 1 + 4 files changed, 68 insertions(+) diff --git a/abstract_client.cpp b/abstract_client.cpp index 86ffdc580c..32ce26a103 100644 --- a/abstract_client.cpp +++ b/abstract_client.cpp @@ -955,6 +955,7 @@ bool AbstractClient::startMoveResize() // Exit quick tile mode when the user attempts to resize a tiled window updateQuickTileMode(QuickTileFlag::None); // Do so without restoring original geometry setGeometryRestore(frameGeometry()); + doSetQuickTileMode(); emit quickTileModeChanged(); } @@ -2864,6 +2865,7 @@ void AbstractClient::setQuickTileMode(QuickTileMode mode, bool keyboard) } setGeometryRestore(prev_geom_restore); } + doSetQuickTileMode(); emit quickTileModeChanged(); return; } @@ -2894,6 +2896,7 @@ void AbstractClient::setQuickTileMode(QuickTileMode mode, bool keyboard) setMaximize(false, false); } + doSetQuickTileMode(); emit quickTileModeChanged(); return; @@ -2973,9 +2976,14 @@ void AbstractClient::setQuickTileMode(QuickTileMode mode, bool keyboard) setFrameGeometry(geometryRestore(), geom_mode); checkWorkspacePosition(); // Just in case it's a different screen } + doSetQuickTileMode(); emit quickTileModeChanged(); } +void AbstractClient::doSetQuickTileMode() +{ +} + void AbstractClient::sendToScreen(int newScreen) { newScreen = rules()->checkScreen(newScreen); diff --git a/abstract_client.h b/abstract_client.h index 4b5febc31b..2e00303f06 100644 --- a/abstract_client.h +++ b/abstract_client.h @@ -973,6 +973,7 @@ protected: virtual void doSetSkipPager(); virtual void doSetSkipSwitcher(); virtual void doSetDemandsAttention(); + virtual void doSetQuickTileMode(); void setupWindowManagementInterface(); void destroyWindowManagementInterface(); diff --git a/xdgshellclient.cpp b/xdgshellclient.cpp index b91e42ee70..e6b56d7d63 100644 --- a/xdgshellclient.cpp +++ b/xdgshellclient.cpp @@ -938,6 +938,62 @@ void XdgToplevelClient::doSetMaximized() scheduleConfigure(); } +static Qt::Edges anchorsForQuickTileMode(QuickTileMode mode) +{ + if (mode == QuickTileMode(QuickTileFlag::None)) { + return Qt::Edges(); + } + + Qt::Edges anchors = Qt::LeftEdge | Qt::TopEdge | Qt::RightEdge | Qt::BottomEdge; + + if ((mode & QuickTileFlag::Left) && !(mode & QuickTileFlag::Right)) { + anchors &= ~Qt::RightEdge; + } + if ((mode & QuickTileFlag::Right) && !(mode & QuickTileFlag::Left)) { + anchors &= ~Qt::LeftEdge; + } + + if ((mode & QuickTileFlag::Top) && !(mode & QuickTileFlag::Bottom)) { + anchors &= ~Qt::BottomEdge; + } + if ((mode & QuickTileFlag::Bottom) && !(mode & QuickTileFlag::Top)) { + anchors &= ~Qt::TopEdge; + } + + return anchors; +} + +void XdgToplevelClient::doSetQuickTileMode() +{ + const Qt::Edges anchors = anchorsForQuickTileMode(quickTileMode()); + + if (anchors & Qt::LeftEdge) { + m_requestedStates |= XdgToplevelInterface::State::TiledLeft; + } else { + m_requestedStates &= ~XdgToplevelInterface::State::TiledLeft; + } + + if (anchors & Qt::RightEdge) { + m_requestedStates |= XdgToplevelInterface::State::TiledRight; + } else { + m_requestedStates &= ~XdgToplevelInterface::State::TiledRight; + } + + if (anchors & Qt::TopEdge) { + m_requestedStates |= XdgToplevelInterface::State::TiledTop; + } else { + m_requestedStates &= ~XdgToplevelInterface::State::TiledTop; + } + + if (anchors & Qt::BottomEdge) { + m_requestedStates |= XdgToplevelInterface::State::TiledBottom; + } else { + m_requestedStates &= ~XdgToplevelInterface::State::TiledBottom; + } + + scheduleConfigure(); +} + bool XdgToplevelClient::doStartMoveResize() { if (moveResizePointerMode() != PositionCenter) { @@ -1721,6 +1777,7 @@ void XdgToplevelClient::changeMaximize(bool horizontal, bool vertical, bool adju updateQuickTileMode(QuickTileFlag::None); } if (quickTileMode() != oldQuickTileMode) { + doSetQuickTileMode(); emit quickTileModeChanged(); } setFrameGeometry(workspace()->clientArea(MaximizeArea, this)); @@ -1729,6 +1786,7 @@ void XdgToplevelClient::changeMaximize(bool horizontal, bool vertical, bool adju updateQuickTileMode(QuickTileFlag::None); } if (quickTileMode() != oldQuickTileMode) { + doSetQuickTileMode(); emit quickTileModeChanged(); } diff --git a/xdgshellclient.h b/xdgshellclient.h index 42c831e0e5..99d9578831 100644 --- a/xdgshellclient.h +++ b/xdgshellclient.h @@ -176,6 +176,7 @@ protected: void changeMaximize(bool horizontal, bool vertical, bool adjust) override; Layer layerForDock() const override; bool stateCompare() const override; + void doSetQuickTileMode() override; private: void handleWindowTitleChanged();