├── .gitignore ├── Changes.md ├── LICENSE ├── README.md ├── data ├── database │ ├── 20-sdio-vendor-model.hwdb │ ├── arm.ids │ ├── database_license.txt │ ├── meson.build │ └── sdcard.ids ├── generate_man_gz.sh ├── icons │ ├── hicolor │ │ └── scalable │ │ │ ├── actions │ │ │ ├── system-monitoring-center-cpu-symbolic.svg │ │ │ ├── system-monitoring-center-disk-hdd-symbolic.svg │ │ │ ├── system-monitoring-center-fan-symbolic.svg │ │ │ ├── system-monitoring-center-graphics-card-symbolic.svg │ │ │ ├── system-monitoring-center-network-symbolic.svg │ │ │ ├── system-monitoring-center-performance-symbolic.svg │ │ │ ├── system-monitoring-center-process-symbolic.svg │ │ │ ├── system-monitoring-center-ram-symbolic.svg │ │ │ ├── system-monitoring-center-services-symbolic.svg │ │ │ ├── system-monitoring-center-system-symbolic.svg │ │ │ ├── system-monitoring-center-temperature-symbolic.svg │ │ │ ├── system-monitoring-center-user-symbolic.svg │ │ │ └── system-monitoring-center-voltage-symbolic.svg │ │ │ └── apps │ │ │ ├── io.github.hakandundar34coding.system-monitoring-center.svg │ │ │ └── system-monitoring-center.svg │ └── meson.build ├── io.github.hakandundar34coding.system-monitoring-center.appdata.xml.in ├── io.github.hakandundar34coding.system-monitoring-center.desktop.in ├── io.github.hakandundar34coding.system-monitoring-center.policy ├── meson.build └── system-monitoring-center.1 ├── debian ├── changelog ├── control ├── copyright ├── rules ├── source │ └── format └── system-monitoring-center.lintian-overrides ├── docs ├── Notes_About_Pardus_Image.txt ├── download_image_pardus.svg ├── flatpak.md ├── translations.md └── uninstall_pypi_package.md ├── io.github.hakandundar34coding.system-monitoring-center.yml ├── meson.build ├── po ├── LINGUAS ├── POTFILES.in ├── command_compile_all.py ├── command_get_text.py ├── cs.po ├── de.po ├── es.po ├── fa.po ├── fr.po ├── hu.po ├── locale │ ├── cs │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ ├── de │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ ├── es │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ ├── fa │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ ├── fr │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ ├── hu │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ ├── pl │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ ├── pt_BR │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ ├── pt_PT │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ ├── ru_RU │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ ├── tr │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ ├── zh_CN │ │ └── LC_MESSAGES │ │ │ └── system-monitoring-center.mo │ └── zh_TW │ │ └── LC_MESSAGES │ │ └── system-monitoring-center.mo ├── meson.build ├── pl.po ├── pt_BR.po ├── pt_PT.po ├── ru_RU.po ├── system-monitoring-center.pot ├── tr.po ├── zh_CN.po └── zh_TW.po ├── screenshots ├── cpu_tab_dark_system_theme.png ├── cpu_tab_per_core_dark_system_theme.png ├── cpu_tab_white_system_theme.png ├── disk_tab_menu_white_system_theme.png ├── gpu_tab_dark_system_theme.png ├── memory_tab_white_system_theme.png ├── network_tab_dark_system_theme.png ├── process_details__dark_system_theme_1.png ├── process_details__dark_system_theme_2.png ├── processes_list_view_dark_system_theme.png ├── processes_tree_view_white_system_theme.png ├── sensors_tab_dark_system_theme.png ├── services_tab_dark_system_theme.png ├── settings_dark_system_theme.png ├── summary_tab_dark_system_theme.png ├── summary_tab_white_system_theme.png └── system_tab_dark_system_theme.png └── src ├── Common.py ├── Config.py ├── Cpu.py ├── CpuMenu.py ├── Disk.py ├── DiskMenu.py ├── Gpu.py ├── GpuMenu.py ├── Libsysmon.py ├── Main.py ├── MainWindow.py ├── Memory.py ├── MemoryMenu.py ├── Network.py ├── NetworkMenu.py ├── Performance.py ├── Processes.py ├── ProcessesDetails.py ├── ProcessesMenu.py ├── Sensors.py ├── SensorsMenu.py ├── Services.py ├── ServicesDetails.py ├── ServicesMenu.py ├── SettingsWindow.py ├── Summary.py ├── SummaryMenu.py ├── System.py ├── Users.py ├── UsersDetails.py ├── UsersMenu.py ├── __init__.py ├── __version__ ├── meson.build ├── run_from_source.py └── system-monitoring-center.in /.gitignore: -------------------------------------------------------------------------------- 1 | .flatpak-builder/ 2 | build-dir/ 3 | dist/ 4 | *.egg-info/ 5 | .git/ 6 | 7 | #PyCharm 8 | *.idea 9 | 10 | #Visual Studio Code 11 | *.vscode 12 | 13 | # Glade temporary files 14 | *.glade~ 15 | *.ui~ 16 | 17 | # Byte-compiled / optimized / DLL files 18 | __pycache__/ 19 | *.py[cod] 20 | *$py.class 21 | 22 | # Environments 23 | .env 24 | .venv 25 | env/ 26 | venv/ 27 | ENV/ 28 | env.bak/ 29 | venv.bak/ 30 | 31 | # Spyder project settings 32 | .spyderproject 33 | .spyproject 34 | 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # System Monitoring Center 2 | 3 |

4 | 5 |

6 | 7 | 8 |

9 | 10 | Multi-featured system monitor 11 | 12 |

13 | 14 | 15 |

16 | 17 | *** Announcement (31.10.2023): End of support for System Monitoring Center v2.x.x. The project is ended. System Monitoring Center 12.2020-10.2023. *** 18 | 19 |

20 | 21 | 22 |

23 | 24 | Platform (GNU/Linux) 25 | 26 | 27 | GitHub tag (latest SemVer) 28 | 29 | 30 | GitHub all releases 31 | 32 | 33 | 34 | 35 | 36 | Flathub 37 | 38 | 39 | 40 | 41 |

42 | 43 | 44 |

45 | 46 | 47 | 48 | 49 | 50 | 51 |

52 | 53 | 54 |

55 | 56 | Translations: 57 | 58 | Chinese (Simplified) | Chinese (Traditional) | Czech | German | English | French | Hungarian | Persian | Polish | Portuguese (Brazilian) | Portuguese (Portugal) | Russian | Spanish | Turkish | Notes for translators 59 |

60 | 61 | 62 |

63 | 64 | Download on Flathub 65 | 66 | 67 | Install From Pardus Software Center 68 | 69 | 70 | Install From Pi-Apps 71 | 72 |

73 | 74 | 75 |

76 | 77 | Packaging status 78 | 79 |

80 |

81 | 82 | Flathub 83 | 84 | 85 | Pi-Apps Packaging Status 86 | 87 |

