From 5638f15edc2bb66a77848a2ec6cb017437417f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomi=20Lepp=C3=A4nen?= Date: Fri, 24 Apr 2020 13:38:25 +0300 Subject: [PATCH] [nemo-systemsettings] Add watched property to UserInfo. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add watched property to UserInfo so that it's not necessary to watch for changes in databases. Reduces some overhead. Note that this doesn't allow disabling wathing. Once it is set to true it remains that way. Separated the watching callback to its own method. Signed-off-by: Tomi Leppänen --- src/userinfo.cpp | 89 +++++++++++++++++++++++++++++++++++------------- src/userinfo.h | 4 +++ src/userinfo_p.h | 4 +++ 3 files changed, 73 insertions(+), 24 deletions(-) diff --git a/src/userinfo.cpp b/src/userinfo.cpp index 994be6c..e950675 100644 --- a/src/userinfo.cpp +++ b/src/userinfo.cpp @@ -91,6 +91,7 @@ UserInfoPrivate::UserInfoPrivate(struct passwd *pwd) UserInfoPrivate::~UserInfoPrivate() { + delete m_watcher; } QWeakPointer UserInfoPrivate::s_current; @@ -207,7 +208,6 @@ UserInfo::UserInfo() UserInfoPrivate::s_current = d_ptr; } connectSignals(); - watchForChanges(); } UserInfo::UserInfo(const UserInfo &other) @@ -389,6 +389,39 @@ bool UserInfo::alone() return d->alone(); } +/** + * Returns true if object follows database changes, defaults to false + * + * Note that even if watched is false, the object can change and emit + * change signals. + */ +bool UserInfo::watched() +{ + Q_D(const UserInfo); + return (bool)d->m_watcher; +} + +/** + * If set true object starts to follow database changes. + * Setting to false is not allowed but it can change back to false + * if watching fails. + * + * Setting to false would be a bit difficult since if some data sharing + * object would like to stop watching it will end watching for all of + * them. Thus it's better if you never set this to false. In practice, + * it's not necessary to set this to false ever. + */ +void UserInfo::setWatched(bool watch) +{ + Q_D(UserInfo); + // UserInfo objects with uid set to InvalidId can not be watched + if (d->m_uid != InvalidId && watch && !d->m_watcher) { + watchForChanges(); + if (d_ptr->m_watcher) + emit d->watchedChanged(); + } +} + /** * Resets object reloading all information */ @@ -424,8 +457,13 @@ void UserInfo::replace(QSharedPointer other) if (old->m_loggedIn != d_ptr->m_loggedIn) emit currentChanged(); - if (old->m_watcher) + if (old->m_watcher && !d_ptr->m_watcher) { watchForChanges(); + if (!d_ptr->m_watcher) + emit watchedChanged(); + } else if (!old->m_watcher && d_ptr->m_watcher) { + emit watchedChanged(); + } // If alone value was known, ensure that new d_ptr also knows it if (old->m_alone != UserInfoPrivate::Unknown && old->alone() != d_ptr->alone()) @@ -465,13 +503,14 @@ void UserInfo::connectSignals() connect(d_ptr.data(), &UserInfoPrivate::nameChanged, this, &UserInfo::nameChanged); connect(d_ptr.data(), &UserInfoPrivate::uidChanged, this, &UserInfo::uidChanged); connect(d_ptr.data(), &UserInfoPrivate::currentChanged, this, &UserInfo::currentChanged); + connect(d_ptr.data(), &UserInfoPrivate::watchedChanged, this, &UserInfo::watchedChanged); connect(d_ptr.data(), &UserInfoPrivate::aloneChanged, this, &UserInfo::aloneChanged); } void UserInfo::watchForChanges() { Q_D(UserInfo); - d->m_watcher = new QFileSystemWatcher(this); + d->m_watcher = new QFileSystemWatcher(d); QStringList missing = d->m_watcher->addPaths(QStringList() << UserDatabaseFile << GroupDatabaseFile); if (missing.count() == 2) { qCWarning(lcUsersLog) << "Could not watch for changes in user or group database"; @@ -480,27 +519,29 @@ void UserInfo::watchForChanges() } else if (missing.count() > 0) { qCWarning(lcUsersLog) << "Could not watch for changes in" << missing; } else { - connect(d->m_watcher, &QFileSystemWatcher::fileChanged, this, [this] (const QString &path) { - Q_D(UserInfo); - if (QFile::exists(path)) { - if (path == UserDatabaseFile) { - // User database updated, reset model - qCDebug(lcUsersLog) << UserDatabaseFile << "changed, reseting model"; - reset(); - } else if (d->m_alone != UserInfoPrivate::Unknown) { // && path == GroupDatabaseFile - // Group database updated, update alone status - qCDebug(lcUsersLog) << GroupDatabaseFile << "changed, checking alone status again"; - d->updateAlone(); - } - } - if (!d->m_watcher->files().contains(path)) { - if (QFile::exists(path) && d->m_watcher->addPath(path)) { - qCDebug(lcUsersLog) << "Re-watching" << path << "for changes"; - } else { - qCWarning(lcUsersLog) << "Stopped watching" << path << "for changes"; - } - } - }); + connect(d->m_watcher, &QFileSystemWatcher::fileChanged, d, &UserInfoPrivate::databaseChanged); + } +} + +void UserInfoPrivate::databaseChanged(const QString &path) +{ + if (QFile::exists(path)) { + if (path == UserDatabaseFile) { + // User database updated, reset model + qCDebug(lcUsersLog) << "User database changed, updating data"; + set(getpwuid(m_uid)); + } else if (m_alone != Unknown) { // && path == GroupDatabaseFile + // Group database updated, update alone status + qCDebug(lcUsersLog) << "Group database changed, checking alone status again"; + updateAlone(); + } + } + if (!m_watcher->files().contains(path)) { + if (QFile::exists(path) && m_watcher->addPath(path)) { + qCDebug(lcUsersLog) << "Re-watching" << path << "for changes"; + } else { + qCWarning(lcUsersLog) << "Stopped watching" << path << "for changes"; + } } } diff --git a/src/userinfo.h b/src/userinfo.h index 0f8cf3e..b0d019f 100644 --- a/src/userinfo.h +++ b/src/userinfo.h @@ -53,6 +53,7 @@ class SYSTEMSETTINGS_EXPORT UserInfo: public QObject Q_PROPERTY(int uid READ uid WRITE setUid NOTIFY uidChanged) Q_PROPERTY(bool current READ current NOTIFY currentChanged) Q_PROPERTY(bool alone READ alone NOTIFY aloneChanged) + Q_PROPERTY(bool watched READ watched WRITE setWatched NOTIFY watchedChanged) friend class UserModel; @@ -79,6 +80,8 @@ class SYSTEMSETTINGS_EXPORT UserInfo: public QObject void setUid(int uid); bool current() const; bool alone(); + bool watched(); + void setWatched(bool watch); Q_INVOKABLE void reset(); @@ -93,6 +96,7 @@ class SYSTEMSETTINGS_EXPORT UserInfo: public QObject void uidChanged(); void currentChanged(); void aloneChanged(); + void watchedChanged(); private: explicit UserInfo(int uid); diff --git a/src/userinfo_p.h b/src/userinfo_p.h index 4f95773..758b042 100644 --- a/src/userinfo_p.h +++ b/src/userinfo_p.h @@ -67,12 +67,16 @@ class UserInfoPrivate : public QObject bool alone(); void updateAlone(bool force = false); +public slots: + void databaseChanged(const QString &path); + signals: void displayNameChanged(); void usernameChanged(); void nameChanged(); void uidChanged(); void currentChanged(); + void watchedChanged(); void aloneChanged(); };