Squashed commit of the following:

commit ec7e087b343f33af7a92b190ed666845dab60f20
Merge: 32b6e63 9912f9d
Author: shadeyg56 <31134255+shadeyg56@users.noreply.github.com>
Date:   Mon Feb 13 14:11:21 2023 -0600

    Merge branch 'AdnanHodzic:master' into gui

commit 32b6e632830fe8a7c3a3ce601ef2ba5b254572d7
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Mon Feb 13 14:10:34 2023 -0600

    increase MenuButton size

commit 12a2cda82a5f56bfbb532c893d822341e9b2d7cb
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 12 23:35:33 2023 -0600

    set app icon

commit d170d07e866644bcb662bf342530c497390f0303
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 12 23:35:15 2023 -0600

    remove unused pixbuf

commit 993333fb5aad448103e24e38bc85fb04e7e4dd0c
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 12 22:43:56 2023 -0600

    fix MenuButton icon

commit d1b8bd74caab2cf216bf40bdfc35ef3520e891c7
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 12 17:19:32 2023 -0600

    add icon

commit 13f43fa0c7d59b2405bac688119690d01a7ec019
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 12 17:19:10 2023 -0600

    add pkexec policy and change wrapper for gui

commit 4ddbb9c6667aa97bb7cd242fb4a376e061c9b308
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 12 14:09:35 2023 -0600

    add icon to destop entry and about dialog