88 | 89 | 90 | ### Features: 91 | - Detailed system performance and usage usage monitoring/managing features: 92 | - Monitoring CPU, RAM, Disk, Network, GPU hardware/usage information 93 | - Monitoring and managing processes and services (systemd) 94 | - Monitoring users, sensors and general system information 95 | - Supports PolicyKit. No need to run the application with "sudo" 96 | - Hardware selection options (selecting CPU cores, disks, network cards, GPUs) 97 | - Plotting performance data of multiple devices at the same time 98 | - Interactive charts for querying performance data on any point 99 | - Option for showing processes as tree or list 100 | - Optimized for low CPU usage 101 | - Customization menus for almost all tabs 102 | - Supports ARM architecture 103 | - Hardware accelerated GUI 104 | - Free and open source 105 | 106 | 107 | ### Installation: 108 | - There are several options for using System Monitoring Center: 109 | - Installing from Flatpak ([Details](docs/flatpak.md)) 110 | - Installing from application stores (Pardus Application Center, Pi-Apps Store) 111 | - Installing from repositories of distributions 112 | - ~~Installing from PyPI as a Python package.~~ There will be no new packages on PyPI ([Details](docs/uninstall_pypi_package.md)) 113 | - Running from source code: 114 | - For SMC v2: in ```src/``` folder, run: ```python3 ./run_from_source.py``` 115 | - For SMC v1: in ```src/``` folder, run: ```python3 ./Main.py``` 116 | 117 | 118 | ### Dependencies: 119 |
120 | Show 121 | 122 | --- 123 | #### Dependencies 124 | 125 | There is no need to install these dependencies for installing the application from Flatpak. 126 | For other installation types: 127 | 128 | - For System Monitoring Center v2.x.x: 129 | - `dmidecode, gir1.2-adw-1, gir1.2-glib-2.0, gir1.2-gtk-4.0, gir1.2-pango-1.0, hwdata, iproute2, python3 (>=3.6), python3-cairo, python3-gi, python3-gi-cairo, util-linux (>=2.31)` 130 | 131 | - For System Monitoring Center v1.x.x: 132 | - `dmidecode, hwdata, iproute2, procps (>=3.3), python3 (>=3.6), python3-cairo, python3-gi, python3-gi-cairo, util-linux (>=2.31)` 133 | 134 | - Following dependencies may be required on some systems: 135 | - `libcairo2-dev` (for systems with .deb packages) 136 | - `polkit` (for Arch Linux) 137 | 138 | - Optional dependencies: 139 | - `vcgencmd` (for physical RAM size, GPU frequency and video memory information on Raspberry Pi devices) 140 | - `x11-xserver-utils` or `xorg-xrandr` (for more accurate screen resolution and refresh rate detection of System Monitoring Center v1.x.x) 141 | --- 142 | 143 |
144 | 145 | 146 | ### Limitations and Known Issues: 147 |
148 | Show 149 | 150 | --- 151 | #### Limitations 152 | 153 | - GPU usage information availability depends on vendor/driver. 154 | - GPU load is not tracked if GPU tab is switched off (for lower CPU usage). 155 | - Virtual machines may not provide CPU min-max frequencies, sensors and RAM hardware information. 156 | - Non-Flatpak versions of the application has higher performance (start speed, CPU, RAM usage). 157 | - GTK4 (used for SMC v2) consumes about 2x RAM when compared to GTK3 (used for SMC v1). 158 | - Running SMC v1 after SMC v2 resets application settings 159 | 160 | #### Known Issues 161 | 162 | - Expander/Collapser arrows do not work sometimes if processes are listes as tree (Processes tab). 163 | Issue 164 | 165 | - Tab customization menus are not closed when clicked outside of the popover menu after using a dropdown menu on the popover menu. 166 | - This is a GTK4 bug. These menus can be closed by using `Esc` key. 167 | --- 168 | 169 |
170 | 171 | 172 | ### Screenshots: 173 | 174 | ![System Monitoring Center](screenshots/summary_tab_dark_system_theme.png) 175 | 176 | ![System Monitoring Center](screenshots/summary_tab_white_system_theme.png) 177 | 178 | ![System Monitoring Center](screenshots/cpu_tab_dark_system_theme.png) 179 | 180 | ![System Monitoring Center](screenshots/cpu_tab_white_system_theme.png) 181 | 182 | ![System Monitoring Center](screenshots/cpu_tab_per_core_dark_system_theme.png) 183 | 184 | ![System Monitoring Center](screenshots/memory_tab_white_system_theme.png) 185 | 186 | ![System Monitoring Center](screenshots/disk_tab_menu_white_system_theme.png) 187 | 188 | ![System Monitoring Center](screenshots/network_tab_dark_system_theme.png) 189 | 190 | ![System Monitoring Center](screenshots/gpu_tab_dark_system_theme.png) 191 | 192 | ![System Monitoring Center](screenshots/sensors_tab_dark_system_theme.png) 193 | 194 | ![System Monitoring Center](screenshots/processes_list_view_dark_system_theme.png) 195 | 196 | ![System Monitoring Center](screenshots/processes_tree_view_white_system_theme.png) 197 | 198 | ![System Monitoring Center](screenshots/services_tab_dark_system_theme.png) 199 | 200 | ![System Monitoring Center](screenshots/system_tab_dark_system_theme.png) 201 | 202 | ![System Monitoring Center](screenshots/settings_dark_system_theme.png) 203 | 204 | ![System Monitoring Center](screenshots/process_details__dark_system_theme_1.png) 205 | 206 | ![System Monitoring Center](screenshots/process_details__dark_system_theme_2.png) 207 | 208 | -------------------------------------------------------------------------------- /data/database/20-sdio-vendor-model.hwdb: -------------------------------------------------------------------------------- 1 | # This file is part of systemd. 2 | # 3 | # Data imported from: hwdb.d/sdio.ids 4 | 5 | sdio:c*v0020* 6 | ID_VENDOR_FROM_DATABASE=ST-Ericsson 7 | 8 | sdio:c*v0020d2280* 9 | ID_MODEL_FROM_DATABASE=CW1200 10 | 11 | sdio:c*v0089* 12 | ID_VENDOR_FROM_DATABASE=Intel Corp. 13 | 14 | sdio:c*v0092* 15 | ID_VENDOR_FROM_DATABASE=C-guys, Inc. 16 | 17 | sdio:c*v0092d0001* 18 | ID_MODEL_FROM_DATABASE=SD-Link11b WiFi Card (TI ACX100) 19 | 20 | sdio:c*v0092d0004* 21 | ID_MODEL_FROM_DATABASE=EW-CG1102GC 22 | 23 | sdio:c*v0092d0005* 24 | ID_MODEL_FROM_DATABASE=SD FM Radio 2 25 | 26 | sdio:c*v0092d5544* 27 | ID_MODEL_FROM_DATABASE=SD FM Radio 28 | 29 | sdio:c*v0097* 30 | ID_VENDOR_FROM_DATABASE=Texas Instruments, Inc. 31 | 32 | sdio:c*v0097d4076* 33 | ID_MODEL_FROM_DATABASE=WL1271 34 | 35 | sdio:c*v0098* 36 | ID_VENDOR_FROM_DATABASE=Toshiba Corp. 37 | 38 | sdio:c*v0098d0001* 39 | ID_MODEL_FROM_DATABASE=SD BT Card 1 40 | 41 | sdio:c*v0098d0002* 42 | ID_MODEL_FROM_DATABASE=SD BT Card 2 43 | 44 | sdio:c*v0098d0003* 45 | ID_MODEL_FROM_DATABASE=SD BT Card 3 46 | 47 | sdio:c*v0104* 48 | ID_VENDOR_FROM_DATABASE=Socket Communications, Inc. 49 | 50 | sdio:c*v0104d005E* 51 | ID_MODEL_FROM_DATABASE=SD Scanner 52 | 53 | sdio:c*v0104d00C5* 54 | ID_MODEL_FROM_DATABASE=Bluetooth SDIO Card 55 | 56 | sdio:c*v0271* 57 | ID_VENDOR_FROM_DATABASE=Atheros Communications, Inc. 58 | 59 | sdio:c*v0271d0108* 60 | ID_MODEL_FROM_DATABASE=AR6001 61 | 62 | sdio:c*v0271d0109* 63 | ID_MODEL_FROM_DATABASE=AR6001 64 | 65 | sdio:c*v0271d010A* 66 | ID_MODEL_FROM_DATABASE=AR6001 67 | 68 | sdio:c*v0271d010B* 69 | ID_MODEL_FROM_DATABASE=AR6001 70 | 71 | sdio:c*v0296* 72 | ID_VENDOR_FROM_DATABASE=GCT Semiconductor, Inc. 73 | 74 | sdio:c*v0296d5347* 75 | ID_MODEL_FROM_DATABASE=GDM72xx WiMAX 76 | 77 | sdio:c*v02D0* 78 | ID_VENDOR_FROM_DATABASE=Broadcom Corp. 79 | 80 | sdio:c*v02D0d044B* 81 | ID_MODEL_FROM_DATABASE=Nintendo Wii WLAN daughter card 82 | 83 | sdio:c*v02D0d4324* 84 | ID_MODEL_FROM_DATABASE=BCM43241 WLAN card 85 | 86 | sdio:c*v02D0d4329* 87 | ID_MODEL_FROM_DATABASE=BCM4329 WLAN card 88 | 89 | sdio:c*v02D0d4330* 90 | ID_MODEL_FROM_DATABASE=BCM4330 WLAN card 91 | 92 | sdio:c*v02D0d4334* 93 | ID_MODEL_FROM_DATABASE=BCM4334 WLAN card 94 | 95 | sdio:c*v02D0d4335* 96 | ID_MODEL_FROM_DATABASE=BCM4335/BCM4339 WLAN card 97 | 98 | sdio:c*v02D0d4354* 99 | ID_MODEL_FROM_DATABASE=BCM4354 WLAN card 100 | 101 | sdio:c*v02D0dA887* 102 | ID_MODEL_FROM_DATABASE=BCM43143 WLAN card 103 | 104 | sdio:c*v02D0dA94C* 105 | ID_MODEL_FROM_DATABASE=BCM43340 WLAN card 106 | 107 | sdio:c*v02D0dA94D* 108 | ID_MODEL_FROM_DATABASE=BCM43341 WLAN card 109 | 110 | sdio:c*v02D0dA962* 111 | ID_MODEL_FROM_DATABASE=BCM43362 WLAN card 112 | 113 | sdio:c*v02D0dA9A6* 114 | ID_MODEL_FROM_DATABASE=BCM43438 combo WLAN and Bluetooth Low Energy (BLE) # As in RPi3B 115 | 116 | sdio:c*v02DB* 117 | ID_VENDOR_FROM_DATABASE=SyChip Inc. 118 | 119 | sdio:c*v02DBd0002* 120 | ID_MODEL_FROM_DATABASE=Pegasus WLAN SDIO Card (6060SD) 121 | 122 | sdio:c*v02DF* 123 | ID_VENDOR_FROM_DATABASE=Marvell Technology Group Ltd. 124 | 125 | sdio:c*v02DFd9103* 126 | ID_MODEL_FROM_DATABASE=Libertas 127 | 128 | sdio:c*v02DFd9104* 129 | ID_MODEL_FROM_DATABASE=SD8688 WLAN 130 | 131 | sdio:c*v02DFd9105* 132 | ID_MODEL_FROM_DATABASE=SD8688 BT 133 | 134 | sdio:c*v02DFd9116* 135 | ID_MODEL_FROM_DATABASE=SD8786 WLAN 136 | 137 | sdio:c*v02DFd9119* 138 | ID_MODEL_FROM_DATABASE=SD8787 WLAN 139 | 140 | sdio:c*v02DFd911A* 141 | ID_MODEL_FROM_DATABASE=SD8787 BT 142 | 143 | sdio:c*v02DFd911B* 144 | ID_MODEL_FROM_DATABASE=SD8787 BT AMP 145 | 146 | sdio:c*v02DFd9129* 147 | ID_MODEL_FROM_DATABASE=SD8797 WLAN 148 | 149 | sdio:c*v02DFd912A* 150 | ID_MODEL_FROM_DATABASE=SD8797 BT 151 | 152 | sdio:c*v02DFd912D* 153 | ID_MODEL_FROM_DATABASE=SD8897 WLAN 154 | 155 | sdio:c*v02DFd912E* 156 | ID_MODEL_FROM_DATABASE=SD8897 BT 157 | 158 | sdio:c*v02FE* 159 | ID_VENDOR_FROM_DATABASE=Spectec Computer Co., Ltd 160 | 161 | sdio:c*v02FEd2128* 162 | ID_MODEL_FROM_DATABASE=SDIO WLAN Card (SDW820) 163 | 164 | sdio:c*v032A* 165 | ID_VENDOR_FROM_DATABASE=Cambridge Silicon Radio 166 | 167 | sdio:c*v032Ad0001* 168 | ID_MODEL_FROM_DATABASE=UniFi 1 169 | 170 | sdio:c*v032Ad0002* 171 | ID_MODEL_FROM_DATABASE=UniFi 2 172 | 173 | sdio:c*v032Ad0007* 174 | ID_MODEL_FROM_DATABASE=UniFi 3 175 | 176 | sdio:c*v032Ad0008* 177 | ID_MODEL_FROM_DATABASE=UniFi 4 178 | 179 | sdio:c*v037A* 180 | ID_VENDOR_FROM_DATABASE=MediaTek Inc. 181 | 182 | sdio:c*v037Ad5911* 183 | ID_MODEL_FROM_DATABASE=Spectec WLAN-11b/g 184 | 185 | sdio:c*v039A* 186 | ID_VENDOR_FROM_DATABASE=Siano Mobile Silicon 187 | 188 | sdio:c*v0501* 189 | ID_VENDOR_FROM_DATABASE=Globalsat Technology Co. 190 | 191 | sdio:c*v0501dF501* 192 | ID_MODEL_FROM_DATABASE=SD-501 GPS Card 193 | 194 | sdio:c*v104C* 195 | ID_VENDOR_FROM_DATABASE=Texas Instruments, Inc. 196 | 197 | sdio:c*v104Cd9066* 198 | ID_MODEL_FROM_DATABASE=WL1251 199 | 200 | sdio:c*v1180* 201 | ID_VENDOR_FROM_DATABASE=Ricoh Co., Ltd 202 | 203 | sdio:c*v1180dE823* 204 | ID_MODEL_FROM_DATABASE=MMC card reader 205 | 206 | sdio:c*v13D1* 207 | ID_VENDOR_FROM_DATABASE=AboCom Systems, Inc. 208 | 209 | sdio:c*v13D1dAC02* 210 | ID_MODEL_FROM_DATABASE=SDW11G 211 | 212 | -------------------------------------------------------------------------------- /data/database/arm.ids: -------------------------------------------------------------------------------- 1 | # 2 | # List of ARM CPU IDs 3 | # in a format similar to pci.ids/usb.ids. 4 | # 5 | # Version: 2019.08.05 6 | # Maintained by: Burt P. (pburt0@gmail.com) 7 | # https://github.com/bp0/armids 8 | # 9 | # Syntax: 10 | # implementer implementer_name 11 | # part part_name <-- single tab 12 | # 13 | # is two hex digits, is three hex digits, keep in order. 14 | # Comments start with '#'. 15 | # 16 | # This file can be distributed under the GNU General Public License 17 | # (version 2 or higher). 18 | # 19 | # Based on lscpu-arm.c by Riku Voipio 20 | # 21 | # The information here is gathered from 22 | # - ARM manuals 23 | # - Linux kernel: arch/armX/include/asm/cputype.h 24 | # - GCC sources: config/arch/arch-cores.def 25 | # - Ancient wisdom 26 | # 27 | 28 | 41 ARM 29 | 810 ARM810 30 | 920 ARM920 31 | 922 ARM922 32 | 926 ARM926 33 | 940 ARM940 34 | 946 ARM946 35 | 966 ARM966 36 | a20 ARM1020 37 | a22 ARM1022 38 | a26 ARM1026 39 | b02 ARM11 MPCore 40 | b36 ARM1136 41 | b56 ARM1156 42 | b76 ARM1176 43 | c05 Cortex-A5 44 | c07 Cortex-A7 45 | c08 Cortex-A8 46 | c09 Cortex-A9 47 | c0d Cortex-A17 # Originally A12 48 | c0f Cortex-A15 49 | c0e Cortex-A17 50 | c14 Cortex-R4 51 | c15 Cortex-R5 52 | c17 Cortex-R7 53 | c18 Cortex-R8 54 | c20 Cortex-M0 55 | c21 Cortex-M1 56 | c23 Cortex-M3 57 | c24 Cortex-M4 58 | c27 Cortex-M7 59 | c60 Cortex-M0+ 60 | d01 Cortex-A32 61 | d03 Cortex-A53 62 | d04 Cortex-A35 63 | d05 Cortex-A55 64 | d07 Cortex-A57 65 | d08 Cortex-A72 66 | d09 Cortex-A73 67 | d0a Cortex-A75 68 | d0b Cortex-A76 69 | d0c Neoverse-N1 70 | d0d Cortex-A77 71 | d13 Cortex-R52 72 | d20 Cortex-M23 73 | d21 Cortex-M33 74 | d4a Neoverse-E1 75 | 42 Broadcom 76 | 00f Brahma B15 77 | 100 Brahma B53 78 | 516 ThunderX2 79 | 43 Cavium 80 | 0a0 ThunderX 81 | 0a1 ThunderX 88XX 82 | 0a2 ThunderX 81XX 83 | 0a3 ThunderX 83XX 84 | 0af ThunderX2 99xx 85 | 44 DEC 86 | a10 SA110 87 | a11 SA1100 88 | 4e nVidia 89 | 000 Denver 90 | 003 Denver 2 91 | 50 APM 92 | 000 X-Gene 93 | 51 Qualcomm 94 | 00f Scorpion 95 | 02d Scorpion 96 | 04d Krait 97 | 06f Krait 98 | 201 Kryo 99 | 205 Kryo 100 | 211 Kryo 101 | 800 Falkor V1/Kryo 102 | 801 Kryo V2 103 | 802 Kryo 3xx gold 104 | 803 Kryo 3xx silver 105 | 805 Kryo 5xx silver 106 | c00 Falkor 107 | c01 Saphira 108 | 53 Samsung 109 | 001 exynos-m1 110 | 54 Texas Instruments 111 | 56 Marvell 112 | 131 Feroceon 88FR131 113 | 581 PJ4/PJ4b 114 | 584 PJ4B-MP 115 | 66 Faraday 116 | 526 FA526 117 | 626 FA626 118 | 69 Intel 119 | 200 i80200 120 | 210 PXA250A 121 | 212 PXA210A 122 | 242 i80321-400 123 | 243 i80321-600 124 | 290 PXA250B/PXA26x 125 | 292 PXA210B 126 | 2c2 i80321-400-B0 127 | 2c3 i80321-600-B0 128 | 2d0 PXA250C/PXA255/PXA26x 129 | 2d2 PXA210C 130 | 2e3 i80219 131 | 411 PXA27x 132 | 41c IPX425-533 133 | 41d IPX425-400 134 | 41f IPX425-266 135 | 682 PXA32x 136 | 683 PXA930/PXA935 137 | 688 PXA30x 138 | 689 PXA31x 139 | b11 SA1110 140 | c12 IPX1200 141 | 142 | -------------------------------------------------------------------------------- /data/database/database_license.txt: -------------------------------------------------------------------------------- 1 | # *************************************************************** 2 | # Database: arm.ids 3 | # Source: https://github.com/bp0/armids 4 | # License: GNU General Public License v2.0 5 | # Update time: 12.01.2023 6 | # Modification: None 7 | # *************************************************************** 8 | 9 | 10 | # *************************************************************** 11 | # Database: sdcard.ids 12 | # Source: https://github.com/bp0/verbose-spork 13 | # License: GNU General Public License v2.0 14 | # Update time: 12.01.2023 15 | # Modification: None 16 | # *************************************************************** 17 | 18 | 19 | # *************************************************************** 20 | # Database: 20-sdio-vendor-model.hwdb 21 | # Source: https://github.com/systemd/systemd 22 | # License: GNU General Public License v2.0 23 | # Update time: 12.01.2023 24 | # Modification: None 25 | # *************************************************************** 26 | 27 | -------------------------------------------------------------------------------- /data/database/meson.build: -------------------------------------------------------------------------------- 1 | pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name()) 2 | 3 | install_data([ 4 | '20-sdio-vendor-model.hwdb', 5 | 'arm.ids', 6 | 'database_license.txt', 7 | 'sdcard.ids', 8 | ], 9 | install_dir: join_paths(pkgdatadir, 'database') 10 | ) 11 | -------------------------------------------------------------------------------- /data/database/sdcard.ids: -------------------------------------------------------------------------------- 1 | # 2 | # https://github.com/bp0/verbose-spork/blob/master/data/sdcard.ids 3 | # 4 | 5 | # 6 | # List of known/observed SD card manfid's 7 | # 8 | # Syntax: 9 | # MANFID id manufacturer_name(s) 10 | 11 | MANFID 000001 Panasonic 12 | MANFID 000002 Toshiba 13 | MANFID 000003 SanDisk 14 | MANFID 00001b Samsung 15 | MANFID 00001d ADATA 16 | MANFID 000027 Phison 17 | MANFID 000028 Lexar 18 | MANFID 000031 Silicon Power 19 | MANFID 000041 Kingston 20 | MANFID 000074 Transcend Information 21 | MANFID 000076 Patriot Memory 22 | MANFID 000082 Sony 23 | MANFID 00009c Angelbird / Hoodman 24 | 25 | # 26 | # List of known/observed SD card oemid's 27 | # 28 | # Syntax: 29 | # OEMID id vendor_name(s) 30 | # 31 | # The id is normally composed of two ascii 32 | # characters read as a big-endian 16-bit 33 | # value. 34 | 35 | OEMID 3432 Kingston # "42" 36 | OEMID 4144 ADATA # "AD" 37 | OEMID 4245 Lexar / Angelbird / Hoodman # "BE" 38 | OEMID 4a45 Transcend Information # "JE" 39 | OEMID 4a54 Sony # "JT" 40 | OEMID 4a60 Transcend Information # "J`" 41 | OEMID 5041 Panasonic # "PA" 42 | OEMID 5048 Phison # "PH" 43 | OEMID 5054 SanDisk # "PT" 44 | OEMID 5344 SanDisk # "SD" 45 | OEMID 534d Samsung # "SM" 46 | OEMID 534f Angelbird / Hoodman # "SO" 47 | OEMID 5350 Silicon Power # "SP" 48 | OEMID 544d Toshiba # "TM" 49 | 50 | -------------------------------------------------------------------------------- /data/generate_man_gz.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | gzip -c system-monitoring-center.1 > system-monitoring-center.1.gz -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-cpu-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 32 | 33 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-disk-hdd-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-fan-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 30 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-graphics-card-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 32 | 33 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-network-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-performance-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 32 | 33 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-process-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-ram-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 30 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-services-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 32 | 33 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-system-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 30 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-temperature-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 32 | 33 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-user-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 30 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/system-monitoring-center-voltage-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 30 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/apps/io.github.hakandundar34coding.system-monitoring-center.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 30 | 34 | 38 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/apps/system-monitoring-center.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 27 | 30 | 34 | 38 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /data/icons/meson.build: -------------------------------------------------------------------------------- 1 | pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name()) 2 | 3 | application_id = 'io.github.hakandundar34coding.system-monitoring-center' 4 | 5 | scalable_apps_dir = join_paths('hicolor', 'scalable', 'apps') 6 | install_data([ 7 | 'hicolor/scalable/apps/io.github.hakandundar34coding.system-monitoring-center.svg', 8 | ], 9 | install_dir: join_paths(get_option('datadir'), 'icons', scalable_apps_dir) 10 | ) 11 | 12 | scalable_apps_theme_dir = join_paths('hicolor', 'scalable', 'apps') 13 | install_data([ 14 | 'hicolor/scalable/apps/system-monitoring-center.svg', 15 | ], 16 | install_dir: join_paths(pkgdatadir, 'icons', scalable_apps_theme_dir) 17 | ) 18 | 19 | scalable_actions_theme_dir = join_paths('hicolor', 'scalable', 'actions') 20 | install_data([ 21 | 'hicolor/scalable/actions/system-monitoring-center-cpu-symbolic.svg', 22 | 'hicolor/scalable/actions/system-monitoring-center-disk-hdd-symbolic.svg', 23 | 'hicolor/scalable/actions/system-monitoring-center-fan-symbolic.svg', 24 | 'hicolor/scalable/actions/system-monitoring-center-graphics-card-symbolic.svg', 25 | 'hicolor/scalable/actions/system-monitoring-center-network-symbolic.svg', 26 | 'hicolor/scalable/actions/system-monitoring-center-performance-symbolic.svg', 27 | 'hicolor/scalable/actions/system-monitoring-center-performance-symbolic.svg', 28 | 'hicolor/scalable/actions/system-monitoring-center-process-symbolic.svg', 29 | 'hicolor/scalable/actions/system-monitoring-center-ram-symbolic.svg', 30 | 'hicolor/scalable/actions/system-monitoring-center-services-symbolic.svg', 31 | 'hicolor/scalable/actions/system-monitoring-center-system-symbolic.svg', 32 | 'hicolor/scalable/actions/system-monitoring-center-temperature-symbolic.svg', 33 | 'hicolor/scalable/actions/system-monitoring-center-user-symbolic.svg', 34 | 'hicolor/scalable/actions/system-monitoring-center-voltage-symbolic.svg', 35 | ], 36 | install_dir: join_paths(pkgdatadir, 'icons', scalable_actions_theme_dir) 37 | ) 38 | -------------------------------------------------------------------------------- /data/io.github.hakandundar34coding.system-monitoring-center.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=System Monitoring Center 3 | GenericName=System Monitor 4 | Comment=Multi-featured system monitor 5 | Keywords=System Monitor;Task Manager;Performance;CPU;RAM;Swap;Memory;Disk;Network;GPU;Processes;Users;Services; 6 | Exec=system-monitoring-center 7 | Icon=io.github.hakandundar34coding.system-monitoring-center 8 | Terminal=false 9 | Type=Application 10 | Categories=System;Utility; 11 | StartupNotify=true 12 | -------------------------------------------------------------------------------- /data/io.github.hakandundar34coding.system-monitoring-center.policy: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | System Monitoring Center 9 | https://github.com/hakandundar34coding/system-monitoring-center 10 | 11 | 12 | System Monitoring Center Authentication 13 | Authentication is required to run System Monitoring Center 14 | Sistem Gözlem Merkezi için yetkilendirme gerekiyor 15 | 16 | auth_admin 17 | auth_admin 18 | auth_admin 19 | 20 | /usr/bin/system-monitoring-center 21 | true 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | desktop_file = i18n.merge_file( 2 | input: 'io.github.hakandundar34coding.system-monitoring-center.desktop.in', 3 | output: 'io.github.hakandundar34coding.system-monitoring-center.desktop', 4 | type: 'desktop', 5 | po_dir: '../po', 6 | install: true, 7 | install_dir: join_paths(get_option('datadir'), 'applications') 8 | ) 9 | 10 | desktop_utils = find_program('desktop-file-validate', required: false) 11 | if desktop_utils.found() 12 | test('Validate desktop file', desktop_utils, args: [desktop_file]) 13 | endif 14 | 15 | appstream_file = i18n.merge_file( 16 | input: 'io.github.hakandundar34coding.system-monitoring-center.appdata.xml.in', 17 | output: 'io.github.hakandundar34coding.system-monitoring-center.appdata.xml', 18 | po_dir: '../po', 19 | install: true, 20 | install_dir: join_paths(get_option('datadir'), 'appdata') 21 | ) 22 | 23 | '''appstream_util = find_program('appstream-util', required: false) 24 | if appstream_util.found() 25 | test('Validate appstream file', appstream_util, args: ['validate', appstream_file]) 26 | endif 27 | 28 | install_data('io.github.hakandundar34coding.system-monitoring-center.gschema.xml', 29 | install_dir: join_paths(get_option('datadir'), 'glib-2.0/schemas') 30 | ) 31 | 32 | compile_schemas = find_program('glib-compile-schemas', required: false) 33 | if compile_schemas.found() 34 | test('Validate schema file', 35 | compile_schemas, 36 | args: ['--strict', '--dry-run', meson.current_source_dir()]) 37 | endif''' 38 | 39 | install_man( 40 | 'system-monitoring-center.1', 41 | ) 42 | 43 | subdir('icons') 44 | subdir('database') 45 | -------------------------------------------------------------------------------- /data/system-monitoring-center.1: -------------------------------------------------------------------------------- 1 | .\" Manpage for system-monitoring-center. 2 | .\" Author: Hakan Dündar 3 | .\" Date: 05/07/2022 4 | .\" Language: English 5 | .TH "system-monitoring-center" "1" "" "system-monitoring-center" "man page" 6 | .SH NAME 7 | system-monitoring-center \- Multi-featured system monitor. 8 | .SH SYNOPSIS 9 | system-monitoring-center 10 | .SH DESCRIPTION 11 | Provides information about CPU/RAM/Disk/Network/GPU performance, sensors, processes, users, services and system. 12 | .SH OPTIONS 13 | system-monitoring-center has no command line options. 14 | .SH MORE INFORMATION 15 | Some labels provide explanatory information when mouse hovering action is performed. 16 | 17 | GPU usage information availability depends on vendor/driver. 18 | 19 | GPU load is not tracked if GPU tab is switched off (for lower CPU usage). 20 | 21 | Virtual machines may not provide CPU min-max frequencies, sensors and RAM hardware information. 22 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: system-monitoring-center 2 | Section: utils 3 | Priority: optional 4 | Maintainer: Hakan Dündar 5 | Build-Depends: debhelper-compat (= 12), 6 | desktop-file-utils, 7 | gtk-update-icon-cache, 8 | meson (>=0.59), 9 | appstream-util (>=0.7.14), 10 | libglib2.0-dev-bin (>=2.58.3), 11 | itstool, 12 | pkg-config, 13 | python3-cairo, 14 | python3-gi (>=3.30.0) 15 | Standards-Version: 4.6.0 16 | Homepage: https://github.com/hakandundar34coding/system-monitoring-center 17 | 18 | Package: system-monitoring-center 19 | Architecture: all 20 | Depends: ${misc:Depends}, 21 | ${python3:Depends}, 22 | dmidecode, 23 | gir1.2-adw-1, 24 | gir1.2-glib-2.0, 25 | gir1.2-gtk-4.0, 26 | gir1.2-pango-1.0, 27 | hwdata, 28 | iproute2, 29 | python3 (>=3.6), 30 | python3-cairo, 31 | python3-gi, 32 | python3-gi-cairo, 33 | util-linux (>=2.31) 34 | Description: Multi-featured system monitor 35 | Provides information about CPU/RAM/Disk/Network/GPU performance, sensors, 36 | processes, users, services and system. 37 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: system-monitoring-center 3 | Source: https://github.com/hakandundar34coding/system-monitoring-center 4 | 5 | 6 | 7 | Files: * 8 | Copyright: 2022 Hakan Dündar 9 | License: GPL-3.0+ 10 | 11 | License: GPL-3.0+ 12 | This program is free software: you can redistribute it and/or modify 13 | it under the terms of the GNU General Public License as published by 14 | the Free Software Foundation, either version 3 of the License, or 15 | (at your option) any later version. 16 | . 17 | This package is distributed in the hope that it will be useful, 18 | but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | GNU General Public License for more details. 21 | . 22 | You should have received a copy of the GNU General Public License 23 | along with this program. If not, see . 24 | . 25 | On Debian systems, the complete text of the GNU General 26 | Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". 27 | 28 | 29 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | %: 4 | dh $@ --buildsystem=meson 5 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) -------------------------------------------------------------------------------- /debian/system-monitoring-center.lintian-overrides: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/debian/system-monitoring-center.lintian-overrides -------------------------------------------------------------------------------- /docs/Notes_About_Pardus_Image.txt: -------------------------------------------------------------------------------- 1 | - Download image for Pardus Software Center is not official image of this product. 2 | -------------------------------------------------------------------------------- /docs/flatpak.md: -------------------------------------------------------------------------------- 1 | # Installing from Flatpak 2 | 3 | ### Installation: 4 | For installing from GUI: 5 | - Install the application by using Flatpak Application Center or Gnome Software Center. 6 | For installing from command line: 7 | - Option-1) Installing for system-wide: `flatpak install flathub io.github.hakandundar34coding.system-monitoring-center` 8 | (This method can be used for preventing source code modifications.) 9 | - Option-2) Installing for current user account: `flatpak install --user flathub io.github.hakandundar34coding.system-monitoring-center` 10 | 11 | ### Updating: 12 | - Run this command to update the application: `flatpak update io.github.hakandundar34coding.system-monitoring-center` 13 | 14 | ### Notes For Flatpak Support: 15 | - Flatpak version of the application uses some permissions (like not sandboxed) to access performance/system information of the host OS. 16 | 17 | -------------------------------------------------------------------------------- /docs/translations.md: -------------------------------------------------------------------------------- 1 | # Status 2 | 3 | | Language Code | Language | Percentage | 4 | | -------------- | ---------------------- | ---------- | 5 | | cs | Czech | 71% | 6 | | de | German | 74% | 7 | | en | English | 100% | 8 | | es | Spanish | 79% | 9 | | fa | Persian | 71% | 10 | | fr | French | 78% | 11 | | hu | Hungarian | 72% | 12 | | pl | Polish | 75% | 13 | | pt_BR | Portuguese (Brazilian) | 79% | 14 | | pt_PT | Portuguese (Portugal) | 97% | 15 | | ru_RU | Russian | 99% | 16 | | tr | Turkish | 100% | 17 | | zh_CN | Chinese (Simplified) | 99% | 18 | | zh_TW | Chinese (Traditional) | 78% | 19 | 20 | 21 | # Notes For Translators: 22 | 23 | - A translation editor (for example: Poedit) may be used for translating the ```.po``` files. 24 | 25 | - Be careful about uppercase and lowercase letters. 26 | 27 | - Send only ```.po``` files. 28 | 29 | 30 | # Details For Some Texts: 31 | 32 | - Boot VGA: Describes if a GPU is used during OS boot. 33 | 34 | - CPU Affinity: Describes CPU cores on which a process can be run. 35 | 36 | - Mass Storage: Describes unformatted state of a disk. Formatted and unformatted disk capacities are different. 37 | 38 | - For texts that are related to systemd services, see: https://man7.org/linux/man-pages/man1/systemctl.1.html 39 | For example: Mask, Unmask, Enabled-Runtime, Unit File State, Sub-State, Static 40 | 41 | - Form Factor, Locator and Bank Locator texts are used for RAM memory hardware. 42 | 43 | -------------------------------------------------------------------------------- /docs/uninstall_pypi_package.md: -------------------------------------------------------------------------------- 1 | # Uninstalling Python (PyPI) package of the application 2 | 3 | ### Uninstallation: 4 | For uninstalling Python (PyPI) package: 5 | - Uninstalling for current user account: `pip uninstall system-monitoring-center` 6 | - Uninstalling for system-wide: `sudo pip uninstall system-monitoring-center` 7 | - Removing files for system integration: 8 | - Delete `io.github.hakandundar34coding.system-monitoring-center.desktop` and `com.github.hakand34.system-monitoring-center.desktop` files in `/home/[USERNAME]/.local/share/applications/` 9 | - Delete `system-monitoring-center.svg` in `/home/[USERNAME]/.local/share/icons/hicolor/scalable/apps/` 10 | - Delete `.svg` files that start with `system-monitoring-center-` in `/home/[USERNAME]/.local/share/icons/hicolor/scalable/actions/` 11 | 12 | Commands for deleting files: 13 | 14 | ``` 15 | rm /home/$USER/.local/share/applications/io.github.hakandundar34coding.system-monitoring-center.desktop 16 | rm /home/$USER/.local/share/applications/com.github.hakand34.system-monitoring-center.desktop 17 | rm /home/$USER/.local/share/icons/hicolor/scalable/apps/system-monitoring-center.svg 18 | rm /home/$USER/.local/share/icons/hicolor/scalable/actions/system-monitoring-center-* 19 | ``` 20 | -------------------------------------------------------------------------------- /io.github.hakandundar34coding.system-monitoring-center.yml: -------------------------------------------------------------------------------- 1 | app-id: io.github.hakandundar34coding.system-monitoring-center 2 | runtime: org.gnome.Platform 3 | runtime-version: '45' 4 | sdk: org.gnome.Sdk 5 | command: system-monitoring-center 6 | 7 | finish-args: 8 | # For X11 shared memory access (higher performance for X11) 9 | - --share=ipc 10 | # For Wayland access 11 | - --socket=wayland 12 | # For X11 fallback 13 | - --socket=fallback-x11 14 | # For monitoring data download/upload speed on network cards 15 | - --device=all 16 | # For monitoring data download/upload speed on network cards 17 | - --share=network 18 | # For host OS commands access (such as 'systemctl' for service details, 'ls /proc' for process list, 'ps' for process information, etc.) 19 | - --talk-name=org.freedesktop.Flatpak 20 | # For reading several files (systemd service files, process information in '/proc' folder, etc.) of host OS 21 | - --filesystem=host:ro 22 | 23 | cleanup: 24 | - /include 25 | - /lib/pkgconfig 26 | - /share/man 27 | - /share/pkgconfig 28 | - /share/bash-completion 29 | 30 | modules: 31 | 32 | # For using hardware database of "hwdata" 33 | - name: hwdata 34 | config-opts: 35 | - --datarootdir=/app/share 36 | sources: 37 | - type: archive 38 | url: https://github.com/vcrhonek/hwdata/archive/refs/tags/v0.375.tar.gz 39 | sha256: 69ffbfe4801c12c2d66d51f98044beec35afa406b1baa619c57b25a9b62b43a0 40 | 41 | # For getting IPv4 and IPv6 addresses by using 'ip a show [network_card]' command 42 | - name: iproute2 43 | buildsystem: autotools 44 | make-install-args: 45 | - PREFIX=${FLATPAK_DEST} 46 | - SBINDIR=${FLATPAK_DEST}/bin 47 | - CONFDIR=${FLATPAK_DEST}/etc/iproute2 48 | sources: 49 | - type: archive 50 | url: https://github.com/shemminger/iproute2/archive/refs/tags/v6.5.0.tar.gz 51 | sha256: a336d4d66e390c51564980152ffdafa0e214eb6e447c12582eafffb6d836b41d 52 | 53 | # For System Monitoring Center 54 | - name: system-monitoring-center 55 | buildsystem: meson 56 | sources: 57 | - type: git 58 | url: https://github.com/hakandundar34coding/system-monitoring-center.git 59 | commit: 698b7b3667ad06a4ea66e528df0bf63e592beb72 60 | 61 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('system-monitoring-center', 2 | version: files('src/__version__'), 3 | meson_version: '>= 0.59.0', 4 | default_options: [ 'warning_level=2', 'werror=false', ], 5 | ) 6 | 7 | i18n = import('i18n') 8 | gnome = import('gnome') 9 | 10 | 11 | subdir('data') 12 | subdir('src') 13 | subdir('po') 14 | 15 | gnome.post_install( 16 | gtk_update_icon_cache: true, 17 | update_desktop_database: true, 18 | ) 19 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | cs 2 | de 3 | es 4 | fa 5 | fr 6 | hu 7 | pl 8 | pt_BR 9 | pt_PT 10 | ru_RU 11 | tr 12 | zh_CN 13 | zh_TW 14 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | data/io.github.hakandundar34coding.system-monitoring-center.desktop.in 2 | 3 | src/__init__.py 4 | src/Common.py 5 | src/Config.py 6 | src/Cpu.py 7 | src/CpuMenu.py 8 | src/Disk.py 9 | src/DiskMenu.py 10 | src/Gpu.py 11 | src/GpuMenu.py 12 | src/Libsysmon.py 13 | src/Main.py 14 | src/MainWindow.py 15 | src/Memory.py 16 | src/MemoryMenu.py 17 | src/Network.py 18 | src/NetworkMenu.py 19 | src/Performance.py 20 | src/Processes.py 21 | src/ProcessesDetails.py 22 | src/ProcessesMenu.py 23 | src/run_from_source.py 24 | src/Sensors.py 25 | src/SensorsMenu.py 26 | src/Services.py 27 | src/ServicesDetails.py 28 | src/ServicesMenu.py 29 | src/SettingsWindow.py 30 | src/Summary.py 31 | src/SummaryMenu.py 32 | src/System.py 33 | src/Users.py 34 | src/UsersDetails.py 35 | src/UsersMenu.py 36 | src/__version__ 37 | 38 | -------------------------------------------------------------------------------- /po/command_compile_all.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import subprocess 5 | 6 | current_dir = os.path.dirname(os.path.realpath(__file__)) 7 | 8 | po_files = [file_name for file_name in os.listdir(current_dir) if file_name.endswith(".po")] 9 | 10 | for po_file in po_files: 11 | file_name_only = po_file.rstrip(".po") 12 | target_dir = current_dir + "/locale/" + file_name_only + "/LC_MESSAGES" 13 | mo_file = target_dir + "/system-monitoring-center.mo" 14 | if os.path.isdir(target_dir) == False: 15 | try: 16 | os.makedirs(target_dir) 17 | except Exception: 18 | pass 19 | command_list = ["msgfmt", "-o", mo_file, po_file] 20 | process = subprocess.run(command_list, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 21 | error_output = process.stderr.decode().strip() 22 | if error_output != "": 23 | print(error_output) 24 | 25 | -------------------------------------------------------------------------------- /po/command_get_text.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import subprocess 5 | 6 | current_dir = os.path.dirname(os.path.realpath(__file__)) 7 | current_path = current_dir.split("/") 8 | current_folder = current_path[-1] 9 | parent_dir = '/'.join(current_path[:-1]) 10 | 11 | command_list = ["xgettext", "-k_tr", "-kN_tr", "--from-code", "utf-8", "-o", current_dir+"/system-monitoring-center.pot", "-f", current_dir+"/POTFILES.in", "-D", parent_dir] 12 | process = subprocess.run(command_list, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 13 | error_output = process.stderr.decode().strip() 14 | if error_output != "": 15 | print(error_output) 16 | 17 | -------------------------------------------------------------------------------- /po/locale/cs/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/cs/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/de/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/de/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/es/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/es/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/fa/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/fa/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/fr/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/fr/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/hu/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/hu/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/pl/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/pl/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/pt_BR/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/pt_BR/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/pt_PT/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/pt_PT/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/ru_RU/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/ru_RU/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/tr/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/tr/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/zh_CN/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/zh_CN/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/locale/zh_TW/LC_MESSAGES/system-monitoring-center.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/po/locale/zh_TW/LC_MESSAGES/system-monitoring-center.mo -------------------------------------------------------------------------------- /po/meson.build: -------------------------------------------------------------------------------- 1 | i18n.gettext('system-monitoring-center', preset: 'glib') 2 | -------------------------------------------------------------------------------- /screenshots/cpu_tab_dark_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/cpu_tab_dark_system_theme.png -------------------------------------------------------------------------------- /screenshots/cpu_tab_per_core_dark_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/cpu_tab_per_core_dark_system_theme.png -------------------------------------------------------------------------------- /screenshots/cpu_tab_white_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/cpu_tab_white_system_theme.png -------------------------------------------------------------------------------- /screenshots/disk_tab_menu_white_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/disk_tab_menu_white_system_theme.png -------------------------------------------------------------------------------- /screenshots/gpu_tab_dark_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/gpu_tab_dark_system_theme.png -------------------------------------------------------------------------------- /screenshots/memory_tab_white_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/memory_tab_white_system_theme.png -------------------------------------------------------------------------------- /screenshots/network_tab_dark_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/network_tab_dark_system_theme.png -------------------------------------------------------------------------------- /screenshots/process_details__dark_system_theme_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/process_details__dark_system_theme_1.png -------------------------------------------------------------------------------- /screenshots/process_details__dark_system_theme_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/process_details__dark_system_theme_2.png -------------------------------------------------------------------------------- /screenshots/processes_list_view_dark_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/processes_list_view_dark_system_theme.png -------------------------------------------------------------------------------- /screenshots/processes_tree_view_white_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/processes_tree_view_white_system_theme.png -------------------------------------------------------------------------------- /screenshots/sensors_tab_dark_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/sensors_tab_dark_system_theme.png -------------------------------------------------------------------------------- /screenshots/services_tab_dark_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/services_tab_dark_system_theme.png -------------------------------------------------------------------------------- /screenshots/settings_dark_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/settings_dark_system_theme.png -------------------------------------------------------------------------------- /screenshots/summary_tab_dark_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/summary_tab_dark_system_theme.png -------------------------------------------------------------------------------- /screenshots/summary_tab_white_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/summary_tab_white_system_theme.png -------------------------------------------------------------------------------- /screenshots/system_tab_dark_system_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/screenshots/system_tab_dark_system_theme.png -------------------------------------------------------------------------------- /src/Cpu.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | from gi.repository import Gtk 4 | 5 | from .Config import Config 6 | from .Performance import Performance 7 | from .MainWindow import MainWindow 8 | from . import Common 9 | from . import Libsysmon 10 | 11 | _tr = Config._tr 12 | 13 | 14 | class Cpu: 15 | 16 | def __init__(self): 17 | 18 | self.name = "Cpu" 19 | 20 | self.tab_gui() 21 | 22 | self.initial_already_run = 0 23 | 24 | 25 | def tab_gui(self): 26 | """ 27 | Generate tab GUI. 28 | """ 29 | 30 | self.tab_grid = Common.tab_grid() 31 | 32 | self.tab_title_grid() 33 | 34 | self.da_grid() 35 | 36 | self.information_grid() 37 | 38 | 39 | def tab_title_grid(self): 40 | """ 41 | Generate tab name, device name labels. 42 | """ 43 | 44 | # Grid (tab title) 45 | grid = Gtk.Grid() 46 | self.tab_grid.attach(grid, 0, 0, 1, 1) 47 | 48 | # Label (CPU) 49 | label = Common.tab_title_label(_tr("CPU")) 50 | grid.attach(label, 0, 0, 1, 2) 51 | 52 | # Label (device vendor-model label) 53 | self.device_vendor_model_label = Common.device_vendor_model_label() 54 | self.device_vendor_model_label.set_tooltip_text(_tr("Vendor") + "-" + _tr("Model")) 55 | grid.attach(self.device_vendor_model_label, 1, 0, 1, 1) 56 | 57 | # Label (device kernel name) 58 | self.device_kernel_name_label = Common.device_kernel_name_label() 59 | self.device_kernel_name_label.set_tooltip_text(_tr("Device Name In Kernel")) 60 | grid.attach(self.device_kernel_name_label, 1, 1, 1, 1) 61 | 62 | 63 | def da_grid(self): 64 | """ 65 | Generate tab drawingarea and related information labels. 66 | """ 67 | 68 | # Grid (drawingarea) 69 | grid = Gtk.Grid() 70 | grid.set_hexpand(True) 71 | grid.set_vexpand(True) 72 | self.tab_grid.attach(grid, 0, 1, 1, 1) 73 | 74 | # Label (drawingarea upper-left) 75 | self.da_upper_left_label = Common.da_upper_lower_label(_tr("CPU Usage (Average)"), Gtk.Align.START) 76 | grid.attach(self.da_upper_left_label, 0, 0, 1, 1) 77 | 78 | # Label (drawingarea upper-right) 79 | label = Common.da_upper_lower_label("100%", Gtk.Align.END) 80 | grid.attach(label, 1, 0, 1, 1) 81 | 82 | # DrawingArea (CPU usage) 83 | self.da_cpu_usage = Common.drawingarea(Performance.performance_line_charts_draw, "da_cpu_usage") 84 | grid.attach(self.da_cpu_usage, 0, 2, 2, 1) 85 | 86 | # Label (drawingarea lower-right) 87 | label = Common.da_upper_lower_label("0", Gtk.Align.END) 88 | grid.attach(label, 0, 3, 2, 1) 89 | 90 | 91 | def information_grid(self): 92 | """ 93 | Generate performance/information labels. 94 | """ 95 | 96 | # Grid (performance/information labels) 97 | performance_info_grid = Common.performance_info_grid() 98 | self.tab_grid.attach(performance_info_grid, 0, 2, 1, 1) 99 | 100 | # Styled information widgets (Average Usage and Frequency) 101 | # ScrolledWindow (Average Usage and Frequency) 102 | scrolledwindow, self.average_usage_label, self.frequency_label = Common.styled_information_scrolledwindow(_tr("Average Usage"), _tr("Average CPU usage of all cores"), _tr("Frequency"), None) 103 | performance_info_grid.attach(scrolledwindow, 0, 0, 1, 1) 104 | 105 | # Styled information widgets (Processes-Threads and Up Time) 106 | # ScrolledWindow (Processes-Threads and Up Time) 107 | scrolledwindow, self.processes_threads_label, self.up_time_label = Common.styled_information_scrolledwindow(_tr("Processes") + "-" + _tr("Threads"), None, _tr("Up Time"), None) 108 | performance_info_grid.attach(scrolledwindow, 0, 1, 1, 1) 109 | 110 | # Grid - Right information labels 111 | performance_info_right_grid = Common.performance_info_right_grid() 112 | performance_info_grid.attach(performance_info_right_grid, 1, 0, 1, 2) 113 | 114 | # Labels - Right information labels 115 | # Label (Min-Max Frequency) 116 | label = Common.static_information_label(_tr("Min-Max Frequency") + ":") 117 | performance_info_right_grid.attach(label, 0, 0, 1, 1) 118 | # Label (Min-Max Frequency) 119 | self.min_max_frequency_label = Common.dynamic_information_label() 120 | performance_info_right_grid.attach(self.min_max_frequency_label, 1, 0, 1, 1) 121 | 122 | # Label (Cache (L1d-L1i)) 123 | label = Common.static_information_label(_tr("Cache") + "(L1d-L1i)" + ":") 124 | performance_info_right_grid.attach(label, 0, 1, 1, 1) 125 | # Label (Cache (L1d-L1i)) 126 | self.cache_l1d_l1i_label = Common.dynamic_information_label() 127 | performance_info_right_grid.attach(self.cache_l1d_l1i_label, 1, 1, 1, 1) 128 | 129 | # Label (Cache (L2-L3)) 130 | label = Common.static_information_label(_tr("Cache") + "(L2-L3)" + ":") 131 | performance_info_right_grid.attach(label, 0, 2, 1, 1) 132 | # Label (Cache (L2-L3)) 133 | self.cache_l2_l3_label = Common.dynamic_information_label() 134 | performance_info_right_grid.attach(self.cache_l2_l3_label, 1, 2, 1, 1) 135 | 136 | # Label (CPU Sockets) 137 | label = Common.static_information_label(_tr("CPU Sockets") + ":") 138 | performance_info_right_grid.attach(label, 0, 3, 1, 1) 139 | # Label (CPU Sockets) 140 | self.cpu_sockets_label = Common.dynamic_information_label() 141 | performance_info_right_grid.attach(self.cpu_sockets_label, 1, 3, 1, 1) 142 | 143 | # Label (Cores (Physical-Logical)) 144 | label = Common.static_information_label(_tr("Cores (Physical-Logical)") + ":") 145 | label.set_tooltip_text(_tr("Number of online physical and logical CPU cores")) 146 | performance_info_right_grid.attach(label, 0, 4, 1, 1) 147 | # Label (Cores (Physical-Logical)) 148 | self.cores_phy_log_label = Common.dynamic_information_label() 149 | performance_info_right_grid.attach(self.cores_phy_log_label, 1, 4, 1, 1) 150 | 151 | # Label (Architecture) 152 | label = Common.static_information_label(_tr("Architecture") + ":") 153 | performance_info_right_grid.attach(label, 0, 5, 1, 1) 154 | # Label (Architecture) 155 | self.architecture_label = Common.dynamic_information_label() 156 | performance_info_right_grid.attach(self.architecture_label, 1, 5, 1, 1) 157 | 158 | 159 | def initial_func(self): 160 | """ 161 | Initial code which which is not wanted to be run in every loop. 162 | """ 163 | 164 | selected_cpu_core = Performance.selected_cpu_core 165 | self.selected_cpu_core_prev = selected_cpu_core 166 | self.logical_core_list_prev = list(Performance.logical_core_list) 167 | 168 | # Get information 169 | cpu_core_min_frequency, cpu_core_max_frequency = Libsysmon.get_cpu_core_min_max_frequency(selected_cpu_core) 170 | if Config.show_cpu_cache_type == "socket": 171 | cpu_l1d_cache, cpu_l1i_cache, cpu_l2_cache, cpu_l3_cache = Libsysmon.get_cpu_socket_l1_l2_l3_cache(selected_cpu_core) 172 | elif Config.show_cpu_cache_type == "core": 173 | cpu_l1d_cache, cpu_l1i_cache, cpu_l2_cache, cpu_l3_cache = Libsysmon.get_cpu_core_l1_l2_l3_cache(selected_cpu_core) 174 | cpu_architecture = Libsysmon.get_cpu_architecture() 175 | 176 | 177 | # Show information on labels 178 | show_cpu_usage_per_core = Config.show_cpu_usage_per_core 179 | if show_cpu_usage_per_core == 0: 180 | self.da_upper_left_label.set_label(_tr("CPU Usage (Average)")) 181 | elif show_cpu_usage_per_core == 1: 182 | self.da_upper_left_label.set_label(_tr("CPU Usage (Per Core)")) 183 | if isinstance(cpu_core_max_frequency, str) is False: 184 | self.min_max_frequency_label.set_label(f'{cpu_core_min_frequency:.2f} - {cpu_core_max_frequency:.2f} GHz') 185 | else: 186 | self.min_max_frequency_label.set_label(f'{cpu_core_min_frequency} - {cpu_core_max_frequency}') 187 | self.architecture_label.set_label(cpu_architecture) 188 | self.cache_l1d_l1i_label.set_label(f'{cpu_l1d_cache} - {cpu_l1i_cache}') 189 | self.cache_l2_l3_label.set_label(f'{cpu_l2_cache} - {cpu_l3_cache}') 190 | 191 | self.initial_already_run = 1 192 | 193 | 194 | def loop_func(self): 195 | """ 196 | Get and show information on the GUI on every loop. 197 | """ 198 | 199 | if self.initial_already_run == 0: 200 | self.initial_func() 201 | 202 | number_of_logical_cores = Libsysmon.get_number_of_logical_cores() 203 | cpu_usage_percent_ave = Performance.cpu_usage_percent_ave 204 | selected_cpu_core = Performance.selected_cpu_core 205 | # Run "initial_func" if selected CPU core is changed since the last loop. 206 | if self.selected_cpu_core_prev != selected_cpu_core: 207 | self.initial_func() 208 | self.selected_cpu_core_prev = selected_cpu_core 209 | 210 | # Run "main_gui_device_selection_list" if selected device list is changed since the last loop. 211 | if self.logical_core_list_prev != Performance.logical_core_list: 212 | MainWindow.main_gui_device_selection_list() 213 | self.logical_core_list_prev = list(Performance.logical_core_list) 214 | 215 | self.da_cpu_usage.queue_draw() 216 | 217 | # Get information 218 | number_of_physical_cores, number_of_cpu_sockets, cpu_model_name = Libsysmon.get_number_of_physical_cores_sockets_cpu_name(selected_cpu_core, number_of_logical_cores) 219 | cpu_core_current_frequency = Libsysmon.get_cpu_core_current_frequency(selected_cpu_core) 220 | number_of_total_processes, number_of_total_threads = Libsysmon.get_processes_threads() 221 | system_up_time = Libsysmon.get_system_up_time() 222 | 223 | 224 | # Show information on labels 225 | self.device_vendor_model_label.set_label(cpu_model_name) 226 | self.device_kernel_name_label.set_label(selected_cpu_core) 227 | self.processes_threads_label.set_label(f'{number_of_total_processes} - {number_of_total_threads}') 228 | self.up_time_label.set_label(system_up_time) 229 | self.average_usage_label.set_label(f'{cpu_usage_percent_ave[-1]:.{Config.performance_cpu_usage_percent_precision}f} %') 230 | self.frequency_label.set_label(f'{cpu_core_current_frequency:.2f} GHz') 231 | self.cpu_sockets_label.set_label(f'{number_of_cpu_sockets}') 232 | self.cores_phy_log_label.set_label(f'{number_of_physical_cores} - {number_of_logical_cores}') 233 | 234 | 235 | Cpu = Cpu() 236 | 237 | -------------------------------------------------------------------------------- /src/CpuMenu.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | gi.require_version('Gdk', '4.0') 4 | from gi.repository import Gtk, Gdk 5 | 6 | from .Config import Config 7 | from .Cpu import Cpu 8 | from .Performance import Performance 9 | from .MainWindow import MainWindow 10 | from . import Common 11 | 12 | _tr = Config._tr 13 | 14 | 15 | class CpuMenu: 16 | 17 | def __init__(self): 18 | 19 | self.name = "CpuMenu" 20 | 21 | self.menu_gui() 22 | 23 | 24 | def menu_gui(self): 25 | """ 26 | Generate menu GUI. 27 | """ 28 | 29 | # Popover 30 | self.menu_po = Gtk.Popover() 31 | 32 | # Grid (main) 33 | main_grid = Common.menu_main_grid() 34 | self.menu_po.set_child(main_grid) 35 | 36 | # Label - menu title (CPU) 37 | label = Common.menu_title_label(_tr("CPU")) 38 | main_grid.attach(label, 0, 0, 1, 1) 39 | 40 | # Label (Graph - Show) 41 | label = Common.title_label(_tr("Graph - Show")) 42 | main_grid.attach(label, 0, 1, 1, 1) 43 | 44 | # CheckButton (CPU Usage (Average)) 45 | self.cpu_usage_average_cb = Common.checkbutton(_tr("CPU Usage (Average)"), None) 46 | main_grid.attach(self.cpu_usage_average_cb, 0, 2, 1, 1) 47 | 48 | # CheckButton (CPU Usage (Per Core)) 49 | self.cpu_usage_per_core_cb = Common.checkbutton(_tr("CPU Usage (Per Core)"), self.cpu_usage_average_cb) 50 | main_grid.attach(self.cpu_usage_per_core_cb, 0, 3, 1, 1) 51 | 52 | # Separator 53 | separator = Common.menu_separator() 54 | main_grid.attach(separator, 0, 4, 1, 1) 55 | 56 | # CheckButton (Show processes using max CPU) 57 | self.show_processes_using_max_cpu_cb = Common.checkbutton(_tr("Show processes using max CPU"), None) 58 | main_grid.attach(self.show_processes_using_max_cpu_cb, 0, 5, 1, 1) 59 | 60 | # Label (This increases CPU usage.) 61 | label = Common.static_information_label(_tr("This increases CPU usage.") + "\n" + "(" + _tr("for all tabs") + ")") 62 | label.set_margin_start(25) 63 | main_grid.attach(label, 0, 6, 1, 1) 64 | 65 | # Separator 66 | separator = Common.menu_separator() 67 | main_grid.attach(separator, 0, 7, 1, 1) 68 | 69 | # Button (Graph Color) 70 | self.graph_color_button = Common.graph_color_button(self) 71 | main_grid.attach(self.graph_color_button, 0, 8, 1, 1) 72 | 73 | # Separator 74 | separator = Common.menu_separator() 75 | main_grid.attach(separator, 0, 9, 1, 1) 76 | 77 | # Label - title (Precision) 78 | label = Common.title_label(_tr("Precision")) 79 | main_grid.attach(label, 0, 10, 1, 1) 80 | 81 | # Label - precision (CPU) 82 | label = Gtk.Label() 83 | label.set_label(_tr("CPU")) 84 | label.set_halign(Gtk.Align.CENTER) 85 | main_grid.attach(label, 0, 11, 1, 1) 86 | 87 | # DropDown - precision (CPU) 88 | item_list = ['0', '0.0', '0.00', '0.000'] 89 | self.cpu_precision_dd = Common.dropdown_and_model(item_list) 90 | main_grid.attach(self.cpu_precision_dd, 0, 12, 1, 1) 91 | 92 | # Separator 93 | separator = Common.menu_separator() 94 | main_grid.attach(separator, 0, 13, 1, 1) 95 | 96 | # Label (Cache) 97 | label = Common.title_label(_tr("Cache")) 98 | main_grid.attach(label, 0, 14, 1, 1) 99 | 100 | # CheckButton (CPU Usage (Average)) 101 | self.cpu_cache_socket_cb = Common.checkbutton(_tr("CPU Socket"), None) 102 | main_grid.attach(self.cpu_cache_socket_cb, 0, 15, 1, 1) 103 | 104 | # CheckButton (CPU Usage (Per Core)) 105 | self.cpu_cache_core_cb = Common.checkbutton(_tr("Selected CPU Core"), self.cpu_cache_socket_cb) 106 | main_grid.attach(self.cpu_cache_core_cb, 0, 16, 1, 1) 107 | 108 | # Separator 109 | separator = Common.menu_separator() 110 | main_grid.attach(separator, 0, 17, 1, 1) 111 | 112 | # Button (Reset) 113 | self.reset_button = Common.reset_button() 114 | main_grid.attach(self.reset_button, 0, 18, 1, 1) 115 | 116 | # Connect signals 117 | self.menu_po.connect("show", self.on_menu_po_show) 118 | self.reset_button.connect("clicked", self.on_reset_button_clicked) 119 | 120 | 121 | def connect_signals(self): 122 | """ 123 | Connect some of the signals to be able to disconnect them for setting GUI. 124 | """ 125 | 126 | self.cpu_usage_average_cb.connect("toggled", self.on_cpu_usage_cb_toggled) 127 | self.cpu_usage_per_core_cb.connect("toggled", self.on_cpu_usage_cb_toggled) 128 | self.cpu_precision_dd.connect("notify::selected-item", self.on_selected_item_notify) 129 | self.show_processes_using_max_cpu_cb.connect("toggled", self.on_show_processes_using_max_cpu_cb_toggled) 130 | self.cpu_cache_socket_cb.connect("toggled", self.on_cpu_cache_cb_toggled) 131 | self.cpu_cache_core_cb.connect("toggled", self.on_cpu_cache_cb_toggled) 132 | 133 | 134 | def disconnect_signals(self): 135 | """ 136 | Disconnect some of the signals for setting GUI. 137 | """ 138 | 139 | self.cpu_usage_average_cb.disconnect_by_func(self.on_cpu_usage_cb_toggled) 140 | self.cpu_usage_per_core_cb.disconnect_by_func(self.on_cpu_usage_cb_toggled) 141 | self.cpu_precision_dd.disconnect_by_func(self.on_selected_item_notify) 142 | self.show_processes_using_max_cpu_cb.disconnect_by_func(self.on_show_processes_using_max_cpu_cb_toggled) 143 | self.cpu_cache_socket_cb.disconnect_by_func(self.on_cpu_cache_cb_toggled) 144 | self.cpu_cache_core_cb.disconnect_by_func(self.on_cpu_cache_cb_toggled) 145 | 146 | 147 | def on_menu_po_show(self, widget): 148 | """ 149 | Run code when menu is shown. 150 | """ 151 | 152 | try: 153 | self.disconnect_signals() 154 | except TypeError: 155 | pass 156 | self.set_gui() 157 | self.connect_signals() 158 | 159 | 160 | def on_cpu_usage_cb_toggled(self, widget): 161 | """ 162 | Change CPU usage type. 163 | """ 164 | 165 | if widget.get_active() == True: 166 | if widget == self.cpu_usage_average_cb: 167 | Config.show_cpu_usage_per_core = 0 168 | self.show_processes_using_max_cpu_cb.set_sensitive(True) 169 | if widget == self.cpu_usage_per_core_cb: 170 | Config.show_cpu_usage_per_core = 1 171 | self.show_processes_using_max_cpu_cb.set_sensitive(False) 172 | 173 | Common.save_tab_settings(Cpu) 174 | 175 | 176 | def on_selected_item_notify(self, widget, parameter): 177 | """ 178 | Change CPU usage percent precision. 179 | Notify signal is sent when DropDown widget selection is changed. 180 | Currently GtkExpression parameter for DropDown can not be used because of PyGObject. 181 | """ 182 | 183 | Config.performance_cpu_usage_percent_precision = widget.get_selected() 184 | 185 | Common.save_tab_settings(Cpu) 186 | 187 | 188 | def on_show_processes_using_max_cpu_cb_toggled(self, widget): 189 | """ 190 | Show/Hide processes that consume max CPU resources. 191 | """ 192 | 193 | if widget.get_active() == True: 194 | Config.show_processes_using_max_cpu = 1 195 | else: 196 | Config.show_processes_using_max_cpu = 0 197 | 198 | Common.save_tab_settings(Cpu) 199 | 200 | 201 | def on_cpu_cache_cb_toggled(self, widget): 202 | """ 203 | Show CPU cache memory values per socket/core. 204 | """ 205 | 206 | if widget.get_active() == True: 207 | if widget == self.cpu_cache_socket_cb: 208 | Config.show_cpu_cache_type = "socket" 209 | if widget == self.cpu_cache_core_cb: 210 | Config.show_cpu_cache_type = "core" 211 | 212 | Common.save_tab_settings(Cpu) 213 | 214 | 215 | def on_reset_button_clicked(self, widget): 216 | """ 217 | Reset all tab settings. 218 | """ 219 | 220 | # Load default settings 221 | Config.config_default_performance_cpu_func() 222 | Config.config_save_func() 223 | Performance.performance_set_selected_cpu_core_func() 224 | 225 | # Reset device list between Performance tab sub-tabs because selected device is reset. 226 | MainWindow.main_gui_device_selection_list() 227 | 228 | Common.update_tab_and_menu_gui(self, Cpu) 229 | 230 | 231 | def set_gui(self): 232 | """ 233 | Set menu GUI items. 234 | """ 235 | 236 | # Select checkbutton appropriate for CPU usage chart setting 237 | if Config.show_cpu_usage_per_core == 0: 238 | self.cpu_usage_average_cb.set_active(True) 239 | self.show_processes_using_max_cpu_cb.set_sensitive(True) 240 | if Config.show_cpu_usage_per_core == 1: 241 | self.cpu_usage_per_core_cb.set_active(True) 242 | self.show_processes_using_max_cpu_cb.set_sensitive(False) 243 | 244 | self.cpu_precision_dd.set_selected(Config.performance_cpu_usage_percent_precision) 245 | 246 | # Set active checkbutton if "Show processes using max CPU" option is enabled. 247 | if Config.show_processes_using_max_cpu == 1: 248 | self.show_processes_using_max_cpu_cb.set_active(True) 249 | if Config.show_processes_using_max_cpu == 0: 250 | self.show_processes_using_max_cpu_cb.set_active(False) 251 | 252 | # Select checkbutton appropriate for CPU cache type setting 253 | if Config.show_cpu_cache_type == "socket": 254 | self.cpu_cache_socket_cb.set_active(True) 255 | if Config.show_cpu_cache_type == "core": 256 | self.cpu_cache_core_cb.set_active(True) 257 | 258 | 259 | CpuMenu = CpuMenu() 260 | 261 | -------------------------------------------------------------------------------- /src/DiskMenu.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | gi.require_version('Gdk', '4.0') 4 | from gi.repository import Gtk, Gdk 5 | 6 | from .Config import Config 7 | from .Disk import Disk 8 | from .Performance import Performance 9 | from .MainWindow import MainWindow 10 | from . import Common 11 | 12 | _tr = Config._tr 13 | 14 | 15 | class DiskMenu: 16 | 17 | def __init__(self): 18 | 19 | self.name = "DiskMenu" 20 | 21 | self.menu_gui() 22 | 23 | 24 | def menu_gui(self): 25 | """ 26 | Generate menu GUI. 27 | """ 28 | 29 | # Popover 30 | self.menu_po = Gtk.Popover() 31 | 32 | # Grid (main) 33 | main_grid = Common.menu_main_grid() 34 | self.menu_po.set_child(main_grid) 35 | 36 | # Label - menu title (Disk) 37 | label = Common.menu_title_label(_tr("Disk")) 38 | main_grid.attach(label, 0, 0, 2, 1) 39 | 40 | # Label (Graph - Show) 41 | label = Common.title_label(_tr("Graph - Show")) 42 | main_grid.attach(label, 0, 1, 2, 1) 43 | 44 | # Checkbutton (Read Speed) 45 | self.read_speed_cb = Common.checkbutton(_tr("Read Speed"), None) 46 | main_grid.attach(self.read_speed_cb, 0, 2, 1, 1) 47 | 48 | # Checkbutton (Write Speed) 49 | self.write_speed_cb = Common.checkbutton(_tr("Write Speed"), None) 50 | main_grid.attach(self.write_speed_cb, 1, 2, 1, 1) 51 | 52 | # Checkbutton (Selected Device) 53 | self.selected_device_cb = Common.checkbutton(_tr("Selected Device"), None) 54 | main_grid.attach(self.selected_device_cb, 0, 3, 1, 1) 55 | 56 | # Checkbutton (All Devices) 57 | self.all_devices_cb = Common.checkbutton(_tr("All Devices"), self.selected_device_cb) 58 | main_grid.attach(self.all_devices_cb, 1, 3, 1, 1) 59 | 60 | # Separator 61 | separator = Common.menu_separator() 62 | main_grid.attach(separator, 0, 4, 2, 1) 63 | 64 | # Button (Graph Color) 65 | self.graph_color_button = Common.graph_color_button(self) 66 | main_grid.attach(self.graph_color_button, 0, 5, 2, 1) 67 | 68 | # Separator 69 | separator = Common.menu_separator() 70 | main_grid.attach(separator, 0, 6, 2, 1) 71 | 72 | # Label - title (Precision) 73 | label = Common.title_label(_tr("Precision")) 74 | main_grid.attach(label, 0, 7, 2, 1) 75 | 76 | # DropDown - precision (Disk) 77 | item_list = ['0', '0.0', '0.00', '0.000'] 78 | self.disk_precision_dd = Common.dropdown_and_model(item_list) 79 | main_grid.attach(self.disk_precision_dd, 0, 8, 2, 1) 80 | 81 | # Separator 82 | separator = Common.menu_separator() 83 | main_grid.attach(separator, 0, 9, 2, 1) 84 | 85 | # Label - title (Data Unit) 86 | label = Common.title_label(_tr("Data Unit")) 87 | main_grid.attach(label, 0, 10, 2, 1) 88 | 89 | # Label (Show data as powers of:) 90 | label = Gtk.Label() 91 | label.set_label(_tr("Show data as powers of") + ":") 92 | label.set_halign(Gtk.Align.START) 93 | main_grid.attach(label, 0, 11, 2, 1) 94 | 95 | # CheckButton (1024) 96 | self.data_power_of_1024_cb = Common.checkbutton("1024", None) 97 | main_grid.attach(self.data_power_of_1024_cb, 0, 12, 1, 1) 98 | 99 | # CheckButton (1000) 100 | self.data_power_of_1000_cb = Common.checkbutton("1000", self.data_power_of_1024_cb) 101 | main_grid.attach(self.data_power_of_1000_cb, 1, 12, 1, 1) 102 | 103 | # CheckButton (Show speed units as multiples of bits) 104 | self.data_bits_cb = Common.checkbutton(_tr("Show speed units as multiples of bits"), None) 105 | main_grid.attach(self.data_bits_cb, 0, 13, 2, 1) 106 | 107 | # Separator 108 | separator = Common.menu_separator() 109 | main_grid.attach(separator, 0, 14, 2, 1) 110 | 111 | # Label - title (Disk) 112 | label = Common.title_label(_tr("Disk")) 113 | main_grid.attach(label, 0, 15, 2, 1) 114 | 115 | # CheckButton (Hide loop, ramdisk, zram disks) 116 | self.hide_loop_ramdisk_zram_disks_cb = Common.checkbutton(_tr("Hide loop, ramdisk, zram disks"), None) 117 | main_grid.attach(self.hide_loop_ramdisk_zram_disks_cb, 0, 16, 2, 1) 118 | 119 | # Separator 120 | separator = Common.menu_separator() 121 | main_grid.attach(separator, 0, 17, 2, 1) 122 | 123 | # Button (Reset) 124 | self.reset_button = Common.reset_button() 125 | main_grid.attach(self.reset_button, 0, 18, 2, 1) 126 | 127 | # Connect signals 128 | self.menu_po.connect("show", self.on_menu_po_show) 129 | self.reset_button.connect("clicked", self.on_reset_button_clicked) 130 | 131 | 132 | def connect_signals(self): 133 | """ 134 | Connect some of the signals to be able to disconnect them for setting GUI. 135 | """ 136 | 137 | self.read_speed_cb.connect("toggled", self.on_read_speed_cb_toggled) 138 | self.write_speed_cb.connect("toggled", self.on_write_speed_cb_toggled) 139 | self.selected_device_cb.connect("toggled", self.on_device_selection_cb) 140 | self.all_devices_cb.connect("toggled", self.on_device_selection_cb) 141 | self.data_power_of_1024_cb.connect("toggled", self.on_data_unit_radiobuttons_toggled) 142 | self.data_power_of_1000_cb.connect("toggled", self.on_data_unit_radiobuttons_toggled) 143 | self.data_bits_cb.connect("toggled", self.on_data_bits_cb_toggled) 144 | self.hide_loop_ramdisk_zram_disks_cb.connect("toggled", self.on_hide_loop_ramdisk_zram_disks_cb_toggled) 145 | self.disk_precision_dd.connect("notify::selected-item", self.on_selected_item_notify) 146 | 147 | 148 | def disconnect_signals(self): 149 | """ 150 | Disconnect some of the signals for setting GUI. 151 | """ 152 | 153 | self.read_speed_cb.disconnect_by_func(self.on_read_speed_cb_toggled) 154 | self.write_speed_cb.disconnect_by_func(self.on_write_speed_cb_toggled) 155 | self.selected_device_cb.disconnect_by_func(self.on_device_selection_cb) 156 | self.all_devices_cb.disconnect_by_func(self.on_device_selection_cb) 157 | self.data_power_of_1024_cb.disconnect_by_func(self.on_data_unit_radiobuttons_toggled) 158 | self.data_power_of_1000_cb.disconnect_by_func(self.on_data_unit_radiobuttons_toggled) 159 | self.data_bits_cb.disconnect_by_func(self.on_data_bits_cb_toggled) 160 | self.hide_loop_ramdisk_zram_disks_cb.disconnect_by_func(self.on_hide_loop_ramdisk_zram_disks_cb_toggled) 161 | self.disk_precision_dd.disconnect_by_func(self.on_selected_item_notify) 162 | 163 | 164 | def on_menu_po_show(self, widget): 165 | """ 166 | Run code when menu is shown. 167 | """ 168 | 169 | try: 170 | self.disconnect_signals() 171 | except TypeError: 172 | pass 173 | self.set_gui() 174 | self.connect_signals() 175 | 176 | 177 | def on_read_speed_cb_toggled(self, widget): 178 | """ 179 | Show/Hide disk read speed line. 180 | """ 181 | 182 | if widget.get_active() == True: 183 | Config.plot_disk_read_speed = 1 184 | if widget.get_active() == False: 185 | if self.write_speed_cb.get_active() == False: 186 | widget.set_active(True) 187 | return 188 | Config.plot_disk_read_speed = 0 189 | 190 | Common.save_tab_settings(Disk) 191 | 192 | 193 | def on_write_speed_cb_toggled(self, widget): 194 | """ 195 | Show/Hide disk write speed line. 196 | """ 197 | 198 | if widget.get_active() == True: 199 | Config.plot_disk_write_speed = 1 200 | if widget.get_active() == False: 201 | if self.read_speed_cb.get_active() == False: 202 | widget.set_active(True) 203 | return 204 | Config.plot_disk_write_speed = 0 205 | 206 | Common.save_tab_settings(Disk) 207 | 208 | 209 | def on_device_selection_cb(self, widget): 210 | """ 211 | Set device selection (Selected/All) for showing speed data. 212 | """ 213 | 214 | if widget.get_active() == True: 215 | if widget == self.selected_device_cb: 216 | Config.show_disk_usage_per_disk = 0 217 | if widget == self.all_devices_cb: 218 | Config.show_disk_usage_per_disk = 1 219 | 220 | Common.save_tab_settings(Disk) 221 | 222 | 223 | def on_selected_item_notify(self, widget, parameter): 224 | """ 225 | Change disk data/speed precision. 226 | Notify signal is sent when DropDown widget selection is changed. 227 | Currently GtkExpression parameter for DropDown can not be used because of PyGObject. 228 | """ 229 | 230 | Config.performance_disk_data_precision = widget.get_selected() 231 | 232 | Common.save_tab_settings(Disk) 233 | 234 | 235 | def on_data_unit_radiobuttons_toggled(self, widget): 236 | """ 237 | Change data unit powers of (1024 or 1000) selection. 238 | """ 239 | 240 | if self.data_power_of_1024_cb.get_active() == True: 241 | Config.performance_disk_data_unit = 0 242 | elif self.data_power_of_1000_cb.get_active() == True: 243 | Config.performance_disk_data_unit = 1 244 | 245 | Common.save_tab_settings(Disk) 246 | 247 | 248 | def on_data_bits_cb_toggled(self, widget): 249 | """ 250 | Show speed units as multiples of bits/bytes. 251 | """ 252 | 253 | if widget.get_active() == True: 254 | Config.performance_disk_speed_bit = 1 255 | else: 256 | Config.performance_disk_speed_bit = 0 257 | 258 | Common.save_tab_settings(Disk) 259 | 260 | 261 | def on_hide_loop_ramdisk_zram_disks_cb_toggled(self, widget): 262 | """ 263 | Show/Hide loop, ramdisk, zram disks. 264 | """ 265 | 266 | if widget.get_active() == True: 267 | Config.hide_loop_ramdisk_zram_disks = 1 268 | else: 269 | Config.hide_loop_ramdisk_zram_disks = 0 270 | 271 | # Reset selected device in order to update selected disk on disk list between Performance tab sub-tabs for avoiding no disk selection or wrong disk selection situation if selected disk is hidden or new disks are shown after the option is changed. 272 | Config.selected_disk = "" 273 | Performance.performance_set_selected_disk_func() 274 | 275 | Common.save_tab_settings(Disk) 276 | 277 | 278 | def on_reset_button_clicked(self, widget): 279 | """ 280 | Reset all tab settings. 281 | """ 282 | 283 | # Load default settings 284 | Config.config_default_performance_disk_func() 285 | Config.config_save_func() 286 | Performance.performance_set_selected_disk_func() 287 | 288 | # Reset device list between Performance tab sub-tabs because selected device is reset. 289 | MainWindow.main_gui_device_selection_list() 290 | 291 | Common.update_tab_and_menu_gui(self, Disk) 292 | 293 | 294 | def set_gui(self): 295 | """ 296 | Set menu GUI items. 297 | """ 298 | 299 | # Set active checkbuttons if disk read speed/disk write speed values are "1". 300 | if Config.plot_disk_read_speed == 1: 301 | self.read_speed_cb.set_active(True) 302 | if Config.plot_disk_read_speed == 0: 303 | self.read_speed_cb.set_active(False) 304 | if Config.plot_disk_write_speed == 1: 305 | self.write_speed_cb.set_active(True) 306 | if Config.plot_disk_write_speed == 0: 307 | self.write_speed_cb.set_active(False) 308 | 309 | # Select radiobutton appropriate for seleted/all devices chart setting 310 | if Config.show_disk_usage_per_disk == 0: 311 | self.selected_device_cb.set_active(True) 312 | if Config.show_disk_usage_per_disk == 1: 313 | self.all_devices_cb.set_active(True) 314 | 315 | # Set data unit checkbuttons and radiobuttons. 316 | if Config.performance_disk_data_unit == 0: 317 | self.data_power_of_1024_cb.set_active(True) 318 | if Config.performance_disk_data_unit == 1: 319 | self.data_power_of_1000_cb.set_active(True) 320 | if Config.performance_disk_speed_bit == 1: 321 | self.data_bits_cb.set_active(True) 322 | if Config.performance_disk_speed_bit == 0: 323 | self.data_bits_cb.set_active(False) 324 | 325 | # Set active checkbutton if "Hide loop, ramdisk, zram disks" option is enabled. 326 | if Config.hide_loop_ramdisk_zram_disks == 1: 327 | self.hide_loop_ramdisk_zram_disks_cb.set_active(True) 328 | if Config.hide_loop_ramdisk_zram_disks == 0: 329 | self.hide_loop_ramdisk_zram_disks_cb.set_active(False) 330 | 331 | self.disk_precision_dd.set_selected(Config.performance_disk_data_precision) 332 | 333 | 334 | DiskMenu = DiskMenu() 335 | 336 | -------------------------------------------------------------------------------- /src/GpuMenu.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | from gi.repository import Gtk 4 | 5 | from .Config import Config 6 | from .Gpu import Gpu 7 | from .MainWindow import MainWindow 8 | from . import Common 9 | from . import Libsysmon 10 | 11 | _tr = Config._tr 12 | 13 | 14 | class GpuMenu: 15 | 16 | def __init__(self): 17 | 18 | self.name = "GpuMenu" 19 | 20 | self.menu_gui() 21 | 22 | 23 | def menu_gui(self): 24 | """ 25 | Generate menu GUI. 26 | """ 27 | 28 | # Popover 29 | self.menu_po = Gtk.Popover() 30 | 31 | # Grid (main) 32 | main_grid = Common.menu_main_grid() 33 | self.menu_po.set_child(main_grid) 34 | 35 | # Label - menu title (GPU) 36 | label = Common.menu_title_label(_tr("GPU")) 37 | main_grid.attach(label, 0, 0, 2, 1) 38 | 39 | # Button (Graph Color) 40 | self.graph_color_button = Common.graph_color_button(self) 41 | main_grid.attach(self.graph_color_button, 0, 1, 2, 1) 42 | 43 | # Separator 44 | separator = Common.menu_separator() 45 | main_grid.attach(separator, 0, 2, 2, 1) 46 | 47 | # Button (Reset) 48 | self.reset_button = Common.reset_button() 49 | main_grid.attach(self.reset_button, 0, 3, 2, 1) 50 | 51 | # Connect signals 52 | self.reset_button.connect("clicked", self.on_reset_button_clicked) 53 | 54 | 55 | def on_reset_button_clicked(self, widget): 56 | """ 57 | Reset all tab settings. 58 | """ 59 | 60 | Config.config_default_performance_gpu_func() 61 | Config.config_save_func() 62 | Libsysmon.gpu_set_selected_gpu(Gpu.selected_gpu, Gpu.default_gpu, Gpu.gpu_list) 63 | 64 | # Reset device list between Performance tab sub-tabs because selected device is reset. 65 | MainWindow.main_gui_device_selection_list() 66 | 67 | Common.update_tab_and_menu_gui(self, Gpu) 68 | 69 | 70 | GpuMenu = GpuMenu() 71 | 72 | -------------------------------------------------------------------------------- /src/Main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import gi 4 | gi.require_version('Gtk', '4.0') 5 | from gi.repository import Gtk 6 | 7 | 8 | class SMCApplication(Gtk.Application): 9 | 10 | def __init__(self): 11 | super().__init__(application_id="io.github.hakandundar34coding.system-monitoring-center") 12 | self.connect('activate', self.on_activate) 13 | self.main_window = None 14 | 15 | def on_activate(self, app): 16 | # Allow opening single instance of the application. 17 | if not self.main_window: 18 | from .MainWindow import MainWindow 19 | self.main_window = MainWindow.main_window 20 | self.main_window.set_application(self) 21 | self.main_window.present() 22 | 23 | 24 | localedir = None 25 | def main(_localedir): 26 | global localedir 27 | localedir = _localedir 28 | app = SMCApplication() 29 | return app.run(None) 30 | 31 | if __name__ == '__main__': 32 | app = SMCApplication() 33 | app.run(None) 34 | 35 | -------------------------------------------------------------------------------- /src/MemoryMenu.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | gi.require_version('Gdk', '4.0') 4 | from gi.repository import Gtk, Gdk 5 | 6 | from .Config import Config 7 | from .Memory import Memory 8 | from .Performance import Performance 9 | from .MainWindow import MainWindow 10 | from . import Common 11 | 12 | _tr = Config._tr 13 | 14 | 15 | class MemoryMenu: 16 | 17 | def __init__(self): 18 | 19 | self.name = "MemoryMenu" 20 | 21 | self.menu_gui() 22 | 23 | 24 | def menu_gui(self): 25 | """ 26 | Generate menu GUI. 27 | """ 28 | 29 | # Popover 30 | self.menu_po = Gtk.Popover() 31 | 32 | # Grid (main) 33 | main_grid = Common.menu_main_grid() 34 | self.menu_po.set_child(main_grid) 35 | 36 | # Label - menu title (Memory) 37 | label = Common.menu_title_label(_tr("Memory")) 38 | main_grid.attach(label, 0, 0, 2, 1) 39 | 40 | # Label (Graph - Show) 41 | label = Common.title_label(_tr("Graph - Show")) 42 | main_grid.attach(label, 0, 1, 2, 1) 43 | 44 | # CheckButton (RAM) 45 | self.ram_usage_cb = Common.checkbutton(_tr("RAM"), None) 46 | main_grid.attach(self.ram_usage_cb, 0, 2, 1, 1) 47 | 48 | # CheckButton (Memory) 49 | self.memory_usage_cb = Common.checkbutton(_tr("Memory"), self.ram_usage_cb) 50 | main_grid.attach(self.memory_usage_cb, 1, 2, 1, 1) 51 | 52 | # Separator 53 | separator = Common.menu_separator() 54 | main_grid.attach(separator, 0, 3, 2, 1) 55 | 56 | # Button (Graph Color) 57 | self.graph_color_button = Common.graph_color_button(self) 58 | main_grid.attach(self.graph_color_button, 0, 4, 2, 1) 59 | 60 | # Separator 61 | separator = Common.menu_separator() 62 | main_grid.attach(separator, 0, 5, 2, 1) 63 | 64 | # Label - title (Precision) 65 | label = Common.title_label(_tr("Precision")) 66 | main_grid.attach(label, 0, 6, 2, 1) 67 | 68 | # DropDown - precision (Memory) 69 | item_list = ['0', '0.0', '0.00', '0.000'] 70 | self.memory_precision_dd = Common.dropdown_and_model(item_list) 71 | main_grid.attach(self.memory_precision_dd, 0, 7, 2, 1) 72 | 73 | # Separator 74 | separator = Common.menu_separator() 75 | main_grid.attach(separator, 0, 8, 2, 1) 76 | 77 | # Label - title (Data Unit) 78 | label = Common.title_label(_tr("Data Unit")) 79 | main_grid.attach(label, 0, 9, 2, 1) 80 | 81 | # Label (Show data as powers of:) 82 | label = Gtk.Label() 83 | label.set_label(_tr("Show data as powers of") + ":") 84 | label.set_halign(Gtk.Align.START) 85 | main_grid.attach(label, 0, 10, 2, 1) 86 | 87 | # CheckButton (1024) 88 | self.data_power_of_1024_cb = Common.checkbutton("1024", None) 89 | main_grid.attach(self.data_power_of_1024_cb, 0, 11, 1, 1) 90 | 91 | # CheckButton (1000) 92 | self.data_power_of_1000_cb = Common.checkbutton("1000", self.data_power_of_1024_cb) 93 | main_grid.attach(self.data_power_of_1000_cb, 1, 11, 1, 1) 94 | 95 | # Separator 96 | separator = Common.menu_separator() 97 | main_grid.attach(separator, 0, 12, 2, 1) 98 | 99 | # Button (Reset) 100 | self.reset_button = Common.reset_button() 101 | main_grid.attach(self.reset_button, 0, 13, 2, 1) 102 | 103 | # Connect signals 104 | self.menu_po.connect("show", self.on_menu_po_show) 105 | self.reset_button.connect("clicked", self.on_reset_button_clicked) 106 | 107 | 108 | def connect_signals(self): 109 | """ 110 | Connect some of the signals to be able to disconnect them for setting GUI. 111 | """ 112 | 113 | self.ram_usage_cb.connect("toggled", self.on_memory_type_cb_toggled) 114 | self.memory_usage_cb.connect("toggled", self.on_memory_type_cb_toggled) 115 | self.data_power_of_1024_cb.connect("toggled", self.on_data_power_of_cb_toggled) 116 | self.data_power_of_1000_cb.connect("toggled", self.on_data_power_of_cb_toggled) 117 | self.memory_precision_dd.connect("notify::selected-item", self.on_selected_item_notify) 118 | 119 | 120 | def disconnect_signals(self): 121 | """ 122 | Disconnect some of the signals for setting GUI. 123 | """ 124 | 125 | self.ram_usage_cb.disconnect_by_func(self.on_memory_type_cb_toggled) 126 | self.memory_usage_cb.disconnect_by_func(self.on_memory_type_cb_toggled) 127 | self.data_power_of_1024_cb.disconnect_by_func(self.on_data_power_of_cb_toggled) 128 | self.data_power_of_1000_cb.disconnect_by_func(self.on_data_power_of_cb_toggled) 129 | self.memory_precision_dd.disconnect_by_func(self.on_selected_item_notify) 130 | 131 | 132 | def on_menu_po_show(self, widget): 133 | """ 134 | Run code when menu is shown. 135 | """ 136 | 137 | try: 138 | self.disconnect_signals() 139 | except TypeError: 140 | pass 141 | self.set_gui() 142 | self.connect_signals() 143 | 144 | 145 | def on_memory_type_cb_toggled(self, widget): 146 | """ 147 | Change memory type. 148 | """ 149 | 150 | if widget.get_active() == True: 151 | if widget == self.ram_usage_cb: 152 | Config.show_memory_usage_per_memory = 0 153 | if widget == self.memory_usage_cb: 154 | Config.show_memory_usage_per_memory = 1 155 | 156 | Common.save_tab_settings(Memory) 157 | 158 | 159 | def on_selected_item_notify(self, widget, parameter): 160 | """ 161 | Change memory usage percent precision. 162 | Notify signal is sent when DropDown widget selection is changed. 163 | Currently GtkExpression parameter for DropDown can not be used because of PyGObject. 164 | """ 165 | 166 | Config.performance_memory_data_precision = widget.get_selected() 167 | 168 | Common.save_tab_settings(Memory) 169 | 170 | 171 | def on_data_power_of_cb_toggled(self, widget): 172 | """ 173 | Change data unit powers of (1024 or 1000) selection. 174 | """ 175 | 176 | if self.data_power_of_1024_cb.get_active() == True: 177 | Config.performance_memory_data_unit = 0 178 | elif self.data_power_of_1000_cb.get_active() == True: 179 | Config.performance_memory_data_unit = 1 180 | 181 | Common.save_tab_settings(Memory) 182 | 183 | 184 | def on_reset_button_clicked(self, widget): 185 | """ 186 | Reset all tab settings. 187 | """ 188 | 189 | # Load default settings 190 | Config.config_default_performance_memory_func() 191 | Config.config_save_func() 192 | 193 | Common.update_tab_and_menu_gui(self, Memory) 194 | 195 | 196 | def set_gui(self): 197 | """ 198 | Set menu GUI items. 199 | """ 200 | 201 | # Select radiobutton appropriate for seleted/all devices chart setting 202 | if Config.show_memory_usage_per_memory == 0: 203 | self.ram_usage_cb.set_active(True) 204 | if Config.show_memory_usage_per_memory == 1: 205 | self.memory_usage_cb.set_active(True) 206 | 207 | # Set data unit checkboxes. 208 | if Config.performance_memory_data_unit == 0: 209 | self.data_power_of_1024_cb.set_active(True) 210 | if Config.performance_memory_data_unit == 1: 211 | self.data_power_of_1000_cb.set_active(True) 212 | 213 | self.memory_precision_dd.set_selected(Config.performance_memory_data_precision) 214 | 215 | 216 | MemoryMenu = MemoryMenu() 217 | 218 | -------------------------------------------------------------------------------- /src/Network.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | from gi.repository import Gtk 4 | 5 | from .Config import Config 6 | from .Performance import Performance 7 | from .MainWindow import MainWindow 8 | from . import Common 9 | from . import Libsysmon 10 | 11 | _tr = Config._tr 12 | 13 | 14 | class Network: 15 | 16 | def __init__(self): 17 | 18 | self.name = "Network" 19 | 20 | self.tab_gui() 21 | 22 | self.initial_already_run = 0 23 | 24 | 25 | def tab_gui(self): 26 | """ 27 | Generate tab GUI. 28 | """ 29 | 30 | self.tab_grid = Common.tab_grid() 31 | 32 | self.tab_title_grid() 33 | 34 | self.da_grid() 35 | 36 | self.information_grid() 37 | 38 | 39 | def tab_title_grid(self): 40 | """ 41 | Generate tab name, device name labels. 42 | """ 43 | 44 | # Grid (tab title) 45 | grid = Gtk.Grid() 46 | self.tab_grid.attach(grid, 0, 0, 1, 1) 47 | 48 | # Label (Network) 49 | label = Common.tab_title_label(_tr("Network")) 50 | grid.attach(label, 0, 0, 1, 2) 51 | 52 | # Label (device vendor-model label) 53 | self.device_vendor_model_label = Common.device_vendor_model_label() 54 | self.device_vendor_model_label.set_tooltip_text(_tr("Vendor") + "-" + _tr("Model")) 55 | grid.attach(self.device_vendor_model_label, 1, 0, 1, 1) 56 | 57 | # Label (device kernel name) 58 | self.device_kernel_name_label = Common.device_kernel_name_label() 59 | self.device_kernel_name_label.set_tooltip_text(_tr("Device Name In Kernel")) 60 | grid.attach(self.device_kernel_name_label, 1, 1, 1, 1) 61 | 62 | 63 | def da_grid(self): 64 | """ 65 | Generate tab drawingarea and related information labels. 66 | """ 67 | 68 | # Grid (drawingarea) 69 | grid = Gtk.Grid() 70 | grid.set_hexpand(True) 71 | grid.set_vexpand(True) 72 | self.tab_grid.attach(grid, 0, 1, 1, 1) 73 | 74 | # Label (drawingarea upper-left) 75 | label = Common.da_upper_lower_label(_tr("Download Speed") + " (-) & " + _tr("Upload Speed") + " (- -)", Gtk.Align.START) 76 | grid.attach(label, 0, 0, 1, 1) 77 | 78 | # Label (drawingarea upper-right) 79 | self.da_upper_right_label = Common.da_upper_lower_label("--", Gtk.Align.END) 80 | grid.attach(self.da_upper_right_label, 1, 0, 1, 1) 81 | 82 | # DrawingArea 83 | self.da_network_speed = Common.drawingarea(Performance.performance_line_charts_draw, "da_network_speed") 84 | grid.attach(self.da_network_speed, 0, 2, 2, 1) 85 | 86 | # Label (drawingarea lower-right) 87 | label = Common.da_upper_lower_label("0", Gtk.Align.END) 88 | grid.attach(label, 0, 3, 2, 1) 89 | 90 | 91 | def information_grid(self): 92 | """ 93 | Generate performance/information labels. 94 | """ 95 | 96 | # Grid (performance/information labels) 97 | performance_info_grid = Common.performance_info_grid() 98 | self.tab_grid.attach(performance_info_grid, 0, 2, 1, 1) 99 | 100 | # Styled information widgets (Download Speed and Upload Speed) 101 | # ScrolledWindow (Download Speed and Upload Speed) 102 | scrolledwindow, self.download_speed_label, self.upload_speed_label = Common.styled_information_scrolledwindow(_tr("Download Speed"), None, _tr("Upload Speed"), None) 103 | performance_info_grid.attach(scrolledwindow, 0, 0, 1, 1) 104 | 105 | # Styled information widgets (Downloaded Data and Uploaded Data) 106 | # ScrolledWindow (Downloaded Data and Uploaded Data) 107 | scrolledwindow, self.download_data_label, self.upload_data_label = Common.styled_information_scrolledwindow(_tr("Downloaded Data"), _tr("Measured value since last system start"), _tr("Uploaded Data"), _tr("Measured value since last system start")) 108 | performance_info_grid.attach(scrolledwindow, 0, 1, 1, 1) 109 | 110 | # Grid - Right information labels 111 | performance_info_right_grid = Common.performance_info_right_grid() 112 | performance_info_grid.attach(performance_info_right_grid, 1, 0, 1, 2) 113 | 114 | # Labels - Right information labels 115 | # Label (Connection Type) 116 | label = Common.static_information_label(_tr("Connection Type") + ":") 117 | performance_info_right_grid.attach(label, 0, 0, 1, 1) 118 | # Label (Connection Type) 119 | self.connection_type_label = Common.dynamic_information_label() 120 | performance_info_right_grid.attach(self.connection_type_label, 1, 0, 1, 1) 121 | 122 | # Label (Connected-SSID) 123 | label = Common.static_information_label(_tr("Connected") + "-" + _tr("SSID") + ":") 124 | performance_info_right_grid.attach(label, 0, 1, 1, 1) 125 | # Label (Connected-SSID) 126 | self.connected_ssid_label = Common.dynamic_information_label() 127 | performance_info_right_grid.attach(self.connected_ssid_label, 1, 1, 1, 1) 128 | 129 | # Label (Link Quality) 130 | label = Common.static_information_label(_tr("Link Quality") + ":") 131 | performance_info_right_grid.attach(label, 0, 2, 1, 1) 132 | # Label (Link Quality) 133 | self.link_quality_label = Common.dynamic_information_label() 134 | performance_info_right_grid.attach(self.link_quality_label, 1, 2, 1, 1) 135 | 136 | # Label (IPv4 Address) 137 | label = Common.static_information_label(_tr("IPv4 Address") + ":") 138 | performance_info_right_grid.attach(label, 0, 3, 1, 1) 139 | # Label (IPv4 Address) 140 | self.ipv4_address_label = Common.dynamic_information_label() 141 | performance_info_right_grid.attach(self.ipv4_address_label, 1, 3, 1, 1) 142 | 143 | # Label (IPv6 Address) 144 | label = Common.static_information_label(_tr("IPv6 Address") + ":") 145 | performance_info_right_grid.attach(label, 0, 4, 1, 1) 146 | # Label (IPv6 Address) 147 | self.ipv6_address_label = Common.dynamic_information_label() 148 | performance_info_right_grid.attach(self.ipv6_address_label, 1, 4, 1, 1) 149 | 150 | # Label (MAC Address) 151 | label = Common.static_information_label(_tr("MAC Address") + ":") 152 | performance_info_right_grid.attach(label, 0, 5, 1, 1) 153 | # Label (MAC Address) 154 | self.mac_address_label = Common.dynamic_information_label() 155 | performance_info_right_grid.attach(self.mac_address_label, 1, 5, 1, 1) 156 | 157 | 158 | def initial_func(self): 159 | """ 160 | Initial code which which is not wanted to be run in every loop. 161 | """ 162 | 163 | network_card_list = Performance.network_card_list 164 | selected_network_card = Performance.selected_network_card 165 | 166 | 167 | # Get information. 168 | network_card_device_model_name = Libsysmon.get_network_card_device_model_name(selected_network_card) 169 | connection_type = Libsysmon.get_connection_type(selected_network_card) 170 | network_card_mac_address = Libsysmon.get_mac_address(selected_network_card) 171 | network_address_ipv4, network_address_ipv6 = Libsysmon.get_ipv4_ipv6_address(selected_network_card) 172 | 173 | 174 | # Set Network tab label texts by using information get 175 | self.device_vendor_model_label.set_label(network_card_device_model_name) 176 | self.device_kernel_name_label.set_label(selected_network_card) 177 | self.connection_type_label.set_label(connection_type) 178 | self.ipv4_address_label.set_label(network_address_ipv4) 179 | self.ipv6_address_label.set_label(network_address_ipv6) 180 | self.mac_address_label.set_label(network_card_mac_address) 181 | 182 | self.initial_already_run = 1 183 | 184 | 185 | def loop_func(self): 186 | """ 187 | Get and show information on the GUI on every loop. 188 | """ 189 | 190 | if self.initial_already_run == 0: 191 | self.initial_func() 192 | 193 | network_card_list = Performance.network_card_list 194 | selected_network_card = Performance.selected_network_card 195 | 196 | # Run "initial_func" if selected network card is changed since the last loop. 197 | try: 198 | if self.selected_network_card_prev != selected_network_card: 199 | self.initial_func() 200 | # Avoid errors if this is first loop of the function. 201 | except AttributeError: 202 | pass 203 | self.selected_network_card_prev = selected_network_card 204 | 205 | network_receive_speed = Performance.network_receive_speed 206 | network_send_speed = Performance.network_send_speed 207 | 208 | performance_network_data_precision = Config.performance_network_data_precision 209 | performance_network_data_unit = Config.performance_network_data_unit 210 | performance_network_speed_bit = Config.performance_network_speed_bit 211 | 212 | self.da_network_speed.queue_draw() 213 | 214 | # Run "main_gui_device_selection_list" if selected device list is changed since the last loop. 215 | network_card_list = Performance.network_card_list 216 | try: 217 | if self.network_card_list_prev != network_card_list: 218 | MainWindow.main_gui_device_selection_list() 219 | # Avoid error if this is first loop of the function. 220 | except AttributeError: 221 | pass 222 | self.network_card_list_prev = list(network_card_list) 223 | 224 | 225 | # Get information. 226 | network_send_bytes, network_receive_bytes = Libsysmon.get_network_download_upload_data(selected_network_card) 227 | network_card_connected = Libsysmon.get_network_card_connected(selected_network_card) 228 | network_ssid = Libsysmon.get_network_ssid(selected_network_card) 229 | network_link_quality = Libsysmon.get_network_link_quality(selected_network_card, network_card_connected) 230 | 231 | 232 | # Set and update Network tab label texts by using information get 233 | self.download_speed_label.set_label(f'{Libsysmon.data_unit_converter("speed", performance_network_speed_bit, network_receive_speed[selected_network_card][-1], performance_network_data_unit, performance_network_data_precision)}/s') 234 | self.upload_speed_label.set_label(f'{Libsysmon.data_unit_converter("speed", performance_network_speed_bit, network_send_speed[selected_network_card][-1], performance_network_data_unit, performance_network_data_precision)}/s') 235 | self.download_data_label.set_label(Libsysmon.data_unit_converter("data", "none", network_receive_bytes, performance_network_data_unit, performance_network_data_precision)) 236 | self.upload_data_label.set_label(Libsysmon.data_unit_converter("data", "none", network_send_bytes, performance_network_data_unit, performance_network_data_precision)) 237 | self.connected_ssid_label.set_label(f'{network_card_connected} - {network_ssid}') 238 | self.link_quality_label.set_label(network_link_quality) 239 | 240 | 241 | Network = Network() 242 | 243 | -------------------------------------------------------------------------------- /src/NetworkMenu.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | gi.require_version('Gdk', '4.0') 4 | from gi.repository import Gtk, Gdk 5 | 6 | from .Config import Config 7 | from .Network import Network 8 | from .Performance import Performance 9 | from .MainWindow import MainWindow 10 | from . import Common 11 | 12 | _tr = Config._tr 13 | 14 | 15 | class NetworkMenu: 16 | 17 | def __init__(self): 18 | 19 | self.name = "NetworkMenu" 20 | 21 | self.menu_gui() 22 | 23 | 24 | def menu_gui(self): 25 | """ 26 | Generate menu GUI. 27 | """ 28 | 29 | # Popover 30 | self.menu_po = Gtk.Popover() 31 | 32 | # Grid (main) 33 | main_grid = Common.menu_main_grid() 34 | self.menu_po.set_child(main_grid) 35 | 36 | # Label - menu title (Network) 37 | label = Common.menu_title_label(_tr("Network")) 38 | main_grid.attach(label, 0, 0, 2, 1) 39 | 40 | # Label (Graph - Show) 41 | label = Common.title_label(_tr("Graph - Show")) 42 | main_grid.attach(label, 0, 1, 2, 1) 43 | 44 | # CheckButton (Download Speed) 45 | self.download_speed_cb = Common.checkbutton(_tr("Download Speed"), None) 46 | main_grid.attach(self.download_speed_cb, 0, 2, 1, 1) 47 | 48 | # CheckButton (Upload Speed) 49 | self.upload_speed_cb = Common.checkbutton(_tr("Upload Speed"), None) 50 | main_grid.attach(self.upload_speed_cb, 1, 2, 1, 1) 51 | 52 | # CheckButton (Selected Device) 53 | self.selected_device_cb = Common.checkbutton(_tr("Selected Device"), None) 54 | main_grid.attach(self.selected_device_cb, 0, 3, 1, 1) 55 | 56 | # CheckButton (All Devices) 57 | self.all_devices_cb = Common.checkbutton(_tr("All Devices"), self.selected_device_cb) 58 | main_grid.attach(self.all_devices_cb, 1, 3, 1, 1) 59 | 60 | # Separator 61 | separator = Common.menu_separator() 62 | main_grid.attach(separator, 0, 4, 2, 1) 63 | 64 | # Button (Graph Color) 65 | self.graph_color_button = Common.graph_color_button(self) 66 | main_grid.attach(self.graph_color_button, 0, 5, 2, 1) 67 | 68 | # Separator 69 | separator = Common.menu_separator() 70 | main_grid.attach(separator, 0, 6, 2, 1) 71 | 72 | # Label - title (Precision) 73 | label = Common.title_label(_tr("Precision")) 74 | main_grid.attach(label, 0, 7, 2, 1) 75 | 76 | # DropDown - precision (Network) 77 | item_list = ['0', '0.0', '0.00', '0.000'] 78 | self.network_precision_dd = Common.dropdown_and_model(item_list) 79 | main_grid.attach(self.network_precision_dd, 0, 8, 2, 1) 80 | 81 | # Separator 82 | separator = Common.menu_separator() 83 | main_grid.attach(separator, 0, 9, 2, 1) 84 | 85 | # Label - title (Data Unit) 86 | label = Common.title_label(_tr("Data Unit")) 87 | main_grid.attach(label, 0, 10, 2, 1) 88 | 89 | # Label (Show data as powers of:) 90 | label = Gtk.Label() 91 | label.set_label(_tr("Show data as powers of") + ":") 92 | label.set_halign(Gtk.Align.START) 93 | main_grid.attach(label, 0, 11, 2, 1) 94 | 95 | # CheckButton (1024) 96 | self.data_power_of_1024_cb = Common.checkbutton("1024", None) 97 | main_grid.attach(self.data_power_of_1024_cb, 0, 12, 1, 1) 98 | 99 | # CheckButton (1000) 100 | self.data_power_of_1000_cb = Common.checkbutton("1000", self.data_power_of_1024_cb) 101 | main_grid.attach(self.data_power_of_1000_cb, 1, 12, 1, 1) 102 | 103 | # CheckButton (Show speed units as multiples of bits) 104 | self.data_bits_cb = Common.checkbutton(_tr("Show speed units as multiples of bits"), None) 105 | main_grid.attach(self.data_bits_cb, 0, 13, 2, 1) 106 | 107 | # Separator 108 | separator = Common.menu_separator() 109 | main_grid.attach(separator, 0, 14, 2, 1) 110 | 111 | # Button (Reset) 112 | self.reset_button = Common.reset_button() 113 | main_grid.attach(self.reset_button, 0, 18, 2, 1) 114 | 115 | # Connect signals 116 | self.menu_po.connect("show", self.on_menu_po_show) 117 | self.reset_button.connect("clicked", self.on_reset_button_clicked) 118 | 119 | 120 | def connect_signals(self): 121 | """ 122 | Connect some of the signals to be able to disconnect them for setting GUI. 123 | """ 124 | 125 | self.download_speed_cb.connect("toggled", self.on_download_speed_cb_toggled) 126 | self.upload_speed_cb.connect("toggled", self.on_upload_speed_cb_toggled) 127 | self.selected_device_cb.connect("toggled", self.on_network_menu_device_selection_cb) 128 | self.all_devices_cb.connect("toggled", self.on_network_menu_device_selection_cb) 129 | self.data_power_of_1024_cb.connect("toggled", self.on_data_unit_radiobuttons_toggled) 130 | self.data_power_of_1000_cb.connect("toggled", self.on_data_unit_radiobuttons_toggled) 131 | self.data_bits_cb.connect("toggled", self.on_data_bits_cb_toggled) 132 | self.network_precision_dd.connect("notify::selected-item", self.on_selected_item_notify) 133 | 134 | 135 | def disconnect_signals(self): 136 | """ 137 | Disconnect some of the signals for setting GUI. 138 | """ 139 | 140 | self.download_speed_cb.disconnect_by_func(self.on_download_speed_cb_toggled) 141 | self.upload_speed_cb.disconnect_by_func(self.on_upload_speed_cb_toggled) 142 | self.selected_device_cb.disconnect_by_func(self.on_network_menu_device_selection_cb) 143 | self.all_devices_cb.disconnect_by_func(self.on_network_menu_device_selection_cb) 144 | self.data_power_of_1024_cb.disconnect_by_func(self.on_data_unit_radiobuttons_toggled) 145 | self.data_power_of_1000_cb.disconnect_by_func(self.on_data_unit_radiobuttons_toggled) 146 | self.data_bits_cb.disconnect_by_func(self.on_data_bits_cb_toggled) 147 | self.network_precision_dd.disconnect_by_func(self.on_selected_item_notify) 148 | 149 | 150 | def on_menu_po_show(self, widget): 151 | """ 152 | Run code when menu is shown. 153 | """ 154 | 155 | try: 156 | self.disconnect_signals() 157 | except TypeError: 158 | pass 159 | self.set_gui() 160 | self.connect_signals() 161 | 162 | 163 | def on_download_speed_cb_toggled(self, widget): 164 | """ 165 | Show/Hide network read speed line. 166 | """ 167 | 168 | if widget.get_active() == True: 169 | Config.plot_network_download_speed = 1 170 | if widget.get_active() == False: 171 | if self.upload_speed_cb.get_active() == False: 172 | widget.set_active(True) 173 | return 174 | Config.plot_network_download_speed = 0 175 | 176 | Common.save_tab_settings(Network) 177 | 178 | 179 | def on_upload_speed_cb_toggled(self, widget): 180 | """ 181 | Show/Hide network write speed line. 182 | """ 183 | 184 | if widget.get_active() == True: 185 | Config.plot_network_upload_speed = 1 186 | if widget.get_active() == False: 187 | if self.download_speed_cb.get_active() == False: 188 | widget.set_active(True) 189 | return 190 | Config.plot_network_upload_speed = 0 191 | 192 | Common.save_tab_settings(Network) 193 | 194 | 195 | def on_network_menu_device_selection_cb(self, widget): 196 | """ 197 | Set device selection (Selected/All) for showing speed data. 198 | """ 199 | 200 | if widget.get_active() == True: 201 | if widget == self.selected_device_cb: 202 | Config.show_network_usage_per_network_card = 0 203 | if widget == self.all_devices_cb: 204 | Config.show_network_usage_per_network_card = 1 205 | 206 | Common.save_tab_settings(Network) 207 | 208 | 209 | def on_selected_item_notify(self, widget, parameter): 210 | """ 211 | Change network data/speed precision. 212 | Notify signal is sent when DropDown widget selection is changed. 213 | Currently GtkExpression parameter for DropDown can not be used because of PyGObject. 214 | """ 215 | 216 | Config.performance_network_data_precision = widget.get_selected() 217 | 218 | Common.save_tab_settings(Network) 219 | 220 | 221 | def on_data_unit_radiobuttons_toggled(self, widget): 222 | """ 223 | Change data unit powers of (1024 or 1000) selection. 224 | """ 225 | 226 | if self.data_power_of_1024_cb.get_active() == True: 227 | Config.performance_network_data_unit = 0 228 | elif self.data_power_of_1000_cb.get_active() == True: 229 | Config.performance_network_data_unit = 1 230 | 231 | Common.save_tab_settings(Network) 232 | 233 | 234 | def on_data_bits_cb_toggled(self, widget): 235 | """ 236 | Show speed units as multiples of bits/bytes. 237 | """ 238 | 239 | if widget.get_active() == True: 240 | Config.performance_network_speed_bit = 1 241 | else: 242 | Config.performance_network_speed_bit = 0 243 | 244 | Common.save_tab_settings(Network) 245 | 246 | 247 | def on_reset_button_clicked(self, widget): 248 | """ 249 | Reset all tab settings. 250 | """ 251 | 252 | # Load default settings 253 | Config.config_default_performance_network_func() 254 | Config.config_save_func() 255 | Performance.performance_set_selected_network_card_func() 256 | 257 | # Reset device list between Performance tab sub-tabs because selected device is reset. 258 | MainWindow.main_gui_device_selection_list() 259 | 260 | Common.update_tab_and_menu_gui(self, Network) 261 | 262 | 263 | def set_gui(self): 264 | """ 265 | Set menu GUI items. 266 | """ 267 | 268 | # Set active checkbuttons if network download speed/network upload speed values are "1" 269 | if Config.plot_network_download_speed == 1: 270 | self.download_speed_cb.set_active(True) 271 | if Config.plot_network_download_speed == 0: 272 | self.download_speed_cb.set_active(False) 273 | if Config.plot_network_upload_speed == 1: 274 | self.upload_speed_cb.set_active(True) 275 | if Config.plot_network_upload_speed == 0: 276 | self.upload_speed_cb.set_active(False) 277 | 278 | # Select radiobutton appropriate for seleted/all devices chart setting 279 | if Config.show_network_usage_per_network_card == 0: 280 | self.selected_device_cb.set_active(True) 281 | if Config.show_network_usage_per_network_card == 1: 282 | self.all_devices_cb.set_active(True) 283 | 284 | # Set data unit radiobuttons and checkbuttons. 285 | if Config.performance_network_data_unit == 0: 286 | self.data_power_of_1024_cb.set_active(True) 287 | if Config.performance_network_data_unit == 1: 288 | self.data_power_of_1000_cb.set_active(True) 289 | if Config.performance_network_speed_bit == 1: 290 | self.data_bits_cb.set_active(True) 291 | if Config.performance_network_speed_bit == 0: 292 | self.data_bits_cb.set_active(False) 293 | 294 | self.network_precision_dd.set_selected(Config.performance_network_data_precision) 295 | 296 | NetworkMenu = NetworkMenu() 297 | 298 | -------------------------------------------------------------------------------- /src/Sensors.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | from gi.repository import Gtk 4 | 5 | import os 6 | 7 | from .Config import Config 8 | from .MainWindow import MainWindow 9 | from . import Common 10 | from . import Libsysmon 11 | 12 | _tr = Config._tr 13 | 14 | 15 | class Sensors: 16 | 17 | def __init__(self): 18 | 19 | self.name = "Sensors" 20 | 21 | self.tab_gui() 22 | 23 | self.initial_already_run = 0 24 | 25 | 26 | def tab_gui(self): 27 | """ 28 | Generate tab GUI. 29 | """ 30 | 31 | self.tab_grid = Common.tab_grid() 32 | 33 | self.tab_title_grid() 34 | 35 | self.tab_info_grid() 36 | 37 | self.gui_signals() 38 | 39 | 40 | def tab_title_grid(self): 41 | """ 42 | Generate tab name label and searchentry. 43 | """ 44 | 45 | # Grid (tab title) 46 | grid = Gtk.Grid() 47 | grid.set_column_spacing(5) 48 | self.tab_grid.attach(grid, 0, 0, 1, 1) 49 | 50 | # Label (Sensors) 51 | label = Common.tab_title_label(_tr("Sensors")) 52 | grid.attach(label, 0, 0, 1, 1) 53 | 54 | # SearchEntry 55 | self.searchentry = Common.searchentry(self.on_searchentry_changed) 56 | grid.attach(self.searchentry, 1, 0, 1, 1) 57 | 58 | 59 | def tab_info_grid(self): 60 | """ 61 | Generate information GUI objects. 62 | """ 63 | 64 | # ScrolledWindow 65 | scrolledwindow = Gtk.ScrolledWindow() 66 | scrolledwindow.set_hexpand(True) 67 | scrolledwindow.set_vexpand(True) 68 | self.tab_grid.attach(scrolledwindow, 0, 1, 1, 1) 69 | 70 | # TreeView 71 | self.treeview = Gtk.TreeView() 72 | self.treeview.set_activate_on_single_click(True) 73 | self.treeview.set_show_expanders(False) 74 | self.treeview.set_fixed_height_mode(True) 75 | self.treeview.set_headers_clickable(True) 76 | self.treeview.set_enable_search(True) 77 | self.treeview.set_search_column(2) 78 | self.treeview.set_tooltip_column(2) 79 | scrolledwindow.set_child(self.treeview) 80 | 81 | 82 | def gui_signals(self): 83 | """ 84 | Connect GUI signals. 85 | """ 86 | 87 | # SeachEntry focus action and accelerator 88 | Common.searchentry_focus_action_and_accelerator(MainWindow) 89 | 90 | 91 | def on_searchentry_changed(self, widget): 92 | """ 93 | Called by searchentry when text is changed. 94 | """ 95 | 96 | sensor_search_text = self.searchentry.get_text().lower() 97 | 98 | # Set visible/hidden sensor data 99 | for piter in self.piter_list: 100 | self.treestore.set_value(piter, 0, False) 101 | sensor_data_text_in_model = self.treestore.get_value(piter, self.filter_column) 102 | if sensor_search_text in str(sensor_data_text_in_model).lower(): 103 | self.treestore.set_value(piter, 0, True) 104 | 105 | 106 | def initial_func(self): 107 | """ 108 | Initial code which which is not wanted to be run in every loop. 109 | """ 110 | 111 | self.row_data_list = [ 112 | [0, _tr('Device'), 3, 2, 3, [bool, str, str], ['internal_column', 'CellRendererPixbuf', 'CellRendererText'], ['no_cell_attribute', 'icon_name', 'text'], [0, 1, 2], ['no_cell_alignment', 0.0, 0.0], ['no_set_expand', False, False], ['no_cell_function', 'no_cell_function', 'no_cell_function']], 113 | [1, _tr('Name'), 1, 1, 1, [str], ['CellRendererText'], ['text'], [0], [0.0], [False], ['no_cell_function']], 114 | [2, _tr('Current Value'), 1, 1, 1, [str], ['CellRendererText'], ['text'], [0], [1.0], [False], ['no_cell_function']], 115 | [3, _tr('High'), 1, 1, 1, [str], ['CellRendererText'], ['text'], [0], [1.0], [False], ['no_cell_function']], 116 | [4, _tr('Critical'), 1, 1, 1, [str], ['CellRendererText'], ['text'], [0], [1.0], [False], ['no_cell_function']] 117 | ] 118 | 119 | Common.reset_tab_settings(self) 120 | 121 | self.tab_data_rows_prev = [] 122 | self.treeview_columns_shown_prev = [] 123 | self.data_row_sorting_column_prev = "" 124 | self.data_row_sorting_order_prev = "" 125 | self.data_column_order_prev = [] 126 | self.data_column_widths_prev = [] 127 | 128 | self.filter_column = self.row_data_list[0][2] - 1 129 | 130 | self.initial_already_run = 1 131 | 132 | 133 | def loop_func(self): 134 | """ 135 | Initial code which which is not wanted to be run in every loop. 136 | """ 137 | 138 | if self.initial_already_run == 0: 139 | self.initial_func() 140 | 141 | update_interval = Config.update_interval 142 | 143 | # Define global variables and get treeview columns, sort column/order, column widths, etc. 144 | self.treeview_columns_shown = Config.sensors_treeview_columns_shown 145 | self.data_row_sorting_column = Config.sensors_data_row_sorting_column 146 | self.data_row_sorting_order = Config.sensors_data_row_sorting_order 147 | self.data_column_order = Config.sensors_data_column_order 148 | self.data_column_widths = Config.sensors_data_column_widths 149 | self.temperature_unit = Config.temperature_unit 150 | # For obtaining lower CPU usage 151 | treeview_columns_shown = self.treeview_columns_shown 152 | treeview_columns_shown = set(treeview_columns_shown) 153 | 154 | rows_data_dict = Libsysmon.get_sensors_information(self.temperature_unit) 155 | self.rows_data_dict_prev = dict(rows_data_dict) 156 | sensor_unique_id_list = rows_data_dict["sensor_unique_id_list"] 157 | 158 | # Get and append sensor data 159 | tab_data_rows = [] 160 | for sensor_unique_id in sensor_unique_id_list: 161 | row_data_dict = rows_data_dict[sensor_unique_id] 162 | sensor_type = row_data_dict["sensor_type"] 163 | sensor_group_name = row_data_dict["sensor_group_name"] 164 | sensor_name = row_data_dict["sensor_name"] 165 | current_value = row_data_dict["current_value"] 166 | max_value = row_data_dict["max_value"] 167 | critical_value = row_data_dict["critical_value"] 168 | 169 | if sensor_type == "temperature": 170 | sensor_image = "system-monitoring-center-temperature-symbolic" 171 | elif sensor_type == "fan": 172 | sensor_image = "system-monitoring-center-fan-symbolic" 173 | elif sensor_type == "voltage_current_power": 174 | sensor_image = "system-monitoring-center-voltage-symbolic" 175 | 176 | tab_data_row = [True, sensor_image, sensor_group_name, sensor_name, current_value, max_value, critical_value] 177 | 178 | # Append sensor data list into main list 179 | tab_data_rows.append(tab_data_row) 180 | 181 | self.tab_data_rows = tab_data_rows 182 | 183 | # Convert set to list (it was set before getting process information) 184 | treeview_columns_shown = sorted(list(treeview_columns_shown)) 185 | 186 | reset_row_unique_data_list_prev = Common.treeview_add_remove_columns(self) 187 | Common.treeview_reorder_columns_sort_rows_set_column_widths(self) 188 | 189 | # Clear piter_list and treestore because sensor data (new/removed) tracking is not performed. 190 | # Because there may be same named sensors and tracking may not be successful while sensors have no unique 191 | # identity (more computer examples are needed for understanding if sensors have unique information). 192 | # PCI tree path could be get from sensor files but this may not be worth because code will be more complex and 193 | # it may not be an exact solution for all sensors. Also CPU usage is very low 194 | # (about 0.67-0.84%, tested on Core i7-2630QM 4-core notebook) even treestore is cleared and sensor data is appended from zero. 195 | self.piter_list = [] 196 | self.treestore.clear() 197 | 198 | # Append sensor data into treeview 199 | for tab_data_row in tab_data_rows: 200 | self.piter_list.append(self.treestore.append(None, tab_data_row)) 201 | # Update search results. 202 | self.on_searchentry_changed(self.searchentry) 203 | 204 | Common.searchentry_update_placeholder_text(self, _tr("Sensors")) 205 | 206 | self.treeview_columns_shown_prev = self.treeview_columns_shown 207 | self.data_row_sorting_column_prev = self.data_row_sorting_column 208 | self.data_row_sorting_order_prev = self.data_row_sorting_order 209 | self.data_column_order_prev = self.data_column_order 210 | self.data_column_widths_prev = self.data_column_widths 211 | 212 | 213 | Sensors = Sensors() 214 | 215 | -------------------------------------------------------------------------------- /src/SensorsMenu.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | from gi.repository import Gtk 4 | 5 | from .Config import Config 6 | from .Sensors import Sensors 7 | from . import Common 8 | 9 | _tr = Config._tr 10 | 11 | 12 | class SensorsMenu: 13 | 14 | def __init__(self): 15 | 16 | self.name = "SensorsMenu" 17 | 18 | self.menu_gui() 19 | 20 | 21 | def menu_gui(self): 22 | """ 23 | Generate menu GUI. 24 | """ 25 | 26 | # Popover 27 | self.menu_po = Gtk.Popover() 28 | 29 | # Grid (main) 30 | main_grid = Common.menu_main_grid() 31 | self.menu_po.set_child(main_grid) 32 | 33 | # Label - menu title (Sensors) 34 | label = Common.menu_title_label(_tr("Sensors")) 35 | main_grid.attach(label, 0, 0, 2, 1) 36 | 37 | # Label (Data Unit) 38 | label = Common.title_label(_tr("Data Unit")) 39 | main_grid.attach(label, 0, 1, 2, 1) 40 | 41 | # Label (Temperature) 42 | label = Gtk.Label() 43 | label.set_label(_tr("Temperature")) 44 | label.set_halign(Gtk.Align.CENTER) 45 | main_grid.attach(label, 0, 2, 1, 1) 46 | 47 | # CheckButton (Celsius) 48 | self.temperature_unit_celsius_cb = Common.checkbutton("°C", None) 49 | main_grid.attach(self.temperature_unit_celsius_cb, 0, 3, 1, 1) 50 | 51 | # CheckButton (Fahrenheit) 52 | self.temperature_unit_fahrenheit_cb = Common.checkbutton("°F", self.temperature_unit_celsius_cb) 53 | main_grid.attach(self.temperature_unit_fahrenheit_cb, 1, 3, 1, 1) 54 | 55 | # Separator 56 | separator = Common.menu_separator() 57 | main_grid.attach(separator, 0, 4, 2, 1) 58 | 59 | # Button (Reset) 60 | self.reset_button = Common.reset_button() 61 | main_grid.attach(self.reset_button, 0, 5, 2, 1) 62 | 63 | # Connect signals 64 | self.reset_button.connect("clicked", self.on_reset_button_clicked) 65 | self.menu_po.connect("show", self.on_menu_po_show) 66 | 67 | 68 | def connect_signals(self): 69 | """ 70 | Connect some of the signals to be able to disconnect them for setting GUI. 71 | """ 72 | 73 | self.temperature_unit_celsius_cb.connect("toggled", self.on_temperature_unit_cb_toggled) 74 | self.temperature_unit_fahrenheit_cb.connect("toggled", self.on_temperature_unit_cb_toggled) 75 | 76 | 77 | def disconnect_signals(self): 78 | """ 79 | Disconnect some of the signals for setting GUI. 80 | """ 81 | 82 | self.temperature_unit_celsius_cb.disconnect_by_func(self.on_temperature_unit_cb_toggled) 83 | self.temperature_unit_fahrenheit_cb.disconnect_by_func(self.on_temperature_unit_cb_toggled) 84 | 85 | 86 | def on_menu_po_show(self, widget): 87 | """ 88 | Run code when menu is shown. 89 | """ 90 | 91 | try: 92 | self.disconnect_signals() 93 | except TypeError: 94 | pass 95 | self.set_gui() 96 | self.connect_signals() 97 | 98 | 99 | def on_temperature_unit_cb_toggled(self, widget): 100 | """ 101 | Set temperature units. 102 | """ 103 | 104 | if widget.get_active() == True: 105 | if widget == self.temperature_unit_celsius_cb: 106 | Config.temperature_unit = "celsius" 107 | if widget == self.temperature_unit_fahrenheit_cb: 108 | Config.temperature_unit = "fahrenheit" 109 | 110 | Common.save_tab_settings(Sensors) 111 | 112 | 113 | def on_reset_button_clicked(self, widget): 114 | """ 115 | Reset all tab settings. 116 | """ 117 | 118 | # Load default settings 119 | Config.config_default_performance_sensors_func() 120 | Config.config_save_func() 121 | 122 | Common.update_tab_and_menu_gui(self, Sensors) 123 | 124 | 125 | def set_gui(self): 126 | """ 127 | Set menu GUI items. 128 | """ 129 | 130 | # Select checkbutton appropriate for temperature unit setting 131 | if Config.temperature_unit == "celsius": 132 | self.temperature_unit_celsius_cb.set_active(True) 133 | if Config.temperature_unit == "fahrenheit": 134 | self.temperature_unit_fahrenheit_cb.set_active(True) 135 | 136 | 137 | SensorsMenu = SensorsMenu() 138 | 139 | -------------------------------------------------------------------------------- /src/ServicesMenu.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | from gi.repository import Gtk 4 | 5 | from .Config import Config 6 | from .Services import Services 7 | from .MainWindow import MainWindow 8 | from . import Common 9 | 10 | _tr = Config._tr 11 | 12 | 13 | class ServicesMenu: 14 | 15 | def __init__(self): 16 | 17 | self.menu_gui() 18 | 19 | 20 | def menu_gui(self): 21 | """ 22 | Generate menu GUI. 23 | """ 24 | 25 | # Popover 26 | self.menu_po = Gtk.Popover() 27 | 28 | # Grid (main) 29 | main_grid = Common.menu_main_grid() 30 | self.menu_po.set_child(main_grid) 31 | 32 | # Label - menu title (Services) 33 | label = Common.menu_title_label(_tr("Services")) 34 | main_grid.attach(label, 0, 0, 1, 1) 35 | 36 | # Notebook 37 | notebook = Gtk.Notebook() 38 | notebook.set_hexpand(True) 39 | notebook.set_vexpand(True) 40 | main_grid.attach(notebook, 0, 1, 1, 1) 41 | 42 | # Tab pages and ScrolledWindow 43 | # "Add/Remove Columns" tab 44 | label = Gtk.Label() 45 | label.set_label(_tr("Add/Remove Columns")) 46 | self.grid_add_remove_columns_tab = Gtk.Grid() 47 | self.grid_add_remove_columns_tab.set_margin_top(15) 48 | self.grid_add_remove_columns_tab.set_margin_bottom(5) 49 | self.grid_add_remove_columns_tab.set_margin_start(5) 50 | self.grid_add_remove_columns_tab.set_margin_end(5) 51 | self.grid_add_remove_columns_tab.set_row_spacing(5) 52 | notebook.append_page(self.grid_add_remove_columns_tab, label) 53 | 54 | # Button (Reset) 55 | self.reset_button = Common.reset_button() 56 | main_grid.attach(self.reset_button, 0, 2, 1, 1) 57 | 58 | # "Add/Remove Columns" tab GUI 59 | self.add_remove_columns_tab_gui() 60 | 61 | # GUI signals 62 | self.gui_signals() 63 | 64 | 65 | def add_remove_columns_tab_gui(self): 66 | """ 67 | Generate "Add/Remove Columns" tab GUI objects. 68 | """ 69 | 70 | # Grid 71 | grid = Gtk.Grid() 72 | grid.set_margin_top(5) 73 | grid.set_margin_bottom(5) 74 | grid.set_margin_start(5) 75 | grid.set_margin_end(5) 76 | grid.set_column_spacing(10) 77 | grid.set_row_spacing(3) 78 | self.grid_add_remove_columns_tab.attach(grid, 0, 0, 1, 1) 79 | 80 | # Label - tab title (Add/Remove Columns) 81 | label = Common.title_label(_tr("Add/Remove Columns")) 82 | grid.attach(label, 0, 0, 2, 1) 83 | 84 | # CheckButton (Name) 85 | self.name_cb = Common.checkbutton(_tr("Name"), None) 86 | self.name_cb.set_active(True) 87 | self.name_cb.set_sensitive(False) 88 | grid.attach(self.name_cb, 0, 1, 1, 1) 89 | 90 | # CheckButton (State) 91 | self.state_cb = Common.checkbutton(_tr("State"), None) 92 | grid.attach(self.state_cb, 0, 2, 1, 1) 93 | 94 | # CheckButton (Main PID) 95 | self.main_pid_cb = Common.checkbutton(_tr("Main PID"), None) 96 | grid.attach(self.main_pid_cb, 0, 3, 1, 1) 97 | 98 | # CheckButton (Active State) 99 | self.active_state_cb = Common.checkbutton(_tr("Active State"), None) 100 | grid.attach(self.active_state_cb, 0, 4, 1, 1) 101 | 102 | # CheckButton (Load State) 103 | self.load_state_cb = Common.checkbutton(_tr("Load State"), None) 104 | grid.attach(self.load_state_cb, 1, 1, 1, 1) 105 | 106 | # CheckButton (Sub-State) 107 | self.sub_state_cb = Common.checkbutton(_tr("Sub-State"), None) 108 | grid.attach(self.sub_state_cb, 1, 2, 1, 1) 109 | 110 | # CheckButton (Memory (RSS)) 111 | self.memory_rss_cb = Common.checkbutton(_tr("Memory (RSS)"), None) 112 | grid.attach(self.memory_rss_cb, 1, 3, 1, 1) 113 | 114 | # CheckButton (Description) 115 | self.description_cb = Common.checkbutton(_tr("Description"), None) 116 | grid.attach(self.description_cb, 1, 4, 1, 1) 117 | 118 | 119 | def gui_signals(self): 120 | """ 121 | Connect GUI signals. 122 | """ 123 | 124 | self.menu_po.connect("show", self.on_menu_po_show) 125 | self.reset_button.connect("clicked", self.on_reset_button_clicked) 126 | 127 | 128 | def connect_signals(self): 129 | """ 130 | Connect some of the signals to be able to disconnect them for setting GUI. 131 | """ 132 | 133 | self.name_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 134 | self.state_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 135 | self.main_pid_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 136 | self.active_state_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 137 | self.load_state_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 138 | self.sub_state_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 139 | self.memory_rss_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 140 | self.description_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 141 | 142 | 143 | def disconnect_signals(self): 144 | """ 145 | Disconnect some of the signals for setting GUI. 146 | """ 147 | 148 | self.name_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 149 | self.state_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 150 | self.main_pid_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 151 | self.active_state_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 152 | self.load_state_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 153 | self.sub_state_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 154 | self.memory_rss_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 155 | self.description_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 156 | 157 | 158 | def on_menu_po_show(self, widget): 159 | """ 160 | Run code when customizations menu popover is shown. 161 | """ 162 | 163 | try: 164 | self.disconnect_signals() 165 | except TypeError: 166 | pass 167 | self.set_gui() 168 | self.connect_signals() 169 | 170 | 171 | def on_reset_button_clicked(self, widget): 172 | """ 173 | Reset customizations. 174 | """ 175 | 176 | # Load default settings 177 | Config.config_default_services_func() 178 | Config.config_save_func() 179 | 180 | Common.update_tab_and_menu_gui(self, Services) 181 | 182 | 183 | def on_add_remove_checkbuttons_toggled(self, widget): 184 | """ 185 | Run a function for adding/removing columns to treeview. 186 | """ 187 | 188 | self.add_remove_columns() 189 | 190 | 191 | def set_gui(self): 192 | """ 193 | Set GUI items. 194 | """ 195 | 196 | if 0 in Config.services_treeview_columns_shown: 197 | self.name_cb.set_active(True) 198 | else: 199 | self.name_cb.set_active(False) 200 | if 1 in Config.services_treeview_columns_shown: 201 | self.state_cb.set_active(True) 202 | else: 203 | self.state_cb.set_active(False) 204 | if 2 in Config.services_treeview_columns_shown: 205 | self.main_pid_cb.set_active(True) 206 | else: 207 | self.main_pid_cb.set_active(False) 208 | if 3 in Config.services_treeview_columns_shown: 209 | self.active_state_cb.set_active(True) 210 | else: 211 | self.active_state_cb.set_active(False) 212 | if 4 in Config.services_treeview_columns_shown: 213 | self.load_state_cb.set_active(True) 214 | else: 215 | self.load_state_cb.set_active(False) 216 | if 5 in Config.services_treeview_columns_shown: 217 | self.sub_state_cb.set_active(True) 218 | else: 219 | self.sub_state_cb.set_active(False) 220 | if 6 in Config.services_treeview_columns_shown: 221 | self.memory_rss_cb.set_active(True) 222 | else: 223 | self.memory_rss_cb.set_active(False) 224 | if 7 in Config.services_treeview_columns_shown: 225 | self.description_cb.set_active(True) 226 | else: 227 | self.description_cb.set_active(False) 228 | 229 | 230 | def add_remove_columns(self): 231 | """ 232 | Add/Remove columns to treeview. 233 | """ 234 | 235 | Config.services_treeview_columns_shown = [] 236 | 237 | if self.name_cb.get_active() == True: 238 | Config.services_treeview_columns_shown.append(0) 239 | if self.state_cb.get_active() == True: 240 | Config.services_treeview_columns_shown.append(1) 241 | if self.main_pid_cb.get_active() == True: 242 | Config.services_treeview_columns_shown.append(2) 243 | if self.active_state_cb.get_active() == True: 244 | Config.services_treeview_columns_shown.append(3) 245 | if self.load_state_cb.get_active() == True: 246 | Config.services_treeview_columns_shown.append(4) 247 | if self.sub_state_cb.get_active() == True: 248 | Config.services_treeview_columns_shown.append(5) 249 | if self.memory_rss_cb.get_active() == True: 250 | Config.services_treeview_columns_shown.append(6) 251 | if self.description_cb.get_active() == True: 252 | Config.services_treeview_columns_shown.append(7) 253 | 254 | # Apply changes immediately (without waiting update interval). 255 | Common.treeview_column_order_width_row_sorting(None, None, Services) 256 | 257 | #Common.save_tab_settings(Services) 258 | Config.config_save_func() 259 | 260 | 261 | ServicesMenu = ServicesMenu() 262 | 263 | -------------------------------------------------------------------------------- /src/SummaryMenu.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | from gi.repository import Gtk 4 | 5 | from .Config import Config 6 | from .Summary import Summary 7 | from . import Common 8 | 9 | _tr = Config._tr 10 | 11 | 12 | class SummaryMenu: 13 | 14 | def __init__(self): 15 | 16 | self.name = "SummaryMenu" 17 | 18 | self.menu_gui() 19 | 20 | 21 | def menu_gui(self): 22 | """ 23 | Generate menu GUI. 24 | """ 25 | 26 | # Popover 27 | self.menu_po = Gtk.Popover() 28 | 29 | # Grid (main) 30 | main_grid = Common.menu_main_grid() 31 | self.menu_po.set_child(main_grid) 32 | 33 | # Label - menu title (Summary) 34 | label = Common.menu_title_label(_tr("Summary")) 35 | main_grid.attach(label, 0, 0, 2, 1) 36 | 37 | # Label (Graph - Show) 38 | label = Common.title_label(_tr("Graph - Show")) 39 | main_grid.attach(label, 0, 1, 2, 1) 40 | 41 | # CheckButton (GPU Usage) 42 | self.gpu_usage_cb = Common.checkbutton(_tr("GPU Usage"), None) 43 | main_grid.attach(self.gpu_usage_cb, 0, 2, 2, 1) 44 | 45 | # Label (This increases CPU usage.) 46 | label = Common.static_information_label(_tr("This increases CPU usage.")) 47 | label.set_margin_start(25) 48 | main_grid.attach(label, 0, 3, 2, 1) 49 | 50 | # Separator 51 | separator = Common.menu_separator() 52 | main_grid.attach(separator, 0, 4, 2, 1) 53 | 54 | # Button (Reset) 55 | self.reset_button = Common.reset_button() 56 | main_grid.attach(self.reset_button, 0, 5, 2, 1) 57 | 58 | # Connect signals 59 | self.reset_button.connect("clicked", self.on_reset_button_clicked) 60 | self.menu_po.connect("show", self.on_menu_po_show) 61 | 62 | 63 | def connect_signals(self): 64 | """ 65 | Connect some of the signals to be able to disconnect them for setting GUI. 66 | """ 67 | 68 | self.gpu_usage_cb.connect("toggled", self.on_gpu_usage_cb_toggled) 69 | 70 | 71 | def disconnect_signals(self): 72 | """ 73 | Disconnect some of the signals for setting GUI. 74 | """ 75 | 76 | self.gpu_usage_cb.disconnect_by_func(self.on_gpu_usage_cb_toggled) 77 | 78 | 79 | def on_menu_po_show(self, widget): 80 | """ 81 | Run code when menu is shown. 82 | """ 83 | 84 | try: 85 | self.disconnect_signals() 86 | except TypeError: 87 | pass 88 | self.set_gui() 89 | self.connect_signals() 90 | 91 | 92 | def on_gpu_usage_cb_toggled(self, widget): 93 | """ 94 | Show/Hide GPU usage percentage graphics. 95 | """ 96 | 97 | if widget.get_active() == True: 98 | Config.summary_show_gpu_usage = 1 99 | if widget.get_active() == False: 100 | Config.summary_show_gpu_usage = 0 101 | 102 | Common.save_tab_settings(Summary) 103 | 104 | 105 | def on_reset_button_clicked(self, widget): 106 | """ 107 | Reset all tab settings. 108 | """ 109 | 110 | # Load default settings 111 | Config.config_default_performance_summary_func() 112 | Config.config_save_func() 113 | 114 | Common.update_tab_and_menu_gui(self, Summary) 115 | 116 | 117 | def set_gui(self): 118 | """ 119 | Set menu GUI items. 120 | """ 121 | 122 | # Set active checkbuttons if disk read speed/disk write speed values are "1". 123 | if Config.summary_show_gpu_usage == 1: 124 | self.gpu_usage_cb.set_active(True) 125 | if Config.summary_show_gpu_usage == 0: 126 | self.gpu_usage_cb.set_active(False) 127 | 128 | 129 | SummaryMenu = SummaryMenu() 130 | 131 | -------------------------------------------------------------------------------- /src/UsersDetails.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | gi.require_version('GLib', '2.0') 4 | from gi.repository import Gtk, GLib 5 | 6 | import os 7 | import time 8 | import subprocess 9 | from datetime import datetime 10 | 11 | from .Config import Config 12 | from .Users import Users 13 | from .Performance import Performance 14 | from .MainWindow import MainWindow 15 | from . import Common 16 | from . import Libsysmon 17 | 18 | _tr = Config._tr 19 | 20 | 21 | class UsersDetails: 22 | 23 | def __init__(self): 24 | 25 | self.window_gui() 26 | 27 | 28 | def window_gui(self): 29 | """ 30 | Generate window GUI. 31 | """ 32 | 33 | # Window 34 | self.user_details_window = Gtk.Window() 35 | self.user_details_window.set_default_size(350, 345) 36 | self.user_details_window.set_title(_tr("User")) 37 | self.user_details_window.set_icon_name("system-monitoring-center") 38 | self.user_details_window.set_transient_for(MainWindow.main_window) 39 | self.user_details_window.set_modal(True) 40 | self.user_details_window.set_hide_on_close(True) 41 | 42 | self.main_tab_gui() 43 | 44 | self.gui_signals() 45 | 46 | 47 | def main_tab_gui(self): 48 | """ 49 | Generate labels on the main (single) tab. 50 | """ 51 | 52 | # ScrolledWindow 53 | scrolledwindow = Common.window_main_scrolledwindow() 54 | self.user_details_window.set_child(scrolledwindow) 55 | 56 | # Viewport 57 | viewport = Gtk.Viewport() 58 | scrolledwindow.set_child(viewport) 59 | 60 | # Grid 61 | grid = Common.window_main_grid() 62 | scrolledwindow.set_child(grid) 63 | 64 | # Label (User) 65 | label = Common.static_information_label(_tr("User")) 66 | grid.attach(label, 0, 0, 1, 1) 67 | # Label (User) 68 | label = Common.static_information_label(":") 69 | grid.attach(label, 1, 0, 1, 1) 70 | # Label (User) 71 | self.user_label = Common.dynamic_information_label() 72 | grid.attach(self.user_label, 2, 0, 1, 1) 73 | 74 | # Label (Full Name) 75 | label = Common.static_information_label(_tr("Full Name")) 76 | grid.attach(label, 0, 1, 1, 1) 77 | # Label (Full Name) 78 | label = Common.static_information_label(":") 79 | grid.attach(label, 1, 1, 1, 1) 80 | # Label (Full Name) 81 | self.full_name_label = Common.dynamic_information_label() 82 | grid.attach(self.full_name_label, 2, 1, 1, 1) 83 | 84 | # Label (Logged In) 85 | label = Common.static_information_label(_tr("Logged In")) 86 | grid.attach(label, 0, 2, 1, 1) 87 | # Label (Logged In) 88 | label = Common.static_information_label(":") 89 | grid.attach(label, 1, 2, 1, 1) 90 | # Label (Logged In) 91 | self.logged_in_label = Common.dynamic_information_label() 92 | grid.attach(self.logged_in_label, 2, 2, 1, 1) 93 | 94 | # Label (UID) 95 | label = Common.static_information_label(_tr("UID")) 96 | grid.attach(label, 0, 3, 1, 1) 97 | # Label (UID) 98 | label = Common.static_information_label(":") 99 | grid.attach(label, 1, 3, 1, 1) 100 | # Label (UID) 101 | self.uid_label = Common.dynamic_information_label() 102 | grid.attach(self.uid_label, 2, 3, 1, 1) 103 | 104 | # Label (GID) 105 | label = Common.static_information_label(_tr("GID")) 106 | grid.attach(label, 0, 4, 1, 1) 107 | # Label (GID) 108 | label = Common.static_information_label(":") 109 | grid.attach(label, 1, 4, 1, 1) 110 | # Label (GID) 111 | self.gid_label = Common.dynamic_information_label() 112 | grid.attach(self.gid_label, 2, 4, 1, 1) 113 | 114 | # Label (Processes) 115 | label = Common.static_information_label(_tr("Processes")) 116 | grid.attach(label, 0, 5, 1, 1) 117 | # Label (Processes) 118 | label = Common.static_information_label(":") 119 | grid.attach(label, 1, 5, 1, 1) 120 | # Label (Processes) 121 | self.processes_label = Common.dynamic_information_label() 122 | grid.attach(self.processes_label, 2, 5, 1, 1) 123 | 124 | # Label (Home Directory) 125 | label = Common.static_information_label(_tr("Home Directory")) 126 | grid.attach(label, 0, 6, 1, 1) 127 | # Label (Home Directory) 128 | label = Common.static_information_label(":") 129 | grid.attach(label, 1, 6, 1, 1) 130 | # Label (Home Directory) 131 | self.home_directory_label = Common.dynamic_information_label() 132 | grid.attach(self.home_directory_label, 2, 6, 1, 1) 133 | 134 | # Label (Group) 135 | label = Common.static_information_label(_tr("Group")) 136 | grid.attach(label, 0, 7, 1, 1) 137 | # Label (Group) 138 | label = Common.static_information_label(":") 139 | grid.attach(label, 1, 7, 1, 1) 140 | # Label (Group) 141 | self.group_label = Common.dynamic_information_label() 142 | grid.attach(self.group_label, 2, 7, 1, 1) 143 | 144 | # Label (Terminal) 145 | label = Common.static_information_label(_tr("Terminal")) 146 | grid.attach(label, 0, 8, 1, 1) 147 | # Label (Terminal) 148 | label = Common.static_information_label(":") 149 | grid.attach(label, 1, 8, 1, 1) 150 | # Label (Terminal) 151 | self.terminal_label = Common.dynamic_information_label() 152 | grid.attach(self.terminal_label, 2, 8, 1, 1) 153 | 154 | # Label (Start Time) 155 | label = Common.static_information_label(_tr("Start Time")) 156 | grid.attach(label, 0, 9, 1, 1) 157 | # Label (Start Time) 158 | label = Common.static_information_label(":") 159 | grid.attach(label, 1, 9, 1, 1) 160 | # Label (Start Time) 161 | self.start_time_label = Common.dynamic_information_label() 162 | grid.attach(self.start_time_label, 2, 9, 1, 1) 163 | 164 | # Label (CPU) 165 | label = Common.static_information_label(_tr("CPU")) 166 | grid.attach(label, 0, 10, 1, 1) 167 | # Label (CPU) 168 | label = Common.static_information_label(":") 169 | grid.attach(label, 1, 10, 1, 1) 170 | # Label (CPU) 171 | self.cpu_label = Common.dynamic_information_label() 172 | grid.attach(self.cpu_label, 2, 10, 1, 1) 173 | 174 | 175 | def gui_signals(self): 176 | """ 177 | Connect GUI signals. 178 | """ 179 | 180 | # Window signals 181 | self.user_details_window.connect("close-request", self.on_user_details_window_delete_event) 182 | self.user_details_window.connect("show", self.on_user_details_window_show) 183 | 184 | 185 | def on_user_details_window_delete_event(self, widget): 186 | """ 187 | Called when window is closed. 188 | """ 189 | 190 | self.update_window_value = 0 191 | self.user_details_window.set_visible(False) 192 | return True 193 | 194 | 195 | def on_user_details_window_show(self, widget): 196 | """ 197 | Run code after window is shown. 198 | """ 199 | 200 | try: 201 | # Delete "update_interval" variable in order to let the code to run initial function. 202 | # Otherwise, data from previous user (if it was viewed) will be used. 203 | del self.update_interval 204 | except AttributeError: 205 | pass 206 | 207 | # This value is checked for repeating the function for getting the user data. 208 | self.update_window_value = 1 209 | 210 | self.users_details_run_func() 211 | 212 | 213 | def users_details_initial_func(self): 214 | """ 215 | Initial code which which is not wanted to be run in every loop. 216 | """ 217 | 218 | self.users_data_dict_prev = {} 219 | 220 | self.system_boot_time = Libsysmon.get_system_boot_time() 221 | 222 | 223 | def users_details_loop_func(self): 224 | """ 225 | Get and show information on the GUI on every loop. 226 | """ 227 | 228 | # Get right clicked user UID and username 229 | selected_user_uid = Users.selected_user_uid 230 | selected_username = Users.selected_username 231 | 232 | # Get configrations one time per floop instead of getting them multiple times in every loop which causes high CPU usage. 233 | users_cpu_precision = Config.users_cpu_precision 234 | 235 | # Set window title 236 | self.user_details_window.set_title(_tr("User") + ": " + selected_username) 237 | 238 | # Get user information 239 | users_data_dict = Libsysmon.get_users_information(self.users_data_dict_prev, self.system_boot_time) 240 | self.users_data_dict_prev = dict(users_data_dict) 241 | human_user_uid_list = users_data_dict["human_user_uid_list"] 242 | 243 | try: 244 | user_data_dict = users_data_dict[selected_user_uid] 245 | # Prevent error if user account is deleted while its detail window is open. 246 | except KeyError: 247 | self.update_window_value = 0 248 | self.user_details_window.set_visible(False) 249 | return 250 | 251 | # Set label text 252 | self.user_label.set_label(user_data_dict["username"]) 253 | self.full_name_label.set_label(user_data_dict["full_name"]) 254 | if user_data_dict["logged_in"] == True: 255 | selected_user_logged_in = _tr("Yes") 256 | else: 257 | selected_user_logged_in = _tr("No") 258 | self.logged_in_label.set_label(selected_user_logged_in) 259 | self.uid_label.set_label(str(selected_user_uid)) 260 | self.gid_label.set_label(str(user_data_dict["gid"])) 261 | self.processes_label.set_label(str(user_data_dict["process_count"])) 262 | self.home_directory_label.set_label(user_data_dict["home_dir"]) 263 | self.group_label.set_label(user_data_dict["group_name"]) 264 | self.terminal_label.set_label(user_data_dict["terminal"]) 265 | selected_user_process_start_time = user_data_dict["log_in_time"] 266 | if selected_user_process_start_time != 0: 267 | self.start_time_label.set_label(datetime.fromtimestamp(selected_user_process_start_time).strftime("%H:%M:%S %d.%m.%Y")) 268 | if selected_user_process_start_time == 0: 269 | self.start_time_label.set_label("-") 270 | self.cpu_label.set_label(f'{user_data_dict["total_cpu_usage"]:.{users_cpu_precision}f} %') 271 | 272 | 273 | def users_details_run_func(self, *args): 274 | """ 275 | Run initial and loop functions of user details window. 276 | "*args" is used in order to prevent "" warning and obtain a repeated function by using "GLib.timeout_source_new()". 277 | "GLib.timeout_source_new()" is used instead of "GLib.timeout_add()" to be able to change the update interval and 278 | run the loop again without waiting ending the previous update interval. 279 | """ 280 | 281 | if hasattr(UsersDetails, "update_interval") == False: 282 | GLib.idle_add(self.users_details_initial_func) 283 | 284 | # Destroy GLib source for preventing it repeating the function. 285 | try: 286 | self.main_glib_source.destroy() 287 | # "try-except" is used in order to prevent errors if this is first run of the function. 288 | except AttributeError: 289 | pass 290 | self.update_interval = Config.update_interval 291 | self.main_glib_source = GLib.timeout_source_new(self.update_interval * 1000) 292 | 293 | if self.update_window_value == 1: 294 | GLib.idle_add(self.users_details_loop_func) 295 | self.main_glib_source.set_callback(self.users_details_run_func) 296 | # Attach GLib.Source to MainContext. Therefore it will be part of the main loop until it is destroyed. A function may be attached to the MainContext multiple times. 297 | self.main_glib_source.attach(GLib.MainContext.default()) 298 | 299 | 300 | UsersDetails = UsersDetails() 301 | 302 | -------------------------------------------------------------------------------- /src/UsersMenu.py: -------------------------------------------------------------------------------- 1 | import gi 2 | gi.require_version('Gtk', '4.0') 3 | from gi.repository import Gtk 4 | 5 | from .Config import Config 6 | from .Users import Users 7 | from .MainWindow import MainWindow 8 | from . import Common 9 | 10 | _tr = Config._tr 11 | 12 | 13 | class UsersMenu: 14 | 15 | def __init__(self): 16 | 17 | self.menu_gui() 18 | 19 | 20 | def menu_gui(self): 21 | """ 22 | Generate menu GUI. 23 | """ 24 | 25 | # Popover 26 | self.menu_po = Gtk.Popover() 27 | 28 | # Grid (main) 29 | main_grid = Common.menu_main_grid() 30 | self.menu_po.set_child(main_grid) 31 | 32 | # Label - menu title (Users) 33 | label = Common.menu_title_label(_tr("Users")) 34 | main_grid.attach(label, 0, 0, 1, 1) 35 | 36 | # Notebook 37 | notebook = Gtk.Notebook() 38 | notebook.set_hexpand(True) 39 | notebook.set_vexpand(True) 40 | main_grid.attach(notebook, 0, 1, 1, 1) 41 | 42 | # Tab pages and ScrolledWindow 43 | # "Add/Remove Columns" tab 44 | label = Gtk.Label() 45 | label.set_label(_tr("Add/Remove Columns")) 46 | self.grid_add_remove_columns_tab = Gtk.Grid() 47 | self.grid_add_remove_columns_tab.set_margin_top(15) 48 | self.grid_add_remove_columns_tab.set_margin_bottom(5) 49 | self.grid_add_remove_columns_tab.set_margin_start(5) 50 | self.grid_add_remove_columns_tab.set_margin_end(5) 51 | self.grid_add_remove_columns_tab.set_row_spacing(5) 52 | notebook.append_page(self.grid_add_remove_columns_tab, label) 53 | 54 | # Button (Reset) 55 | self.reset_button = Common.reset_button() 56 | main_grid.attach(self.reset_button, 0, 2, 1, 1) 57 | 58 | # "Add/Remove Columns" tab GUI 59 | self.add_remove_columns_tab_gui() 60 | 61 | # GUI signals 62 | self.gui_signals() 63 | 64 | 65 | def add_remove_columns_tab_gui(self): 66 | """ 67 | Generate "Add/Remove Columns" tab GUI objects. 68 | """ 69 | 70 | # Grid 71 | grid = Gtk.Grid() 72 | grid.set_margin_top(5) 73 | grid.set_margin_bottom(5) 74 | grid.set_margin_start(5) 75 | grid.set_margin_end(5) 76 | grid.set_column_spacing(10) 77 | grid.set_row_spacing(3) 78 | self.grid_add_remove_columns_tab.attach(grid, 0, 0, 1, 1) 79 | 80 | # Label - tab title (Add/Remove Columns) 81 | label = Common.title_label(_tr("Add/Remove Columns")) 82 | grid.attach(label, 0, 0, 2, 1) 83 | 84 | # CheckButton (User) 85 | self.user_cb = Common.checkbutton(_tr("User"), None) 86 | self.user_cb.set_active(True) 87 | self.user_cb.set_sensitive(False) 88 | grid.attach(self.user_cb, 0, 1, 1, 1) 89 | 90 | # CheckButton (Full Name) 91 | self.full_name_cb = Common.checkbutton(_tr("Full Name"), None) 92 | grid.attach(self.full_name_cb, 0, 2, 1, 1) 93 | 94 | # CheckButton (Logged In) 95 | self.logged_in_cb = Common.checkbutton(_tr("Logged In"), None) 96 | grid.attach(self.logged_in_cb, 0, 3, 1, 1) 97 | 98 | # CheckButton (UID) 99 | self.uid_cb = Common.checkbutton(_tr("UID"), None) 100 | grid.attach(self.uid_cb, 0, 4, 1, 1) 101 | 102 | # CheckButton (GID) 103 | self.gid_cb = Common.checkbutton(_tr("GID"), None) 104 | grid.attach(self.gid_cb, 0, 5, 1, 1) 105 | 106 | # CheckButton (Processes) 107 | self.processes_cb = Common.checkbutton(_tr("Processes"), None) 108 | grid.attach(self.processes_cb, 0, 6, 1, 1) 109 | 110 | # CheckButton (Home Directory) 111 | self.home_directory_cb = Common.checkbutton(_tr("Home Directory"), None) 112 | grid.attach(self.home_directory_cb, 1, 1, 1, 1) 113 | 114 | # CheckButton (Group) 115 | self.group_cb = Common.checkbutton(_tr("Group"), None) 116 | grid.attach(self.group_cb, 1, 2, 1, 1) 117 | 118 | # CheckButton (Terminal) 119 | self.terminal_cb = Common.checkbutton(_tr("Terminal"), None) 120 | grid.attach(self.terminal_cb, 1, 3, 1, 1) 121 | 122 | # CheckButton (Start Time) 123 | self.start_time_cb = Common.checkbutton(_tr("Start Time"), None) 124 | grid.attach(self.start_time_cb, 1, 4, 1, 1) 125 | 126 | # CheckButton (CPU) 127 | self.cpu_cb = Common.checkbutton(_tr("CPU"), None) 128 | grid.attach(self.cpu_cb, 1, 5, 1, 1) 129 | 130 | 131 | def gui_signals(self): 132 | """ 133 | Connect GUI signals. 134 | """ 135 | 136 | self.menu_po.connect("show", self.on_menu_po_show) 137 | self.reset_button.connect("clicked", self.on_reset_button_clicked) 138 | 139 | 140 | def connect_signals(self): 141 | """ 142 | Connect some of the signals to be able to disconnect them for setting GUI. 143 | """ 144 | 145 | self.user_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 146 | self.full_name_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 147 | self.logged_in_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 148 | self.uid_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 149 | self.gid_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 150 | self.processes_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 151 | self.home_directory_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 152 | self.group_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 153 | self.terminal_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 154 | self.start_time_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 155 | self.cpu_cb.connect("toggled", self.on_add_remove_checkbuttons_toggled) 156 | 157 | 158 | def disconnect_signals(self): 159 | """ 160 | Disconnect some of the signals for setting GUI. 161 | """ 162 | 163 | self.user_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 164 | self.full_name_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 165 | self.logged_in_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 166 | self.uid_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 167 | self.gid_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 168 | self.processes_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 169 | self.home_directory_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 170 | self.group_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 171 | self.terminal_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 172 | self.start_time_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 173 | self.cpu_cb.disconnect_by_func(self.on_add_remove_checkbuttons_toggled) 174 | 175 | 176 | def on_menu_po_show(self, widget): 177 | """ 178 | Run code when customizations menu popover is shown. 179 | """ 180 | 181 | try: 182 | self.disconnect_signals() 183 | except TypeError: 184 | pass 185 | self.set_gui() 186 | self.connect_signals() 187 | 188 | 189 | def on_reset_button_clicked(self, widget): 190 | """ 191 | Reset customizations. 192 | """ 193 | 194 | # Load default settings 195 | Config.config_default_users_func() 196 | Config.config_save_func() 197 | 198 | Common.update_tab_and_menu_gui(self, Users) 199 | 200 | 201 | def on_add_remove_checkbuttons_toggled(self, widget): 202 | """ 203 | Run a function for adding/removing columns to treeview. 204 | """ 205 | 206 | self.add_remove_columns() 207 | 208 | 209 | def set_gui(self): 210 | """ 211 | Set GUI items. 212 | """ 213 | 214 | # Set GUI objects on Add/Remove Column tab 215 | if 0 in Config.users_treeview_columns_shown: 216 | self.user_cb.set_active(True) 217 | else: 218 | self.user_cb.set_active(False) 219 | if 1 in Config.users_treeview_columns_shown: 220 | self.full_name_cb.set_active(True) 221 | else: 222 | self.full_name_cb.set_active(False) 223 | if 2 in Config.users_treeview_columns_shown: 224 | self.logged_in_cb.set_active(True) 225 | else: 226 | self.logged_in_cb.set_active(False) 227 | if 3 in Config.users_treeview_columns_shown: 228 | self.uid_cb.set_active(True) 229 | else: 230 | self.uid_cb.set_active(False) 231 | if 4 in Config.users_treeview_columns_shown: 232 | self.gid_cb.set_active(True) 233 | else: 234 | self.gid_cb.set_active(False) 235 | if 5 in Config.users_treeview_columns_shown: 236 | self.processes_cb.set_active(True) 237 | else: 238 | self.processes_cb.set_active(False) 239 | if 6 in Config.users_treeview_columns_shown: 240 | self.home_directory_cb.set_active(True) 241 | else: 242 | self.home_directory_cb.set_active(False) 243 | if 7 in Config.users_treeview_columns_shown: 244 | self.group_cb.set_active(True) 245 | else: 246 | self.group_cb.set_active(False) 247 | if 8 in Config.users_treeview_columns_shown: 248 | self.terminal_cb.set_active(True) 249 | else: 250 | self.terminal_cb.set_active(False) 251 | if 9 in Config.users_treeview_columns_shown: 252 | self.start_time_cb.set_active(True) 253 | else: 254 | self.start_time_cb.set_active(False) 255 | if 10 in Config.users_treeview_columns_shown: 256 | self.cpu_cb.set_active(True) 257 | else: 258 | self.cpu_cb.set_active(False) 259 | 260 | 261 | def add_remove_columns(self): 262 | """ 263 | Add/Remove columns to treeview. 264 | """ 265 | 266 | Config.users_treeview_columns_shown = [] 267 | 268 | if self.user_cb.get_active() == True: 269 | Config.users_treeview_columns_shown.append(0) 270 | if self.full_name_cb.get_active() == True: 271 | Config.users_treeview_columns_shown.append(1) 272 | if self.logged_in_cb.get_active() == True: 273 | Config.users_treeview_columns_shown.append(2) 274 | if self.uid_cb.get_active() == True: 275 | Config.users_treeview_columns_shown.append(3) 276 | if self.gid_cb.get_active() == True: 277 | Config.users_treeview_columns_shown.append(4) 278 | if self.processes_cb.get_active() == True: 279 | Config.users_treeview_columns_shown.append(5) 280 | if self.home_directory_cb.get_active() == True: 281 | Config.users_treeview_columns_shown.append(6) 282 | if self.group_cb.get_active() == True: 283 | Config.users_treeview_columns_shown.append(7) 284 | if self.terminal_cb.get_active() == True: 285 | Config.users_treeview_columns_shown.append(8) 286 | if self.start_time_cb.get_active() == True: 287 | Config.users_treeview_columns_shown.append(9) 288 | if self.cpu_cb.get_active() == True: 289 | Config.users_treeview_columns_shown.append(10) 290 | 291 | # Apply changes immediately (without waiting update interval). 292 | Common.treeview_column_order_width_row_sorting(None, None, Users) 293 | 294 | Common.save_tab_settings(Users) 295 | 296 | 297 | UsersMenu = UsersMenu() 298 | 299 | -------------------------------------------------------------------------------- /src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakandundar34coding/system-monitoring-center/4d9424833bd36cfd4fe7521139fe57faf9ee626b/src/__init__.py -------------------------------------------------------------------------------- /src/__version__: -------------------------------------------------------------------------------- 1 | 2.26.0 2 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name()) 2 | moduledir = join_paths(pkgdatadir, 'systemmonitoringcenter') 3 | 4 | '''gnome.compile_resources(meson.project_name(), 5 | meson.project_name() + '.gresource.xml', 6 | gresource_bundle: true, 7 | install: true, 8 | install_dir: pkgdatadir, 9 | )''' 10 | 11 | python = import('python') 12 | 13 | conf = configuration_data() 14 | conf.set('PYTHON', python.find_installation().full_path()) 15 | conf.set('VERSION', meson.project_version()) 16 | conf.set('localedir', join_paths(get_option('prefix'), get_option('localedir'))) 17 | conf.set('pkgdatadir', pkgdatadir) 18 | 19 | configure_file( 20 | input: meson.project_name() + '.in', 21 | output: meson.project_name(), 22 | configuration: conf, 23 | install: true, 24 | install_dir: get_option('bindir') 25 | ) 26 | 27 | system_monitoring_center_sources = [ 28 | '__init__.py', 29 | 'Common.py', 30 | 'Config.py', 31 | 'Cpu.py', 32 | 'CpuMenu.py', 33 | 'Disk.py', 34 | 'DiskMenu.py', 35 | 'Gpu.py', 36 | 'GpuMenu.py', 37 | 'Libsysmon.py', 38 | 'Main.py', 39 | 'MainWindow.py', 40 | 'Memory.py', 41 | 'MemoryMenu.py', 42 | 'Network.py', 43 | 'NetworkMenu.py', 44 | 'Performance.py', 45 | 'Processes.py', 46 | 'ProcessesDetails.py', 47 | 'ProcessesMenu.py', 48 | 'run_from_source.py', 49 | 'Sensors.py', 50 | 'SensorsMenu.py', 51 | 'Services.py', 52 | 'ServicesDetails.py', 53 | 'ServicesMenu.py', 54 | 'SettingsWindow.py', 55 | 'Summary.py', 56 | 'SummaryMenu.py', 57 | 'System.py', 58 | 'Users.py', 59 | 'UsersDetails.py', 60 | 'UsersMenu.py', 61 | '__version__', 62 | ] 63 | 64 | install_data(system_monitoring_center_sources, install_dir: moduledir) 65 | -------------------------------------------------------------------------------- /src/run_from_source.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | 6 | current_path = os.path.dirname(os.path.realpath(__file__)).split("/") 7 | parent_dir = '/'.join(current_path[:-1]) 8 | current_folder = current_path[-1] 9 | sys.path.append(parent_dir) 10 | 11 | if current_folder == "src": 12 | from src import Main 13 | if current_folder == "systemmonitoringcenter": 14 | from systemmonitoringcenter import Main 15 | localedir = None 16 | Main.main(localedir) 17 | 18 | -------------------------------------------------------------------------------- /src/system-monitoring-center.in: -------------------------------------------------------------------------------- 1 | #!@PYTHON@ 2 | 3 | # system-monitoring-center.in 4 | # 5 | # Copyright 2020-2023 Hakan Dündar. 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | 20 | 21 | import sys 22 | import signal 23 | 24 | 25 | pkgdatadir = '@pkgdatadir@' 26 | localedir = '@localedir@' 27 | 28 | sys.path.insert(1, pkgdatadir) 29 | signal.signal(signal.SIGINT, signal.SIG_DFL) 30 | 31 | if __name__ == '__main__': 32 | from systemmonitoringcenter import Main 33 | sys.exit(Main.main(localedir)) 34 | 35 | --------------------------------------------------------------------------------