File indexing completed on 2024-04-28 16:50:01
0001 /* 0002 KSysGuard, the KDE System Guard 0003 0004 SPDX-FileCopyrightText: 2006-2007 John Tapsell <john.tapsell@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef PROCESSMODEL_P_H_ 0010 #define PROCESSMODEL_P_H_ 0011 0012 #include "ProcessModel.h" 0013 #include <processcore/extended_process_list.h> 0014 0015 #include "../config-ksysguard.h" 0016 #include <QDebug> 0017 #include <QHash> 0018 #include <QList> 0019 #include <QObject> 0020 #include <QPixmap> 0021 #include <QSet> 0022 #include <QTime> 0023 #include <QVariant> 0024 #include <kuser.h> 0025 0026 #if HAVE_X11 0027 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0028 #include <private/qtx11extras_p.h> 0029 #else 0030 #include <QX11Info> 0031 #endif 0032 #include <X11/Xatom.h> 0033 #include <X11/Xlib.h> 0034 #include <fixx11h.h> 0035 #include <kwindowsystem.h> 0036 #include <netwm.h> 0037 0038 struct WindowInfo { 0039 WindowInfo(WId _wid, qlonglong _pid) 0040 : wid(_wid) 0041 { 0042 pid = 0; 0043 pid = _pid; 0044 } 0045 qlonglong pid; 0046 QPixmap icon; 0047 WId wid; 0048 QString name; 0049 }; 0050 #endif 0051 0052 namespace KSysGuard 0053 { 0054 class Processes; 0055 } 0056 0057 class ProcessModelPrivate : public QObject 0058 { 0059 Q_OBJECT 0060 public: 0061 ProcessModelPrivate(); 0062 ~ProcessModelPrivate() override; 0063 public Q_SLOTS: 0064 0065 #if HAVE_X11 0066 /** When an X window is changed, this is called */ 0067 void windowChanged(WId wid, NET::Properties properties, NET::Properties2 properties2); 0068 /** When an X window is created, this is called 0069 */ 0070 void windowAdded(WId wid); 0071 /** When an X window is closed, this is called 0072 */ 0073 void windowRemoved(WId wid); 0074 #endif 0075 0076 /** Change the data for a process. This is called from KSysGuard::Processes 0077 * if @p onlyCpuOrMem is set, only the total cpu usage is updated. 0078 * process->changes contains a bitfield of what has been changed 0079 */ 0080 void processChanged(KSysGuard::Process *process, bool onlyCpuOrMem); 0081 /** Called from KSysGuard::Processes 0082 * This indicates we are about to insert a process in the model. Emit the appropriate signals 0083 */ 0084 void beginInsertRow(KSysGuard::Process *parent); 0085 /** Called from KSysGuard::Processes 0086 * We have finished inserting a process 0087 */ 0088 void endInsertRow(); 0089 /** Called from KSysGuard::Processes 0090 * This indicates we are about to remove a process in the model. Emit the appropriate signals 0091 */ 0092 void beginRemoveRow(KSysGuard::Process *process); 0093 /** Called from KSysGuard::Processes 0094 * We have finished removing a process 0095 */ 0096 void endRemoveRow(); 0097 /** Called from KSysGuard::Processes 0098 * This indicates we are about to move a process in the model from one parent process to another. Emit the appropriate signals 0099 */ 0100 void beginMoveProcess(KSysGuard::Process *process, KSysGuard::Process *new_parent); 0101 /** Called from KSysGuard::Processes 0102 * We have finished moving a process 0103 */ 0104 void endMoveRow(); 0105 0106 public: 0107 /** Connects to the host */ 0108 void setupProcesses(); 0109 /** A mapping of running,stopped,etc to a friendly description like 'Stopped, either by a job control signal or because it is being traced.'*/ 0110 QString getStatusDescription(KSysGuard::Process::ProcessStatus status) const; 0111 0112 /** Return a qt markup tooltip string for a local user. It will have their full name etc. 0113 * This will be slow the first time, as it practically indirectly reads the whole of /etc/passwd 0114 * But the second time will be as fast as hash lookup as we cache the result 0115 */ 0116 inline QString getTooltipForUser(const KSysGuard::Process *process) const; 0117 0118 /** Return a username for a local user if it can, otherwise just their uid. 0119 * This may have been given from the result of "ps" (but not necessarily). 0120 * If it's not found, then it needs to find out the username from the uid. 0121 * This will be slow the first time, as it practically indirectly reads the whole of /etc/passwd 0122 * But the second time will be as fast as hash lookup as we cache the result 0123 * 0124 * If withuid is set, and the username is found, return: "username (Uid: uid)" 0125 */ 0126 inline QString getUsernameForUser(long uid, bool withuid) const; 0127 0128 /** Return the groupname for a given gid. This is in the form of "gid" if not known, or 0129 * "groupname (Uid: gid)" if known. 0130 */ 0131 inline QString getGroupnameForGroup(long gid) const; 0132 #if HAVE_X11 0133 /** On X11 system, connects to the signals emitted when windows are created/destroyed */ 0134 void setupWindows(); 0135 void updateWindowInfo(WId wid, NET::Properties properties, NET::Properties2 properties2, bool newWindow); 0136 QMultiHash<long long, WindowInfo *> mPidToWindowInfo; ///< Map a process pid to X window info if available 0137 QHash<WId, WindowInfo *> mWIdToWindowInfo; ///< Map an X window id to window info 0138 #if HAVE_XRES 0139 bool updateXResClientData(); 0140 void queryForAndUpdateAllXWindows(); 0141 #endif 0142 #endif 0143 void timerEvent(QTimerEvent *event) override; ///< Call dataChanged() for all the processes in mPidsToUpdate 0144 /** @see setIsLocalhost */ 0145 bool mIsLocalhost; 0146 0147 /** A caching hash for tooltips for a user. 0148 * @see getTooltipForUser */ 0149 mutable QHash<long long, QString> mUserTooltips; 0150 0151 /** A caching hash for username for a user uid, or just their uid if it can't be found (as a long long) 0152 * @see getUsernameForUser */ 0153 mutable QHash<long long, QString> mUserUsername; 0154 0155 /** A mapping of a user id to whether this user can log in. We have to guess based on the shell. 0156 * All are set to true to non localhost. 0157 * It is set to: 0158 * 0 if the user cannot login 0159 * 1 is the user can login 0160 * The reason for using an int and not a bool is so that we can do 0161 * \code mUidCanLogin.value(uid,-1) \endcode and thus we get a tristate for whether 0162 * they are logged in, not logged in, or not known yet. 0163 * */ 0164 mutable QHash<long long, int> mUidCanLogin; 0165 0166 /** A translated list of headings (column titles) in the order we want to display them. Used in headerData() */ 0167 QStringList mHeadings; 0168 0169 bool mShowChildTotals; ///< If set to true, a parent will return the CPU usage of all its children recursively 0170 0171 bool mSimple; //< In simple mode, the model returns everything as flat, with no icons, etc. This is set by changing cmbFilter 0172 0173 QTime mLastUpdated; ///< Time that we last updated the processes. 0174 0175 long long mMemTotal; ///< the total amount of physical memory in kb in the machine. We can used this to determine the percentage of memory an app is using 0176 int mNumProcessorCores; ///< The number of (enabled) processor cores in the this machine 0177 0178 QSharedPointer<KSysGuard::ExtendedProcesses> mProcesses; ///< The processes instance 0179 0180 QPixmap mBlankPixmap; ///< Used to pad out process names which don't have an icon 0181 0182 /** Show the process command line options in the process name column */ 0183 bool mShowCommandLineOptions; 0184 0185 bool mShowingTooltips; 0186 bool mNormalizeCPUUsage; 0187 /** When displaying memory sizes, this is the units it should be displayed in */ 0188 ProcessModel::Units mUnits; 0189 ProcessModel::Units mIoUnits; 0190 0191 ProcessModel::IoInformation mIoInformation; 0192 0193 /** The hostname */ 0194 QString mHostName; 0195 bool mHaveTimer; 0196 int mTimerId; 0197 QList<long> mPidsToUpdate; ///< A list of pids that we need to emit dataChanged() for regularly 0198 0199 static const int MAX_HIST_ENTRIES = 100; 0200 static const int MIN_HIST_AGE = 200; ///< If the latest history entry is at least this ms old, a new one gets added 0201 /** Storage for the history entries. We need one per percentage column. */ 0202 QHash<KSysGuard::Process *, QVector<ProcessModel::PercentageHistoryEntry>> mMapProcessCPUHistory; 0203 0204 QVector<KSysGuard::ProcessAttribute *> mExtraAttributes; 0205 0206 #if HAVE_XRES 0207 bool mHaveXRes; ///< True if the XRes extension is available at run time 0208 QMap<qlonglong, XID> mXResClientResources; 0209 #endif 0210 0211 bool mMovingRow; 0212 bool mRemovingRow; 0213 bool mInsertingRow; 0214 0215 bool mIsX11; 0216 0217 ProcessModel *q; 0218 }; 0219 0220 #endif