Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Backports:SLE-15-SP1:Update
libksysguard5
0001-Port-scripting-to-Qt-WebEngine.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Port-scripting-to-Qt-WebEngine.patch of Package libksysguard5
From 9c16eca77f731a12d2c9e1a2bcb668c0a5a22c54 Mon Sep 17 00:00:00 2001 From: Fabian Vogt <fabian@ritter-vogt.de> Date: Sat, 1 Sep 2018 18:41:59 +0200 Subject: [PATCH] Port scripting to Qt WebEngine Summary: Unfortunately it relies on Qt WebKit features quite intensely, so a few godawful hacks were necessary to make it work. Most of those are needed to workaround restrictions of QWebChannel as bridge to the browser page. We gain: + Independence from WebKit + Support for newer JS and HTML features in scripts We lose: - Performance (especially memory use) - Independence from WebEngine - Sanity Test Plan: Tested the detailed memory info pages on a few processes, info is correct and the page seems to work fully. Reviewers: #plasma, davidedmundson Reviewed By: #plasma, davidedmundson Subscribers: davidedmundson, plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D15209 --- CMakeLists.txt | 10 +-- config-ksysguard.h.cmake | 4 +- processui/CMakeLists.txt | 4 +- processui/scripting.cpp | 182 +++++++++++++++++++++++++++++---------- processui/scripting.h | 109 ++++++++++++----------- 5 files changed, 204 insertions(+), 105 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e5c73d6..4c39308 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,10 +10,10 @@ find_package(ECM 1.2.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) find_package(Qt5 REQUIRED CONFIG COMPONENTS DBus Network Widgets) -find_package(Qt5WebKitWidgets CONFIG) -set_package_properties(Qt5WebKitWidgets PROPERTIES - URL "git://gitorious.org/qt/qtwebkit.git" - DESCRIPTION "Qt Webkit module (web browsing engine)" +find_package(Qt5WebEngineWidgets ${QT_MIN_VERSION} CONFIG) +set_package_properties(Qt5WebEngineWidgets PROPERTIES + URL "git://code.qt.org/qt/qtwebenginewidgets.git" + DESCRIPTION "Qt WebEngine module (web browsing engine)" TYPE OPTIONAL PURPOSE "Used by the HTML-based GUI ksysguard library" ) @@ -71,7 +71,7 @@ endif() set(HAVE_X11 ${X11_FOUND}) set(HAVE_XRES ${X11_XRes_FOUND}) -set(HAVE_QTWEBKITWIDGETS ${Qt5WebKitWidgets_FOUND}) +set(HAVE_QTWEBENGINEWIDGETS ${Qt5WebEngineWidgets_FOUND}) configure_file(config-ksysguard.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-ksysguard.h ) add_subdirectory( lsofui ) diff --git a/config-ksysguard.h.cmake b/config-ksysguard.h.cmake index e5b8609..ad648f1 100644 --- a/config-ksysguard.h.cmake +++ b/config-ksysguard.h.cmake @@ -10,8 +10,8 @@ /* Define to 1 if you have the X11 xres file */ #cmakedefine HAVE_XRES 1 -/* Define if you have QtWebKitWidgets */ -#cmakedefine01 HAVE_QTWEBKITWIDGETS +/* Define if you have QtWebEngineWidgets */ +#cmakedefine01 HAVE_QTWEBENGINEWIDGETS /* Define if you have X11 at all */ #cmakedefine01 HAVE_X11 diff --git a/processui/CMakeLists.txt b/processui/CMakeLists.txt index 4dfcbd4..54faf93 100644 --- a/processui/CMakeLists.txt +++ b/processui/CMakeLists.txt @@ -53,8 +53,8 @@ if(X11_FOUND) target_link_libraries(processui PRIVATE Qt5::X11Extras KF5::WindowSystem) endif() -if(Qt5WebKitWidgets_FOUND) - target_link_libraries(processui PRIVATE Qt5::WebKitWidgets) +if(Qt5WebEngineWidgets_FOUND) + target_link_libraries(processui PRIVATE Qt5::WebEngineWidgets) endif() if(NOT HAVE_CLOCK_GETTIME_C) diff --git a/processui/scripting.cpp b/processui/scripting.cpp index 9cb1658..68aa579 100644 --- a/processui/scripting.cpp +++ b/processui/scripting.cpp @@ -1,7 +1,8 @@ /* KSysGuard, the KDE System Guard - Copyright (c) 2009 John Tapsell <john.tapsell@kde.org> + Copyright (c) 2009 John Tapsell <john.tapsell@kde.org> + Copyright (c) 2018 Fabian Vogt <fabian@ritter-vogt.de> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -42,11 +43,32 @@ #include <QMessageBox> #include <QDialogButtonBox> -#if HAVE_QTWEBKITWIDGETS -#include <QWebView> -#include <QWebFrame> +#if HAVE_QTWEBENGINEWIDGETS +#include <QWebChannel> +#include <QWebEngineSettings> +#include <QWebEngineView> +#include <QWebEngineProfile> +#include <QWebEngineScriptCollection> +#include <QWebEngineUrlRequestInterceptor> #endif +class RemoteUrlInterceptor : public QWebEngineUrlRequestInterceptor { +public: + RemoteUrlInterceptor(QObject *parent) : QWebEngineUrlRequestInterceptor(parent) {} + void interceptRequest(QWebEngineUrlRequestInfo &info) override + { + // Block non-GET/HEAD requests + if(!QStringList({QStringLiteral("GET"), QStringLiteral("HEAD")}) + .contains(QString::fromLatin1(info.requestMethod()))) + info.block(true); + + // Block remote URLs + if(!QStringList({QStringLiteral("blob"), QStringLiteral("data"), + QStringLiteral("file")}).contains(info.requestUrl().scheme())) + info.block(true); + } +}; + class ScriptingHtmlDialog : public QDialog { public: ScriptingHtmlDialog(QWidget *parent) : QDialog(parent) { @@ -56,44 +78,22 @@ class ScriptingHtmlDialog : public QDialog { connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); -#if HAVE_QTWEBKITWIDGETS +#if HAVE_QTWEBENGINEWIDGETS QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(&m_webView); layout->addWidget(buttonBox); setLayout(layout); - (void)minimumSizeHint(); //Force the dialog to be laid out now layout->setContentsMargins(0,0,0,0); - m_webView.settings()->setOfflineStoragePath(QString()); - m_webView.settings()->setObjectCacheCapacities(0,0,0); - m_webView.settings()->setAttribute(QWebSettings::PluginsEnabled, false); - m_webView.settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, false); - m_webView.page()->setNetworkAccessManager(nullptr); //Disable talking to remote servers - m_webView.page()->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAsNeeded); - m_webView.page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded); - - // inject a style sheet that follows system colors, otherwise we might end up with black text on dark gray background - const QString styleSheet = QStringLiteral( - "body { background: %1; color: %2; }" \ - "a { color: %3; }" \ - "a:visited { color: %4; } " - ).arg(palette().background().color().name(), - palette().text().color().name(), - palette().link().color().name(), - palette().linkVisited().color().name()); - - // you can only provide a user style sheet url, so we turn it into a data url here - const QUrl dataUrl(QStringLiteral("data:text/css;charset=utf-8;base64,") + QString::fromLatin1(styleSheet.toUtf8().toBase64())); - - m_webView.settings()->setUserStyleSheetUrl(dataUrl); - + m_webView.settings()->setAttribute(QWebEngineSettings::PluginsEnabled, false); + m_webView.page()->profile()->setRequestInterceptor(new RemoteUrlInterceptor(this)); #endif } -#if HAVE_QTWEBKITWIDGETS - QWebView *webView() { +#if HAVE_QTWEBENGINEWIDGETS + QWebEngineView *webView() { return &m_webView; } protected: - QWebView m_webView; + QWebEngineView m_webView; #endif }; @@ -127,11 +127,15 @@ void Scripting::runScript(const QString &path, const QString &name) { mScriptPath = path; mScriptName = name; -#if HAVE_QTWEBKITWIDGETS - QUrl fileName = QUrl::fromLocalFile(path + "index.html"); +#if HAVE_QTWEBENGINEWIDGETS + QUrl fileName = QUrl::fromLocalFile(path + QStringLiteral("index.html")); if(!mScriptingHtmlDialog) { mScriptingHtmlDialog = new ScriptingHtmlDialog(this); + mWebChannel = new QWebChannel(mScriptingHtmlDialog); connect(mScriptingHtmlDialog, &QDialog::rejected, this, &Scripting::stopAllScripts); + // Only show after page loaded to allow for layouting + mScriptingHtmlDialog->connect(mScriptingHtmlDialog->webView(), &QWebEngineView::loadFinished, + mScriptingHtmlDialog, &ScriptingHtmlDialog::show); QAction *refreshAction = new QAction(QStringLiteral("refresh"), mScriptingHtmlDialog); refreshAction->setShortcut(QKeySequence::Refresh); @@ -145,23 +149,107 @@ void Scripting::runScript(const QString &path, const QString &name) { mScriptingHtmlDialog->addAction(zoomOutAction); } - //Make the process information available to the script - mScriptingHtmlDialog->webView()->load(fileName); - mScriptingHtmlDialog->show(); - connect(mScriptingHtmlDialog->webView()->page()->mainFrame(), &QWebFrame::javaScriptWindowObjectCleared, this, &Scripting::setupJavascriptObjects); + // Make the process information available to the script + QWebEngineProfile *profile = mScriptingHtmlDialog->webView()->page()->profile(); + QFile webChannelJsFile(QStringLiteral(":/qtwebchannel/qwebchannel.js")); + webChannelJsFile.open(QIODevice::ReadOnly); + QString webChannelJs = QString::fromUtf8(webChannelJsFile.readAll()); + + /* Warning: Awful hack ahead! + * WebChannel does not allow synchonous calls so we need to make + * asynchronous calls synchronous. + * The conversion is achieved by caching the result of all readFile + * and fileExists calls and restarting the script on every result until + * all requests can be fulfilled synchronously. + * Another challenge is that WebEngine does not support reading + * files from /proc over file:// (they are always empty) so we need + * to keep using the ProcessObject helper methods. + */ + webChannelJs.append(QStringLiteral(R"JS( +new QWebChannel(window.qt.webChannelTransport, function(channel) { + window.process = channel.objects.process; + window.process.realReadFile = window.process.readFile; + window.process.realFileExists = window.process.fileExists; + var files = {}; // Map of all read files. null means does not exist + window.process.fileExists = function(name, cb) { + if(cb) return window.process.realFileExists(name, cb); + if (files[name] === null) + return false; // Definitely does not exist + if (typeof(files[name]) == 'string') + return true; // Definitely exists + + window.process.realFileExists(name, function(r) { + if(!r) { + files[name] = null; + refresh(); + return; + } + window.process.realReadFile(name, function(r) { + files[name] = r; + refresh(); + }); + }); + + return true; // Might exist + }; + window.process.readFile = function(name,cb) { + if(cb) return window.process.realReadFile(name, cb); + if (typeof(files[name]) == 'string') + return files[name]; // From cache + + window.process.fileExists(name); // Fill the cache + return ''; + }; + refresh && refresh(); +});)JS")); + + QWebEngineScript webChannelScript; + webChannelScript.setSourceCode(webChannelJs); + webChannelScript.setName(QStringLiteral("qwebchannel.js")); + webChannelScript.setWorldId(QWebEngineScript::MainWorld); + webChannelScript.setInjectionPoint(QWebEngineScript::DocumentCreation); + webChannelScript.setRunsOnSubFrames(false); + + profile->scripts()->insert(webChannelScript); + + // Inject a style sheet that follows system colors, otherwise we might end up with black text on dark gray background + const QString styleSheet = QStringLiteral( + "body { background: %1; color: %2; }" \ + "a { color: %3; }" \ + "a:visited { color: %4; } " + ).arg(palette().background().color().name(), + palette().text().color().name(), + palette().link().color().name(), + palette().linkVisited().color().name()); + + QString styleSheetJs = QStringLiteral("\nvar node = document.createElement('style');" + "node.innerHTML = '%1';" + "document.body.appendChild(node);").arg(styleSheet); + + QWebEngineScript styleSheetScript; + styleSheetScript.setSourceCode(styleSheetJs); + styleSheetScript.setName(QStringLiteral("stylesheet.js")); + styleSheetScript.setWorldId(QWebEngineScript::MainWorld); + styleSheetScript.setInjectionPoint(QWebEngineScript::DocumentReady); + styleSheetScript.setRunsOnSubFrames(false); + + profile->scripts()->insert(styleSheetScript); + setupJavascriptObjects(); + + mScriptingHtmlDialog->webView()->load(fileName); #else - QMessageBox::critical(this, i18n("QtWebKitWidgets not available"), - i18n("KSysGuard library was compiled without QtWebKitWidgets, please contact your distribution.")); + QMessageBox::critical(this, i18n("QtWebEngineWidgets not available"), + i18n("KSysGuard library was compiled without QtWebEngineWidgets, please contact your distribution.")); #endif } -#if HAVE_QTWEBKITWIDGETS +#if HAVE_QTWEBENGINEWIDGETS void Scripting::zoomIn() { - QWebView *webView = mScriptingHtmlDialog->webView(); + QWebEngineView *webView = mScriptingHtmlDialog->webView(); webView->setZoomFactor( webView->zoomFactor() * 1.1 ); } void Scripting::zoomOut() { - QWebView *webView = mScriptingHtmlDialog->webView(); + QWebEngineView *webView = mScriptingHtmlDialog->webView(); if(webView->zoomFactor() > 0.1) //Prevent it getting too small webView->setZoomFactor( webView->zoomFactor() / 1.1 ); } @@ -169,14 +257,16 @@ void Scripting::zoomOut() { void Scripting::refreshScript() { //Call any refresh function, if it exists mProcessList->processModel()->update(0, KSysGuard::Processes::XMemory); - if(mScriptingHtmlDialog && mScriptingHtmlDialog->webView() && mScriptingHtmlDialog->webView()->page() && mScriptingHtmlDialog->webView()->page()->mainFrame()) { - mScriptingHtmlDialog->webView()->page()->mainFrame()->evaluateJavaScript(QStringLiteral("refresh();")); + mProcessObject->anythingChanged(); + if(mScriptingHtmlDialog && mScriptingHtmlDialog->webView() && mScriptingHtmlDialog->webView()->page()) { + mScriptingHtmlDialog->webView()->page()->runJavaScript(QStringLiteral("refresh && refresh();")); } } void Scripting::setupJavascriptObjects() { mProcessList->processModel()->update(0, KSysGuard::Processes::XMemory); mProcessObject = new ProcessObject(mProcessList->processModel(), mPid); - mScriptingHtmlDialog->webView()->page()->mainFrame()->addToJavaScriptWindowObject(QStringLiteral("process"), mProcessObject, QWebFrame::ScriptOwnership); + mWebChannel->registerObject(QStringLiteral("process"), mProcessObject); + mScriptingHtmlDialog->webView()->page()->setWebChannel(mWebChannel); } #endif void Scripting::stopAllScripts() diff --git a/processui/scripting.h b/processui/scripting.h index 2a02f26..70fb2cb 100644 --- a/processui/scripting.h +++ b/processui/scripting.h @@ -34,6 +34,7 @@ class QAction; class ScriptingHtmlDialog; //Defined in scripting.cpp file class KSysGuardProcessList; class ProcessObject; +class QWebChannel; class Scripting : public QWidget { Q_OBJECT @@ -55,7 +56,7 @@ class Scripting : public QWidget { private Q_SLOTS: /** Run the script associated with the QAction that called this slot */ void runScriptSlot(); -#if HAVE_QTWEBKITWIDGETS +#if HAVE_QTWEBENGINEWIDGETS void setupJavascriptObjects(); void refreshScript(); void zoomIn(); @@ -64,6 +65,8 @@ class Scripting : public QWidget { private: /** This is created on the fly as needed, and deleted when no longer used */ ScriptingHtmlDialog *mScriptingHtmlDialog; + /** Used to expose mProcessObject to the WebEnginePage */ + QWebChannel *mWebChannel; /** The parent process list to script for */ KSysGuardProcessList * const mProcessList; /** List of context menu actions that are created by loadContextMenu() */ @@ -75,60 +78,62 @@ class Scripting : public QWidget { qlonglong mPid; }; +// QWebChannel only reloads properties on demand, so we need a signal. +#define P_PROPERTY(x) Q_PROPERTY(x NOTIFY anythingChanged) #define PROPERTY(Type,Name) Type Name() const { KSysGuard::Process *process = mModel->getProcess(mPid); if(process) return process->Name(); else return Type();} class ProcessObject : public QObject { Q_OBJECT public: - Q_PROPERTY(qlonglong pid READ pid WRITE setPid) /* Add functionality to 'set' the pid to change which process to read from */ - Q_PROPERTY(qlonglong ppid READ parentPid) /* Map 'ppid' to 'parentPid' to give it a nicer scripting name */ - Q_PROPERTY(QString name READ name) /* Defined below to return the first word of the name */ - Q_PROPERTY(QString fullname READ fullname) /* Defined below to return 'name' */ - Q_PROPERTY(qlonglong rss READ vmRSS) /* Map 'rss' to 'vmRSS' just to give it a nicer scripting name */ - Q_PROPERTY(qlonglong urss READ vmURSS) /* Map 'urss' to 'vmURSS' just to give it a nicer scripting name */ - Q_PROPERTY(int numThreads READ numThreads) PROPERTY(int, numThreads) - Q_PROPERTY(qlonglong fsgid READ fsgid) PROPERTY(qlonglong, fsgid) - Q_PROPERTY(qlonglong parentPid READ parentPid) PROPERTY(qlonglong, parentPid) - Q_PROPERTY(QString login READ login) PROPERTY(QString, login) - Q_PROPERTY(qlonglong uid READ uid) PROPERTY(qlonglong, uid) - Q_PROPERTY(qlonglong euid READ euid) PROPERTY(qlonglong, euid) - Q_PROPERTY(qlonglong suid READ suid) PROPERTY(qlonglong, suid) - Q_PROPERTY(qlonglong fsuid READ fsuid) PROPERTY(qlonglong, fsuid) - Q_PROPERTY(qlonglong gid READ gid) PROPERTY(qlonglong, gid) - Q_PROPERTY(qlonglong egid READ egid) PROPERTY(qlonglong, egid) - Q_PROPERTY(qlonglong sgid READ sgid) PROPERTY(qlonglong, sgid) - Q_PROPERTY(qlonglong tracerpid READ tracerpid) PROPERTY(qlonglong, tracerpid) - Q_PROPERTY(QByteArray tty READ tty) PROPERTY(QByteArray, tty) - Q_PROPERTY(qlonglong userTime READ userTime) PROPERTY(qlonglong, userTime) - Q_PROPERTY(qlonglong sysTime READ sysTime) PROPERTY(qlonglong, sysTime) - Q_PROPERTY(int userUsage READ userUsage) PROPERTY(int, userUsage) - Q_PROPERTY(int sysUsage READ sysUsage) PROPERTY(int, sysUsage) - Q_PROPERTY(int totalUserUsage READ totalUserUsage) PROPERTY(int, totalUserUsage) - Q_PROPERTY(int totalSysUsage READ totalSysUsage) PROPERTY(int, totalSysUsage) - Q_PROPERTY(int numChildren READ numChildren) PROPERTY(int, numChildren) - Q_PROPERTY(int niceLevel READ niceLevel) PROPERTY(int, niceLevel) - Q_PROPERTY(int scheduler READ scheduler) PROPERTY(int, scheduler) - Q_PROPERTY(int ioPriorityClass READ ioPriorityClass) PROPERTY(int, ioPriorityClass) - Q_PROPERTY(int ioniceLevel READ ioniceLevel) PROPERTY(int, ioniceLevel) - Q_PROPERTY(qlonglong vmSize READ vmSize) PROPERTY(qlonglong, vmSize) - Q_PROPERTY(qlonglong vmRSS READ vmRSS) PROPERTY(qlonglong, vmRSS) - Q_PROPERTY(qlonglong vmURSS READ vmURSS) PROPERTY(qlonglong, vmURSS) - Q_PROPERTY(qlonglong pixmapBytes READ pixmapBytes) PROPERTY(qlonglong, pixmapBytes) - Q_PROPERTY(bool hasManagedGuiWindow READ hasManagedGuiWindow) PROPERTY(bool, hasManagedGuiWindow) - Q_PROPERTY(QString command READ command) PROPERTY(QString, command) - Q_PROPERTY(qlonglong status READ status) PROPERTY(qlonglong, status) - Q_PROPERTY(qlonglong ioCharactersRead READ ioCharactersRead) PROPERTY(qlonglong, ioCharactersRead) - Q_PROPERTY(qlonglong ioCharactersWritten READ ioCharactersWritten) PROPERTY(qlonglong, ioCharactersWritten) - Q_PROPERTY(qlonglong ioReadSyscalls READ ioReadSyscalls) PROPERTY(qlonglong, ioReadSyscalls) - Q_PROPERTY(qlonglong ioWriteSyscalls READ ioWriteSyscalls) PROPERTY(qlonglong, ioWriteSyscalls) - Q_PROPERTY(qlonglong ioCharactersActuallyRead READ ioCharactersActuallyRead) PROPERTY(qlonglong, ioCharactersActuallyRead) - Q_PROPERTY(qlonglong ioCharactersActuallyWritten READ ioCharactersActuallyWritten) PROPERTY(qlonglong, ioCharactersActuallyWritten) - Q_PROPERTY(qlonglong ioCharactersReadRate READ ioCharactersReadRate) PROPERTY(qlonglong, ioCharactersReadRate) - Q_PROPERTY(qlonglong ioCharactersWrittenRate READ ioCharactersWrittenRate) PROPERTY(qlonglong, ioCharactersWrittenRate) - Q_PROPERTY(qlonglong ioReadSyscallsRate READ ioReadSyscallsRate) PROPERTY(qlonglong, ioReadSyscallsRate) - Q_PROPERTY(qlonglong ioWriteSyscallsRate READ ioWriteSyscallsRate) PROPERTY(qlonglong, ioWriteSyscallsRate) - Q_PROPERTY(qlonglong ioCharactersActuallyReadRate READ ioCharactersActuallyReadRate) PROPERTY(qlonglong, ioCharactersActuallyReadRate) - Q_PROPERTY(qlonglong ioCharactersActuallyWrittenRate READ ioCharactersActuallyWrittenRate) PROPERTY(qlonglong, ioCharactersActuallyWrittenRate) + P_PROPERTY(qlonglong pid READ pid WRITE setPid) /* Add functionality to 'set' the pid to change which process to read from */ + P_PROPERTY(qlonglong ppid READ parentPid) /* Map 'ppid' to 'parentPid' to give it a nicer scripting name */ + P_PROPERTY(QString name READ name) /* Defined below to return the first word of the name */ + P_PROPERTY(QString fullname READ fullname) /* Defined below to return 'name' */ + P_PROPERTY(qlonglong rss READ vmRSS) /* Map 'rss' to 'vmRSS' just to give it a nicer scripting name */ + P_PROPERTY(qlonglong urss READ vmURSS) /* Map 'urss' to 'vmURSS' just to give it a nicer scripting name */ + P_PROPERTY(int numThreads READ numThreads) PROPERTY(int, numThreads) + P_PROPERTY(qlonglong fsgid READ fsgid) PROPERTY(qlonglong, fsgid) + P_PROPERTY(qlonglong parentPid READ parentPid) PROPERTY(qlonglong, parentPid) + P_PROPERTY(QString login READ login) PROPERTY(QString, login) + P_PROPERTY(qlonglong uid READ uid) PROPERTY(qlonglong, uid) + P_PROPERTY(qlonglong euid READ euid) PROPERTY(qlonglong, euid) + P_PROPERTY(qlonglong suid READ suid) PROPERTY(qlonglong, suid) + P_PROPERTY(qlonglong fsuid READ fsuid) PROPERTY(qlonglong, fsuid) + P_PROPERTY(qlonglong gid READ gid) PROPERTY(qlonglong, gid) + P_PROPERTY(qlonglong egid READ egid) PROPERTY(qlonglong, egid) + P_PROPERTY(qlonglong sgid READ sgid) PROPERTY(qlonglong, sgid) + P_PROPERTY(qlonglong tracerpid READ tracerpid) PROPERTY(qlonglong, tracerpid) + P_PROPERTY(QByteArray tty READ tty) PROPERTY(QByteArray, tty) + P_PROPERTY(qlonglong userTime READ userTime) PROPERTY(qlonglong, userTime) + P_PROPERTY(qlonglong sysTime READ sysTime) PROPERTY(qlonglong, sysTime) + P_PROPERTY(int userUsage READ userUsage) PROPERTY(int, userUsage) + P_PROPERTY(int sysUsage READ sysUsage) PROPERTY(int, sysUsage) + P_PROPERTY(int totalUserUsage READ totalUserUsage) PROPERTY(int, totalUserUsage) + P_PROPERTY(int totalSysUsage READ totalSysUsage) PROPERTY(int, totalSysUsage) + P_PROPERTY(int numChildren READ numChildren) PROPERTY(int, numChildren) + P_PROPERTY(int niceLevel READ niceLevel) PROPERTY(int, niceLevel) + P_PROPERTY(int scheduler READ scheduler) PROPERTY(int, scheduler) + P_PROPERTY(int ioPriorityClass READ ioPriorityClass) PROPERTY(int, ioPriorityClass) + P_PROPERTY(int ioniceLevel READ ioniceLevel) PROPERTY(int, ioniceLevel) + P_PROPERTY(qlonglong vmSize READ vmSize) PROPERTY(qlonglong, vmSize) + P_PROPERTY(qlonglong vmRSS READ vmRSS) PROPERTY(qlonglong, vmRSS) + P_PROPERTY(qlonglong vmURSS READ vmURSS) PROPERTY(qlonglong, vmURSS) + P_PROPERTY(qlonglong pixmapBytes READ pixmapBytes) PROPERTY(qlonglong, pixmapBytes) + P_PROPERTY(bool hasManagedGuiWindow READ hasManagedGuiWindow) PROPERTY(bool, hasManagedGuiWindow) + P_PROPERTY(QString command READ command) PROPERTY(QString, command) + P_PROPERTY(qlonglong status READ status) PROPERTY(qlonglong, status) + P_PROPERTY(qlonglong ioCharactersRead READ ioCharactersRead) PROPERTY(qlonglong, ioCharactersRead) + P_PROPERTY(qlonglong ioCharactersWritten READ ioCharactersWritten) PROPERTY(qlonglong, ioCharactersWritten) + P_PROPERTY(qlonglong ioReadSyscalls READ ioReadSyscalls) PROPERTY(qlonglong, ioReadSyscalls) + P_PROPERTY(qlonglong ioWriteSyscalls READ ioWriteSyscalls) PROPERTY(qlonglong, ioWriteSyscalls) + P_PROPERTY(qlonglong ioCharactersActuallyRead READ ioCharactersActuallyRead) PROPERTY(qlonglong, ioCharactersActuallyRead) + P_PROPERTY(qlonglong ioCharactersActuallyWritten READ ioCharactersActuallyWritten) PROPERTY(qlonglong, ioCharactersActuallyWritten) + P_PROPERTY(qlonglong ioCharactersReadRate READ ioCharactersReadRate) PROPERTY(qlonglong, ioCharactersReadRate) + P_PROPERTY(qlonglong ioCharactersWrittenRate READ ioCharactersWrittenRate) PROPERTY(qlonglong, ioCharactersWrittenRate) + P_PROPERTY(qlonglong ioReadSyscallsRate READ ioReadSyscallsRate) PROPERTY(qlonglong, ioReadSyscallsRate) + P_PROPERTY(qlonglong ioWriteSyscallsRate READ ioWriteSyscallsRate) PROPERTY(qlonglong, ioWriteSyscallsRate) + P_PROPERTY(qlonglong ioCharactersActuallyReadRate READ ioCharactersActuallyReadRate) PROPERTY(qlonglong, ioCharactersActuallyReadRate) + P_PROPERTY(qlonglong ioCharactersActuallyWrittenRate READ ioCharactersActuallyWrittenRate) PROPERTY(qlonglong, ioCharactersActuallyWrittenRate) ProcessObject(ProcessModel * processModel, int pid); void update(KSysGuard::Process *process); @@ -141,6 +146,10 @@ class ProcessObject : public QObject { public Q_SLOTS: bool fileExists(const QString &filename); QString readFile(const QString &filename); + + Q_SIGNALS: + void anythingChanged(); + private: int mPid; ProcessModel *mModel; -- 2.18.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor