Commit 25488715 authored by Martin Flöser's avatar Martin Flöser

Implement virtual desktop handling in AbstractClient

parent 1bfba176
......@@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#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());
}
}
......@@ -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
};
}
......
......@@ -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
......
......@@ -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<Decoration::DecoratedClientImpl> m_decoratedClient;
QElapsedTimer m_decorationDoubleClickTimer;
int desk;
QStringList activityList;
int m_activityUpdatesBlocked;
bool m_blockedActivityUpdatesRequireTransients;
......
......@@ -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<int>(VirtualDesktopManager::self()->count()));
setDesktop(desk);
info->setDesktop(desk);
workspace()->updateOnAllDesktopsOfTransients(this); // SELI TODO
//onAllDesktopsChange(); // Decoration doesn't exist here yet
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment