diff --git a/abstract_client.cpp b/abstract_client.cpp
index 8b0655686b..5cd40d985a 100644
--- a/abstract_client.cpp
+++ b/abstract_client.cpp
@@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*********************************************************************/
#include "abstract_client.h"
+#include "focuschain.h"
#ifdef KWIN_BUILD_TABBOX
#include "tabbox.h"
#endif
@@ -239,4 +240,44 @@ void AbstractClient::demandAttention(bool set)
emit demandsAttentionChanged();
}
+void AbstractClient::setDesktop(int desktop)
+{
+ const int numberOfDesktops = VirtualDesktopManager::self()->count();
+ if (desktop != NET::OnAllDesktops) // Do range check
+ desktop = qMax(1, qMin(numberOfDesktops, desktop));
+ desktop = qMin(numberOfDesktops, rules()->checkDesktop(desktop));
+ if (m_desktop == desktop)
+ return;
+
+ int was_desk = m_desktop;
+ const bool wasOnCurrentDesktop = isOnCurrentDesktop();
+ m_desktop = desktop;
+
+ doSetDesktop(desktop, was_desk);
+
+ FocusChain::self()->update(this, FocusChain::MakeFirst);
+ updateWindowRules(Rules::Desktop);
+
+ emit desktopChanged();
+ if (wasOnCurrentDesktop != isOnCurrentDesktop())
+ emit desktopPresenceChanged(this, was_desk);
+}
+
+void AbstractClient::doSetDesktop(int desktop, int was_desk)
+{
+ Q_UNUSED(desktop)
+ Q_UNUSED(was_desk)
+}
+
+void AbstractClient::setOnAllDesktops(bool b)
+{
+ if ((b && isOnAllDesktops()) ||
+ (!b && !isOnAllDesktops()))
+ return;
+ if (b)
+ setDesktop(NET::OnAllDesktops);
+ else
+ setDesktop(VirtualDesktopManager::self()->current());
+}
+
}
diff --git a/abstract_client.h b/abstract_client.h
index 2f70061364..f92550f37e 100644
--- a/abstract_client.h
+++ b/abstract_client.h
@@ -47,6 +47,14 @@ class AbstractClient : public Toplevel
* @see Workspace::activateClient
**/
Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
+ /**
+ * The desktop this Client is on. If the Client is on all desktops the property has value -1.
+ **/
+ Q_PROPERTY(int desktop READ desktop WRITE setDesktop NOTIFY desktopChanged)
+ /**
+ * Whether the Client is on all desktops. That is desktop is -1.
+ **/
+ Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops WRITE setOnAllDesktops NOTIFY desktopChanged)
/**
* Whether the Client should be excluded from window switching effects.
**/
@@ -154,8 +162,11 @@ public:
virtual const QKeySequence &shortcut() const = 0;
virtual void setShortcut(const QString &cut) = 0;
virtual bool performMouseCommand(Options::MouseCommand, const QPoint &globalPos) = 0;
- virtual void setOnAllDesktops(bool set) = 0;
- virtual void setDesktop(int) = 0;
+ void setOnAllDesktops(bool set);
+ void setDesktop(int);
+ int desktop() const override {
+ return m_desktop;
+ }
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;
@@ -248,6 +259,7 @@ Q_SIGNALS:
**/
void demandsAttentionChanged();
void desktopPresenceChanged(KWin::AbstractClient*, int); // to be forwarded by Workspace
+ void desktopChanged();
protected:
AbstractClient();
@@ -278,6 +290,15 @@ protected:
* Default implementation does nothing.
**/
virtual void doSetKeepBelow();
+ /**
+ * Called from ::setDeskop once the desktop value got updated, but before the changed signal
+ * is emitted.
+ *
+ * Default implementation does nothing.
+ * @param desktop The new desktop the Client is on
+ * @param was_desk The desktop the Client was on before
+ **/
+ virtual void doSetDesktop(int desktop, int was_desk);
// TODO: remove boolean trap
virtual bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const = 0;
@@ -291,6 +312,7 @@ private:
bool m_keepBelow = false;
bool m_demandsAttention = false;
QTimer *m_autoRaiseTimer = nullptr;
+ int m_desktop = 0; // 0 means not on any desktop yet
};
}
diff --git a/client.cpp b/client.cpp
index ffbe0b95c6..8e8a4268bb 100644
--- a/client.cpp
+++ b/client.cpp
@@ -147,7 +147,6 @@ Client::Client()
// Set the initial mapping state
mapping_state = Withdrawn;
quick_tile_mode = QuickTileNone;
- desk = 0; // No desktop yet
mode = PositionCenter;
buttonDown = false;
@@ -262,7 +261,6 @@ void Client::releaseWindow(bool on_shutdown)
workspace()->removeClient(this);
// Only when the window is being unmapped, not when closing down KWin (NETWM sections 5.5,5.7)
info->setDesktop(0);
- desk = 0;
info->setState(0, info->state()); // Reset all state flags
} else
untab();
@@ -1304,18 +1302,8 @@ void Client::setModal(bool m)
// _NET_WM_STATE_MODAL should possibly rather be _NET_WM_WINDOW_TYPE_MODAL_DIALOG
}
-void Client::setDesktop(int desktop)
+void Client::doSetDesktop(int desktop, int was_desk)
{
- const int numberOfDesktops = VirtualDesktopManager::self()->count();
- if (desktop != NET::OnAllDesktops) // Do range check
- desktop = qMax(1, qMin(numberOfDesktops, desktop));
- desktop = qMin(numberOfDesktops, rules()->checkDesktop(desktop));
- if (desk == desktop)
- return;
-
- int was_desk = desk;
- const bool wasOnCurrentDesktop = isOnCurrentDesktop();
- desk = desktop;
info->setDesktop(desktop);
if ((was_desk == NET::OnAllDesktops) != (desktop == NET::OnAllDesktops)) {
// onAllDesktops changed
@@ -1335,17 +1323,11 @@ void Client::setDesktop(int desktop)
foreach (Client * c2, mainClients())
c2->setDesktop(desktop);
}
-
- FocusChain::self()->update(this, FocusChain::MakeFirst);
updateVisibility();
- updateWindowRules(Rules::Desktop);
// Update states of all other windows in this group
if (tabGroup())
tabGroup()->updateStates(this, TabGroup::Desktop);
- emit desktopChanged();
- if (wasOnCurrentDesktop != isOnCurrentDesktop())
- emit desktopPresenceChanged(this, was_desk);
}
/**
@@ -1450,7 +1432,7 @@ int Client::desktop() const
if (needsSessionInteract) {
return NET::OnAllDesktops;
}
- return desk;
+ return AbstractClient::desktop();
}
/**
@@ -1466,21 +1448,6 @@ QStringList Client::activities() const
return activityList;
}
-void Client::setOnAllDesktops(bool b)
-{
- if ((b && isOnAllDesktops()) ||
- (!b && !isOnAllDesktops()))
- return;
- if (b)
- setDesktop(NET::OnAllDesktops);
- else
- setDesktop(VirtualDesktopManager::self()->current());
-
- // Update states of all other windows in this group
- if (tabGroup())
- tabGroup()->updateStates(this, TabGroup::Desktop);
-}
-
/**
* if @p on is true, sets on all activities.
* if it's false, sets it to only be on the current activity
diff --git a/client.h b/client.h
index fc637ed77c..6abc1738d0 100644
--- a/client.h
+++ b/client.h
@@ -81,14 +81,6 @@ class Client
* To read only the caption as provided by WM_NAME, use the getter with an additional @c false value.
**/
Q_PROPERTY(QString caption READ caption NOTIFY captionChanged)
- /**
- * The desktop this Client is on. If the Client is on all desktops the property has value -1.
- **/
- Q_PROPERTY(int desktop READ desktop WRITE setDesktop NOTIFY desktopChanged)
- /**
- * Whether the Client is on all desktops. That is desktop is -1.
- **/
- Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops WRITE setOnAllDesktops NOTIFY desktopChanged)
/**
* Whether this Client is fullScreen. A Client might either be fullScreen due to the _NET_WM property
* or through a legacy support hack. The fullScreen state can only be changed if the Client does not
@@ -298,8 +290,6 @@ public:
QSize adjustedSize() const;
virtual int desktop() const;
- void setDesktop(int) override;
- void setOnAllDesktops(bool set) override;
void sendToScreen(int screen) override;
@@ -615,6 +605,7 @@ protected:
void doSetActive() override;
void doSetKeepAbove() override;
void doSetKeepBelow() override;
+ void doSetDesktop(int desktop, int was_desk) override;
private Q_SLOTS:
void delayedSetShortcut();
@@ -635,7 +626,6 @@ Q_SIGNALS:
void clientStepUserMovedResized(KWin::Client *, const QRect&);
void clientFinishUserMovedResized(KWin::Client*);
void captionChanged();
- void desktopChanged();
void fullScreenChanged();
void transientChanged();
void modalChanged();
@@ -775,7 +765,6 @@ private:
KDecoration2::Decoration *m_decoration;
QPointer m_decoratedClient;
QElapsedTimer m_decorationDoubleClickTimer;
- int desk;
QStringList activityList;
int m_activityUpdatesBlocked;
bool m_blockedActivityUpdatesRequireTransients;
diff --git a/manage.cpp b/manage.cpp
index 75af4e519b..295aafc8df 100644
--- a/manage.cpp
+++ b/manage.cpp
@@ -177,6 +177,7 @@ bool Client::manage(xcb_window_t w, bool isMapped)
readActivities(activitiesCookie);
// Initial desktop placement
+ int desk = 0;
if (session) {
desk = session->desktop;
if (session->onAllDesktops)
@@ -236,6 +237,7 @@ bool Client::manage(xcb_window_t w, bool isMapped)
desk = rules()->checkDesktop(desk, !isMapped);
if (desk != NET::OnAllDesktops) // Do range check
desk = qBound(1, desk, static_cast(VirtualDesktopManager::self()->count()));
+ setDesktop(desk);
info->setDesktop(desk);
workspace()->updateOnAllDesktopsOfTransients(this); // SELI TODO
//onAllDesktopsChange(); // Decoration doesn't exist here yet