Drop support for _KDE_NET_WM_TEMPORARY_RULES
It's an obscure feature, which perhaps not worth putting an effort to make it work on wayland and x11.
This commit is contained in:
parent
d18f7efac2
commit
e5901070cc
9 changed files with 22 additions and 163 deletions
|
@ -1,3 +1,4 @@
|
|||
[1]
|
||||
Description=Window settings for kpat
|
||||
clientmachine=localhost
|
||||
clientmachinematch=0
|
||||
|
@ -11,3 +12,6 @@ windowrolematch=1
|
|||
wmclass=kpat
|
||||
wmclasscomplete=false
|
||||
wmclassmatch=1
|
||||
|
||||
[General]
|
||||
count=1
|
||||
|
|
|
@ -89,9 +89,8 @@ void WindowRuleTest::testApplyInitialMaximizeVert()
|
|||
// this test creates the situation of BUG 367554: creates a window and initial apply maximize vertical
|
||||
// the window is matched by class and role
|
||||
// load the rule
|
||||
QFile ruleFile(QFINDTESTDATA("./data/rules/maximize-vert-apply-initial"));
|
||||
QVERIFY(ruleFile.open(QIODevice::ReadOnly | QIODevice::Text));
|
||||
QMetaObject::invokeMethod(workspace()->rulebook(), "temporaryRulesMessage", Q_ARG(QString, QString::fromUtf8(ruleFile.readAll())));
|
||||
workspace()->rulebook()->setConfig(KSharedConfig::openConfig(QFINDTESTDATA("./data/rules/maximize-vert-apply-initial"), KConfig::SimpleConfig));
|
||||
workspace()->slotReconfigure();
|
||||
|
||||
// create the test window
|
||||
std::unique_ptr<xcb_connection_t, XcbConnectionDeleter> c(xcb_connect(nullptr, nullptr));
|
||||
|
|
|
@ -92,7 +92,6 @@ RootInfo *RootInfo::create()
|
|||
| NET::WM2RestackWindow
|
||||
| NET::WM2MoveResizeWindow
|
||||
| NET::WM2ExtendedStrut
|
||||
| NET::WM2KDETemporaryRules
|
||||
| NET::WM2ShowingDesktop
|
||||
| NET::WM2DesktopLayout
|
||||
| NET::WM2FullPlacement
|
||||
|
|
140
src/rules.cpp
140
src/rules.cpp
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include "rules.h"
|
||||
|
||||
#include <KXMessages>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
|
@ -34,8 +33,7 @@ namespace KWin
|
|||
{
|
||||
|
||||
Rules::Rules()
|
||||
: temporary_state(0)
|
||||
, wmclassmatch(UnimportantMatch)
|
||||
: wmclassmatch(UnimportantMatch)
|
||||
, wmclasscomplete(UnimportantMatch)
|
||||
, windowrolematch(UnimportantMatch)
|
||||
, titlematch(UnimportantMatch)
|
||||
|
@ -80,23 +78,6 @@ Rules::Rules()
|
|||
{
|
||||
}
|
||||
|
||||
Rules::Rules(const QString &str, bool temporary)
|
||||
: temporary_state(temporary ? 2 : 0)
|
||||
{
|
||||
QTemporaryFile file;
|
||||
if (file.open()) {
|
||||
QByteArray s = str.toUtf8();
|
||||
file.write(s.data(), s.length());
|
||||
}
|
||||
file.flush();
|
||||
auto cfg = KSharedConfig::openConfig(file.fileName(), KConfig::SimpleConfig);
|
||||
RuleSettings settings(cfg, QString());
|
||||
readFromSettings(&settings);
|
||||
if (description.isEmpty()) {
|
||||
description = QStringLiteral("temporary");
|
||||
}
|
||||
}
|
||||
|
||||
#define READ_MATCH_STRING(var, func) \
|
||||
var = settings->var() func; \
|
||||
var##match = static_cast<StringMatch>(settings->var##match())
|
||||
|
@ -110,7 +91,6 @@ Rules::Rules(const QString &str, bool temporary)
|
|||
var##rule = convertForceRule(settings->var##rule())
|
||||
|
||||
Rules::Rules(const RuleSettings *settings)
|
||||
: temporary_state(0)
|
||||
{
|
||||
readFromSettings(settings);
|
||||
}
|
||||
|
@ -666,23 +646,6 @@ APPLY_RULE(desktopfile, DesktopFile, QString)
|
|||
#undef APPLY_RULE
|
||||
#undef APPLY_FORCE_RULE
|
||||
|
||||
bool Rules::isTemporary() const
|
||||
{
|
||||
return temporary_state > 0;
|
||||
}
|
||||
|
||||
bool Rules::discardTemporary(bool force)
|
||||
{
|
||||
if (temporary_state == 0) { // not temporary
|
||||
return false;
|
||||
}
|
||||
if (force || --temporary_state == 0) { // too old
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define DISCARD_USED_SET_RULE(var) \
|
||||
do { \
|
||||
if (var##rule == (SetRule)ApplyNow || (withdrawn && var##rule == (SetRule)ForceTemporarily)) { \
|
||||
|
@ -751,19 +714,6 @@ QDebug &operator<<(QDebug &stream, const Rules *r)
|
|||
}
|
||||
|
||||
#ifndef KCMRULES
|
||||
void WindowRules::discardTemporary()
|
||||
{
|
||||
QVector<Rules *>::Iterator it2 = rules.begin();
|
||||
for (QVector<Rules *>::Iterator it = rules.begin();
|
||||
it != rules.end();) {
|
||||
if ((*it)->discardTemporary(true)) {
|
||||
++it;
|
||||
} else {
|
||||
*it2++ = *it++;
|
||||
}
|
||||
}
|
||||
rules.erase(it2, rules.end());
|
||||
}
|
||||
|
||||
void WindowRules::update(Window *c, int selection)
|
||||
{
|
||||
|
@ -904,11 +854,7 @@ CHECK_RULE(DesktopFile, QString)
|
|||
RuleBook::RuleBook()
|
||||
: m_updateTimer(new QTimer(this))
|
||||
, m_updatesDisabled(false)
|
||||
, m_temporaryRulesMessages()
|
||||
{
|
||||
initializeX11();
|
||||
connect(kwinApp(), &Application::x11ConnectionChanged, this, &RuleBook::initializeX11);
|
||||
connect(kwinApp(), &Application::x11ConnectionAboutToBeDestroyed, this, &RuleBook::cleanupX11);
|
||||
connect(m_updateTimer, &QTimer::timeout, this, &RuleBook::save);
|
||||
m_updateTimer->setInterval(1000);
|
||||
m_updateTimer->setSingleShot(true);
|
||||
|
@ -920,48 +866,20 @@ RuleBook::~RuleBook()
|
|||
deleteAll();
|
||||
}
|
||||
|
||||
void RuleBook::initializeX11()
|
||||
{
|
||||
auto c = kwinApp()->x11Connection();
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
m_temporaryRulesMessages.reset(new KXMessages(c, kwinApp()->x11RootWindow(), "_KDE_NET_WM_TEMPORARY_RULES", nullptr));
|
||||
connect(m_temporaryRulesMessages.get(), &KXMessages::gotMessage, this, &RuleBook::temporaryRulesMessage);
|
||||
}
|
||||
|
||||
void RuleBook::cleanupX11()
|
||||
{
|
||||
m_temporaryRulesMessages.reset();
|
||||
}
|
||||
|
||||
void RuleBook::deleteAll()
|
||||
{
|
||||
qDeleteAll(m_rules);
|
||||
m_rules.clear();
|
||||
}
|
||||
|
||||
WindowRules RuleBook::find(const Window *c, bool ignore_temporary)
|
||||
WindowRules RuleBook::find(const Window *window) const
|
||||
{
|
||||
QVector<Rules *> ret;
|
||||
for (QList<Rules *>::Iterator it = m_rules.begin();
|
||||
it != m_rules.end();) {
|
||||
if (ignore_temporary && (*it)->isTemporary()) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
if ((*it)->match(c)) {
|
||||
Rules *rule = *it;
|
||||
qCDebug(KWIN_CORE) << "Rule found:" << rule << ":" << c;
|
||||
if (rule->isTemporary()) {
|
||||
it = m_rules.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
for (Rules *rule : m_rules) {
|
||||
if (rule->match(window)) {
|
||||
qCDebug(KWIN_CORE) << "Rule found:" << rule << ":" << window;
|
||||
ret.append(rule);
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
return WindowRules(ret);
|
||||
}
|
||||
|
@ -999,7 +917,7 @@ void RuleBook::load()
|
|||
}
|
||||
RuleBookSettings book(m_config);
|
||||
book.load();
|
||||
m_rules = book.rules().toList();
|
||||
m_rules = book.rules();
|
||||
}
|
||||
|
||||
void RuleBook::save()
|
||||
|
@ -1009,57 +927,15 @@ void RuleBook::save()
|
|||
qCWarning(KWIN_CORE) << "RuleBook::save invoked without prior invocation of RuleBook::load";
|
||||
return;
|
||||
}
|
||||
QVector<Rules *> filteredRules;
|
||||
for (const auto &rule : std::as_const(m_rules)) {
|
||||
if (!rule->isTemporary()) {
|
||||
filteredRules.append(rule);
|
||||
}
|
||||
}
|
||||
RuleBookSettings settings(m_config);
|
||||
settings.setRules(filteredRules);
|
||||
settings.setRules(m_rules);
|
||||
settings.save();
|
||||
}
|
||||
|
||||
void RuleBook::temporaryRulesMessage(const QString &message)
|
||||
{
|
||||
bool was_temporary = false;
|
||||
for (QList<Rules *>::ConstIterator it = m_rules.constBegin();
|
||||
it != m_rules.constEnd();
|
||||
++it) {
|
||||
if ((*it)->isTemporary()) {
|
||||
was_temporary = true;
|
||||
}
|
||||
}
|
||||
Rules *rule = new Rules(message, true);
|
||||
m_rules.prepend(rule); // highest priority first
|
||||
if (!was_temporary) {
|
||||
QTimer::singleShot(60000, this, &RuleBook::cleanupTemporaryRules);
|
||||
}
|
||||
}
|
||||
|
||||
void RuleBook::cleanupTemporaryRules()
|
||||
{
|
||||
bool has_temporary = false;
|
||||
for (QList<Rules *>::Iterator it = m_rules.begin();
|
||||
it != m_rules.end();) {
|
||||
if ((*it)->discardTemporary(false)) { // deletes (*it)
|
||||
it = m_rules.erase(it);
|
||||
} else {
|
||||
if ((*it)->isTemporary()) {
|
||||
has_temporary = true;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
if (has_temporary) {
|
||||
QTimer::singleShot(60000, this, &RuleBook::cleanupTemporaryRules);
|
||||
}
|
||||
}
|
||||
|
||||
void RuleBook::discardUsed(Window *c, bool withdrawn)
|
||||
{
|
||||
bool updated = false;
|
||||
for (QList<Rules *>::Iterator it = m_rules.begin();
|
||||
for (QVector<Rules *>::Iterator it = m_rules.begin();
|
||||
it != m_rules.end();) {
|
||||
if (c->rules()->contains(*it)) {
|
||||
if ((*it)->discardUsed(withdrawn)) {
|
||||
|
|
15
src/rules.h
15
src/rules.h
|
@ -18,7 +18,6 @@
|
|||
|
||||
class QDebug;
|
||||
class KConfig;
|
||||
class KXMessages;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -37,7 +36,6 @@ public:
|
|||
explicit WindowRules(const QVector<Rules *> &rules);
|
||||
WindowRules();
|
||||
void update(Window *, int selection);
|
||||
void discardTemporary();
|
||||
bool contains(const Rules *rule) const;
|
||||
void remove(Rules *rule);
|
||||
PlacementPolicy checkPlacement(PlacementPolicy placement) const;
|
||||
|
@ -93,7 +91,6 @@ class Rules
|
|||
public:
|
||||
Rules();
|
||||
explicit Rules(const RuleSettings *);
|
||||
Rules(const QString &, bool temporary);
|
||||
enum Type {
|
||||
Position = 1 << 0,
|
||||
Size = 1 << 1,
|
||||
|
@ -149,8 +146,6 @@ public:
|
|||
bool discardUsed(bool withdrawn);
|
||||
bool match(const Window *c) const;
|
||||
bool update(Window *, int selection);
|
||||
bool isTemporary() const;
|
||||
bool discardTemporary(bool force); // removes if temporary and forced or too old
|
||||
bool applyPlacement(PlacementPolicy &placement) const;
|
||||
bool applyGeometry(QRectF &rect, bool init) const;
|
||||
// use 'invalidPoint' with applyPosition, unlike QSize() and QRect(), QPoint() is a valid point
|
||||
|
@ -209,7 +204,6 @@ private:
|
|||
static bool checkSetStop(SetRule rule);
|
||||
static bool checkForceStop(ForceRule rule);
|
||||
#endif
|
||||
int temporary_state; // e.g. for kstart
|
||||
QString description;
|
||||
QString wmclass;
|
||||
StringMatch wmclassmatch;
|
||||
|
@ -303,7 +297,7 @@ class KWIN_EXPORT RuleBook : public QObject
|
|||
public:
|
||||
explicit RuleBook();
|
||||
~RuleBook() override;
|
||||
WindowRules find(const Window *, bool);
|
||||
WindowRules find(const Window *window) const;
|
||||
void discardUsed(Window *c, bool withdraw);
|
||||
void setUpdatesDisabled(bool disable);
|
||||
bool areUpdatesDisabled() const;
|
||||
|
@ -317,18 +311,13 @@ public:
|
|||
}
|
||||
|
||||
private Q_SLOTS:
|
||||
void temporaryRulesMessage(const QString &);
|
||||
void cleanupTemporaryRules();
|
||||
void save();
|
||||
|
||||
private:
|
||||
void deleteAll();
|
||||
void initializeX11();
|
||||
void cleanupX11();
|
||||
QTimer *m_updateTimer;
|
||||
bool m_updatesDisabled;
|
||||
QList<Rules *> m_rules;
|
||||
std::unique_ptr<KXMessages> m_temporaryRulesMessages;
|
||||
QVector<Rules *> m_rules;
|
||||
KSharedConfig::Ptr m_config;
|
||||
};
|
||||
|
||||
|
|
|
@ -3477,14 +3477,9 @@ void Window::removeRule(Rules *rule)
|
|||
m_rules.remove(rule);
|
||||
}
|
||||
|
||||
void Window::discardTemporaryRules()
|
||||
{
|
||||
m_rules.discardTemporary();
|
||||
}
|
||||
|
||||
void Window::evaluateWindowRules()
|
||||
{
|
||||
setupWindowRules(true);
|
||||
setupWindowRules();
|
||||
applyWindowRules();
|
||||
}
|
||||
|
||||
|
@ -4448,10 +4443,10 @@ void Window::cleanTabBox()
|
|||
#endif
|
||||
}
|
||||
|
||||
void Window::setupWindowRules(bool ignore_temporary)
|
||||
void Window::setupWindowRules()
|
||||
{
|
||||
disconnect(this, &Window::captionChanged, this, &Window::evaluateWindowRules);
|
||||
m_rules = workspace()->rulebook()->find(this, ignore_temporary);
|
||||
m_rules = workspace()->rulebook()->find(this);
|
||||
// check only after getting the rules, because there may be a rule forcing window type
|
||||
}
|
||||
|
||||
|
|
|
@ -1084,7 +1084,7 @@ public:
|
|||
return &m_rules;
|
||||
}
|
||||
void removeRule(Rules *r);
|
||||
void setupWindowRules(bool ignore_temporary);
|
||||
void setupWindowRules();
|
||||
void evaluateWindowRules();
|
||||
virtual void applyWindowRules();
|
||||
virtual bool takeFocus() = 0;
|
||||
|
@ -1890,7 +1890,6 @@ protected:
|
|||
Window *findWindowWithSameCaption() const;
|
||||
|
||||
void finishWindowRules();
|
||||
void discardTemporaryRules();
|
||||
|
||||
bool tabTo(Window *other, bool behind, bool activate);
|
||||
|
||||
|
|
|
@ -493,7 +493,7 @@ bool X11Window::manage(xcb_window_t w, bool isMapped)
|
|||
// and only then really set the caption using setCaption(), which checks for duplicates etc.
|
||||
// and also relies on rules already existing
|
||||
cap_normal = readName();
|
||||
setupWindowRules(false);
|
||||
setupWindowRules();
|
||||
setCaption(cap_normal, true);
|
||||
|
||||
connect(this, &X11Window::windowClassChanged, this, &X11Window::evaluateWindowRules);
|
||||
|
@ -1006,7 +1006,6 @@ bool X11Window::manage(xcb_window_t w, bool isMapped)
|
|||
|
||||
delete session;
|
||||
|
||||
discardTemporaryRules();
|
||||
applyWindowRules(); // Just in case
|
||||
workspace()->rulebook()->discardUsed(this, false); // Remove ApplyNow rules
|
||||
updateWindowRules(Rules::All); // Was blocked while !isManaged()
|
||||
|
|
|
@ -1360,7 +1360,7 @@ bool XdgToplevelWindow::initialFullScreenMode() const
|
|||
void XdgToplevelWindow::initialize()
|
||||
{
|
||||
bool needsPlacement = isPlaceable();
|
||||
setupWindowRules(false);
|
||||
setupWindowRules();
|
||||
|
||||
// Move or resize the window only if enforced by a window rule.
|
||||
const QPointF forcedPosition = rules()->checkPositionSafe(invalidPoint, true);
|
||||
|
@ -1398,7 +1398,6 @@ void XdgToplevelWindow::initialize()
|
|||
needsPlacement = false;
|
||||
}
|
||||
|
||||
discardTemporaryRules();
|
||||
workspace()->rulebook()->discardUsed(this, false); // Remove Apply Now rules.
|
||||
updateWindowRules(Rules::All);
|
||||
|
||||
|
|
Loading…
Reference in a new issue