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:
Vlad Zahorodnii 2023-01-26 19:39:53 +02:00
parent d18f7efac2
commit e5901070cc
9 changed files with 22 additions and 163 deletions

View file

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

View file

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

View file

@ -92,7 +92,6 @@ RootInfo *RootInfo::create()
| NET::WM2RestackWindow
| NET::WM2MoveResizeWindow
| NET::WM2ExtendedStrut
| NET::WM2KDETemporaryRules
| NET::WM2ShowingDesktop
| NET::WM2DesktopLayout
| NET::WM2FullPlacement

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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