diff --git a/bridge.cpp b/bridge.cpp index e352d577ca..9c9d88f8b5 100644 --- a/bridge.cpp +++ b/bridge.cpp @@ -26,6 +26,7 @@ along with this program. If not, see . #include #include "composite.h" #include "paintredirector.h" +#include "virtualdesktops.h" #include "workspace.h" #include @@ -363,6 +364,11 @@ void Bridge::closeTabGroup() //END TABBING +bool Bridge::isOnAllDesktopsAvailable() const +{ + return VirtualDesktopManager::self()->count() > 1; +} + KDecoration::WindowOperation Bridge::buttonToWindowOperation(Qt::MouseButtons button) { return c->mouseButtonToWindowOperation(button); diff --git a/bridge.h b/bridge.h index 56da287536..dbed9d118b 100644 --- a/bridge.h +++ b/bridge.h @@ -40,6 +40,7 @@ public: virtual bool isMinimizable() const override; virtual bool providesContextHelp() const override; virtual int desktop() const override; + bool isOnAllDesktopsAvailable() const override; virtual bool isModal() const override; virtual bool isShadeable() const override; virtual bool isShade() const override; diff --git a/client.cpp b/client.cpp index de574d7a13..0dd5591779 100644 --- a/client.cpp +++ b/client.cpp @@ -213,6 +213,12 @@ Client::Client() connect(clientMachine(), SIGNAL(localhostChanged()), SLOT(updateCaption())); connect(options, SIGNAL(condensedTitleChanged()), SLOT(updateCaption())); + m_connections << connect(VirtualDesktopManager::self(), &VirtualDesktopManager::countChanged, [this]() { + if (decoration) { + decoration->onAllDesktopsAvailableChanged(); + } + }); + // SELI TODO: Initialize xsizehints?? } @@ -236,6 +242,9 @@ Client::~Client() assert(block_geometry_updates == 0); assert(!check_active_modal); delete bridge; + for (auto it = m_connections.constBegin(); it != m_connections.constEnd(); ++it) { + disconnect(*it); + } } // Use destroyClient() or releaseWindow(), Client instances cannot be deleted directly diff --git a/client.h b/client.h index a8ab0027bd..24fe70b361 100644 --- a/client.h +++ b/client.h @@ -1004,6 +1004,7 @@ private: QTimer *m_focusOutTimer; QPalette m_palette; + QList m_connections; }; /** diff --git a/kcmkwin/kwindecoration/preview.cpp b/kcmkwin/kwindecoration/preview.cpp index 12eef4a0d4..d199139afb 100644 --- a/kcmkwin/kwindecoration/preview.cpp +++ b/kcmkwin/kwindecoration/preview.cpp @@ -313,6 +313,11 @@ int KDecorationPreviewBridge::desktop() const return 1; } +bool KDecorationPreviewBridge::isOnAllDesktopsAvailable() const +{ + return true; +} + bool KDecorationPreviewBridge::isModal() const { return false; diff --git a/kcmkwin/kwindecoration/preview.h b/kcmkwin/kwindecoration/preview.h index 05404fb354..2dd6d8d130 100644 --- a/kcmkwin/kwindecoration/preview.h +++ b/kcmkwin/kwindecoration/preview.h @@ -109,6 +109,7 @@ public: virtual bool isMinimizable() const override; virtual bool providesContextHelp() const override; virtual int desktop() const override; + bool isOnAllDesktopsAvailable() const override; virtual bool isModal() const override; virtual bool isShadeable() const override; virtual bool isShade() const override; diff --git a/libkdecorations/kcommondecoration.cpp b/libkdecorations/kcommondecoration.cpp index bf25488feb..07eab606ea 100644 --- a/libkdecorations/kcommondecoration.cpp +++ b/libkdecorations/kcommondecoration.cpp @@ -93,6 +93,12 @@ KCommonDecoration::KCommonDecoration(KDecorationBridge* bridge, KDecorationFacto connect(d->wrapper, &KDecoration::shadeChanged, this, &KCommonDecoration::shadeChange); connect(d->wrapper, &KDecoration::iconChanged, this, &KCommonDecoration::iconChange); connect(d->wrapper, &KDecoration::maximizeChanged, this, &KCommonDecoration::maximizeChange); + connect(d->wrapper, &KDecoration::onAllDesktopsAvailableChanged, [this]() { + if (d->button[OnAllDesktopsButton]) { + d->button[OnAllDesktopsButton]->setVisible(d->wrapper->isOnAllDesktopsAvailable()); + updateLayout(); + } + }); } KCommonDecoration::~KCommonDecoration() @@ -564,6 +570,8 @@ void KCommonDecoration::addButtons(ButtonContainer &btnContainer, const QListtype() == AppMenuButton && !isPreview() && !d->wrapper->menuAvailable()) { btn->hide(); + } else if (btn->type() == OnAllDesktopsButton && !isPreview() && !d->wrapper->isOnAllDesktopsAvailable()) { + btn->hide(); } else { btn->show(); } @@ -607,8 +615,11 @@ void KCommonDecoration::calcHiddenButtons() if (! btnArray[i]->isHidden()) break; // all buttons shown... - if (btnArray[i]->type() != AppMenuButton || d->wrapper->menuAvailable()) - btnArray[i]->show(); + if (btnArray[i]->type() == AppMenuButton && !d->wrapper->menuAvailable()) + continue; + if (btnArray[i]->type() == OnAllDesktopsButton && !d->wrapper->isOnAllDesktopsAvailable()) + continue; + btnArray[i]->show(); } } } diff --git a/libkdecorations/kdecoration.cpp b/libkdecorations/kdecoration.cpp index a0ac761d5a..ec164c3c7d 100644 --- a/libkdecorations/kdecoration.cpp +++ b/libkdecorations/kdecoration.cpp @@ -583,6 +583,11 @@ bool KDecoration::isOnAllDesktops() const return desktop() == NET::OnAllDesktops; } +bool KDecoration::isOnAllDesktopsAvailable() const +{ + return d->bridge->isOnAllDesktopsAvailable(); +} + int KDecoration::width() const { return geometry().width(); diff --git a/libkdecorations/kdecoration.h b/libkdecorations/kdecoration.h index d7118cd762..2fb206ca2b 100644 --- a/libkdecorations/kdecoration.h +++ b/libkdecorations/kdecoration.h @@ -550,6 +550,7 @@ class KDECORATIONS_EXPORT KDecoration Q_PROPERTY(bool maximized READ isMaximized NOTIFY maximizeChanged) Q_PROPERTY(bool keepAbove READ keepAbove WRITE setKeepAbove NOTIFY keepAboveChanged) Q_PROPERTY(bool keepBelow READ keepBelow WRITE setKeepBelow NOTIFY keepBelowChanged) + Q_PROPERTY(bool onAllDesktopsAvailable READ isOnAllDesktopsAvailable NOTIFY onAllDesktopsAvailableChanged) public: /** * Constructs a KDecoration object. Both the arguments are passed from @@ -626,6 +627,12 @@ public: * virtual desktops. */ bool isOnAllDesktops() const; // convenience + /** + * @returns @c true if the decorated window can be put on all desktops + * @since 5.0 + * @see onAllDesktopsAvailableChanged() + **/ + bool isOnAllDesktopsAvailable() const; /** * Returns @a true if the decoration window is modal (usually a modal dialog). */ @@ -997,6 +1004,14 @@ Q_SIGNALS: * @since 4.10 **/ void alphaEnabledChanged(bool enabled); + /** + * This signal is emitted whenever the decorated window can be put on all desktops or no + * longer be put on all desktops. + * + * @see isOnAllDesktopsAvailable() + * @since 5.0 + **/ + void onAllDesktopsAvailableChanged(); public: /** diff --git a/libkdecorations/kdecorationbridge.h b/libkdecorations/kdecorationbridge.h index 0b58d6de0e..a98e4ac6ea 100644 --- a/libkdecorations/kdecorationbridge.h +++ b/libkdecorations/kdecorationbridge.h @@ -46,6 +46,7 @@ public: virtual bool isMinimizable() const = 0; virtual bool providesContextHelp() const = 0; virtual int desktop() const = 0; + virtual bool isOnAllDesktopsAvailable() const = 0; virtual bool isModal() const = 0; virtual bool isShadeable() const = 0; virtual bool isShade() const = 0;