[wayland] Apply window rules only to xdg-shell clients

Summary:
There are rules that have to be applied only once, e.g. every Remember
and Apply Initially rule, as well rules that need to configure the client,
e.g. size, etc. In the best scenario the compositor would evaluate such
rules when the client is about to be mapped.

This change limits window rules only to xdg-shell clients because right
now only this protocol lets compositors to intervene in the client
initialization process. Also, it makes things a bit easier for us on the
compositor side.

xdg-shell protocol satisfies most of ours requirements to implement window
rules, but not all of them. If the client is about to be mapped for the
second time and its size is forced by a rule, then compositor may need
to configure it. Currently, xdg-shell protocol doesn't have any mechanism
that a client could use to notify the compositor about its intent to map.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: fmonteiro, davidedmundson, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D19411
remotes/origin/fredrik/swap-event-wip
Vlad Zagorodniy 7 years ago
parent be48d36349
commit 18844f5925
  1. 5
      abstract_client.cpp
  2. 7
      abstract_client.h
  3. 5
      internal_client.cpp
  4. 1
      internal_client.h
  5. 60
      shell_client.cpp
  6. 3
      shell_client.h
  7. 4
      useractions.cpp

@ -2087,4 +2087,9 @@ bool AbstractClient::isInternal() const
return false;
}
bool AbstractClient::supportsWindowRules() const
{
return true;
}
}

@ -866,6 +866,13 @@ public:
**/
virtual bool isInternal() const;
/**
* Returns whether window rules can be applied to this client.
*
* Default implementation returns @c true.
**/
virtual bool supportsWindowRules() const;
public Q_SLOTS:
virtual void closeWindow() = 0;

@ -328,4 +328,9 @@ QWindow *InternalClient::internalWindow() const
return m_internalWindow;
}
bool InternalClient::supportsWindowRules() const
{
return false;
}
}

@ -60,6 +60,7 @@ public:
using AbstractClient::resizeWithChecks;
void resizeWithChecks(int w, int h, ForceGeometry_t force = NormalGeometrySet) override;
QWindow *internalWindow() const override;
bool supportsWindowRules() const override;
protected:
bool acceptsFocus() const override;

@ -76,6 +76,7 @@ ShellClient::ShellClient(ShellSurfaceInterface *surface)
{
setSurface(surface->surface());
init();
m_isInitialized = true;
}
ShellClient::ShellClient(XdgShellSurfaceInterface *surface)
@ -140,10 +141,11 @@ void ShellClient::initSurface(T *shellSurface)
resourceName = info.fileName().toUtf8();
}
setResourceClass(resourceName, shellSurface->windowClass());
setDesktopFileName(shellSurface->windowClass());
connect(shellSurface, &T::windowClassChanged, this,
[this, resourceName] (const QByteArray &windowClass) {
setResourceClass(resourceName, windowClass);
if (!m_internal) {
if (m_isInitialized && supportsWindowRules()) {
setupWindowRules(true);
applyWindowRules();
}
@ -201,11 +203,6 @@ void ShellClient::initSurface(T *shellSurface)
connect(this, &ShellClient::geometryChanged, this, &ShellClient::updateClientOutputs);
connect(screens(), &Screens::changed, this, &ShellClient::updateClientOutputs);
if (!m_internal) {
setupWindowRules(false);
}
setDesktopFileName(rules()->checkDesktopFile(shellSurface->windowClass(), true).toUtf8());
}
void ShellClient::init()
@ -335,17 +332,7 @@ void ShellClient::init()
}
// set initial desktop
setDesktop(rules()->checkDesktop(m_internal ? int(NET::OnAllDesktops) : VirtualDesktopManager::self()->current(), true));
// TODO: merge in checks from Client::manage?
if (rules()->checkMinimize(false, true)) {
minimize(true); // No animation
}
setSkipTaskbar(rules()->checkSkipTaskbar(m_plasmaShellSurface ? m_plasmaShellSurface->skipTaskbar() : false, true));
setSkipPager(rules()->checkSkipPager(false, true));
setSkipSwitcher(rules()->checkSkipSwitcher(false, true));
setKeepAbove(rules()->checkKeepAbove(false, true));
setKeepBelow(rules()->checkKeepBelow(false, true));
setShortcut(rules()->checkShortcut(QString(), true));
setDesktop(m_internal ? int(NET::OnAllDesktops) : VirtualDesktopManager::self()->current());
// setup shadow integration
getShadow();
@ -359,13 +346,6 @@ void ShellClient::init()
setTransient();
AbstractClient::updateColorScheme(QString());
if (!m_internal) {
discardTemporaryRules();
applyWindowRules(); // Just in case
RuleBook::self()->discardUsed(this, false); // Remove ApplyNow rules
updateWindowRules(Rules::All); // Was blocked while !isManaged()
}
}
void ShellClient::finishInit() {
@ -373,6 +353,28 @@ void ShellClient::finishInit() {
disconnect(s, &SurfaceInterface::committed, this, &ShellClient::finishInit);
updateWindowMargins();
if (supportsWindowRules()) {
setupWindowRules(false);
setDesktop(rules()->checkDesktop(desktop(), true));
setDesktopFileName(rules()->checkDesktopFile(desktopFileName(), true).toUtf8());
if (rules()->checkMinimize(isMinimized(), true)) {
minimize(true); // No animation.
}
setSkipTaskbar(rules()->checkSkipTaskbar(skipTaskbar(), true));
setSkipPager(rules()->checkSkipPager(skipPager(), true));
setSkipSwitcher(rules()->checkSkipSwitcher(skipSwitcher(), true));
setKeepAbove(rules()->checkKeepAbove(keepAbove(), true));
setKeepBelow(rules()->checkKeepBelow(keepBelow(), true));
setShortcut(rules()->checkShortcut(shortcut().toString(), true));
updateColorScheme();
discardTemporaryRules();
RuleBook::self()->discardUsed(this, false); // Remove Apply Now rules.
updateWindowRules(Rules::All);
}
if (!isInitialPositionSet()) {
QRect area = workspace()->clientArea(PlacementArea, Screens::self()->current(), desktop());
placeIn(area);
@ -382,6 +384,8 @@ void ShellClient::finishInit() {
if (m_requestGeometryBlockCounter == 0) {
requestGeometry(m_blockedRequestGeometry);
}
m_isInitialized = true;
}
void ShellClient::destroyClient()
@ -1945,4 +1949,12 @@ QWindow *ShellClient::internalWindow() const
return nullptr;
}
bool ShellClient::supportsWindowRules() const
{
if (m_plasmaShellSurface) {
return false;
}
return m_xdgShellSurface;
}
}

@ -163,6 +163,8 @@ public:
return true;
}
bool supportsWindowRules() const override;
protected:
void addDamage(const QRegion &damage) override;
bool belongsToSameApplication(const AbstractClient *other, SameApplicationChecks checks) const override;
@ -297,6 +299,7 @@ private:
QMargins m_windowMargins;
bool m_compositingSetup = false;
bool m_isInitialized = false;
};
}

@ -471,8 +471,8 @@ void UserActionsMenu::menuAboutToShow()
action->setText(i18n("&Extensions"));
}
m_rulesOperation->setEnabled(true);
m_applicationRulesOperation->setEnabled(true);
m_rulesOperation->setEnabled(m_client.data()->supportsWindowRules());
m_applicationRulesOperation->setEnabled(m_client.data()->supportsWindowRules());
showHideActivityMenu();
}

Loading…
Cancel
Save