From 0372fdaf9275bd7ed5401f8c11fe85a050266e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= Date: Sun, 1 Oct 2017 16:38:57 +0200 Subject: [PATCH] Move WindowRules from Client to AbstractClient Summary: So far window rule specific functionality was only implemented in Client and in ShellClient there was only a dummy implementation. This change moves the client_rules member variable from Client to AbstractClient. Areas which would not compile anymore are adjusted. This is a first step to get window rule support for Wayland windows. Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D8090 --- abstract_client.cpp | 21 +++++++++++++++++++++ abstract_client.h | 17 +++++++++++++++-- client.cpp | 8 +------- client.h | 21 ++------------------- manage.cpp | 2 +- rules.cpp | 40 +++++++++++++++++++++++----------------- rules.h | 8 ++++---- shell_client.cpp | 24 +++++++++++------------- shell_client.h | 4 ++-- 9 files changed, 80 insertions(+), 65 deletions(-) diff --git a/abstract_client.cpp b/abstract_client.cpp index c26e2dfdc7..7ee63e6a20 100644 --- a/abstract_client.cpp +++ b/abstract_client.cpp @@ -1776,4 +1776,25 @@ QString AbstractClient::caption() const return cap; } +void AbstractClient::removeRule(Rules* rule) +{ + m_rules.remove(rule); +} + +void AbstractClient::discardTemporaryRules() +{ + m_rules.discardTemporary(); +} + +void AbstractClient::evaluateWindowRules() +{ + setupWindowRules(true); + applyWindowRules(); +} + +void AbstractClient::setOnActivities(QStringList newActivitiesList) +{ + Q_UNUSED(newActivitiesList) +} + } diff --git a/abstract_client.h b/abstract_client.h index 0f486c6f33..a6f05caab8 100644 --- a/abstract_client.h +++ b/abstract_client.h @@ -460,8 +460,15 @@ public: virtual QRect iconGeometry() const; virtual bool userCanSetFullScreen() const = 0; virtual bool userCanSetNoBorder() const = 0; + virtual void setOnActivities(QStringList newActivitiesList); virtual void setOnAllActivities(bool set) = 0; - virtual const WindowRules* rules() const = 0; + const WindowRules* rules() const { + return &m_rules; + } + void removeRule(Rules* r); + void setupWindowRules(bool ignore_temporary); + void evaluateWindowRules(); + void applyWindowRules(); virtual void takeFocus() = 0; virtual bool wantsInput() const = 0; /** @@ -478,7 +485,7 @@ public: virtual bool dockWantsInput() const; void checkWorkspacePosition(QRect oldGeometry = QRect(), int oldDesktop = -2, QRect oldClientGeometry = QRect()); virtual xcb_timestamp_t userTime() const; - virtual void updateWindowRules(Rules::Types selection) = 0; + virtual void updateWindowRules(Rules::Types selection); void growHorizontal(); void shrinkHorizontal(); @@ -775,6 +782,7 @@ protected: void destroyWindowManagementInterface(); void updateColorScheme(QString path); + virtual void updateColorScheme() = 0; void setTransientFor(AbstractClient *transientFor); virtual void addTransient(AbstractClient* cl); @@ -1009,6 +1017,9 @@ protected: **/ AbstractClient *findClientWithSameCaption() const; + void finishWindowRules(); + void discardTemporaryRules(); + private: void handlePaletteChange(); QSharedPointer m_tabBoxClient; @@ -1085,6 +1096,8 @@ private: QKeySequence _shortcut; + WindowRules m_rules; + static bool s_haveResizeEffect; }; diff --git a/client.cpp b/client.cpp index 1a2d89e104..a654b7fc43 100644 --- a/client.cpp +++ b/client.cpp @@ -1487,12 +1487,6 @@ void Client::updateCaption() setCaption(cap_normal, true); } -void Client::evaluateWindowRules() -{ - setupWindowRules(true); - applyWindowRules(); -} - void Client::fetchIconicName() { QString s; @@ -1987,7 +1981,7 @@ NET::WindowType Client::windowType(bool direct, int supportedTypes) const if (direct) { return wt; } - NET::WindowType wt2 = client_rules.checkType(wt); + NET::WindowType wt2 = rules()->checkType(wt); if (wt != wt2) { wt = wt2; info->setWindowType(wt); // force hint change diff --git a/client.h b/client.h index 656536ceee..2022545830 100644 --- a/client.h +++ b/client.h @@ -109,10 +109,6 @@ public: Group* group(); void checkGroup(Group* gr = NULL, bool force = false); void changeClientLeaderGroup(Group* gr); - const WindowRules* rules() const override; - void removeRule(Rules* r); - void setupWindowRules(bool ignore_temporary); - void applyWindowRules(); void updateWindowRules(Rules::Types selection) override; void updateFullscreenMonitors(NETFullscreenMonitors topology); @@ -135,7 +131,7 @@ public: virtual QStringList activities() const; void setOnActivity(const QString &activity, bool enable); void setOnAllActivities(bool set) override; - void setOnActivities(QStringList newActivitiesList); + void setOnActivities(QStringList newActivitiesList) override; void updateActivities(bool includeTransients); void blockActivityUpdates(bool b = true) override; @@ -315,7 +311,7 @@ public: void updateFirstInTabBox(); Xcb::StringProperty fetchColorScheme() const; void readColorScheme(Xcb::StringProperty &property); - void updateColorScheme(); + void updateColorScheme() override; //sets whether the client should be faked as being on all activities (and be shown during session save) void setSessionActivityOverride(bool needed); @@ -345,7 +341,6 @@ public: public Q_SLOTS: void closeWindow() override; void updateCaption() override; - void evaluateWindowRules(); private Q_SLOTS: void shadeHover(); @@ -450,7 +445,6 @@ private: QString readName() const; void setCaption(const QString& s, bool force = false); bool hasTransientInternal(const Client* c, bool indirect, ConstClientList& set) const; - void finishWindowRules(); void setShortcutInternal() override; void configureRequest(int value_mask, int rx, int ry, int rw, int rh, int gravity, bool from_tool); @@ -547,7 +541,6 @@ private: uint app_noborder : 1; ///< App requested no border via window type, shape extension, etc. uint ignore_focus_stealing : 1; ///< Don't apply focus stealing prevention to this client bool blocks_compositing; - WindowRules client_rules; // DON'T reorder - Saved to config files !!! enum FullScreenMode { FullScreenNone, @@ -727,21 +720,11 @@ inline bool Client::hasUserTimeSupport() const return info->userTime() != -1U; } -inline const WindowRules* Client::rules() const -{ - return &client_rules; -} - inline xcb_window_t Client::moveResizeGrabWindow() const { return m_moveResizeGrabWindow; } -inline void Client::removeRule(Rules* rule) -{ - client_rules.remove(rule); -} - inline bool Client::hiddenPreview() const { return mapping_state == Kept; diff --git a/manage.cpp b/manage.cpp index 6ffb2220b1..8daebebe72 100644 --- a/manage.cpp +++ b/manage.cpp @@ -641,7 +641,7 @@ bool Client::manage(xcb_window_t w, bool isMapped) delete session; - client_rules.discardTemporary(); + discardTemporaryRules(); applyWindowRules(); // Just in case RuleBook::self()->discardUsed(this, false); // Remove ApplyNow rules updateWindowRules(Rules::All); // Was blocked while !isManaged() diff --git a/rules.cpp b/rules.cpp index efeb107c07..fd3a4f80f2 100644 --- a/rules.cpp +++ b/rules.cpp @@ -445,7 +445,7 @@ bool Rules::matchClientMachine(const QByteArray& match_machine, bool local) cons } #ifndef KCMRULES -bool Rules::match(const Client* c) const +bool Rules::match(const AbstractClient* c) const { if (!matchType(c->windowType(true))) return false; @@ -456,7 +456,7 @@ bool Rules::match(const Client* c) const if (!matchClientMachine(c->clientMachine()->hostName(), c->clientMachine()->isLocal())) return false; if (titlematch != UnimportantMatch) // track title changes to rematch rules - QObject::connect(c, &Client::captionChanged, c, &Client::evaluateWindowRules, + QObject::connect(c, &AbstractClient::captionChanged, c, &AbstractClient::evaluateWindowRules, // QueuedConnection, because title may change before // the client is ready (could segfault!) static_cast(Qt::QueuedConnection|Qt::UniqueConnection)); @@ -467,7 +467,7 @@ bool Rules::match(const Client* c) const #define NOW_REMEMBER(_T_, _V_) ((selection & _T_) && (_V_##rule == (SetRule)Remember)) -bool Rules::update(Client* c, int selection) +bool Rules::update(AbstractClient* c, int selection) { // TODO check this setting is for this client ? bool updated = false; @@ -759,7 +759,7 @@ void WindowRules::discardTemporary() rules.erase(it2, rules.end()); } -void WindowRules::update(Client* c, int selection) +void WindowRules::update(AbstractClient* c, int selection) { bool updated = false; for (QVector< Rules* >::ConstIterator it = rules.constBegin(); @@ -872,22 +872,23 @@ CHECK_FORCE_RULE(DisableGlobalShortcuts, bool) // Client -void Client::setupWindowRules(bool ignore_temporary) +void AbstractClient::setupWindowRules(bool ignore_temporary) { - disconnect(this, &Client::captionChanged, this, &Client::evaluateWindowRules); - client_rules = RuleBook::self()->find(this, ignore_temporary); + disconnect(this, &AbstractClient::captionChanged, this, &AbstractClient::evaluateWindowRules); + m_rules = RuleBook::self()->find(this, ignore_temporary); // check only after getting the rules, because there may be a rule forcing window type } // Applies Force, ForceTemporarily and ApplyNow rules // Used e.g. after the rules have been modified using the kcm. -void Client::applyWindowRules() +void AbstractClient::applyWindowRules() { // apply force rules // Placement - does need explicit update, just like some others below // Geometry : setGeometry() doesn't check rules + auto client_rules = rules(); QRect orig_geom = QRect(pos(), sizeForClientSize(clientSize())); // handle shading - QRect geom = client_rules.checkGeometry(orig_geom); + QRect geom = client_rules->checkGeometry(orig_geom); if (geom != orig_geom) setGeometry(geom); // MinSize, MaxSize handled by Geometry @@ -898,7 +899,7 @@ void Client::applyWindowRules() // Type maximize(maximizeMode()); // Minimize : functions don't check, and there are two functions - if (client_rules.checkMinimize(isMinimized())) + if (client_rules->checkMinimize(isMinimized())) minimize(); else unminimize(); @@ -914,7 +915,7 @@ void Client::applyWindowRules() // FSP // AcceptFocus : if (workspace()->mostRecentlyActivatedClient() == this - && !client_rules.checkAcceptFocus(true)) + && !client_rules->checkAcceptFocus(true)) workspace()->activateNextClient(this); // Closeable QSize s = adjustedSize(); @@ -937,15 +938,20 @@ void Client::updateWindowRules(Rules::Types selection) { if (!isManaged()) // not fully setup yet return; - if (RuleBook::self()->areUpdatesDisabled()) - return; - client_rules.update(this, selection); + AbstractClient::updateWindowRules(selection); } -void Client::finishWindowRules() +void AbstractClient::updateWindowRules(Rules::Types selection) +{ + if (RuleBook::self()->areUpdatesDisabled()) + return; + m_rules.update(this, selection); +} + +void AbstractClient::finishWindowRules() { updateWindowRules(Rules::All); - client_rules = WindowRules(); + m_rules = WindowRules(); } // Workspace @@ -987,7 +993,7 @@ void RuleBook::deleteAll() m_rules.clear(); } -WindowRules RuleBook::find(const Client* c, bool ignore_temporary) +WindowRules RuleBook::find(const AbstractClient* c, bool ignore_temporary) { QVector< Rules* > ret; for (QList< Rules* >::Iterator it = m_rules.begin(); diff --git a/rules.h b/rules.h index 25044d8610..8e230c8465 100644 --- a/rules.h +++ b/rules.h @@ -49,7 +49,7 @@ class WindowRules public: explicit WindowRules(const QVector< Rules* >& rules); WindowRules(); - void update(Client*, int selection); + void update(AbstractClient*, int selection); void discardTemporary(); bool contains(const Rules* rule) const; void remove(Rules* rule); @@ -116,8 +116,8 @@ public: bool isEmpty() const; #ifndef KCMRULES void discardUsed(bool withdrawn); - bool match(const Client* c) const; - bool update(Client*, int selection); + bool match(const AbstractClient* c) const; + bool update(AbstractClient*, int selection); bool isTemporary() const; bool discardTemporary(bool force); // removes if temporary and forced or too old bool applyPlacement(Placement::Policy& placement) const; @@ -292,7 +292,7 @@ class KWIN_EXPORT RuleBook : public QObject Q_OBJECT public: virtual ~RuleBook(); - WindowRules find(const Client*, bool); + WindowRules find(const AbstractClient*, bool); void discardUsed(Client* c, bool withdraw); void setUpdatesDisabled(bool disable); bool areUpdatesDisabled() const; diff --git a/shell_client.cpp b/shell_client.cpp index 282af776ae..93fd2ae544 100644 --- a/shell_client.cpp +++ b/shell_client.cpp @@ -321,7 +321,7 @@ void ShellClient::init() installServerSideDecoration(deco); } - updateColorScheme(QString()); + AbstractClient::updateColorScheme(QString()); updateApplicationMenu(); } @@ -866,12 +866,6 @@ bool ShellClient::noBorder() const return true; } -const WindowRules *ShellClient::rules() const -{ - static WindowRules s_rules; - return &s_rules; -} - void ShellClient::setFullScreen(bool set, bool user) { Q_UNUSED(set) @@ -934,11 +928,6 @@ void ShellClient::doSetActive() workspace()->focusToNull(); } -void ShellClient::updateWindowRules(Rules::Types selection) -{ - Q_UNUSED(selection) -} - bool ShellClient::userCanSetFullScreen() const { return false; @@ -1334,7 +1323,7 @@ bool ShellClient::eventFilter(QObject *watched, QEvent *event) if (watched == m_qtExtendedSurface.data() && event->type() == QEvent::DynamicPropertyChange) { QDynamicPropertyChangeEvent *pe = static_cast(event); if (pe->propertyName() == s_schemePropertyName) { - updateColorScheme(rules()->checkDecoColor(m_qtExtendedSurface->property(pe->propertyName().constData()).toString())); + AbstractClient::updateColorScheme(rules()->checkDecoColor(m_qtExtendedSurface->property(pe->propertyName().constData()).toString())); } else if (pe->propertyName() == s_appMenuServiceNamePropertyName) { updateApplicationMenuServiceName(m_qtExtendedSurface->property(pe->propertyName().constData()).toString()); } else if (pe->propertyName() == s_appMenuObjectPathPropertyName) { @@ -1350,6 +1339,15 @@ bool ShellClient::eventFilter(QObject *watched, QEvent *event) return false; } +void ShellClient::updateColorScheme() +{ + if (m_qtExtendedSurface) { + AbstractClient::updateColorScheme(rules()->checkDecoColor(m_qtExtendedSurface->property(s_schemePropertyName.constData()).toString())); + } else { + AbstractClient::updateColorScheme(rules()->checkDecoColor(QString())); + } +} + bool ShellClient::hasStrut() const { if (!isShown(true)) { diff --git a/shell_client.h b/shell_client.h index 91f7fed539..517dc91d49 100644 --- a/shell_client.h +++ b/shell_client.h @@ -97,13 +97,11 @@ public: return m_geomMaximizeRestore; } bool noBorder() const override; - const WindowRules *rules() const override; void setFullScreen(bool set, bool user = true) override; void setNoBorder(bool set) override; void updateDecoration(bool check_workspace_pos, bool force = false) override; void setOnAllActivities(bool set) override; void takeFocus() override; - void updateWindowRules(Rules::Types selection) override; bool userCanSetFullScreen() const override; bool userCanSetNoBorder() const override; bool wantsInput() const override; @@ -162,6 +160,8 @@ public: bool hasPopupGrab() const override; void popupDone() override; + void updateColorScheme() override; + protected: void addDamage(const QRegion &damage) override; bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const override;