Implement keepAbove and keepBelow in AbstractClient

Moves the properties and the base implementation into AbstractClient.
Methods invoke a new protected virtual method which is implemented in
Client to update the TabGroup.
This commit is contained in:
Martin Gräßlin 2015-03-13 09:36:43 +01:00
parent b84118a51b
commit 25e3af5988
5 changed files with 91 additions and 64 deletions

View file

@ -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()
{
}
}

View file

@ -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;
};
}

View file

@ -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;

View file

@ -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;

View file

@ -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