diff --git a/README.md b/README.md index 32d3ab76..5809d8eb 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,16 @@ Check dependencies in [the deb control file](debian/control). sudo ninja install ``` +#### Build Flatpak + + flatpak-builder build com.github.stsdc.monitor.yml --user --install --force-clean + ### Debug logging ```bash G_MESSAGES_DEBUG=all GTK_DEBUG=interactive com.github.stsdc.monitor ``` + +#### Debug Flatpak + + flatpak run --command=sh --devel com.github.stsdc.monitor \ No newline at end of file diff --git a/com.github.stsdc.monitor.json b/com.github.stsdc.monitor.json new file mode 100644 index 00000000..78dd2144 --- /dev/null +++ b/com.github.stsdc.monitor.json @@ -0,0 +1,346 @@ +{ + "app-id": "com.github.stsdc.monitor", + "runtime": "io.elementary.Platform", + "runtime-version": "7.3", + "sdk": "io.elementary.Sdk", + "command": "com.github.stsdc.monitor", + "finish-args": [ + "--share=ipc", + "--socket=fallback-x11", + "--socket=wayland", + "--socket=session-bus", + "--socket=system-bus", + "--device=shm", + "--device=all", + "--share=network", + "--env=XDG_DATA_DIRS=/app/share:/usr/share:/usr/share/runtime/share:/run/host/user-share:/run/host/usr/share:/run/host/share:/var/lib/flatpak/exports/share:~/.local/share/flatpak/exports/share", + "--talk-name=org.freedesktop.Flatpak", + "--talk-name=com.github.stsdc.monitor", + "--system-talk-name=org.freedesktop.Accounts", + "--system-talk-name=org.freedesktop.UDisks2", + "--filesystem=host:ro", + "--filesystem=/var/lib/flatpak/app:ro", + "--filesystem=/var/lib/flatpak/exports/share:ro", + "--filesystem=xdg-data/flatpak/app:ro", + "--filesystem=xdg-data/flatpak/exports/share:ro", + "--filesystem=/run/docker.sock", + "--filesystem=xdg-run/docker.sock", + "--filesystem=/run/podman/podman.sock", + "--filesystem=xdg-run/podman/podman.sock", + "--filesystem=/tmp" + ], + "modules": [ + { + "name": "sassc", + "cleanup": [ + "*" + ], + "sources": [ + { + "type": "git", + "url": "https://github.com/sass/sassc.git", + "tag": "3.6.2" + }, + { + "type": "script", + "dest-filename": "autogen.sh", + "commands": [ + "autoreconf -si" + ] + } + ], + "modules": [ + { + "name": "pam", + "config-opts": [ + "--includedir=/app/include/security", + "--disable-doc" + ], + "sources": [ + { + "type": "archive", + "url": "https://github.com/linux-pam/linux-pam/releases/download/v1.4.0/Linux-PAM-1.4.0.tar.xz", + "sha256": "cd6d928c51e64139be3bdb38692c68183a509b83d4f2c221024ccd4bcddfd034" + } + ] + }, + { + "name": "polkit", + "buildsystem": "meson", + "config-opts": [ + "-Dlibs-only=true", + "-Dauthfw=pam" + ], + "sources": [ + { + "type": "git", + "url": "https://gitlab.freedesktop.org/stsdc/polkit.git", + "branch": "polkit-agent-building-option" + } + ] + }, + { + "name": "udisks2", + "buildsystem": "autotools", + "config-opts": [ + "--enable-available-modules=no", + "--enable-bcache=no", + "--enable-btrfs=no", + "--enable-introspection=yes", + "--enable-lvm2=no", + "--enable-modules=no", + "--enable-vdo=no", + "--enable-zram=no", + "--with-systemdsystemunitdir=no", + "--with-tmpfilesdir=no", + "--disable-daemon" + ], + "sources": [ + { + "type": "git", + "url": "https://github.com/storaged-project/udisks.git", + "tag": "udisks-2.9.4" + } + ] + }, + { + "name": "libsass", + "cleanup": [ + "*" + ], + "sources": [ + { + "type": "git", + "url": "https://github.com/sass/libsass.git", + "tag": "3.6.5" + }, + { + "type": "script", + "dest-filename": "autogen.sh", + "commands": [ + "autoreconf -si" + ] + } + ] + } + ] + }, + { + "name": "libstartup-notification", + "sources": [ + { + "type": "archive", + "url": "http://www.freedesktop.org/software/startup-notification/releases/startup-notification-0.12.tar.gz", + "sha256": "3c391f7e930c583095045cd2d10eb73a64f085c7fde9d260f2652c7cb3cfbe4a" + } + ] + }, + { + "name": "flatpak", + "config-opts": [ + "--disable-documentation", + "--disable-seccomp", + "--disable-sandboxed-triggers", + "--disable-system-helper", + "--with-system-install-dir=/var/lib/flatpak" + ], + "cleanup": [ + "/etc/profile.d", + "/lib/systemd", + "/share/dbus-1/interfaces/org.freedesktop.*", + "/share/dbus-1/services/org.freedesktop.*", + "/share/gdm" + ], + "post-install": [ + "cp /usr/bin/update-mime-database /app/bin", + "cp /usr/bin/update-desktop-database /app/bin" + ], + "sources": [ + { + "type": "archive", + "url": "https://github.com/flatpak/flatpak/releases/download/1.14.4/flatpak-1.14.4.tar.xz", + "sha256": "8a34dbd0b67c434e7598b98ec690953d046f0db26e480aeafb46d72aec716799", + "x-checker-data": { + "type": "json", + "url": "https://api.github.com/repos/flatpak/flatpak/releases/latest", + "version-query": ".tag_name", + "url-query": "\"https://github.com/flatpak/flatpak/releases/download/\\($version)/flatpak-\\($version).tar.xz\"" + } + } + ], + "modules": [ + { + "name": "snowball", + "buildsystem": "simple", + "sources": [ + { + "type": "archive", + "url": "https://github.com/snowballstem/snowball/archive/refs/tags/v2.2.0.tar.gz", + "sha512": "02c43313de9de2518ea51cfb11f1c29145fc046c7838329bfdefd70b604009ad44b6db8175c25b0db31f03db30a6aec5857aa35775a9c204ec976df9cae62957" + }, + { + "type": "patch", + "paths": [ + "flatpak/patches/snowball.patch" + ] + } + ], + "build-commands": [ + "make libstemmer.so -j$FLATPAK_BUILDER_N_JOBS", + "install -Dm644 include/libstemmer.h /app/include/libstemmer.h", + "install -Dm644 libstemmer.so /app/lib/libstemmer.so.0.0.0", + "ln -s libstemmer.so.0.0.0 /app/lib/libstemmer.so.0", + "ln -s libstemmer.so.0 /app/lib/libstemmer.so" + ] + }, + { + "name": "libfuse", + "buildsystem": "meson", + "config-opts": [ + "-Dexamples=false", + "-Dinitscriptdir=", + "-Duseroot=false", + "-Dtests=false", + "-Dudevrulesdir=/tmp/" + ], + "sources": [ + { + "type": "archive", + "url": "https://github.com/libfuse/libfuse/releases/download/fuse-3.14.1/fuse-3.14.1.tar.xz", + "sha256": "126919d72b46b3e0eb58a9c6933a2a50c36f2ea69f61fe9e78bdba9f463ffa20", + "x-checker-data": { + "type": "anitya", + "project-id": 861, + "url-template": "https://github.com/libfuse/libfuse/releases/download/fuse-$version/fuse-$version.tar.gz", + "versions": { + "<": "4.0" + } + } + } + ] + }, + { + "name": "ostree", + "config-opts": [ + "--disable-man", + "--with-systemdsystemgeneratordir=/app/lib/systemd/system-generators", + "--without-systemdsystemunitdir", + "--with-curl" + ], + "cleanup": [ + "/etc/grub.d", + "/etc/ostree", + "/share/ostree", + "/libexec" + ], + "sources": [ + { + "type": "archive", + "url": "https://github.com/ostreedev/ostree/releases/download/v2023.7/libostree-2023.7.tar.xz", + "sha256": "19cda718705f7ac8c018c939c38b1bb8412deaaa04862da98cd9fe9243f073bf", + "x-checker-data": { + "type": "json", + "url": "https://api.github.com/repos/ostreedev/ostree/releases/latest", + "version-query": ".tag_name", + "url-query": ".assets | first | .browser_download_url" + } + } + ] + }, + { + "name": "python3-pyparsing", + "cleanup": [ + "*" + ], + "buildsystem": "simple", + "build-commands": [ + "pip3 install --prefix=/app pyparsing-2.4.7-py2.py3-none-any.whl" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/8a/bb/488841f56197b13700afd5658fc279a2025a39e22449b7cf29864669b15d/pyparsing-2.4.7-py2.py3-none-any.whl", + "sha256": "ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" + } + ] + } + ] + }, + { + "name": "libwnck", + "buildsystem": "meson", + "config-opts": [ + "-Dstartup_notification=enabled" + ], + "cleanup": [ + "/include", + "/lib/pkgconfig", + "/bin" + ], + "sources": [ + { + "type": "archive", + "url": "https://download.gnome.org/sources/libwnck/3.36/libwnck-3.36.0.tar.xz", + "sha256": "bc508150b3ed5d22354b0e6774ad4eee465381ebc0ace45eb0e2d3a4186c925f" + } + ] + }, + { + "name": "libgtop", + "sources": [ + { + "type": "archive", + "url": "https://download.gnome.org/sources/libgtop/2.40/libgtop-2.40.0.tar.xz", + "sha256": "78f3274c0c79c434c03655c1b35edf7b95ec0421430897fb1345a98a265ed2d4" + } + ] + }, + { + "name": "libNVCtrl", + "build-options": { + "env": { + "LIB": "lib/x86_64-linux-gnu" + } + }, + "no-autogen": true, + "no-make-install": true, + "build-commands": [ + "mkdir -p ${FLATPAK_DEST}/lib", + "cp -a libXNVCtrl.so* ${FLATPAK_DEST}/lib/", + "install -D *.h -t ${FLATPAK_DEST}/include/NVCtrl" + ], + "subdir": "src/libXNVCtrl", + "sources": [ + { + "type": "archive", + "archive-type": "tar", + "url": "https://api.github.com/repos/NVIDIA/nvidia-settings/tarball/refs/tags/470.63.01", + "sha256": "0ede63515851d85ac0d1ed5f00e355f539968e6d1fd226120a27b2c66c3575de" + }, + { + "type": "patch", + "path": "flatpak/patches/libxnvctrl_so_0.patch", + "x-checker-data": { + "type": "json", + "url": "https://api.github.com/repos/NVIDIA/nvidia-settings/tags", + "url-query": ".[0].tarball_url", + "version-query": ".[0].name" + } + } + ] + }, + { + "name": "com.github.stsdc.monitor", + "buildsystem": "meson", + "config-opts": [ + "-Dflatpak-workaround=enabled" + ], + "sources": [ + { + "type": "dir", + "path": "." + } + ] + } + ] +} \ No newline at end of file diff --git a/data/com.github.stsdc.monitor.appdata.xml.in b/data/com.github.stsdc.monitor.appdata.xml.in index db9e884d..1d54f4bd 100644 --- a/data/com.github.stsdc.monitor.appdata.xml.in +++ b/data/com.github.stsdc.monitor.appdata.xml.in @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Copyright 2021 Stanisław <@ststdc> --> +<!-- Copyright 2023 Stanisław <@ststdc> --> <component type="desktop"> <id>com.github.stsdc.monitor</id> <metadata_license>CC0</metadata_license> @@ -9,12 +9,12 @@ <description> <p>Display usage of system resources, filter and manage processes.</p> </description> - <custom> - <value key="x-appcenter-color-primary">#d7f4d7</value> - <value key="x-appcenter-color-primary-text">#242d40</value> - <value key="x-appcenter-suggested-price">0</value> + <custom> + <value key="x-appcenter-color-primary">#d7f4d7</value> + <value key="x-appcenter-color-primary-text">#242d40</value> + <value key="x-appcenter-suggested-price">0</value> </custom> - <screenshots> + <screenshots> <screenshot type="default"> <image>https://github.com/stsdc/monitor/raw/master/data/screenshots/monitor-processes.png</image> </screenshot> @@ -25,198 +25,198 @@ <developer_name>Stanisław Dac</developer_name> <url type="homepage">https://github.com/stsdc/monitor</url> <url type="bugtracker">https://github.com/stsdc/monitor/issues</url> -<url type="help">https://github.com/stsdc/monitor/issues</url> - -<releases> -<release version="0.11.0" date="2021-10-24"> - <description> - <p>Add info about drives (based on Dirli's code)</p> - </description> -</release> -<release version="0.10.0" date="2021-09-23"> - <description> - <p>Adds dark theme 🌚</p> - </description> -</release> -<release version="0.9.5" date="2021-08-30"> - <description> - <p>Uses Wingpanel v3; New *.deb package maintainer: Kristopher Ives </p> - </description> -</release> -<release version="0.9.4" date="2021-04-23"> - <description> - <p>🐛 Should fix empty Indicator. Please reboot after installation ⚡️</p> - </description> - </release> -<release version="0.9.3" date="2021-04-17"> - <description> - <ul> - <li>🐛 Try to fix frequent GUI hangs 🥶</li> - <li>🇳🇱 Update Dutch translation (@Vistaus)</li> - <li>🇵🇹 Update Portuguese translation (@hugok79)</li> - <li>🇷🇴 Add Romanian translation (@tiberiufrat)</li> - </ul> - </description> - </release> -<release version="0.9.2" date="2020-12-14"> - <description> - <ul> - <li>Display Storage usage</li> - <li>Update Russian translation (@camellan)</li> - <li>Update Portuguese translation (@hugok79)</li> - <li>Different colours for Upload and Download</li> - </ul> - </description> - </release> -<release version="0.9.1" date="2020-09-04"> - <description> - <ul> - <li>Update Portuguese translation (@rottenpants466)</li> - <li>Update Dutch translation (@Vistaus)</li> - <li>Smoother animations (@DevAlien)</li> - <li>Preselect first entry so that the info panel is always open (@DevAlien)</li> - <li>Show CPU temperature in the Indicator</li> - </ul> - </description> - </release> + <url type="help">https://github.com/stsdc/monitor/issues</url> + <releases> + <release version="0.11.0" date="2021-10-24"> + <description> + <p>Add info about drives (based on Dirli's code)</p> + </description> + </release> + <release version="0.10.0" date="2021-09-23"> + <description> + <p>Adds dark theme 🌚</p> + </description> + </release> + <release version="0.9.5" date="2021-08-30"> + <description> + <p>Uses Wingpanel v3; New *.deb package maintainer: Kristopher Ives</p> + </description> + </release> + <release version="0.9.4" date="2021-04-23"> + <description> + <p>🐛 Should fix empty Indicator. Please reboot after installation ⚡️</p> + </description> + </release> + <release version="0.9.3" date="2021-04-17"> + <description> + <ul> + <li>🐛 Try to fix frequent GUI hangs 🥶</li> + <li>🇳🇱 Update Dutch translation (@Vistaus)</li> + <li>🇵🇹 Update Portuguese translation (@hugok79)</li> + <li>🇷🇴 Add Romanian translation (@tiberiufrat)</li> + </ul> + </description> + </release> + <release version="0.9.2" date="2020-12-14"> + <description> + <ul> + <li>Display Storage usage</li> + <li>Update Russian translation (@camellan)</li> + <li>Update Portuguese translation (@hugok79)</li> + <li>Different colours for Upload and Download</li> + </ul> + </description> + </release> + <release version="0.9.1" date="2020-09-04"> + <description> + <ul> + <li>Update Portuguese translation (@rottenpants466)</li> + <li>Update Dutch translation (@Vistaus)</li> + <li>Smoother animations (@DevAlien)</li> + <li>Preselect first entry so that the info panel is always open (@DevAlien)</li> + <li>Show CPU temperature in the Indicator</li> + </ul> + </description> + </release> <release version="0.9.0" date="2020-08-18"> - <description> - <ul> - <li>Better System Tab</li> - <li>Update Portuguese translation (@rottenpants466)</li> - <li>Save last opened view (@ryonakano)</li> - </ul> - </description> - </release> + <description> + <ul> + <li>Better System Tab</li> + <li>Update Portuguese translation (@rottenpants466)</li> + <li>Save last opened view (@ryonakano)</li> + </ul> + </description> + </release> <release version="0.8.1" date="2020-07-20"> - <description> - <ul> - <li>Update Japanese translation (Ryo Nakano)</li> - <li>Disable search entry, when System tab is active</li> - <li>Add screenshots</li> - </ul> - </description> - </release> + <description> + <ul> + <li>Update Japanese translation (Ryo Nakano)</li> + <li>Disable search entry, when System tab is active</li> + <li>Add screenshots</li> + </ul> + </description> + </release> <release version="0.8.0" date="2020-07-19"> - <description> - <ul> - <li>Add System resources tab</li> + <description> + <ul> + <li>Add System resources tab</li> </ul> - </description> - </release> + </description> + </release> <release version="0.7.3" date="2020-06-22"> - <description> - <ul> - <li>Added tooltips to process state label (Ryo Nakano)</li> - <li>Small bugfix</li> + <description> + <ul> + <li>Added tooltips to process state label (Ryo Nakano)</li> + <li>Small bugfix</li> </ul> - </description> - </release> + </description> + </release> <release version="0.7.2" date="2020-04-15"> - <description> - <ul> - <li>Fix sorting arrows</li> - <li>Update Russian translation (camellan)</li> - <li>Add Turkish translation (Harun Yasar)</li> - <li>Use newest version of live-chart (Laurent Callarec) ← Check his lib for creating charts, it's amazing!</li> - </ul> - </description> - </release> + <description> + <ul> + <li>Fix sorting arrows</li> + <li>Update Russian translation (camellan)</li> + <li>Add Turkish translation (Harun Yasar)</li> + <li>Use newest version of live-chart (Laurent Callarec) ← Check his lib for creating charts, it's amazing!</li> + </ul> + + </description> + </release> <release version="0.7.0" date="2020-04-11"> - <description> - <ul> - <li>Detailed process info in sidebar</li> - <li>CPU frequency in tooltip (Ryo Nakano)</li> + <description> + <ul> + <li>Detailed process info in sidebar</li> + <li>CPU frequency in tooltip (Ryo Nakano)</li> </ul> - </description> - </release> + </description> + </release> <release version="0.6.2" date="2019-12-21"> - <description> - <ul> - <li>Bugfix (potential) of crushes and high CPU usage</li> - <li>Update German translation (Carsten Dietrich)</li> + <description> + <ul> + <li>Bugfix (potential) of crushes and high CPU usage</li> + <li>Update German translation (Carsten Dietrich)</li> </ul> - </description> - </release> + </description> + </release> <release version="0.6.1" date="2019-11-13"> - <description> - <ul> - <li>Update Portuguese translation (Hugo Carvalho)</li> - <li>Update French translation (Nathan Bonnemains and Skeudwenn)</li> - <li>Fix: Don't show swap percentage when it's not available (Ryo Nakano)</li> - </ul> - </description> - </release> + <description> + <ul> + <li>Update Portuguese translation (Hugo Carvalho)</li> + <li>Update French translation (Nathan Bonnemains and Skeudwenn)</li> + <li>Fix: Don't show swap percentage when it's not available (Ryo Nakano)</li> + </ul> + </description> + </release> <release version="0.6.0" date="2019-10-29"> - <description> - <ul> - <li>Update Italian translation (Mirko Brombin)</li> - <li>Show swap usage (Ryo Nakano)</li> - <li>Update Russian translation (camellan)</li> - <li>Code refactoring (Ryo Nakano)</li> - <li>Update Japanese translation (Ryo Nakano)</li> - </ul> - </description> - </release> + <description> + <ul> + <li>Update Italian translation (Mirko Brombin)</li> + <li>Show swap usage (Ryo Nakano)</li> + <li>Update Russian translation (camellan)</li> + <li>Code refactoring (Ryo Nakano)</li> + <li>Update Japanese translation (Ryo Nakano)</li> + </ul> + </description> + </release> <release version="0.5.0" date="2019-06-07"> - <description> - <ul> - <li>Fix contents of the window are not shown (Ryo Nakano)</li> - <li>ix no row is still selected when indicator options are enabled (Ryo Nakano)</li> - <li>Fix the app crashes by clicking the "End/Kill Process" buttons when no process is selected (Ryo Nakano)</li> - <li>Added buttons to either "kill" or "end" a process. (Evan Buss)</li> - <li>Change screenshot to English (Christopher Crouse)</li> - <li>Update Russian translation (camellan)</li> - <li>Check if the default display is a X11 display (Hannes Schulze)</li> - <li>Update Spanish translation (Mario Rodrigo)</li> - </ul> - </description> - </release> + <description> + <ul> + <li>Fix contents of the window are not shown (Ryo Nakano)</li> + <li>ix no row is still selected when indicator options are enabled (Ryo Nakano)</li> + <li>Fix the app crashes by clicking the "End/Kill Process" buttons when no process is selected (Ryo Nakano)</li> + <li>Added buttons to either "kill" or "end" a process. (Evan Buss)</li> + <li>Change screenshot to English (Christopher Crouse)</li> + <li>Update Russian translation (camellan)</li> + <li>Check if the default display is a X11 display (Hannes Schulze)</li> + <li>Update Spanish translation (Mario Rodrigo)</li> + </ul> + </description> + </release> <release version="0.4.4" date="2019-06-07"> - <description> - <ul> - <li>Add start-in-background option to UI</li> + <description> + <ul> + <li>Add start-in-background option to UI</li> </ul> - </description> - </release> + </description> + </release> <release version="0.4.3" date="2019-04-11"> - <description> - <ul> - <li>Add start-in-background command line option</li> - <li>Add Italian and Portuguese translations</li> - <li>Update Dutch, French and Spanish translations</li> - <li>Fix Japanese translation</li> - </ul> - </description> - </release> + <description> + <ul> + <li>Add start-in-background command line option</li> + <li>Add Italian and Portuguese translations</li> + <li>Update Dutch, French and Spanish translations</li> + <li>Fix Japanese translation</li> + </ul> + </description> + </release> <release version="0.4.2" date="2019-03-11"> - <description> - <ul> - <li>Minor bug fix</li> - <li>Make End process button red</li> - <li>Add Japanese translation</li> - </ul> - </description> - </release> + <description> + <ul> + <li>Minor bug fix</li> + <li>Make End process button red</li> + <li>Add Japanese translation</li> + </ul> + </description> + </release> <release version="0.4.1" date="2019-02-20"> - <description> - <ul> - <li>Add CPU and RAM icons</li> - <li>Fix bug, that caused hanging</li> - <li>Update Polish and Russian translation</li> - </ul> - </description> - </release> + <description> + <ul> + <li>Add CPU and RAM icons</li> + <li>Fix bug, that caused hanging</li> + <li>Update Polish and Russian translation</li> + </ul> + </description> + </release> <release version="0.4.0" date="2019-01-31"> - <description> - <ul> - <li>Add Monitor indicator</li> - <li>Add missing extra French translations</li> - <li>Fix: if icon missing for the process, icon is taken from previous process</li> - <li>Fix: search erases my input while I'm typing</li> - <li>Fix POTFILES</li> - </ul> - </description> - </release> - </releases> + <description> + <ul> + <li>Add Monitor indicator</li> + <li>Add missing extra French translations</li> + <li>Fix: if icon missing for the process, icon is taken from previous process</li> + <li>Fix: search erases my input while I'm typing</li> + <li>Fix POTFILES</li> + </ul> + </description> + </release> + </releases> </component> diff --git a/data/com.github.stsdc.monitor.gschema.xml b/data/com.github.stsdc.monitor.gschema.xml index a242f8ff..dd366b6b 100644 --- a/data/com.github.stsdc.monitor.gschema.xml +++ b/data/com.github.stsdc.monitor.gschema.xml @@ -90,10 +90,15 @@ <summary>Update time</summary> <description>This value sets update time for updating data and charts.</description> </key> - <key type='b' name="containers-view-state"> + <key type='b' name="containers-view-state"> <default>false</default> <summary>To show Containers view or not</summary> <description>To show Containers view or not</description> </key> + <key type='b' name="flatpak-infobar-state"> + <default>true</default> + <summary>To show Flatpak infobar or not</summary> + <description>To show Flatpak infobar or not</description> + </key> </schema> </schemalist> diff --git a/flatpak/patches/libxnvctrl_so_0.patch b/flatpak/patches/libxnvctrl_so_0.patch new file mode 100644 index 00000000..279ae92f --- /dev/null +++ b/flatpak/patches/libxnvctrl_so_0.patch @@ -0,0 +1,39 @@ +diff -up nvidia-settings-435.17/src/libXNVCtrl/Makefile.shared nvidia-settings-435.17/src/libXNVCtrl/Makefile +--- nvidia-settings-435.17/src/libXNVCtrl/Makefile.shared 2019-08-07 06:12:32.000000000 +0200 ++++ nvidia-settings-435.17/src/libXNVCtrl/Makefile 2019-08-26 16:23:41.921778088 +0200 +@@ -50,8 +50,9 @@ LDFLAGS += $(XNVCTRL_LDFLAGS) + + .PHONY: clean + +-all: $(LIBXNVCTRL) ++all: $(LIBXNVCTRL) libXNVCtrl.so + + clean: + rm -rf $(LIBXNVCTRL) *~ \ + $(OUTPUTDIR)/*.o $(OUTPUTDIR)/*.d ++ rm -f libXNVCtrl.so libXNVCtrl.so.* +diff -up nvidia-settings-435.17/src/Makefile.shared nvidia-settings-435.17/src/Makefile +--- nvidia-settings-435.17/src/Makefile.shared 2019-08-07 06:12:31.000000000 +0200 ++++ nvidia-settings-435.17/src/Makefile 2019-08-26 16:17:31.133406921 +0200 +@@ -106,6 +106,9 @@ endif + XNVCTRL_DIR ?= libXNVCtrl + XCONFIG_PARSER_DIR ?= XF86Config-parser + COMMON_UTILS_DIR ?= common-utils ++XNVCTRL_SHARED ?= $(XNVCTRL_DIR)/libXNVCtrl.so.0 ++#XNVCTRL_LIB ?= $(XNVCTRL_ARCHIVE) ++XNVCTRL_LIB ?= $(XNVCTRL_SHARED) + COMMON_UNIX_DIR ?= common-unix + VIRTUAL_RESOLUTIONS_DIR ?= $(COMMON_UNIX_DIR)/virtual-resolutions + +diff -up nvidia-settings-435.17/src/libXNVCtrl/xnvctrl.mk.shared nvidia-settings-435.17/src/libXNVCtrl/xnvctrl.mk +--- nvidia-settings-435.17/src/libXNVCtrl/xnvctrl.mk.shared 2019-08-07 06:12:32.000000000 +0200 ++++ nvidia-settings-435.17/src/libXNVCtrl/xnvctrl.mk 2019-08-26 16:54:44.518016474 +0200 +@@ -47,3 +47,8 @@ $(eval $(call DEFINE_OBJECT_RULE,TARGET, + + $(LIBXNVCTRL) : $(LIBXNVCTRL_OBJ) + $(call quiet_cmd,AR) ru $@ $(LIBXNVCTRL_OBJ) ++ ++libXNVCtrl.so: $(LIBXNVCTRL_OBJ) ++ $(CC) -shared -Wl,-soname=$@.0 -o $@.0.0.0 $(LDFLAGS) $^ -lXext -lX11 ++ ln -s $@.0.0.0 $@.0 ++ ln -s $@.0 $@ diff --git a/flatpak/patches/snowball.patch b/flatpak/patches/snowball.patch new file mode 100644 index 00000000..8b30670f --- /dev/null +++ b/flatpak/patches/snowball.patch @@ -0,0 +1,68 @@ + GNUmakefile | 15 +++++++-------- + libstemmer/symbol.map | 6 ++++++ + 2 files changed, 13 insertions(+), 8 deletions(-) + +diff --git c/GNUmakefile i/GNUmakefile +index 98eb1fa..86e4855 100644 +--- c/GNUmakefile ++++ i/GNUmakefile +@@ -170,20 +170,19 @@ C_OTHER_OBJECTS = $(C_OTHER_SOURCES:.c=.o) + JAVA_CLASSES = $(JAVA_SOURCES:.java=.class) + JAVA_RUNTIME_CLASSES=$(JAVARUNTIME_SOURCES:.java=.class) + +-CFLAGS=-O2 -W -Wall -Wmissing-prototypes -Wmissing-declarations +-CPPFLAGS= ++CFLAGS+=-fPIC -W -Wall -Wmissing-prototypes -Wmissing-declarations + + INCLUDES=-Iinclude + +-all: snowball$(EXEEXT) libstemmer.a stemwords$(EXEEXT) $(C_OTHER_SOURCES) $(C_OTHER_HEADERS) $(C_OTHER_OBJECTS) ++all: snowball$(EXEEXT) libstemmer.so stemwords$(EXEEXT) $(C_OTHER_SOURCES) $(C_OTHER_HEADERS) $(C_OTHER_OBJECTS) + + algorithms.mk: libstemmer/mkalgorithms.pl libstemmer/modules.txt + libstemmer/mkalgorithms.pl algorithms.mk libstemmer/modules.txt + + clean: + rm -f $(COMPILER_OBJECTS) $(RUNTIME_OBJECTS) \ + $(LIBSTEMMER_OBJECTS) $(LIBSTEMMER_UTF8_OBJECTS) $(STEMWORDS_OBJECTS) snowball$(EXEEXT) \ +- libstemmer.a stemwords$(EXEEXT) \ ++ libstemmer.so stemwords$(EXEEXT) \ + libstemmer/modules.h \ + libstemmer/modules_utf8.h \ + $(C_LIB_SOURCES) $(C_LIB_HEADERS) $(C_LIB_OBJECTS) \ +@@ -222,19 +221,19 @@ libstemmer/modules_utf8.h libstemmer/mkinc_utf8.mak: libstemmer/mkmodules.pl lib + + libstemmer/libstemmer.o: libstemmer/modules.h $(C_LIB_HEADERS) + +-libstemmer.a: libstemmer/libstemmer.o $(RUNTIME_OBJECTS) $(C_LIB_OBJECTS) +- $(AR) -cru $@ $^ ++libstemmer.so: libstemmer/libstemmer.o $(RUNTIME_OBJECTS) $(C_LIB_OBJECTS) ++ $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname,$@,-version-script,libstemmer/symbol.map -o $@ $^ + + examples/%.o: examples/%.c + $(CC) $(CFLAGS) $(INCLUDES) $(CPPFLAGS) -c -o $@ $< + +-stemwords$(EXEEXT): $(STEMWORDS_OBJECTS) libstemmer.a ++stemwords$(EXEEXT): $(STEMWORDS_OBJECTS) libstemmer.so + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ + + tests/%.o: tests/%.c + $(CC) $(CFLAGS) $(INCLUDES) $(CPPFLAGS) -c -o $@ $< + +-stemtest$(EXEEXT): $(STEMTEST_OBJECTS) libstemmer.a ++stemtest$(EXEEXT): $(STEMTEST_OBJECTS) libstemmer.so + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ + + csharp_stemwords$(EXEEXT): $(CSHARP_STEMWORDS_SOURCES) $(CSHARP_RUNTIME_SOURCES) $(CSHARP_SOURCES) +diff --git c/libstemmer/symbol.map i/libstemmer/symbol.map +new file mode 100644 +index 0000000..7a3d423 +--- /dev/null ++++ i/libstemmer/symbol.map +@@ -0,0 +1,6 @@ ++SB_STEMMER_0 { ++ global: ++ sb_stemmer_*; ++ local: ++ *; ++}; diff --git a/flatpak/workaround/com.github.stsdc.monitor-workaround.py b/flatpak/workaround/com.github.stsdc.monitor-workaround.py new file mode 100755 index 00000000..73ef24a8 --- /dev/null +++ b/flatpak/workaround/com.github.stsdc.monitor-workaround.py @@ -0,0 +1,103 @@ +#!/usr/bin/python + +"""The workaround script should run only in Flatpak environment.""" + +import os +import subprocess +import dbus +import dbus.service +import dbus.mainloop.glib +from gi.repository import GLib + +def get_pids(): + # Define the path to the directory + path = '/proc' + + # Get a list of all directories in the path + directories = [d for d in os.listdir(path) if os.path.isdir(os.path.join(path, d))] + + # Filter out directories that contain only numbers in their names + return [d for d in directories if d.isnumeric()] + +def get_processes_stats(): + processes = [] + for pid in get_pids(): + process = [pid] + with open(f'/proc/{pid}/stat', 'r') as file: + process.append(file.read()) + processes.append(process) + return processes + + +class HelloWorld(dbus.service.Object): + + def __init__(self, conn=None, object_path=None, bus_name=None): + dbus.service.Object.__init__(self, conn, object_path, bus_name) + + @dbus.service.method(dbus_interface="com.github.stsdc.monitor.workaround.GetProcesses", in_signature="s", out_signature="aa{ss}", sender_keyword="sender", connection_keyword="conn") + def GetProcesses(self, name, sender=None, conn=None): + print("WorkaroundServer: GetProcesses") + processes = [] + for pid in get_pids(): + process = { + "pid": pid, + "cmdline": "", + "stat": "", + "statm": "", + "status": "", + "io": "", + "children": "" + } + try: + with open(f'/proc/{pid}/cmdline', 'rb') as file: + process["cmdline"] = (file.read().decode('utf-8', 'ignore').replace('\0', ' ')) + except FileNotFoundError as err: + process["cmdline"] = None + continue + + with open(f'/proc/{pid}/stat', 'rb') as file: + process["stat"] = (file.read().decode('utf-8', 'ignore').replace('\0', ' ')) + + with open(f'/proc/{pid}/status', 'rb') as file: + process["status"] = (file.read().decode('utf-8', 'ignore').replace('\0', ' ')) + + with open(f'/proc/{pid}/task/{pid}/children', 'rb') as file: + process["children"] = (file.read().decode('utf-8', 'ignore').replace('\0', ' ')) + + with open(f'/proc/{pid}/statm', 'rb') as file: + process["statm"] = (file.read().decode('utf-8', 'ignore').replace('\0', ' ')) + try: + with open(f'/proc/{pid}/io', 'rb') as file: + process["io"] = (file.read().decode('utf-8', 'ignore').replace('\0', ' ')) + # print(process["io"]) + + except PermissionError as err: + # print(err) + pass + processes.append(process) + return processes + + @dbus.service.method(dbus_interface="com.github.stsdc.monitor.workaround.GetProcesses", in_signature="i", sender_keyword="sender", connection_keyword="conn") + def EndProcess(self, pid, sender=None, conn=None): + print(f"WorkaroundServer: EndProcess: kill -15 {pid}") + try: + (subprocess.check_output(["kill", "-15", str(pid)], stderr=subprocess.STDOUT, shell=False)).decode() + except subprocess.CalledProcessError as err: + print(err) + + @dbus.service.method(dbus_interface="com.github.stsdc.monitor.workaround.GetProcesses", in_signature="i", sender_keyword="sender", connection_keyword="conn") + def KillProcess(self, pid, sender=None, conn=None): + print(f"WorkaroundServer: KillProcess: kill -9 {pid}") + try: + (subprocess.check_output(["kill", "-9", str(pid)], stderr=subprocess.STDOUT, shell=False)).decode() + except subprocess.CalledProcessError as err: + print(err) + +if __name__ == "__main__": + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + bus = dbus.SessionBus() + name = dbus.service.BusName("com.github.stsdc.monitor.workaround", bus) + helloworld = HelloWorld(bus, "/com/github/stsdc/monitor/workaround") + mainloop = GLib.MainLoop() + mainloop.run() + diff --git a/flatpak/workaround/meson.build b/flatpak/workaround/meson.build new file mode 100644 index 00000000..375f837d --- /dev/null +++ b/flatpak/workaround/meson.build @@ -0,0 +1,4 @@ +install_data( + join_paths('com.github.stsdc.monitor-workaround.py'), + install_dir: join_paths(datadir, 'workaround') +) diff --git a/meson.build b/meson.build index 2c47b0f3..3dc1863b 100644 --- a/meson.build +++ b/meson.build @@ -74,4 +74,10 @@ subdir('src') meson.add_install_script('meson/post_install.py') subdir('po') + + +if get_option('flatpak-workaround').enabled() + subdir('flatpak/workaround') +endif + # subdir('tests') \ No newline at end of file diff --git a/meson_options.txt b/meson_options.txt index d0fedb3b..c19f93f2 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1 +1,2 @@ -option('indicator-wingpanel', type : 'feature', value : 'disabled', description : 'Enables the Indicator for Wingpanel.') \ No newline at end of file +option('indicator-wingpanel', type : 'feature', value : 'disabled', description : 'Enables the Indicator for Wingpanel.') +option('flatpak-workaround', type : 'feature', value : 'disabled', description : 'Enables the Flatpak workaround.') \ No newline at end of file diff --git a/src/MainWindow.vala b/src/MainWindow.vala index eba8a92b..93235af1 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -60,7 +60,23 @@ public class Monitor.MainWindow : Hdy.ApplicationWindow { orientation = Gtk.Orientation.VERTICAL }; + var flatpak_infobar = new Gtk.InfoBar (); + flatpak_infobar.message_type = Gtk.MessageType.WARNING; + flatpak_infobar.revealed = MonitorApp.settings.get_boolean ("flatpak-infobar-state"); + var button = new Gtk.Button.with_label ("Hide"); + button.margin_start = 20; + button.hexpand = true; + button.halign = Gtk.Align.END; + flatpak_infobar.get_content_area ().add (new Gtk.Label (_("Some of Monitor features are limited by Flatpak environment."))); + flatpak_infobar.get_content_area ().add (new Gtk.LinkButton.with_label ("https://github.com/stsdc/monitor", _("Try native."))); + flatpak_infobar.get_content_area ().add (button); + button.clicked.connect (() => { + flatpak_infobar.revealed = false; + MonitorApp.settings.set_boolean ("flatpak-infobar-state", false); + }); + grid.add (headerbar); + if (ProcessUtils.is_flatpak_env ()) grid.add (flatpak_infobar); grid.add (stack); grid.add (statusbar); @@ -89,6 +105,7 @@ public class Monitor.MainWindow : Hdy.ApplicationWindow { var res = resources.serialize (); statusbar.update (res); dbusserver.update (res); + return false; }); return true; diff --git a/src/Managers/ContainerManager.vala b/src/Managers/ContainerManager.vala index 9d04fae1..75e21183 100644 --- a/src/Managers/ContainerManager.vala +++ b/src/Managers/ContainerManager.vala @@ -157,8 +157,6 @@ namespace Monitor { assert_nonnull (container_object); this.add_container (container_object); - - } var remove_me = new Gee.HashSet<DockerContainer> (); foreach (var container in this.container_list.values) { diff --git a/src/Managers/HttpClientAsync.vala b/src/Managers/HttpClientAsync.vala index f5a222b0..d641d3a0 100644 --- a/src/Managers/HttpClientAsync.vala +++ b/src/Managers/HttpClientAsync.vala @@ -49,7 +49,7 @@ namespace Monitor { r = curl.setopt (Curl.Option.WRITEFUNCTION, HttpClientResponse.read_body_data); assert_true (r == Curl.Code.OK); - // debug ("call api method: %s - %s", this.get_request_method (method), url); + // debug ("call api method: %s - %s", this.get_request_method (method), url); yield this.perform (curl); diff --git a/src/Managers/Process.vala b/src/Managers/Process.vala index ff55c5f1..b21edc0a 100644 --- a/src/Managers/Process.vala +++ b/src/Managers/Process.vala @@ -56,7 +56,6 @@ public class Monitor.Process : GLib.Object { private uint64 cpu_last_used; // Memory usage of the process, measured in KiB. - public uint64 mem_usage { get; private set; } public double mem_percentage { get; private set; } @@ -81,13 +80,11 @@ public class Monitor.Process : GLib.Object { stat.pid = _pid; // getting uid - GTop.ProcUid proc_uid; - GTop.get_proc_uid (out proc_uid, stat.pid); - uid = proc_uid.uid; - + uid = get_uid (); // getting username - // @TOFIX: Can't get username for postgres when started from docker (?) + // @TOFIX: Can't get username for postgres which + // is started from docker (?) unowned Posix.Passwd passwd = Posix.getpwuid (uid); if (passwd != null) { username = passwd.pw_name; @@ -98,6 +95,23 @@ public class Monitor.Process : GLib.Object { get_usage (0, 1); } + private int get_uid () { + if (ProcessUtils.is_flatpak_env ()) { + var process_provider = ProcessProvider.get_default (); + string ? status = process_provider.pids_status.get (this.stat.pid); + var status_line = status.split ("\n"); + + int uid = int.parse (status_line[8].split ("\t")[1]); + + // @TODO parse users file instead + if (uid == 0) username = "root"; + return uid; + + } + GTop.ProcUid proc_uid; + GTop.get_proc_uid (out proc_uid, stat.pid); + return proc_uid.uid; + } // Updates the process to get latest information // Returns if the update was successful @@ -114,6 +128,15 @@ public class Monitor.Process : GLib.Object { // Kills the process public bool kill () { + if (ProcessUtils.is_flatpak_env ()) { + try { + DBusWorkaroundClient.get_default ().interface.kill_process (this.stat.pid); + return true; + } catch (Error e) { + warning (e.message); + } + } + // Sends a kill signal that cannot be ignored if (Posix.kill (stat.pid, Posix.Signal.KILL) == 0) { return true; @@ -123,6 +146,15 @@ public class Monitor.Process : GLib.Object { // Ends the process public bool end () { + if (ProcessUtils.is_flatpak_env ()) { + try { + DBusWorkaroundClient.get_default ().interface.end_process (this.stat.pid); + return true; + } catch (Error e) { + warning (e.message); + } + } + // Sends a terminate signal if (Posix.kill (stat.pid, Posix.Signal.TERM) == 0) { return true; @@ -143,7 +175,52 @@ public class Monitor.Process : GLib.Object { return true; } + private bool parse_io_workaround () { + var process_provider = ProcessProvider.get_default (); + string ? io_stats = process_provider.pids_io.get (this.stat.pid); + + if (io_stats == "") return false; + + foreach (string line in io_stats.split ("\n")) { + if (line == "") continue; + var splitted_line = line.split (":"); + switch (splitted_line[0]) { + case "wchar": + io.wchar = uint64.parse (splitted_line[1]); + break; + case "rchar": + io.rchar = uint64.parse (splitted_line[1]); + break; + case "syscr": + io.syscr = uint64.parse (splitted_line[1]); + break; + case "syscw": + io.syscw = uint64.parse (splitted_line[1]); + break; + case "read_bytes": + io.read_bytes = uint64.parse (splitted_line[1]); + break; + case "write_bytes": + io.write_bytes = uint64.parse (splitted_line[1]); + break; + case "cancelled_write_bytes": + io.cancelled_write_bytes = uint64.parse (splitted_line[1]); + break; + default: + warning ("Unknown value in /proc/%d/io", stat.pid); + break; + } + } + + return true; + } + private bool parse_io () { + + if (ProcessUtils.is_flatpak_env ()) { + return parse_io_workaround (); + } + var io_file = File.new_for_path ("/proc/%d/io".printf (stat.pid)); if (!io_file.query_exists ()) { @@ -197,12 +274,18 @@ public class Monitor.Process : GLib.Object { // Reads the /proc/%pid%/stat file and updates the process with the information therein. private bool parse_stat () { - string ? stat_contents = ProcessUtils.read_file ("/proc/%d/stat".printf (stat.pid)); - - if (stat_contents == null) { - return false; + string ? stat_contents; + if (ProcessUtils.is_flatpak_env ()) { + var process_provider = ProcessProvider.get_default (); + stat_contents = process_provider.pids_stat.get (this.stat.pid); + } else { + stat_contents = ProcessUtils.read_file ("/proc/%d/stat".printf (stat.pid)); } + if (stat_contents == null) return false; + + // debug (stat_contents); + // Split the contents into an array and parse each value that we care about // But first we have to extract the command name, since it might include spaces @@ -229,12 +312,21 @@ public class Monitor.Process : GLib.Object { stat.priority = int.parse (splitted_stat[17]); stat.nice = int.parse (splitted_stat[18]); stat.num_threads = int.parse (splitted_stat[19]); + stat.utime = ulong.parse (splitted_stat[13]); + stat.stime = ulong.parse (splitted_stat[14]); + stat.rss = long.parse (splitted_stat[23]); return true; } private bool parse_statm () { - string ? statm_contents = ProcessUtils.read_file ("/proc/%d/statm".printf (stat.pid)); + string ? statm_contents; + if (ProcessUtils.is_flatpak_env ()) { + var process_provider = ProcessProvider.get_default (); + statm_contents = process_provider.pids_statm.get (this.stat.pid); + } else { + statm_contents = ProcessUtils.read_file ("/proc/%d/statm".printf (stat.pid)); + } if (statm_contents == null) return false; @@ -251,26 +343,26 @@ public class Monitor.Process : GLib.Object { } private bool get_open_files () { - try { - string directory = "/proc/%d/fd".printf (stat.pid); - Dir dir = Dir.open (directory, 0); - string ? name = null; - while ((name = dir.read_name ()) != null) { - string path = Path.build_filename (directory, name); - - if (FileUtils.test (path, FileTest.IS_SYMLINK)) { - string real_path = FileUtils.read_link (path); - // debug(content); - open_files_paths.add (real_path); - } - } - } catch (FileError err) { - if (err is FileError.ACCES) { - fd_permission_error (err.message); - } else { - warning (err.message); - } - } + // try { + // string directory = "/proc/%d/fd".printf (stat.pid); + // Dir dir = Dir.open (directory, 0); + // string ? name = null; + // while ((name = dir.read_name ()) != null) { + // string path = Path.build_filename (directory, name); + + // if (FileUtils.test (path, FileTest.IS_SYMLINK)) { + // string real_path = FileUtils.read_link (path); + //// debug(content); + // open_files_paths.add (real_path); + // } + // } + // } catch (FileError err) { + // if (err is FileError.ACCES) { + // fd_permission_error (err.message); + // } else { + // warning (err.message); + // } + // } return true; } @@ -278,7 +370,13 @@ public class Monitor.Process : GLib.Object { * Reads the /proc/%pid%/cmdline file and updates from the information contained therein. */ private bool read_cmdline () { - string ? cmdline = ProcessUtils.read_file ("/proc/%d/cmdline".printf (stat.pid)); + string ? cmdline; + if (ProcessUtils.is_flatpak_env ()) { + var process_provider = ProcessProvider.get_default (); + cmdline = process_provider.pids_cmdline.get (this.stat.pid); + } else { + cmdline = ProcessUtils.read_file ("/proc/%d/cmdline".printf (stat.pid)); + } if (cmdline == null) { return false; @@ -288,20 +386,26 @@ public class Monitor.Process : GLib.Object { // if cmdline has 0 length we look into stat file // useful for kworker processes command = stat.comm; - return true; } command = cmdline; + return true; } private void get_usage (uint64 cpu_total, uint64 cpu_last_total) { // Get CPU usage by process - GTop.ProcTime proc_time; - GTop.get_proc_time (out proc_time, stat.pid); - cpu_percentage = 100 * ((double) (proc_time.rtime - cpu_last_used)) / (cpu_total - cpu_last_total); - cpu_last_used = proc_time.rtime; + if (ProcessUtils.is_flatpak_env ()) { + var rtime = stat.utime + stat.stime; + cpu_percentage = 100 * ((double) (rtime - cpu_last_used)) / (cpu_total - cpu_last_total); + cpu_last_used = rtime; + } else { + GTop.ProcTime proc_time; + GTop.get_proc_time (out proc_time, stat.pid); + cpu_percentage = 100 * ((double) (proc_time.rtime - cpu_last_used)) / (cpu_total - cpu_last_total); + cpu_last_used = proc_time.rtime; + } // Making CPU history if (cpu_percentage_history.size == HISTORY_BUFFER_SIZE) { @@ -313,9 +417,14 @@ public class Monitor.Process : GLib.Object { GTop.Memory mem; GTop.get_mem (out mem); - GTop.ProcMem proc_mem; - GTop.get_proc_mem (out proc_mem, stat.pid); - mem_usage = (proc_mem.resident - proc_mem.share) / 1024; // in KiB + if (ProcessUtils.is_flatpak_env ()) { + mem_usage = (stat.rss * 4096 - statm.shared) / 1024; + } else { + GTop.ProcMem proc_mem; + GTop.get_proc_mem (out proc_mem, stat.pid); + mem_usage = (proc_mem.resident - proc_mem.share) / 1024; // in KiB + } + // also if it is using X Window Server if (Gdk.Display.get_default () is Gdk.X11.Display) { diff --git a/src/Managers/ProcessManager.vala b/src/Managers/ProcessManager.vala index b2d38659..8ef55611 100644 --- a/src/Managers/ProcessManager.vala +++ b/src/Managers/ProcessManager.vala @@ -97,7 +97,7 @@ namespace Monitor { /** * Gets all new process and adds them */ - public async void update_processes () { + public async void update_processes () { /* CPU */ GTop.Cpu cpu_data; GTop.get_cpu (out cpu_data); @@ -130,14 +130,10 @@ namespace Monitor { remove_process (pid); } - var uid = Posix.getuid (); - GTop.ProcList proclist; - // var pids = GTop.get_proclist (out proclist, GTop.GLIBTOP_KERN_PROC_UID, uid); - var pids = GTop.get_proclist (out proclist, GTop.GLIBTOP_KERN_PROC_ALL, uid); - - for (int i = 0; i < proclist.number; i++) { - int pid = pids[i]; + var process_provider = ProcessProvider.get_default (); + var pids = process_provider.get_pids (); + foreach (int pid in pids) { if (!process_list.has_key (pid) && !kernel_process_blacklist.contains (pid)) { add_process (pid); } @@ -225,7 +221,7 @@ namespace Monitor { return true; } // some processes have semicolon in command - // do not sanitizing to improve readability + // do not sanitize to improve readability else if (process.command.split (" ")[0].contains (":")) { process.application_name = process.command; return true; diff --git a/src/Managers/ProcessProvider.vala b/src/Managers/ProcessProvider.vala new file mode 100644 index 00000000..df3b2ba2 --- /dev/null +++ b/src/Managers/ProcessProvider.vala @@ -0,0 +1,79 @@ +namespace Monitor { + public class ProcessProvider : GLib.Object { + private static GLib.Once<ProcessProvider> instance; + public static unowned ProcessProvider get_default () { + return instance.once (() => { return new ProcessProvider (); }); + } + + private bool is_flatpak; + + public Gee.HashMap<int, string> pids_cmdline = new Gee.HashMap<int, string> (); + public Gee.HashMap<int, string> pids_stat = new Gee.HashMap<int, string> (); + public Gee.HashMap<int, string> pids_statm = new Gee.HashMap<int, string> (); + public Gee.HashMap<int, string> pids_io = new Gee.HashMap<int, string> (); + public Gee.HashMap<int, string> pids_status = new Gee.HashMap<int, string> (); + public Gee.HashMap<int, string> pids_children = new Gee.HashMap<int, string> (); + + DBusWorkaroundClient dbus_workaround_client; + + construct { + this.is_flatpak = ProcessUtils.is_flatpak_env (); + if (this.is_flatpak) { + this.spawn_workaround (); + dbus_workaround_client = DBusWorkaroundClient.get_default (); + } + } + + private bool spawn_workaround () { + try { + debug ("Spawning workaround. . ."); + string app_path = ProcessUtils.get_flatpak_app_path (); + string command = @"flatpak-spawn --host env LANG=C $app_path/share/workaround/com.github.stsdc.monitor-workaround.py"; + return GLib.Process.spawn_command_line_async (command); + } catch (SpawnError e) { + warning ("Spawning workaround error: %s\n", e.message); + return false; + } + } + + public int[] get_pids () { + if (this.is_flatpak) { + int[] pids; + pids_cmdline.clear (); + pids_stat.clear (); + pids_io.clear (); + pids_status.clear (); + pids_children.clear (); + try { + HashTable<string, string>[] procs = dbus_workaround_client.interface.get_processes (""); + pids = new int[procs.length]; + debug ("Workaround client: retrieved pids: %d", procs.length); + for (int i = 0; i < procs.length; i++) { + // debug (procs[i]["pid"]); + pids[i] = int.parse (procs[i]["pid"]); + pids_cmdline.set (pids[i], procs[i]["cmdline"]); + pids_stat.set (pids[i], procs[i]["stat"]); + pids_statm.set (pids[i], procs[i]["statm"]); + pids_io.set (pids[i], procs[i]["io"]); + pids_children.set (pids[i], procs[i]["children"]); + pids_status.set (pids[i], procs[i]["status"]); + } + } catch (Error e) { + warning (e.message); + } + return pids; + } + GTop.ProcList proclist; + // var pids = GTop.get_proclist (out proclist, GTop.GLIBTOP_KERN_PROC_UID, uid); + var pids = GTop.get_proclist (out proclist, GTop.GLIBTOP_KERN_PROC_ALL, Posix.getuid ()); + pids.length = (int) proclist.number; + + return pids; + } + + public void end_process (int pid) { + DBusWorkaroundClient.get_default (); + } + + } +} diff --git a/src/Managers/ProcessStructs.vala b/src/Managers/ProcessStructs.vala index 97f06889..2a352772 100644 --- a/src/Managers/ProcessStructs.vala +++ b/src/Managers/ProcessStructs.vala @@ -101,4 +101,10 @@ public struct Monitor.ProcessStatus { // The time the process started after system boot. public uint64 starttime; + + public ulong utime; + public ulong stime; + + /** Resident Set Size: number of pages the process has in real memory. */ + public long rss; } diff --git a/src/Managers/ProcessUtils.vala b/src/Managers/ProcessUtils.vala index 31807093..43e57679 100644 --- a/src/Managers/ProcessUtils.vala +++ b/src/Managers/ProcessUtils.vala @@ -15,18 +15,26 @@ public class Monitor.ProcessUtils { var splitted_commandline = commandline.split (" "); // check if started by any shell - if (is_shell (splitted_commandline[0]) || is_python (splitted_commandline[0]) ) { + if (is_shell (splitted_commandline[0]) || is_python (splitted_commandline[0])) { return commandline; } - // if (!splitted_commandline[0].contains ("/")) { - // return commandline; - // } + // if (!splitted_commandline[0].contains ("/")) { + // return commandline; + // } return splitted_commandline[0]; } public static string ? read_file (string path) { + // if (ProcessUtils.is_flatpak_env ()) { + // return ProcessUtils.read_file_on_host (path); + // } + + return ProcessUtils.read_file_native (path); + } + + public static string ? read_file_native (string path) { var file = File.new_for_path (path); /* make sure that it exists, not an error if it doesn't */ @@ -54,6 +62,54 @@ public class Monitor.ProcessUtils { } } + public static string ? read_file_on_host (string path) { + string stdout; + string stderr; + string stdin; + int status; + + int standard_input; + int standard_output; + int standard_error; + + + string command = "flatpak-spawn --host cat " + path; + string[] spawn_args = { "flatpak-spawn", "--host", "env", "LANG=C", "cat", path }; + Pid child_pid; + + try { + // string command = "flatpak-spawn --host cat " + path + " | grep -av DEBUG"; + debug (command); + GLib.Process.spawn_command_line_sync + ( + command, + out stdout, + out stderr, + out status + ); + + } catch (SpawnError e) { + error (e.message); + } + + + string ? stdout_no_debug = ""; + + if (stdout == "" || status != 0) { + warning ("Tried to execute %s, but got null. Status: %d", command, status); + return null; + } + + foreach (var line in stdout.split ("\n")) { + if (!line.contains ("DEBUG")) { + stdout_no_debug += line + "\n"; + } + } + // print (stdout_no_debug); + // return null; + return stdout_no_debug; + } + public static Icon ? get_default_icon () { try { return Icon.new_for_string ("application-x-executable"); @@ -62,4 +118,24 @@ public class Monitor.ProcessUtils { return null; } } + + public static bool is_flatpak_env () { + string environment = GLib.Environment.get_variable ("container"); + // debug ("Monitor is running in %s environment", environment); + if (environment == "flatpak") { + return true; + } + return false; + } + + public static string get_flatpak_app_path () { + string ? flatpak_info_content = ProcessUtils.read_file ("/.flatpak-info"); + foreach (var line in flatpak_info_content.split ("\n")) { + if (line.contains ("app-path")) { + return line.replace ("app-path=", ""); + } + } + return ""; + } + } diff --git a/src/Services/DBusWorkaroundClient.vala b/src/Services/DBusWorkaroundClient.vala new file mode 100644 index 00000000..46e01be7 --- /dev/null +++ b/src/Services/DBusWorkaroundClient.vala @@ -0,0 +1,36 @@ +[DBus (name = "com.github.stsdc.monitor.workaround.GetProcesses")] +public interface Monitor.DBusWorkaroundClientInterface : Object { + public abstract HashTable<string, string>[] get_processes (string empty) throws Error; + public abstract void end_process (int pid) throws Error; + public abstract void kill_process (int pid) throws Error; + +} + +public class Monitor.DBusWorkaroundClient : Object { + public DBusWorkaroundClientInterface ? interface = null; + + private static GLib.Once<DBusWorkaroundClient> instance; + public static unowned DBusWorkaroundClient get_default () { + return instance.once (() => { return new DBusWorkaroundClient (); }); + } + + construct { + try { + interface = Bus.get_proxy_sync ( + BusType.SESSION, + "com.github.stsdc.monitor.workaround", + "/com/github/stsdc/monitor/workaround" + ); + + Bus.watch_name ( + BusType.SESSION, + "com.github.stsdc.monitor.workaround", + BusNameWatcherFlags.NONE + ); + } catch (IOError e) { + error ("Monitor Indicator DBus: %s\n", e.message); + } + + + } +} diff --git a/src/meson.build b/src/meson.build index 24ef83a5..f7fb6f2a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -57,10 +57,14 @@ source_app_files = [ 'Managers/HttpClientAsync.vala', 'Managers/ContainerManager.vala', 'Managers/Container.vala', + 'Managers/ProcessProvider.vala', + # 'Managers/ProcessWorkaround.vala', + # 'Managers/IProcess.vala', # Services 'Services/Shortcuts.vala', 'Services/DBusServer.vala', + 'Services/DBusWorkaroundClient.vala', 'Services/Appearance.vala', # Resources diff --git a/subprojects/stylesheet b/subprojects/stylesheet index da0c4196..fbe2b247 160000 --- a/subprojects/stylesheet +++ b/subprojects/stylesheet @@ -1 +1 @@ -Subproject commit da0c4196ce246c6506a8a709f4140a098796fd4f +Subproject commit fbe2b24704bbfd489152350627033295b3770a38