diff --git a/abstract_client.cpp b/abstract_client.cpp index c4bedb91c6..8482d6db0e 100644 --- a/abstract_client.cpp +++ b/abstract_client.cpp @@ -141,4 +141,56 @@ void AbstractClient::updateLayer() { } +void AbstractClient::setKeepAbove(bool b) +{ + b = rules()->checkKeepAbove(b); + if (b && !rules()->checkKeepBelow(false)) + setKeepBelow(false); + if (b == keepAbove()) { + // force hint change if different + if (info && bool(info->state() & NET::KeepAbove) != keepAbove()) + info->setState(keepAbove() ? NET::KeepAbove : NET::States(0), NET::KeepAbove); + return; + } + m_keepAbove = b; + if (info) { + info->setState(keepAbove() ? NET::KeepAbove : NET::States(0), NET::KeepAbove); + } + workspace()->updateClientLayer(this); + updateWindowRules(Rules::Above); + + doSetKeepAbove(); + emit keepAboveChanged(m_keepAbove); +} + +void AbstractClient::doSetKeepAbove() +{ +} + +void AbstractClient::setKeepBelow(bool b) +{ + b = rules()->checkKeepBelow(b); + if (b && !rules()->checkKeepAbove(false)) + setKeepAbove(false); + if (b == keepBelow()) { + // force hint change if different + if (info && bool(info->state() & NET::KeepBelow) != keepBelow()) + info->setState(keepBelow() ? NET::KeepBelow : NET::States(0), NET::KeepBelow); + return; + } + m_keepBelow = b; + if (info) { + info->setState(keepBelow() ? NET::KeepBelow : NET::States(0), NET::KeepBelow); + } + workspace()->updateClientLayer(this); + updateWindowRules(Rules::Below); + + doSetKeepBelow(); + emit keepBelowChanged(m_keepBelow); +} + +void AbstractClient::doSetKeepBelow() +{ +} + } diff --git a/abstract_client.h b/abstract_client.h index e9637d1761..80702ed3db 100644 --- a/abstract_client.h +++ b/abstract_client.h @@ -57,6 +57,14 @@ class AbstractClient : public Toplevel **/ Q_PROPERTY(bool closeable READ isCloseable) Q_PROPERTY(QIcon icon READ icon NOTIFY iconChanged) + /** + * Whether the Client is set to be kept above other windows. + **/ + Q_PROPERTY(bool keepAbove READ keepAbove WRITE setKeepAbove NOTIFY keepAboveChanged) + /** + * Whether the Client is set to be kept below other windows. + **/ + Q_PROPERTY(bool keepBelow READ keepBelow WRITE setKeepBelow NOTIFY keepBelowChanged) public: virtual ~AbstractClient(); @@ -90,6 +98,15 @@ public: **/ void setActive(bool); + bool keepAbove() const { + return m_keepAbove; + } + void setKeepAbove(bool); + bool keepBelow() const { + return m_keepBelow; + } + void setKeepBelow(bool); + virtual void updateMouseGrab(); virtual QString caption(bool full = true, bool stripped = false) const = 0; virtual bool isMinimized() const = 0; @@ -118,10 +135,6 @@ public: virtual void minimize(bool avoid_animation = false) = 0; virtual void unminimize(bool avoid_animation = false)= 0; virtual void setFullScreen(bool set, bool user = true) = 0; - virtual bool keepAbove() const = 0; - virtual void setKeepAbove(bool) = 0; - virtual bool keepBelow() const = 0; - virtual void setKeepBelow(bool) = 0; virtual TabGroup *tabGroup() const; Q_INVOKABLE virtual bool untab(const QRect &toGeometry = QRect(), bool clientRemoved = false); virtual bool isCurrentTab() const; @@ -205,6 +218,8 @@ Q_SIGNALS: void skipSwitcherChanged(); void iconChanged(); void activeChanged(); + void keepAboveChanged(bool); + void keepBelowChanged(bool); protected: AbstractClient(); @@ -219,6 +234,20 @@ protected: * Default implementation does nothing. **/ virtual void doSetActive(); + /** + * Called from ::setKeepAbove once the keepBelow value got updated, but before the changed signal + * is emitted. + * + * Default implementation does nothing. + **/ + virtual void doSetKeepAbove(); + /** + * Called from ::setKeepBelow once the keepBelow value got updated, but before the changed signal + * is emitted. + * + * Default implementation does nothing. + **/ + virtual void doSetKeepBelow(); // TODO: remove boolean trap virtual bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const = 0; @@ -228,6 +257,8 @@ private: bool m_skipSwitcher = false; QIcon m_icon; bool m_active = false; + bool m_keepAbove = false; + bool m_keepBelow = false; }; } diff --git a/client.cpp b/client.cpp index 7563620cb1..4055593819 100644 --- a/client.cpp +++ b/client.cpp @@ -158,8 +158,6 @@ Client::Client() shade_mode = ShadeNone; deleting = false; - keep_above = false; - keep_below = false; fullscreen_mode = FullScreenNone; skip_taskbar = false; original_skip_taskbar = false; diff --git a/client.h b/client.h index d2e7801440..1c404baf45 100644 --- a/client.h +++ b/client.h @@ -105,14 +105,6 @@ class Client * might be emitted at each resize step or only at the end of the resize operation. **/ Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry) - /** - * Whether the Client is set to be kept above other windows. - **/ - Q_PROPERTY(bool keepAbove READ keepAbove WRITE setKeepAbove NOTIFY keepAboveChanged) - /** - * Whether the Client is set to be kept below other windows. - **/ - Q_PROPERTY(bool keepBelow READ keepBelow WRITE setKeepBelow NOTIFY keepBelowChanged) /** * Whether the Client can be maximized both horizontally and vertically. * The property is evaluated each time it is invoked. @@ -385,10 +377,6 @@ public: bool skipPager() const; void setSkipPager(bool); - bool keepAbove() const override; - void setKeepAbove(bool) override; - bool keepBelow() const override; - void setKeepBelow(bool) override; virtual Layer layer() const; Layer belongsToLayer() const; void invalidateLayer(); @@ -656,6 +644,8 @@ protected: void addDamage(const QRegion &damage) override; bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const override; void doSetActive() override; + void doSetKeepAbove() override; + void doSetKeepBelow() override; private Q_SLOTS: void delayedSetShortcut(); @@ -682,8 +672,6 @@ Q_SIGNALS: void transientChanged(); void modalChanged(); void shadeChanged(); - void keepAboveChanged(bool); - void keepBelowChanged(bool); void minimizedChanged(); void moveResizedChanged(); void skipTaskbarChanged(); @@ -872,12 +860,10 @@ private: ShadeMode shade_mode; Client *shade_below; uint deleting : 1; ///< True when doing cleanup and destroying the client - uint keep_above : 1; ///< NET::KeepAbove (was stays_on_top) uint skip_taskbar : 1; uint original_skip_taskbar : 1; ///< Unaffected by KWin uint skip_pager : 1; Xcb::MotifHints m_motif; - uint keep_below : 1; ///< NET::KeepBelow uint minimized : 1; uint hidden : 1; ///< Forcibly hidden by calling hide() uint modal : 1; ///< NET::Modal @@ -1089,16 +1075,6 @@ inline bool Client::skipPager() const return skip_pager; } -inline bool Client::keepAbove() const -{ - return keep_above; -} - -inline bool Client::keepBelow() const -{ - return keep_below; -} - inline bool Client::isFullScreen() const { return fullscreen_mode != FullScreenNone; diff --git a/layers.cpp b/layers.cpp index 5cfaadbd19..b1d0aa3a63 100644 --- a/layers.cpp +++ b/layers.cpp @@ -773,48 +773,18 @@ void Client::restackWindow(xcb_window_t above, int detail, NET::RequestSource sr sendSyntheticConfigureNotify(); } -void Client::setKeepAbove(bool b) +void Client::doSetKeepAbove() { - b = rules()->checkKeepAbove(b); - if (b && !rules()->checkKeepBelow(false)) - setKeepBelow(false); - if (b == keepAbove()) { - // force hint change if different - if (bool(info->state() & NET::KeepAbove) != keepAbove()) - info->setState(keepAbove() ? NET::KeepAbove : NET::States(0), NET::KeepAbove); - return; - } - keep_above = b; - info->setState(keepAbove() ? NET::KeepAbove : NET::States(0), NET::KeepAbove); - workspace()->updateClientLayer(this); - updateWindowRules(Rules::Above); - // Update states of all other windows in this group if (tabGroup()) tabGroup()->updateStates(this, TabGroup::Layer); - emit keepAboveChanged(keep_above); } -void Client::setKeepBelow(bool b) +void Client::doSetKeepBelow() { - b = rules()->checkKeepBelow(b); - if (b && !rules()->checkKeepAbove(false)) - setKeepAbove(false); - if (b == keepBelow()) { - // force hint change if different - if (bool(info->state() & NET::KeepBelow) != keepBelow()) - info->setState(keepBelow() ? NET::KeepBelow : NET::States(0), NET::KeepBelow); - return; - } - keep_below = b; - info->setState(keepBelow() ? NET::KeepBelow : NET::States(0), NET::KeepBelow); - workspace()->updateClientLayer(this); - updateWindowRules(Rules::Below); - // Update states of all other windows in this group if (tabGroup()) tabGroup()->updateStates(this, TabGroup::Layer); - emit keepBelowChanged(keep_below); } Layer Client::layer() const