Move layer functionality to AbstractClient
Merges together the code from ShellClient and Client and removes the starting differences. Long term it's better to have only one implementation to prevent diversions in the implementation. As it doesn't match exactly protected virtual methods are called which allow more specific implementations for a certain aspect of the layer resolving.
This commit is contained in:
parent
49e5e81970
commit
d25c465211
7 changed files with 105 additions and 101 deletions
|
@ -189,8 +189,17 @@ void AbstractClient::doSetActive()
|
|||
{
|
||||
}
|
||||
|
||||
Layer AbstractClient::layer() const
|
||||
{
|
||||
if (m_layer == UnknownLayer)
|
||||
const_cast< AbstractClient* >(this)->m_layer = belongsToLayer();
|
||||
return m_layer;
|
||||
}
|
||||
|
||||
void AbstractClient::updateLayer()
|
||||
{
|
||||
if (layer() == belongsToLayer())
|
||||
return;
|
||||
StackingUpdatesBlocker blocker(workspace());
|
||||
invalidateLayer(); // invalidate, will be updated when doing restacking
|
||||
for (auto it = transients().constBegin(),
|
||||
|
@ -200,6 +209,57 @@ void AbstractClient::updateLayer()
|
|||
|
||||
void AbstractClient::invalidateLayer()
|
||||
{
|
||||
m_layer = UnknownLayer;
|
||||
}
|
||||
|
||||
Layer AbstractClient::belongsToLayer() const
|
||||
{
|
||||
// NOTICE while showingDesktop, desktops move to the AboveLayer
|
||||
// (interchangeable w/ eg. yakuake etc. which will at first remain visible)
|
||||
// and the docks move into the NotificationLayer (which is between Above- and
|
||||
// ActiveLayer, so that active fullscreen windows will still cover everything)
|
||||
// Since the desktop is also activated, nothing should be in the ActiveLayer, though
|
||||
if (isDesktop())
|
||||
return workspace()->showingDesktop() ? AboveLayer : DesktopLayer;
|
||||
if (isSplash()) // no damn annoying splashscreens
|
||||
return NormalLayer; // getting in the way of everything else
|
||||
if (isDock()) {
|
||||
if (workspace()->showingDesktop())
|
||||
return NotificationLayer;
|
||||
return layerForDock();
|
||||
}
|
||||
if (isOnScreenDisplay())
|
||||
return OnScreenDisplayLayer;
|
||||
if (isNotification())
|
||||
return NotificationLayer;
|
||||
if (workspace()->showingDesktop() && belongsToDesktop()) {
|
||||
return AboveLayer;
|
||||
}
|
||||
if (keepBelow())
|
||||
return BelowLayer;
|
||||
if (isActiveFullScreen())
|
||||
return ActiveLayer;
|
||||
if (keepAbove())
|
||||
return AboveLayer;
|
||||
|
||||
return NormalLayer;
|
||||
}
|
||||
|
||||
bool AbstractClient::belongsToDesktop() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Layer AbstractClient::layerForDock() const
|
||||
{
|
||||
// slight hack for the 'allow window to cover panel' Kicker setting
|
||||
// don't move keepbelow docks below normal window, but only to the same
|
||||
// layer, so that both may be raised to cover the other
|
||||
if (keepBelow())
|
||||
return NormalLayer;
|
||||
if (keepAbove()) // slight hack for the autohiding panels
|
||||
return AboveLayer;
|
||||
return DockLayer;
|
||||
}
|
||||
|
||||
void AbstractClient::setKeepAbove(bool b)
|
||||
|
@ -909,4 +969,16 @@ void AbstractClient::removeTransientFromList(AbstractClient *cl)
|
|||
m_transients.removeAll(cl);
|
||||
}
|
||||
|
||||
bool AbstractClient::isActiveFullScreen() const
|
||||
{
|
||||
if (!isFullScreen())
|
||||
return false;
|
||||
|
||||
const auto ac = workspace()->mostRecentlyActivatedClient(); // instead of activeClient() - avoids flicker
|
||||
// according to NETWM spec implementation notes suggests
|
||||
// "focused windows having state _NET_WM_STATE_FULLSCREEN" to be on the highest layer.
|
||||
// we'll also take the screen into account
|
||||
return ac && (ac == this || ac->screen() != screen());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -384,7 +384,8 @@ public:
|
|||
* @param mode The tile mode (left/right) to give this window.
|
||||
*/
|
||||
virtual void setQuickTileMode(QuickTileMode mode, bool keyboard = false) = 0;
|
||||
virtual void updateLayer();
|
||||
Layer layer() const override;
|
||||
void updateLayer();
|
||||
|
||||
enum ForceGeometry_t { NormalGeometrySet, ForceGeometrySet };
|
||||
virtual void move(int x, int y, ForceGeometry_t force = NormalGeometrySet) = 0;
|
||||
|
@ -505,7 +506,11 @@ protected:
|
|||
**/
|
||||
void removeTransientFromList(AbstractClient* cl);
|
||||
|
||||
virtual void invalidateLayer();
|
||||
Layer belongsToLayer() const;
|
||||
virtual bool belongsToDesktop() const;
|
||||
void invalidateLayer();
|
||||
virtual bool isActiveFullScreen() const;
|
||||
virtual Layer layerForDock() const;
|
||||
|
||||
private:
|
||||
void handlePaletteChange();
|
||||
|
@ -537,6 +542,7 @@ private:
|
|||
AbstractClient *m_transientFor = nullptr;
|
||||
QList<AbstractClient*> m_transients;
|
||||
bool m_modal = false;
|
||||
Layer m_layer = UnknownLayer;
|
||||
};
|
||||
|
||||
inline void AbstractClient::move(const QPoint& p, ForceGeometry_t force)
|
||||
|
|
|
@ -116,7 +116,6 @@ Client::Client()
|
|||
, m_colormap(XCB_COLORMAP_NONE)
|
||||
, in_group(NULL)
|
||||
, tab_group(NULL)
|
||||
, in_layer(UnknownLayer)
|
||||
, ping_timer(NULL)
|
||||
, m_killHelperPID(0)
|
||||
, m_pingTimestamp(XCB_TIME_CURRENT_TIME)
|
||||
|
|
13
client.h
13
client.h
|
@ -251,7 +251,6 @@ public:
|
|||
bool isFullScreen() const override;
|
||||
bool isFullScreenable() const override;
|
||||
bool isFullScreenable(bool fullscreen_hack) const;
|
||||
bool isActiveFullScreen() const;
|
||||
bool userCanSetFullScreen() const override;
|
||||
QRect geometryFSRestore() const {
|
||||
return geom_fs_restore; // Only for session saving
|
||||
|
@ -265,9 +264,6 @@ public:
|
|||
bool userCanSetNoBorder() const override;
|
||||
void checkNoBorder();
|
||||
|
||||
virtual Layer layer() const;
|
||||
Layer belongsToLayer() const;
|
||||
void updateLayer() override;
|
||||
int sessionStackingOrder() const;
|
||||
|
||||
// Auxiliary functions, depend on the windowType
|
||||
|
@ -520,7 +516,8 @@ protected:
|
|||
void doMinimize() override;
|
||||
void doSetSkipPager() override;
|
||||
void doSetSkipTaskbar() override;
|
||||
void invalidateLayer() override;
|
||||
bool belongsToDesktop() const override;
|
||||
bool isActiveFullScreen() const override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void delayedSetShortcut();
|
||||
|
@ -734,7 +731,6 @@ private:
|
|||
QString cap_normal, cap_iconic, cap_suffix, cap_deco;
|
||||
Group* in_group;
|
||||
TabGroup* tab_group;
|
||||
Layer in_layer;
|
||||
QTimer* ping_timer;
|
||||
qint64 m_killHelperPID;
|
||||
xcb_timestamp_t m_pingTimestamp;
|
||||
|
@ -894,11 +890,6 @@ inline xcb_colormap_t Client::colormap() const
|
|||
return m_colormap;
|
||||
}
|
||||
|
||||
inline void Client::invalidateLayer()
|
||||
{
|
||||
in_layer = UnknownLayer;
|
||||
}
|
||||
|
||||
inline int Client::sessionStackingOrder() const
|
||||
{
|
||||
return sm_stacking_order;
|
||||
|
|
63
layers.cpp
63
layers.cpp
|
@ -820,61 +820,13 @@ void Client::doSetKeepBelow()
|
|||
tabGroup()->updateStates(this, TabGroup::Layer);
|
||||
}
|
||||
|
||||
Layer Client::layer() const
|
||||
bool Client::belongsToDesktop() const
|
||||
{
|
||||
if (in_layer == UnknownLayer)
|
||||
const_cast< Client* >(this)->in_layer = belongsToLayer();
|
||||
return in_layer;
|
||||
}
|
||||
|
||||
Layer Client::belongsToLayer() const
|
||||
{
|
||||
// NOTICE while showingDesktop, desktops move to the AboveLayer
|
||||
// (interchangeable w/ eg. yakuake etc. which will at first remain visible)
|
||||
// and the docks move into the NotificationLayer (which is between Above- and
|
||||
// ActiveLayer, so that active fullscreen windows will still cover everything)
|
||||
// Since the desktop is also activated, nothing should be in the ActiveLayer, though
|
||||
if (isDesktop())
|
||||
return workspace()->showingDesktop() ? AboveLayer : DesktopLayer;
|
||||
if (isSplash()) // no damn annoying splashscreens
|
||||
return NormalLayer; // getting in the way of everything else
|
||||
if (isDock()) {
|
||||
if (workspace()->showingDesktop())
|
||||
return NotificationLayer;
|
||||
// slight hack for the 'allow window to cover panel' Kicker setting
|
||||
// don't move keepbelow docks below normal window, but only to the same
|
||||
// layer, so that both may be raised to cover the other
|
||||
if (keepBelow())
|
||||
return NormalLayer;
|
||||
if (keepAbove()) // slight hack for the autohiding panels
|
||||
return AboveLayer;
|
||||
return DockLayer;
|
||||
foreach (const Client *c, group()->members()) {
|
||||
if (c->isDesktop())
|
||||
return true;
|
||||
}
|
||||
if (isOnScreenDisplay())
|
||||
return OnScreenDisplayLayer;
|
||||
if (isNotification())
|
||||
return NotificationLayer;
|
||||
if (workspace()->showingDesktop()) {
|
||||
foreach (const Client *c, group()->members()) {
|
||||
if (c->isDesktop())
|
||||
return AboveLayer;
|
||||
}
|
||||
}
|
||||
if (keepBelow())
|
||||
return BelowLayer;
|
||||
if (isActiveFullScreen())
|
||||
return ActiveLayer;
|
||||
if (keepAbove())
|
||||
return AboveLayer;
|
||||
|
||||
return NormalLayer;
|
||||
}
|
||||
|
||||
void Client::updateLayer()
|
||||
{
|
||||
if (layer() == belongsToLayer())
|
||||
return;
|
||||
AbstractClient::updateLayer();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool rec_checkTransientOnTop(const QList<AbstractClient*> &transients, const Client *topmost)
|
||||
|
@ -889,6 +841,9 @@ bool rec_checkTransientOnTop(const QList<AbstractClient*> &transients, const Cli
|
|||
|
||||
bool Client::isActiveFullScreen() const
|
||||
{
|
||||
if (AbstractClient::isActiveFullScreen()) {
|
||||
return true;
|
||||
}
|
||||
if (!isFullScreen())
|
||||
return false;
|
||||
|
||||
|
@ -896,7 +851,7 @@ bool Client::isActiveFullScreen() const
|
|||
// according to NETWM spec implementation notes suggests
|
||||
// "focused windows having state _NET_WM_STATE_FULLSCREEN" to be on the highest layer.
|
||||
// we'll also take the screen into account
|
||||
return ac && (ac == this || this->group() == ac->group() || ac->screen() != screen());
|
||||
return ac && (this->group() == ac->group());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -148,42 +148,23 @@ void ShellClient::debug(QDebug &stream) const
|
|||
Q_UNUSED(stream)
|
||||
}
|
||||
|
||||
Layer ShellClient::layer() const
|
||||
Layer ShellClient::layerForDock() const
|
||||
{
|
||||
// TODO: implement the rest
|
||||
if (isDesktop())
|
||||
return workspace()->showingDesktop() ? AboveLayer : DesktopLayer;
|
||||
if (isDock()) {
|
||||
if (workspace()->showingDesktop())
|
||||
return NotificationLayer;
|
||||
if (m_plasmaShellSurface) {
|
||||
switch (m_plasmaShellSurface->panelBehavior()) {
|
||||
case PlasmaShellSurfaceInterface::PanelBehavior::WindowsCanCover:
|
||||
return NormalLayer;
|
||||
case PlasmaShellSurfaceInterface::PanelBehavior::AutoHide:
|
||||
return AboveLayer;
|
||||
case PlasmaShellSurfaceInterface::PanelBehavior::WindowsGoBelow:
|
||||
case PlasmaShellSurfaceInterface::PanelBehavior::AlwaysVisible:
|
||||
return DockLayer;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// slight hack for the 'allow window to cover panel' Kicker setting
|
||||
// don't move keepbelow docks below normal window, but only to the same
|
||||
// layer, so that both may be raised to cover the other
|
||||
if (keepBelow())
|
||||
if (m_plasmaShellSurface) {
|
||||
switch (m_plasmaShellSurface->panelBehavior()) {
|
||||
case PlasmaShellSurfaceInterface::PanelBehavior::WindowsCanCover:
|
||||
return NormalLayer;
|
||||
if (keepAbove()) // slight hack for the autohiding panels
|
||||
case PlasmaShellSurfaceInterface::PanelBehavior::AutoHide:
|
||||
return AboveLayer;
|
||||
return DockLayer;
|
||||
case PlasmaShellSurfaceInterface::PanelBehavior::WindowsGoBelow:
|
||||
case PlasmaShellSurfaceInterface::PanelBehavior::AlwaysVisible:
|
||||
return DockLayer;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isOnScreenDisplay())
|
||||
return OnScreenDisplayLayer;
|
||||
if (isFullScreen() && isActive())
|
||||
return ActiveLayer;
|
||||
return KWin::NormalLayer;
|
||||
return AbstractClient::layerForDock();
|
||||
}
|
||||
|
||||
bool ShellClient::shouldUnredirect() const
|
||||
|
|
|
@ -45,7 +45,6 @@ public:
|
|||
QStringList activities() const override;
|
||||
QPoint clientPos() const override;
|
||||
QSize clientSize() const override;
|
||||
Layer layer() const override;
|
||||
QRect transparentRect() const override;
|
||||
bool shouldUnredirect() const override;
|
||||
NET::WindowType windowType(bool direct = false, int supported_types = 0) const override;
|
||||
|
@ -119,6 +118,7 @@ protected:
|
|||
void addDamage(const QRegion &damage) override;
|
||||
bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const override;
|
||||
void doSetActive() override;
|
||||
Layer layerForDock() const override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void clientFullScreenChanged(bool fullScreen);
|
||||
|
|
Loading…
Reference in a new issue