From 65ec86113a152f987fc549fb4a9972ae3d09d6db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 26 Apr 2013 14:40:35 +0200 Subject: [PATCH] Split out Rules related code from Workspace into class RuleBook Workspace is hardly interacting with Rules and all the Rules related code is already in rules.cpp. This highly qualifies to move all the code out of Workspace and improve the names. REVIEW: 110207 --- client.cpp | 4 +- manage.cpp | 2 +- rules.cpp | 106 +++++++++++++++++++++++++++++------------------- rules.h | 35 ++++++++++++++++ sm.cpp | 4 +- useractions.cpp | 4 +- workspace.cpp | 17 ++------ workspace.h | 23 ----------- 8 files changed, 111 insertions(+), 84 deletions(-) diff --git a/client.cpp b/client.cpp index ac66746da8..f7ffa31c2d 100644 --- a/client.cpp +++ b/client.cpp @@ -262,7 +262,7 @@ void Client::releaseWindow(bool on_shutdown) emit clientFinishUserMovedResized(this); emit windowClosed(this, del); finishCompositing(); - workspace()->discardUsedWindowRules(this, true); // Remove ForceTemporarily rules + RuleBook::self()->discardUsed(this, true); // Remove ForceTemporarily rules StackingUpdatesBlocker blocker(workspace()); if (moveResizeMode) leaveMoveResize(); @@ -330,7 +330,7 @@ void Client::destroyClient() emit clientFinishUserMovedResized(this); emit windowClosed(this, del); finishCompositing(); - workspace()->discardUsedWindowRules(this, true); // Remove ForceTemporarily rules + RuleBook::self()->discardUsed(this, true); // Remove ForceTemporarily rules StackingUpdatesBlocker blocker(workspace()); if (moveResizeMode) leaveMoveResize(); diff --git a/manage.cpp b/manage.cpp index 36d3578d03..93eaa592cf 100644 --- a/manage.cpp +++ b/manage.cpp @@ -612,7 +612,7 @@ bool Client::manage(Window w, bool isMapped) client_rules.discardTemporary(); applyWindowRules(); // Just in case - workspace()->discardUsedWindowRules(this, false); // Remove ApplyNow rules + RuleBook::self()->discardUsed(this, false); // Remove ApplyNow rules updateWindowRules(Rules::All); // Was blocked while !isManaged() updateCompositeBlocking(true); diff --git a/rules.cpp b/rules.cpp index acb927a964..df5f50908e 100644 --- a/rules.cpp +++ b/rules.cpp @@ -22,6 +22,7 @@ along with this program. If not, see . #include #include +#include #include #include #include @@ -736,7 +737,7 @@ void WindowRules::update(Client* c, int selection) if ((*it)->update(c, selection)) // no short-circuiting here updated = true; if (updated) - Workspace::self()->rulesUpdated(); + RuleBook::self()->requestDiskStorage(); } #define CHECK_RULE( rule, type ) \ @@ -840,7 +841,7 @@ CHECK_FORCE_RULE(DisableGlobalShortcuts, bool) void Client::setupWindowRules(bool ignore_temporary) { - client_rules = workspace()->findWindowRules(this, ignore_temporary); + client_rules = RuleBook::self()->find(this, ignore_temporary); // check only after getting the rules, because there may be a rule forcing window type } @@ -901,7 +902,7 @@ void Client::updateWindowRules(Rules::Types selection) { if (!isManaged()) // not fully setup yet return; - if (workspace()->rulesUpdatesDisabled()) + if (RuleBook::self()->areUpdatesDisabled()) return; client_rules.update(this, selection); } @@ -913,12 +914,37 @@ void Client::finishWindowRules() } // Workspace +KWIN_SINGLETON_FACTORY(RuleBook) -WindowRules Workspace::findWindowRules(const Client* c, bool ignore_temporary) +RuleBook::RuleBook(QObject *parent) + : QObject(parent) + , m_updateTimer(new QTimer(this)) + , m_updatesDisabled(false) + , m_temporaryRulesMessages(new KXMessages("_KDE_NET_WM_TEMPORARY_RULES", NULL)) +{ + connect(m_temporaryRulesMessages.data(), SIGNAL(gotMessage(QString)), SLOT(temporaryRulesMessage(QString))); + connect(m_updateTimer, SIGNAL(timeout()), SLOT(save())); + m_updateTimer->setInterval(1000); + m_updateTimer->setSingleShot(true); +} + +RuleBook::~RuleBook() +{ + save(); + deleteAll(); +} + +void RuleBook::deleteAll() +{ + qDeleteAll(m_rules); + m_rules.clear(); +} + +WindowRules RuleBook::find(const Client* c, bool ignore_temporary) { QVector< Rules* > ret; - for (QList< Rules* >::Iterator it = rules.begin(); - it != rules.end(); + for (QList< Rules* >::Iterator it = m_rules.begin(); + it != m_rules.end(); ) { if (ignore_temporary && (*it)->isTemporary()) { ++it; @@ -928,7 +954,7 @@ WindowRules Workspace::findWindowRules(const Client* c, bool ignore_temporary) Rules* rule = *it; kDebug(1212) << "Rule found:" << rule << ":" << c; if (rule->isTemporary()) - it = rules.erase(it); + it = m_rules.erase(it); else ++it; ret.append(rule); @@ -939,9 +965,9 @@ WindowRules Workspace::findWindowRules(const Client* c, bool ignore_temporary) return WindowRules(ret); } -void Workspace::editWindowRules(Client* c, bool whole_app) +void RuleBook::edit(Client* c, bool whole_app) { - writeWindowRules(); + save(); QStringList args; args << "--wid" << QString::number(c->window()); if (whole_app) @@ -949,12 +975,9 @@ void Workspace::editWindowRules(Client* c, bool whole_app) KToolInvocation::kdeinitExec("kwin_rules_dialog", args); } -void Workspace::loadWindowRules() +void RuleBook::load() { - while (!rules.isEmpty()) { - delete rules.front(); - rules.pop_front(); - } + deleteAll(); KConfig cfg(QLatin1String(KWIN_NAME) + "rulesrc", KConfig::NoGlobals); int count = cfg.group("General").readEntry("count", 0); for (int i = 1; @@ -962,23 +985,23 @@ void Workspace::loadWindowRules() ++i) { KConfigGroup cg(&cfg, QString::number(i)); Rules* rule = new Rules(cg); - rules.append(rule); + m_rules.append(rule); } } -void Workspace::writeWindowRules() +void RuleBook::save() { - rulesUpdatedTimer.stop(); + m_updateTimer->stop(); KConfig cfg(QLatin1String(KWIN_NAME) + "rulesrc", KConfig::NoGlobals); QStringList groups = cfg.groupList(); for (QStringList::ConstIterator it = groups.constBegin(); it != groups.constEnd(); ++it) cfg.deleteGroup(*it); - cfg.group("General").writeEntry("count", rules.count()); + cfg.group("General").writeEntry("count", m_rules.count()); int i = 1; - for (QList< Rules* >::ConstIterator it = rules.constBegin(); - it != rules.constEnd(); + for (QList< Rules* >::ConstIterator it = m_rules.constBegin(); + it != m_rules.constEnd(); ++it) { if ((*it)->isTemporary()) continue; @@ -988,29 +1011,31 @@ void Workspace::writeWindowRules() } } -void Workspace::gotTemporaryRulesMessage(const QString& message) +void RuleBook::temporaryRulesMessage(const QString& message) { bool was_temporary = false; - for (QList< Rules* >::ConstIterator it = rules.constBegin(); - it != rules.constEnd(); + 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); - rules.prepend(rule); // highest priority first + m_rules.prepend(rule); // highest priority first if (!was_temporary) QTimer::singleShot(60000, this, SLOT(cleanupTemporaryRules())); } -void Workspace::cleanupTemporaryRules() +void RuleBook::cleanupTemporaryRules() { bool has_temporary = false; - for (QList< Rules* >::Iterator it = rules.begin(); - it != rules.end(); + for (QList< Rules* >::Iterator it = m_rules.begin(); + it != m_rules.end(); ) { - if ((*it)->discardTemporary(false)) - it = rules.erase(it); - else { + if ((*it)->discardTemporary(false)) { + Rules *rules = (*it); + it = m_rules.erase(it); + delete rules; + } else { if ((*it)->isTemporary()) has_temporary = true; ++it; @@ -1020,11 +1045,11 @@ void Workspace::cleanupTemporaryRules() QTimer::singleShot(60000, this, SLOT(cleanupTemporaryRules())); } -void Workspace::discardUsedWindowRules(Client* c, bool withdrawn) +void RuleBook::discardUsed(Client* c, bool withdrawn) { bool updated = false; - for (QList< Rules* >::Iterator it = rules.begin(); - it != rules.end(); + for (QList< Rules* >::Iterator it = m_rules.begin(); + it != m_rules.end(); ) { if (c->rules()->contains(*it)) { updated = true; @@ -1032,7 +1057,7 @@ void Workspace::discardUsedWindowRules(Client* c, bool withdrawn) if ((*it)->isEmpty()) { c->removeRule(*it); Rules* r = *it; - it = rules.erase(it); + it = m_rules.erase(it); delete r; continue; } @@ -1040,20 +1065,19 @@ void Workspace::discardUsedWindowRules(Client* c, bool withdrawn) ++it; } if (updated) - rulesUpdated(); + requestDiskStorage(); } -void Workspace::rulesUpdated() +void RuleBook::requestDiskStorage() { - rulesUpdatedTimer.setSingleShot(true); - rulesUpdatedTimer.start(1000); + m_updateTimer->start(); } -void Workspace::disableRulesUpdates(bool disable) +void RuleBook::setUpdatesDisabled(bool disable) { - rules_updates_disabled = disable; + m_updatesDisabled = disable; if (!disable) { - foreach (Client * c, clients) + foreach (Client * c, Workspace::self()->clientList()) c->updateWindowRules(Rules::All); } } diff --git a/rules.h b/rules.h index a4893b5fc0..2a635535af 100644 --- a/rules.h +++ b/rules.h @@ -33,6 +33,7 @@ along with this program. If not, see . #include "utils.h" class KConfig; +class KXMessages; namespace KWin { @@ -91,6 +92,7 @@ private: MaximizeMode checkMaximizeHoriz(MaximizeMode mode, bool init) const; QVector< Rules* > rules; }; + #endif class Rules @@ -277,6 +279,39 @@ private: }; #ifndef KCMRULES +class RuleBook : public QObject +{ + Q_OBJECT +public: + virtual ~RuleBook(); + WindowRules find(const Client*, bool); + void discardUsed(Client* c, bool withdraw); + void setUpdatesDisabled(bool disable); + bool areUpdatesDisabled() const; + void load(); + void edit(Client* c, bool whole_app); + void requestDiskStorage(); +private Q_SLOTS: + void temporaryRulesMessage(const QString&); + void cleanupTemporaryRules(); + void save(); + +private: + void deleteAll(); + QTimer *m_updateTimer; + bool m_updatesDisabled; + QList m_rules; + QScopedPointer m_temporaryRulesMessages; + + KWIN_SINGLETON(RuleBook) +}; + +inline +bool RuleBook::areUpdatesDisabled() const +{ + return m_updatesDisabled; +} + inline bool Rules::checkSetRule(SetRule rule, bool init) { diff --git a/sm.cpp b/sm.cpp index 1d6b89aaf6..1e90eb63cf 100644 --- a/sm.cpp +++ b/sm.cpp @@ -369,7 +369,7 @@ static void save_yourself(SmcConn conn_P, SmPointer ptr, int, Bool shutdown, int if (conn_P != session->connection()) return; if (shutdown) - Workspace::self()->disableRulesUpdates(true); + RuleBook::self()->setUpdatesDisabled(true); SmcSaveYourselfDone(conn_P, True); } @@ -395,7 +395,7 @@ static void shutdown_cancelled(SmcConn conn_P, SmPointer ptr) SessionSaveDoneHelper* session = reinterpret_cast< SessionSaveDoneHelper* >(ptr); if (conn_P != session->connection()) return; - Workspace::self()->disableRulesUpdates(false); // re-enable + RuleBook::self()->setUpdatesDisabled(false); // re-enable // no need to differentiate between successful finish and cancel session->saveDone(); } diff --git a/useractions.cpp b/useractions.cpp index 20d6ad828c..753b8c16cb 100755 --- a/useractions.cpp +++ b/useractions.cpp @@ -1111,10 +1111,10 @@ void Workspace::performWindowOperation(Client* c, Options::WindowOperation op) c->performMouseCommand(Options::MouseShade, cursorPos()); break; case Options::WindowRulesOp: - editWindowRules(c, false); + RuleBook::self()->edit(c, false); break; case Options::ApplicationRulesOp: - editWindowRules(c, true); + RuleBook::self()->edit(c, true); break; case Options::SetupWindowShortcutOp: setupWindowShortcut(c); diff --git a/workspace.cpp b/workspace.cpp index 5aee3f8e7f..42dd9c185e 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -86,8 +86,6 @@ Workspace::Workspace(bool restore) // Unsorted , active_popup(NULL) , active_popup_client(NULL) - , temporaryRulesMessages("_KDE_NET_WM_TEMPORARY_RULES", NULL) - , rules_updates_disabled(false) , active_client(0) , last_active_client(0) , most_recently_raised(0) @@ -148,9 +146,6 @@ Workspace::Workspace(bool restore) default_colormap = DefaultColormap(display(), screen_number); installed_colormap = default_colormap; - connect(&temporaryRulesMessages, SIGNAL(gotMessage(QString)), - this, SLOT(gotTemporaryRulesMessage(QString))); - connect(&rulesUpdatedTimer, SIGNAL(timeout()), this, SLOT(writeWindowRules())); updateXTime(); // Needed for proper initialization of user_time in Client ctor delayFocusTimer = 0; @@ -158,7 +153,7 @@ Workspace::Workspace(bool restore) if (restore) loadSessionInfo(); - loadWindowRules(); + RuleBook::create(this)->load(); // Call this before XSelectInput() on the root window startup = new KStartupInfo( @@ -505,7 +500,7 @@ Workspace::~Workspace() (*it)->release(true); XDeleteProperty(display(), rootWindow(), atoms->kwin_running); - writeWindowRules(); + delete RuleBook::self(); KGlobal::config()->sync(); delete rootInfo; @@ -513,10 +508,6 @@ Workspace::~Workspace() delete startup; delete Placement::self(); delete client_keys_dialog; - while (!rules.isEmpty()) { - delete rules.front(); - rules.pop_front(); - } foreach (SessionInfo * s, session) delete s; XDestroyWindow(display(), null_focus_window); @@ -907,13 +898,13 @@ void Workspace::slotReconfigure() c->triggerDecorationRepaint(); } - loadWindowRules(); + RuleBook::self()->load(); for (ClientList::Iterator it = clients.begin(); it != clients.end(); ++it) { (*it)->setupWindowRules(true); (*it)->applyWindowRules(); - discardUsedWindowRules(*it, false); + RuleBook::self()->discardUsed(*it, false); } if (borderlessMaximizedWindows != options->borderlessMaximizedWindows() && diff --git a/workspace.h b/workspace.h index 3ea9c2e27a..da968c8549 100644 --- a/workspace.h +++ b/workspace.h @@ -29,7 +29,6 @@ along with this program. If not, see . #include "utils.h" // KDE #include -#include // Qt #include #include @@ -52,10 +51,8 @@ namespace KWin class Client; class KillWindow; class RootInfo; -class Rules; class ShortcutDialog; class UserActionsMenu; -class WindowRules; class Compositor; class Workspace : public QObject, public KDecorationDefines @@ -246,11 +243,6 @@ public: void loadSubSessionInfo(const QString &name); SessionInfo* takeSessionInfo(Client*); - WindowRules findWindowRules(const Client*, bool); - void rulesUpdated(); - void discardUsedWindowRules(Client* c, bool withdraw); - void disableRulesUpdates(bool disable); - bool rulesUpdatesDisabled() const; // D-Bus interface bool waitForCompositingSetup(); @@ -397,9 +389,6 @@ private slots: void desktopResized(); void slotUpdateToolWindows(); void delayFocus(); - void gotTemporaryRulesMessage(const QString&); - void cleanupTemporaryRules(); - void writeWindowRules(); void slotBlockShortcuts(int data); void slotReloadConfig(); void updateCurrentActivity(const QString &new_activity); @@ -481,14 +470,7 @@ private: void loadSessionInfo(); void addSessionInfo(KConfigGroup &cg); - void loadWindowRules(); - void editWindowRules(Client* c, bool whole_app); - QList session; - QList rules; - KXMessages temporaryRulesMessages; - QTimer rulesUpdatedTimer; - bool rules_updates_disabled; static const char* windowTypeToTxt(NET::WindowType type); static NET::WindowType txtToWindowType(const char* txt); static bool sessionInfoWindowTypeMatch(Client* c, SessionInfo* info); @@ -712,11 +694,6 @@ inline bool Workspace::globalShortcutsDisabled() const return global_shortcuts_disabled || global_shortcuts_disabled_for_client; } -inline bool Workspace::rulesUpdatesDisabled() const -{ - return rules_updates_disabled; -} - inline void Workspace::forceRestacking() { force_restacking = true;