commit 9912f9d80935bb51c9cb759ab95c9ba7fde15524
Author: Siddharth Kumar Jha <101443068+siddharthkumarjha@users.noreply.github.com>
Date:   Sun Feb 12 12:55:14 2023 +0530

    Update Readme for issue of auto-cpufreq not autostarting on AUR  (#485)

    * Updated Readme for issue auto-cpufreq not autostarting

    Added solution to issue https://github.com/AdnanHodzic/auto-cpufreq/issues/463

    * Fixed minor errors

    * Fixed auto-cpufreq.serivce Typo

    * Reprashed text as per suggestion

commit 4379024adab282fcdb58a7091df2a6adf833e700
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Tue Feb 7 19:06:59 2023 -0600

    add removal of gui and desktop entry

commit 42693703324762418a7f810f04a3d77803afa236
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Mon Feb 6 23:28:44 2023 -0600

    CPU stats refresh and style stuff

commit 7149db72c0bb39af57ceccb16df8e9164c77fae3
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Mon Feb 6 23:10:29 2023 -0600

    daemon detection, daemon install/removal, and layout stuff

commit f7e03c9bcc2e2578703807ceeb7a652903571b71
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 5 19:26:42 2023 -0600

    improve AboutDialog

    Please enter the commit message for your changes. Lines starting

commit cb8cfe7b3194273dea229fe550fdf66cd6af82fa
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 5 18:28:19 2023 -0600

    add dropdown menu and (not completed) about dialog

commit ade1fed790f2ebbaae4e92ce8879ab812c9b2850
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 5 15:57:17 2023 -0600

    actually fix css

commit 67c8c97bcf2f2f408431bc162c38dee5c278ed0b
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 5 15:54:47 2023 -0600

    fix css

commit c65eac3472f724bed10a0f530b2a828463bbe7fe
Author: Adnan Hodzic <adnan@hodzic.org>
Date:   Sun Feb 5 09:29:19 2023 +0100

    Update readme, install psutil lib for power_helper

commit bd3feae38824764155d31ccd6debc1fcf18830da
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 5 00:42:52 2023 -0600

    add desktop entry for gui

commit 5426a6a443c90a9d65b858ae1951219898cba332
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sun Feb 5 00:33:08 2023 -0600

    add gui to install file, update required packages, and create wrapper script

commit 84124dfa605b930b3722ed852486cbe11c254092
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sat Feb 4 23:28:24 2023 -0600

    create system tray

commit 7b0d46d8ddafdeff9006a1ad10ccd99c24b9eb1e
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sat Feb 4 23:28:01 2023 -0600

    small changes to layout

commit cd51ea317085ac6ea5b4918ef057ad4c19a71640
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sat Feb 4 00:44:08 2023 -0600

    css styling support

commit 136b449febece04c036b72b4a14ccceb422f62dd
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Sat Feb 4 00:14:52 2023 -0600

    several improvements

commit f9f7170391e1abc1499b7d5ae93327999e013730
Merge: 242a8d0 8f343df
Author: shadeyg56 <31134255+shadeyg56@users.noreply.github.com>
Date:   Fri Feb 3 22:44:01 2023 -0600

    Merge branch 'AdnanHodzic:master' into gui

commit 8f343df8b8b82846364fbc14b2fc2e5144abebaa
Merge: dadfae0 b38919f
Author: shadeyg56 <31134255+shadeyg56@users.noreply.github.com>
Date:   Fri Feb 3 14:54:11 2023 -0600

    Merge pull request #481 from shadeyg56/master

    Fix uncaught error in checking for snap

commit b38919f56b6329c81c4c96eabe9bfd27d590d16e
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Fri Feb 3 14:48:01 2023 -0600

    fix uncaught error in checking for snap

commit 242a8d0401d1ffd00c982aa731c04ef7ea726fee
Merge: f50b982 dadfae0
Author: shadeyg56 <31134255+shadeyg56@users.noreply.github.com>
Date:   Fri Feb 3 14:19:01 2023 -0600

    Merge branch 'AdnanHodzic:master' into gui

commit dadfae087f102c0f69329d5ad79e3a648c35b459
Author: Adnan Hodzic <adnan@hodzic.org>
Date:   Fri Feb 3 20:02:03 2023 +0100

    Update README with  new config options

commit 471611de7da97b7da8580646612d4f910311e16e
Author: Adnan Hodzic <adnan@hodzic.org>
Date:   Fri Feb 3 18:44:33 2023 +0100

    Remove GNOME Power Profiles Daemon performance install

commit f574257dc475f942fa39179787acf09c567e76dd
Author: Adnan Hodzic <adnan@hodzic.org>
Date:   Fri Feb 3 18:32:04 2023 +0100

    Remove install_performance flag

commit 04b878360c7dff4b0e44fc8935e9667a597806b4
Author: Adnan Hodzic <adnan@hodzic.org>
Date:   Fri Feb 3 17:52:20 2023 +0100

    Snap tag 2.0-beta + governor_override improvements

commit fe21ddf24585164ed0f8cfa8f9ad7d3db627ab79
Author: Adnan Hodzic <adnan@hodzic.org>
Date:   Fri Feb 3 17:28:12 2023 +0100

    Working governor override on Snap package

commit f50b9829e5438bb96ded73775668fa048fcd3951
Merge: a98225e 69ef913
Author: shadeyg56 <31134255+shadeyg56@users.noreply.github.com>
Date:   Thu Feb 2 18:19:10 2023 -0600

    Merge branch 'AdnanHodzic:master' into gui

commit a98225e7280802c2fb09a9a52a40f7e55b26b3b1
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Thu Feb 2 18:18:43 2023 -0600

    Revert "basic GUI"

    This reverts commit d2610c921b7209fde7d7be13f187510631cc33b3.

commit 9606472fdbbff6dd551cd291b37349df17098d2e
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Thu Feb 2 18:13:41 2023 -0600

    basic gui

commit d2610c921b7209fde7d7be13f187510631cc33b3
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Thu Feb 2 17:47:55 2023 -0600

    basic GUI

commit bdbe12018b380ed70f100729c9ea3732ba24f572
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Thu Feb 2 15:21:42 2023 -0600

    rename folder

commit 31095c472e4af734a3a601f804787de89ad47964
Author: shadeyg56 <shadeyg56@gmail.com>
Date:   Wed Jan 25 23:39:52 2023 -0600

    add tray
This commit is contained in:
shadeyg56 2023-02-13 14:13:11 -06:00
parent 69ef913c1b
commit 31b1ddec08
17 changed files with 548 additions and 122 deletions

View File

@ -19,7 +19,7 @@ auto-cpufreq is looking for [co-maintainers & open source developers to help sha
* [Snap store](https://github.com/AdnanHodzic/auto-cpufreq/#snap-store)
* [auto-cpufreq-installer](https://github.com/AdnanHodzic/auto-cpufreq/#auto-cpufreq-installer)
* [AUR package (Arch/Manjaro Linux)](https://github.com/AdnanHodzic/auto-cpufreq/#aur-package-archmanjaro-linux)
* [Post Installation]
* [Post Installation](https://github.com/AdnanHodzic/auto-cpufreq/blob/install_performance_rm/README.md#post-installation)
* [Configuring auto-cpufreq](https://github.com/AdnanHodzic/auto-cpufreq/#configuring-auto-cpufreq)
* [1: power_helper.py script](https://github.com/AdnanHodzic/auto-cpufreq/#1-power_helperpy-script)
* [2: auto-cpufreq config file](https://github.com/AdnanHodzic/auto-cpufreq/#2-auto-cpufreq-config-file)
@ -33,6 +33,7 @@ auto-cpufreq is looking for [co-maintainers & open source developers to help sha
* [Remove - auto-cpufreq daemon](https://github.com/AdnanHodzic/auto-cpufreq/#remove---auto-cpufreq-daemon)
* [stats](https://github.com/AdnanHodzic/auto-cpufreq/#stats)
* [Troubleshooting](https://github.com/AdnanHodzic/auto-cpufreq/#troubleshooting)
* [AUR](https://github.com/AdnanHodzic/auto-cpufreq/#aur)
* [Discussion](https://github.com/AdnanHodzic/auto-cpufreq/#discussion)
* [Donate](https://github.com/AdnanHodzic/auto-cpufreq/#donate)
* [Financial donation](https://github.com/AdnanHodzic/auto-cpufreq/#financial-donation)
@ -102,7 +103,7 @@ In case you encounter any problems with `auto-cpufreq-installer`, please [submit
### AUR package (Arch/Manjaro Linux)
*AUR is currently unmaintained & has issues*! Until someone starts maintaining it, use the [auto-cpufreq-installer](https://github.com/AdnanHodzic/auto-cpufreq#auto-cpufreq-installer) if you intend to have the latest changes as otherwise you'll run into errors, i.e: [#471](https://github.com/AdnanHodzic/auto-cpufreq/issues/471).
*AUR is currently unmaintained & has issues*! Until someone starts maintaining it, use the [auto-cpufreq-installer](https://github.com/AdnanHodzic/auto-cpufreq#auto-cpufreq-installer) if you intend to have the latest changes as otherwise you'll run into errors, i.e: [#471](https://github.com/AdnanHodzic/auto-cpufreq/issues/471). However, if you still wish to use AUR then follow the [Troubleshooting](https://github.com/AdnanHodzic/auto-cpufreq/#aur) section for solved known issues.
* [Binary Package](https://aur.archlinux.org/packages/auto-cpufreq)
(For the latest binary release on github)
@ -114,32 +115,39 @@ After installation `auto-cpufreq` will be available as a binary and you can refe
## Configuring auto-cpufreq
auto-cpufreq makes all decisions automatically based on various factors like cpu usage, temperature or system load. However, it's possible to perform additional configurations in 2 ways:
auto-cpufreq makes all decisions automatically based on various factors like cpu usage, temperature or system load. However, it's possible to perform additional configurations:
### 1: power_helper.py script
### 1: power_helper.py script (Snap package install **only**)
If detected as running, auto-cpufreq will disable [GNOME Power profiles service](https://twitter.com/fooctrl/status/1467469508373884933), which would otherwise cause conflicts and cause problems.
When installing auto-cpufreq using [auto-cpufreq-installer](https://github.com/AdnanHodzic/auto-cpufreq/#auto-cpufreq-installer) if it detects [GNOME Power profiles service](https://twitter.com/fooctrl/status/1467469508373884933) is running it will automatically disable it. Otherwise this daemon will cause conflicts and various other performance issues.
By default auto-cpufreq uses `balanced` mode which works the best on various systems. However, if you're not reaching maximum frequencies your CPU is capable of with auto-cpufreq ([#361](https://github.com/AdnanHodzic/auto-cpufreq/issues/361)), you can switch to `performance` mode. Which will result in higher frequencies by default, but also results in higher energy use (battery consumption).
If you installed auto-cpufreq using [auto-cpufreq-installer](https://github.com/AdnanHodzic/auto-cpufreq/edit/master/README.md#auto-cpufreq-installer), you can switch to `performance` mode by running:
`sudo auto-cpufreq --install_performance`
Or if you installed auto-cpufreq using [Snap package](https://github.com/AdnanHodzic/auto-cpufreq/edit/master/README.md#snap-store) you can switch to `performance` mode by running:
`sudo python3 power_helper.py --gnome_power_disable performance`
However, when auto-cpufreq is installed as Snap package it's running as part of a container with limited permissions to your host machine, hence it's *highly recommended* you disable GNOME Power Profiles Daemon using `power_helper.py` script.
**Please Note:**
The `power_helper.py` script is located at `auto_cpufreq/power_helper.py`. In order to have access to it, you need to first clone
The [`power_helper.py`](https://github.com/AdnanHodzic/auto-cpufreq/blob/master/auto_cpufreq/power_helper.py) script is located at `auto_cpufreq/power_helper.py`. In order to have access to it, you need to first clone
the repository:
`git clone https://github.com/AdnanHodzic/auto-cpufreq`
Navigate to repo location where `power_helper.py` resides, i.e:
After this step, all necessary changes will still be made automatically. However, if you wish to perform additional "manual" settings this can be done by following instructions explained in next step.
`cd auto-cpufreq/auto_cpufreq`
### 2: auto-cpufreq config file
Make sure to have `psutil` Python library installed before next step, i.e: `sudo python3 -m pip install psutil`
Then disable GNOME Power Profiles Daemon by runing:
`sudo python3 power_helper.py --gnome_power_disable`
### 2: `--force` governor override
By default auto-cpufreq uses `balanced` mode which works the best on various systems and situations.
However, you can override this behaviour by switching to `performance` or `powersave` mode manually. Performance will result in higher frequencies by default, but also results in higher energy use (battery consumption) and should be used if max performance is necessary. Otherwise `powersave` will do the opposite and extend the battery life to its maximum.
See [`--force` flag](https://github.com/AdnanHodzic/auto-cpufreq/#overriding-governor) for more info.
### 3: auto-cpufreq config file
You can configure seperate profiles for the battery and power supply. These profiles will let you pick which governor to use, and how and when turbo boost is enabled. The possible values for turbo boost behavior are `always`, `auto` and `never`. The default behavior is `auto`, which only kicks in during high load.
@ -310,6 +318,21 @@ GRUB_CMDLINE_LINUX_DEFAULT="quiet splash initcall_blacklist=amd_pstate_init amd_
After you are done, run `sudo update-grub` or `sudo grub-mkconfig -o /boot/grub/grub.cfg`, if you are using Arch.
### AUR
* The command ```sudo auto-cpufreq --install``` produces error [#471](https://github.com/AdnanHodzic/auto-cpufreq/issues/471) please don't use it.
* This script is supposed to automate the process of enabling auto-cpufreq.service so you need to manually open terminal and type
~~~
sudo systemctl enable --now auto-cpufreq.service
~~~
for the service to work.
* Power Profiles Daemon is [automatically disabled by auto-cpufreq-installer](https://github.com/AdnanHodzic/auto-cpufreq#1-power_helperpy-script-snap-package-install-only) due to it's conflict with auto-cpufreq.service. However this doesn't happen with AUR package and will lead to problems (i.e: [#463](https://github.com/AdnanHodzic/auto-cpufreq/issues/463)) if not masked manually.
* So open your terminal and type
~~~
sudo systemctl mask power-profiles-daemon.service
~~~
Following this command ```enable``` the auto-cpufreq.service if you haven't already.
## Discussion:
* Blogpost: [auto-cpufreq - Automatic CPU speed & power optimizer for Linux](http://foolcontrol.org/?p=3124)

View File

@ -63,10 +63,18 @@ function install {
python3 setup.py install --record files.txt
mkdir -p /usr/local/share/auto-cpufreq/
cp -r scripts/ /usr/local/share/auto-cpufreq/
cp -r images/ /usr/local/share/auto-cpufreq/
cp images/icon.png /usr/share/pixmaps/auto-cpufreq.png
cp scripts/org.auto-cpufreq.pkexec.policy /usr/share/polkit-1/actions
# this is necessary since we need this script before we can run auto-cpufreq itself
cp scripts/auto-cpufreq-venv-wrapper /usr/local/bin/auto-cpufreq
cp scripts/start_app /usr/local/bin/auto-cpufreq-gtk
chmod a+x /usr/local/bin/auto-cpufreq
chmod a+x /usr/local/bin/auto-cpufreq-gtk
desktop-file-install --dir=/usr/share/applications scripts/auto-cpufreq-gtk.desktop
update-desktop-database /usr/share/applications
}
# First argument is the distro
@ -140,7 +148,7 @@ function tool_install {
separator
if [ -f /etc/debian_version ]; then
detected_distro "Debian based"
apt install python3-dev python3-pip python3-venv python3-setuptools dmidecode -y
apt install python3-dev python3-pip python3-venv python3-setuptools dmidecode libgirepository1.0-dev libcairo2-dev -y
completed
complete_msg
elif [ -f /etc/redhat-release ]; then
@ -170,12 +178,12 @@ elif [ -f /etc/os-release ];then
opensuse)
detected_distro "OpenSUSE"
echo -e "\nDetected an OpenSUSE distribution\n\nSetting up Python environment\n"
zypper install -y python38 python3-pip python3-setuptools python3-devel gcc dmidecode
zypper install -y python38 python3-pip python3-setuptools python3-devel gcc dmidecode gobject-introspection-devel python3-cairo-devel
completed
;;
arch|manjaro|endeavouros|garuda|artix)
detected_distro "Arch Linux based"
pacman -S --noconfirm --needed python python-pip python-setuptools base-devel dmidecode
pacman -S --noconfirm --needed python python-pip python-setuptools base-devel dmidecode gobject-introspection
completed
;;
void)
@ -208,12 +216,15 @@ function tool_remove {
tool_proc_rm="/usr/local/bin/auto-cpufreq --remove"
wrapper_script="/usr/local/bin/auto-cpufreq"
gui_wrapper_script="/usr/local/bin/auto-cpufreq-gtk"
unit_file="/etc/systemd/system/auto-cpufreq.service"
venv_path="/opt/auto-cpufreq"
cpufreqctl="/usr/local/bin/cpufreqctl.auto-cpufreq"
cpufreqctl_old="/usr/bin/cpufreqctl.auto-cpufreq"
desktop_file="/usr/share/applications/auto-cpufreq-gtk.desktop"
# stop any running auto-cpufreq argument (daemon/live/monitor)
tool_arg_pids=($(pgrep -f "auto-cpufreq --"))
for pid in "${tool_arg_pids[@]}"; do
@ -246,10 +257,14 @@ function tool_remove {
[ -f $stats_file ] && rm $stats_file
[ -f $unit_file ] && rm $unit_file
[ -f $wrapper_script ] && rm $wrapper_script
[ -f $gui_wrapper_script ] && rm $gui_wrapper_script
[ -f $cpufreqctl ] && rm $cpufreqctl
[ -f $cpufreqctl_old ] && rm $cpufreqctl_old
[ -f $desktop_file ] && rm $desktop_file
update-desktop-database /usr/share/applications
# remove python virtual environment
rm -rf "${venv_path}"

View File

@ -27,6 +27,9 @@ from auto_cpufreq.power_helper import *
warnings.filterwarnings("ignore")
# add path to auto-cpufreq executables for GUI
os.environ["PATH"] += ":/usr/local/bin"
# ToDo:
# - replace get system/CPU load from: psutil.getloadavg() | available in 5.6.2)
@ -59,7 +62,10 @@ auto_cpufreq_stats_path = None
auto_cpufreq_stats_file = None
# track governor override
STORE = "/opt/auto-cpufreq/override.pickle"
if os.getenv("PKG_MARKER") == "SNAP":
governor_override_state = Path("/var/snap/auto-cpufreq/current/override.pickle")
else:
governor_override_state = Path("/opt/auto-cpufreq/override.pickle")
if os.getenv("PKG_MARKER") == "SNAP":
auto_cpufreq_stats_path = Path("/var/snap/auto-cpufreq/current/auto-cpufreq.stats")
@ -86,20 +92,20 @@ def get_config(config_file=""):
return get_config.config
def get_override():
if os.path.isfile(STORE):
with open(STORE, "rb") as store:
if os.path.isfile(governor_override_state):
with open(governor_override_state, "rb") as store:
return pickle.load(store)
else:
return "default"
def set_override(override):
if override in ["powersave", "performance"]:
with open(STORE, "wb") as store:
with open(governor_override_state, "wb") as store:
pickle.dump(override, store)
print(f"Set governor override to {override}")
elif override == "reset":
if os.path.isfile(STORE):
os.remove(STORE)
if os.path.isfile(governor_override_state):
os.remove(governor_override_state)
print("Governor override removed")
elif override is not None:
print("Invalid option.\nUse force=performance, force=powersave, or force=reset")
@ -442,8 +448,8 @@ def remove_daemon():
os.remove("/usr/local/bin/auto-cpufreq-remove")
# delete override pickle if it exists
if os.path.exists(STORE):
os.remove(STORE)
if os.path.exists(governor_override_state):
os.remove(governor_override_state)
# delete stats file
if auto_cpufreq_stats_path.exists():

View File

87
auto_cpufreq/gui/app.py Normal file
View File

@ -0,0 +1,87 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk, Gio, GdkPixbuf
import os
import sys
sys.path.append("../")
from auto_cpufreq.core import is_running
from auto_cpufreq.gui.objects import RadioButtonView, SystemStatsLabel, CPUFreqStatsLabel, CurrentGovernorBox, DropDownMenu, DaemonNotRunningView
CSS_FILE = "/usr/local/share/auto-cpufreq/scripts/style.css"
HBOX_PADDING = 20
class MyWindow(Gtk.Window):
def __init__(self):
super().__init__(title="auto-cpufreq")
self.set_default_size(600, 480)
self.set_border_width(10)
self.set_resizable(False)
self.load_css()
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(filename="/usr/local/share/auto-cpufreq/images/icon.png", width=500, height=500, preserve_aspect_ratio=True)
self.set_icon(pixbuf)
self.build()
def main(self):
# main VBOX
self.vbox_top = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.vbox_top.set_valign(Gtk.Align.CENTER)
self.vbox_top.set_halign(Gtk.Align.CENTER)
self.add(self.vbox_top)
self.hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=HBOX_PADDING)
self.systemstats = SystemStatsLabel()
self.hbox.pack_start(self.systemstats, False, False, 0)
self.vbox_right = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=20)
self.menu = DropDownMenu(self)
self.vbox_top.pack_start(self.menu, False, False, 0)
self.currentgovernor = CurrentGovernorBox()
self.vbox_right.pack_start(self.currentgovernor, False, False, 0)
self.vbox_right.pack_start(RadioButtonView(), False, False, 0)
self.cpufreqstats = CPUFreqStatsLabel()
self.vbox_right.pack_start(self.cpufreqstats, False, False, 0)
self.hbox.pack_start(self.vbox_right, True, True, 0)
self.vbox_top.pack_start(self.hbox, False, False, 0)
GLib.timeout_add_seconds(5, self.refresh)
def daemon_not_running(self):
self.box = DaemonNotRunningView(self)
self.add(self.box)
def build(self):
if is_running("auto-cpufreq", "--daemon"):
self.main()
else:
self.daemon_not_running()
def load_css(self):
screen = Gdk.Screen.get_default()
self.gtk_provider = Gtk.CssProvider()
self.gtk_context = Gtk.StyleContext()
self.gtk_context.add_provider_for_screen(screen, self.gtk_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
self.gtk_provider.load_from_file(Gio.File.new_for_path(CSS_FILE))
def refresh(self):
self.systemstats.refresh()
self.currentgovernor.refresh()
self.cpufreqstats.refresh()
return True
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

272
auto_cpufreq/gui/objects.py Normal file
View File

@ -0,0 +1,272 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GdkPixbuf
import sys
import os
import platform as pl
sys.path.append("../../")
from subprocess import getoutput, call
from auto_cpufreq.core import sysinfo, distro_info, set_override, get_override, get_formatted_version, dist_name, deploy_daemon, remove_daemon
from io import StringIO
if os.getenv("PKG_MARKER") == "SNAP":
auto_cpufreq_stats_path = "/var/snap/auto-cpufreq/current/auto-cpufreq.stats"
else:
auto_cpufreq_stats_path = "/var/run/auto-cpufreq.stats"
def get_stats():
if os.path.isfile(auto_cpufreq_stats_path):
with open(auto_cpufreq_stats_path, "r") as file:
stats = [line for line in (file.readlines() [-50:])]
return "".join(stats)
def get_version():
# snap package
if os.getenv("PKG_MARKER") == "SNAP":
return getoutput("echo \(Snap\) $SNAP_VERSION")
# aur package
elif dist_name in ["arch", "manjaro", "garuda"]:
aur_pkg_check = call("pacman -Qs auto-cpufreq > /dev/null", shell=True)
if aur_pkg_check == 1:
return get_formatted_version()
else:
return getoutput("pacman -Qi auto-cpufreq | grep Version")
else:
# source code (auto-cpufreq-installer)
try:
return get_formatted_version()
except Exception as e:
print(repr(e))
pass
class RadioButtonView(Gtk.Box):
def __init__(self):
super().__init__(orientation=Gtk.Orientation.HORIZONTAL)
self.set_hexpand(True)
self.hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.label = Gtk.Label("Governor Override", name="bold")
self.default = Gtk.RadioButton.new_with_label_from_widget(None, "Default")
self.default.connect("toggled", self.on_button_toggled, "reset")
self.default.set_halign(Gtk.Align.END)
self.powersave = Gtk.RadioButton.new_with_label_from_widget(self.default, "Powersave")
self.powersave.connect("toggled", self.on_button_toggled, "powersave")
self.powersave.set_halign(Gtk.Align.END)
self.performance = Gtk.RadioButton.new_with_label_from_widget(self.default, "Performance")
self.performance.connect("toggled", self.on_button_toggled, "performance")
self.performance.set_halign(Gtk.Align.END)
self.set_selected()
self.pack_start(self.label, False, False, 0)
self.pack_start(self.default, True, True, 0)
self.pack_start(self.powersave, True, True, 0)
self.pack_start(self.performance, True, True, 0)
#self.pack_start(self.label, False, False, 0)
#self.pack_start(self.hbox, False, False, 0)
def on_button_toggled(self, button, override):
if button.get_active():
set_override(override)
def set_selected(self):
override = get_override()
match override:
case "powersave":
self.powersave.set_active(True)
case "performance":
self.performance.set_active(True)
case "default":
self.default.set_active(True)
class CurrentGovernorBox(Gtk.Box):
def __init__(self):
super().__init__(spacing=25)
self.static = Gtk.Label(label="Current Governor", name="bold")
self.governor = Gtk.Label(label=getoutput("cpufreqctl.auto-cpufreq --governor").strip().split(" ")[0], halign=Gtk.Align.END)
self.pack_start(self.static, False, False, 0)
self.pack_start(self.governor, False, False, 0)
def refresh(self):
self.governor.set_label(getoutput("cpufreqctl.auto-cpufreq --governor").strip().split(" ")[0])
class SystemStatsLabel(Gtk.Label):
def __init__(self):
super().__init__()
self.refresh()
def refresh(self):
# change stdout and store label text to file-like object
old_stdout = sys.stdout
text = StringIO()
sys.stdout = text
sysinfo()
distro_info()
self.set_label(text.getvalue())
sys.stdout = old_stdout
class CPUFreqStatsLabel(Gtk.Label):
def __init__(self):
super().__init__()
self.refresh()
def refresh(self):
stats = get_stats().split("\n")
start = None
for i, line in enumerate(stats):
if line == ("-" * 28 + " CPU frequency scaling " + "-" * 28):
start = i
break
if start is not None:
del stats[:i]
del stats[-4:]
self.set_label("\n".join(stats))
class DropDownMenu(Gtk.MenuButton):
def __init__(self, parent):
super().__init__()
self.set_halign(Gtk.Align.END)
self.image = Gtk.Image.new_from_icon_name("open-menu-symbolic", Gtk.IconSize.LARGE_TOOLBAR)
self.add(self.image)
self.menu = self.build_menu(parent)
self.set_popup(self.menu)
def build_menu(self, parent):
menu = Gtk.Menu()
daemon = Gtk.MenuItem(label="Remove Daemon")
daemon.connect("activate", self._remove_daemon, parent)
menu.append(daemon)
about = Gtk.MenuItem(label="About")
about.connect("activate", self.about_dialog, parent)
menu.append(about)
menu.show_all()
return menu
def about_dialog(self, MenuItem, parent):
dialog = AboutDialog(parent)
response = dialog.run()
dialog.destroy()
def _remove_daemon(self, MenuItem, parent):
confirm = ConfirmDialog(parent, message="Are you sure you want to remove the daemon?")
response = confirm.run()
confirm.destroy()
if response == Gtk.ResponseType.YES:
try:
remove_daemon()
dialog = Gtk.MessageDialog(
transient_for=parent,
message_type=Gtk.MessageType.INFO,
buttons=Gtk.ButtonsType.OK,
text="Daemon succesfully removed"
)
dialog.format_secondary_text("The app will now close. Please reopen to apply changes")
dialog.run()
dialog.destroy()
parent.destroy()
except Exception as e:
dialog = Gtk.MessageDialog(
transient_for=parent,
message_type=Gtk.MessageType.ERROR,
buttons=Gtk.ButtonsType.OK,
text="Daemon removal failed"
)
dialog.format_secondary_text(f"The following error occured:\n{e}")
dialog.run()
dialog.destroy()
class AboutDialog(Gtk.Dialog):
def __init__(self, parent):
super().__init__(title="About", transient_for=parent)
app_version = get_version()
self.box = self.get_content_area()
# self.box.set_homogeneous(True)
self.box.set_spacing(10)
self.add_button("Close", Gtk.ResponseType.CLOSE)
self.set_default_size(400, 350)
img_buffer = GdkPixbuf.Pixbuf.new_from_file_at_scale(
filename="/usr/local/share/auto-cpufreq/images/icon.png",
width=150,
height=150,
preserve_aspect_ratio=True)
self.image = Gtk.Image.new_from_pixbuf(img_buffer)
self.title = Gtk.Label(label="auto-cpufreq", name="bold")
self.version = Gtk.Label(label=app_version)
self.python = Gtk.Label(label=f"Python {pl.python_version()}")
self.github = Gtk.Label(label="https://github.com/AdnanHodzic/auto-cpufreq")
self.license = Gtk.Label(label="Licensed under LGPL3", name="small")
self.love = Gtk.Label(label="Made with <3", name="small")
self.box.pack_start(self.image, False, False, 0)
self.box.pack_start(self.title, False, False, 0)
self.box.pack_start(self.version, False, False, 0)
self.box.pack_start(self.python, False, False, 0)
self.box.pack_start(self.github, False, False, 0)
self.box.pack_start(self.license, False, False, 0)
self.box.pack_start(self.love, False, False, 0)
self.show_all()
class ConfirmDialog(Gtk.Dialog):
def __init__(self, parent, message: str):
super().__init__(title="Confirmation", transient_for=parent)
self.box = self.get_content_area()
self.set_default_size(400, 100)
self.add_buttons("Yes", Gtk.ResponseType.YES, "No", Gtk.ResponseType.NO)
self.label = Gtk.Label(label=message)
self.box.pack_start(self.label, True, False, 0)
self.show_all()
class DaemonNotRunningView(Gtk.Box):
def __init__(self, parent):
super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=10, halign=Gtk.Align.CENTER, valign=Gtk.Align.CENTER)
self.label = Gtk.Label(label="auto-cpufreq daemon is not running. Please click the install button")
self.install_button = Gtk.Button.new_with_label("Install")
self.install_button.connect("clicked", self.install_daemon, parent)
self.pack_start(self.label, False, False, 0)
self.pack_start(self.install_button, False, False, 0)
def install_daemon(self, button, parent):
try:
deploy_daemon()
dialog = Gtk.MessageDialog(
transient_for=parent,
message_type=Gtk.MessageType.INFO,
buttons=Gtk.ButtonsType.OK,
text="Daemon succesfully installed"
)
dialog.format_secondary_text("The app will now close. Please reopen to apply changes")
dialog.run()
dialog.destroy()
parent.destroy()
except Exception as e:
dialog = Gtk.MessageDialog(
transient_for=parent,
message_type=Gtk.MessageType.ERROR,
buttons=Gtk.ButtonsType.OK,
text="Daemon install failed"
)
dialog.format_secondary_text(f"The following error occured:\n{e}")
dialog.run()
dialog.destroy()

32
auto_cpufreq/gui/tray.py Normal file
View File

@ -0,0 +1,32 @@
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, AppIndicator3 as appindicator
from subprocess import run
def main():
indicator = appindicator.Indicator.new("auto-cpufreq-tray", "network-idle-symbolic", appindicator.IndicatorCategory.APPLICATION_STATUS)
indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
indicator.set_menu(build_menu())
Gtk.main()
def build_menu():
menu = Gtk.Menu()
program = Gtk.MenuItem("auto-cpufreq")
program.connect("activate", open_app)
menu.append(program)
_quit = Gtk.MenuItem("Quit")
_quit.connect("activate", Gtk.main_quit)
menu.append(_quit)
menu.show_all()
return menu
def open_app(MenuItem):
run("sudo -E python app.py", shell=True)
if __name__ == "__main__":
main()

View File

@ -129,7 +129,7 @@ def gnome_power_start_live():
def gnome_power_svc_enable():
if systemctl_exists:
try:
print("\n* Enabling GNOME power profiles")
print("* Enabling GNOME power profiles\n")
call(["systemctl", "unmask", "power-profiles-daemon"])
call(["systemctl", "start", "power-profiles-daemon"])
call(["systemctl", "enable", "power-profiles-daemon"])
@ -256,95 +256,50 @@ def disable_power_profiles_daemon():
# default gnome_power_svc_disable func (balanced)
def gnome_power_svc_disable():
if systemctl_exists:
# set balanced profile if its running before disabling it
if gnome_power_status == 0 and powerprofilesctl_exists:
print("Using profile: ", "balanced")
call(["powerprofilesctl", "set", "balanced"])
disable_power_profiles_daemon()
# default gnome_power_svc_disable func (performance)
def gnome_power_svc_disable_performance():
if systemctl_exists:
# set performance profile if its running before disabling it
if gnome_power_status == 0 and powerprofilesctl_exists:
print("Using profile: ", "performance")
call(["powerprofilesctl", "set", "performance"])
disable_power_profiles_daemon()
# cli
@click.pass_context
# external gnome power srevice disable function
def gnome_power_svc_disable_ext(ctx, power_selection):
raw_power_disable = ctx.params["gnome_power_disable"]
gnome_power_disable = str(raw_power_disable).replace('[','').replace(']','').replace(",", "").replace("(","").replace(")","").replace("'","")
snap_pkg_check = 0
if systemctl_exists:
# 0 is active
if gnome_power_status != 0:
try:
# check if snap package installed
snap_pkg_check = call(['snap', 'list', '|', 'grep', 'auto-cpufreq'],
stdout=subprocess.DEVNULL,
stderr=subprocess.STDOUT)
# check if snapd is present and if snap package is installed | 0 is success
if snap_pkg_check == 0:
print("Power Profiles Daemon is already disabled, re-enable by running:\n"
print("GNOME Power Profiles Daemon is already disabled, it can be re-enabled by running:\n"
"sudo python3 power_helper.py --gnome_power_enable\n"
"\nfollowed by running:\n"
"sudo python3 power_helper.py --gnome_power_disable"
)
else:
# snapd present, snap package not installed
print("Power Profiles Daemon is already disabled, first remove auto-cpufreq:\n"
"sudo auto-cpufreq --remove\n"
"\nfollowed by installing auto-cpufreq in performance mode:\n"
"sudo auto-cpufreq --install_performance"
elif snap_pkg_check == 1:
print("auto-cpufreq snap package not installed\nGNOME Power Profiles Daemon should be enabled. run:\n\n"
"sudo python3 power_helper.py --gnome_power_enable"
)
except FileNotFoundError:
except:
# snapd not found on the system
print("Power Profiles Daemon is already disabled, first remove auto-cpufreq:\n"
"sudo auto-cpufreq --remove\n"
"\nfollowed by installing auto-cpufreq in performance mode:\n"
"sudo auto-cpufreq --install_performance"
)
print("There was a problem, couldn't determine GNOME Power Profiles Daemon")
snap_pkg_check = 0
# set balanced profile if its running before disabling it
if gnome_power_status == 0 and powerprofilesctl_exists:
# 0 is success (snap package is installed)
try:
snap_pkg_check = call(['snap', 'list', '|', 'grep', 'auto-cpufreq'],
stdout=subprocess.DEVNULL,
stderr=subprocess.STDOUT)
if snap_pkg_check == 0:
#if snap_exist == 0 and snap_pkg_install == 0:
print("Using profile: ", gnome_power_disable)
call(["powerprofilesctl", "set", gnome_power_disable])
disable_power_profiles_daemon()
else:
print("Install auto-cpufreq in performance mode by running:\n"
"sudo auto-cpufreq --install_performance\n"
)
except FileNotFoundError:
print("Install auto-cpufreq in performance mode by running:\n"
"sudo auto-cpufreq --install_performance\n"
if snap_pkg_check == 1:
print("auto-cpufreq snap package not installed.\nGNOME Power Profiles Daemon should be enabled, run:\n\n"
"sudo python3 power_helper.py --gnome_power_enable"
)
else:
print("auto-cpufreq snap package installed, GNOME Power Profiles Daemon should be disabled.\n")
print("Using profile: ", "balanced")
call(["powerprofilesctl", "set", "balanced"])
disable_power_profiles_daemon()
# cli
@click.command()
@click.option("--gnome_power_disable", help="Disable GNOME Power profiles service (default: balanced), reference:\n https://bit.ly/3bjVZW1", type=click.Choice(['balanced', 'performance'], case_sensitive=False))
#@click.option("--gnome_power_disable", help="Disable GNOME Power profiles service (default: balanced), reference:\n https://bit.ly/3bjVZW1", type=click.Choice(['balanced', 'performance'], case_sensitive=False))
@click.option("--gnome_power_disable", is_flag=True, help="Disable GNOME Power profiles service")
# ToDo:
# * update readme/docs
@click.option("--power_selection", hidden=True)
@click.option("--gnome_power_enable", is_flag=True, help="Enable GNOME Power profiles service")
@click.option("--gnome_power_status", is_flag=True, help="Get status of GNOME Power profiles service"
@ -352,7 +307,6 @@ def gnome_power_svc_disable_ext(ctx, power_selection):
@click.option("--bluetooth_boot_on", is_flag=True, help="Turn on Bluetooth on boot")
@click.option("--bluetooth_boot_off", is_flag=True, help="Turn off Bluetooth on boot")
def main(
power_selection,
gnome_power_enable,
gnome_power_disable,
gnome_power_status,
@ -377,7 +331,7 @@ def main(
elif gnome_power_disable:
header()
root_check()
gnome_power_svc_disable_ext(power_selection)
gnome_power_svc_disable()
helper_opts()
footer()
elif gnome_power_status:
@ -401,4 +355,4 @@ def main(
if __name__ == "__main__":
main()
main()

View File

@ -21,7 +21,6 @@ from auto_cpufreq.power_helper import *
@click.option("--install", is_flag=True, help="Install daemon for (permanent) automatic CPU optimizations")
@click.option("--remove", is_flag=True, help="Remove daemon for (permanent) automatic CPU optimizations")
@click.option("--install_performance", is_flag=True, help="Install daemon in \"performance\" mode, reference:\n https://bit.ly/3bjVZW1")
@click.option("--stats", is_flag=True, help="View live stats of CPU optimizations made by daemon")
@click.option("--force", is_flag=False, help="Force use of either \"powersave\" or \"performance\" governors. Setting to \"reset\" will go back to normal mode")
@click.option("--get-state", is_flag=True, hidden=True)
@ -36,7 +35,7 @@ from auto_cpufreq.power_helper import *
@click.option("--donate", is_flag=True, help="Support the project")
@click.option("--log", is_flag=True, hidden=True)
@click.option("--daemon", is_flag=True, hidden=True)
def main(config, daemon, debug, install, remove, install_performance, live, log, monitor, stats, version, donate, force, get_state):
def main(config, daemon, debug, install, remove, live, log, monitor, stats, version, donate, force, get_state):
# display info if config file is used
def config_info_dialog():
@ -185,18 +184,6 @@ def main(config, daemon, debug, install, remove, install_performance, live, log,
print("Show your appreciation by donating!")
print("https://github.com/AdnanHodzic/auto-cpufreq/#donate")
footer()
elif install_performance:
if os.getenv("PKG_MARKER") == "SNAP":
root_check()
print("\nThis option is only available on non Snap installs.\n\n"
"Please refer to auto-cpufreq power_helper.py script for more info\n"
"Reference: https://github.com/AdnanHodzic/auto-cpufreq#configuring-auto-cpufreq\n")
else:
root_check()
running_daemon_check()
gov_check()
deploy_daemon_performance()
deploy_complete_msg()
elif install:
if os.getenv("PKG_MARKER") == "SNAP":
root_check()

BIN
images/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View File

@ -2,3 +2,4 @@ setuptools
psutil
click
distro
PyGObject

View File

@ -0,0 +1,7 @@
[Desktop Entry]
Name=auto-cpufreq
Exec=auto-cpufreq-gtk
Type=Application
Terminal=false
Icon=auto-cpufreq
Categories=System;

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<action id="org.auto-cpufreq.pkexec">
<description>Run auto-cpufreq command</description>
<message>Authentication is required to run auto-cpufreq</message>
<icon_name>auto-cpufreq</icon_name>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/opt/auto-cpufreq/venv/bin/python</annotate>
<annotate key="org.freedesktop.policykit.exec.argv1">/opt/auto-cpufreq/venv/bin/app.py</annotate>
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>
</policyconfig>

16
scripts/start_app Normal file
View File

@ -0,0 +1,16 @@
#!/usr/bin/sh
# load python virtual environment
venv_dir=/opt/auto-cpufreq/venv
. "${venv_dir}/bin/activate"
python_command="${venv_dir}/bin/python ${venv_dir}/bin/app.py"
if [ "$XDG_SESSION_TYPE" = "wayland" ] ; then
# necessary for running on wayland
xhost +SI:localuser:root
pkexec ${python_command}
xhost -SI:localuser:root
xhost
else
pkexec ${python_command}
fi

12
scripts/style.css Normal file
View File

@ -0,0 +1,12 @@
label{
/*font-family: Noto Sans;*/
font-size: 15px;
}
#bold{
font-weight: bold;
}
#small{
font-size: 12px;
}

View File

@ -13,7 +13,7 @@ def read(name):
return f.read()
# Used for the tar.gz/snap releases
VERSION = "1.9.7"
VERSION = "2.0-beta"
setup(
name="auto-cpufreq",
@ -29,7 +29,7 @@ setup(
author="Adnan Hodzic",
author_email="adnan@hodzic.org",
url="https://github.com/AdnanHodzic/auto-cpufreq",
packages=["auto_cpufreq"],
packages=["auto_cpufreq", "auto_cpufreq/gui"],
install_requires=read("requirements.txt"),
include_package_data=True,
zip_safe=True,
@ -40,5 +40,5 @@ setup(
"Intended Audience :: Developers",
"Operating System :: POSIX :: Linux" "Environment :: Console" "Natural Language :: English",
],
scripts=["bin/auto-cpufreq"],
scripts=["bin/auto-cpufreq", "auto_cpufreq/gui/app.py"],
)

View File

@ -43,10 +43,6 @@ plugs:
interface: system-files
write:
- /etc/auto-cpufreq.conf
opt-auto-cpufreq:
interface: system-files
write:
- /opt/auto-cpufreq/override.pickle
apps:
auto-cpufreq:
@ -60,15 +56,14 @@ apps:
- cpu-control
- system-observe
- hardware-observe
- opt-auto-cpufreq
- etc-auto-cpufreq-conf
service:
command: usr/bin/snapdaemon
plugs:
- cpu-control
- system-observe
- hardware-observe
- etc-auto-cpufreq
- opt-auto-cpufreq
- etc-auto-cpufreq-conf
environment:
LC_ALL: C.UTF-8
LANG: C.UTF-8