Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43de4d979d | ||
|
|
d1ea86f694 | ||
|
|
aa8e05f676 | ||
|
|
f45cb3db36 | ||
|
|
a91556e3e6 | ||
|
|
f8f043cf48 | ||
|
|
8453f41914 | ||
|
|
a0ba66ab99 | ||
|
|
7c89b4197f | ||
|
|
c9b659e22a | ||
|
|
3e7873de8f | ||
|
|
988aabea07 | ||
|
|
804ae3fcb6 | ||
|
|
a97148f7a5 | ||
|
|
8b10c49ed4 | ||
|
|
f31054c18b | ||
|
|
2b50f0816f | ||
|
|
1fc4b94237 | ||
|
|
90a994a685 | ||
|
|
7b123da001 | ||
|
|
c8fd626446 | ||
|
|
0f6fee40ae | ||
|
|
4a788c2395 | ||
|
|
d2f34c9b5a | ||
|
|
4958722edd | ||
|
|
23b54ee397 | ||
|
|
73bb7abf6e | ||
|
|
9f0fabb91f | ||
|
|
a31f851707 | ||
|
|
70d3788dd6 | ||
|
|
f3b74ccc02 | ||
|
|
335a0881b3 | ||
|
|
c39a88b7db | ||
|
|
ba78392b24 | ||
|
|
c1205c7661 | ||
|
|
973ff26fa7 | ||
|
|
4a8dfbad47 | ||
|
|
2a0675d3be | ||
|
|
55580535db | ||
|
|
8fcb2098cb | ||
|
|
3c55f8fdd6 | ||
|
|
b5dfa93dcf | ||
|
|
154be557ed | ||
|
|
624fed2c71 | ||
|
|
f50a11deaa |
2
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
github: [Steve-Tech]
|
||||||
|
thanks_dev: u/gh/steve-tech
|
||||||
4
.github/workflows/flatpak.yml
vendored
@@ -8,10 +8,10 @@ jobs:
|
|||||||
flatpak:
|
flatpak:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-48
|
image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-50
|
||||||
options: --privileged
|
options: --privileged
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- name: Build Flatpak
|
- name: Build Flatpak
|
||||||
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||||
with:
|
with:
|
||||||
|
|||||||
8
.github/workflows/pyinstaller-linux.yml
vendored
@@ -8,12 +8,12 @@ jobs:
|
|||||||
pyinstaller-linux:
|
pyinstaller-linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
# We shouldn't use actions/setup-python since PyGObject is compiled against the system Python
|
# We shouldn't use actions/setup-python since PyGObject is compiled against the system Python
|
||||||
- name: Install System Dependencies
|
- name: Install System Dependencies
|
||||||
uses: awalsh128/cache-apt-pkgs-action@latest
|
uses: awalsh128/cache-apt-pkgs-action@latest
|
||||||
with:
|
with:
|
||||||
packages: python3-gi gir1.2-gtk-4.0 gir1.2-adw-1 libglib2.0-bin
|
packages: python3-gi gir1.2-gtk-4.0 gir1.2-adw-1 libglib2.0-bin python3-tk
|
||||||
version: 0
|
version: 0
|
||||||
- name: Install PyInstaller
|
- name: Install PyInstaller
|
||||||
run: pip install pyinstaller
|
run: pip install pyinstaller
|
||||||
@@ -21,10 +21,10 @@ jobs:
|
|||||||
run: pip install .
|
run: pip install .
|
||||||
- name: Build with PyInstaller
|
- name: Build with PyInstaller
|
||||||
# pyinstaller doesn't find the GTK libraries after caching?
|
# pyinstaller doesn't find the GTK libraries after caching?
|
||||||
run: LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu pyinstaller yafi.spec
|
run: LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu pyinstaller yafi.spec -- --onefile
|
||||||
working-directory: pyinstaller
|
working-directory: pyinstaller
|
||||||
- name: Upload PyInstaller Artifact
|
- name: Upload PyInstaller Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
path: pyinstaller/dist/YAFI
|
path: pyinstaller/dist/YAFI
|
||||||
name: yafi-linux-${{ github.sha }}
|
name: yafi-linux-${{ github.sha }}
|
||||||
|
|||||||
30
.github/workflows/pyinstaller-windows.yml
vendored
@@ -8,22 +8,22 @@ jobs:
|
|||||||
pyinstaller-windows:
|
pyinstaller-windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v6
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: '3.14'
|
||||||
cache: 'pip'
|
cache: 'pip'
|
||||||
|
|
||||||
- name: Cache GTK4
|
- name: Cache GTK4
|
||||||
id: cache-gtk4
|
id: cache-gtk4
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v5
|
||||||
with:
|
with:
|
||||||
path: C:\gtk
|
path: C:\gtk
|
||||||
key: Gvsbuild_2025.8.0
|
key: Gvsbuild_2026.2.0
|
||||||
|
|
||||||
- name: Download GTK4 Gvsbuild zip
|
- name: Download GTK4 Gvsbuild zip
|
||||||
if: steps.cache-gtk4.outputs.cache-hit != 'true'
|
if: steps.cache-gtk4.outputs.cache-hit != 'true'
|
||||||
run: Start-BitsTransfer -Source https://github.com/wingtk/gvsbuild/releases/download/2025.8.0/GTK4_Gvsbuild_2025.8.0_x64.zip -Destination Gvsbuild.zip
|
run: Start-BitsTransfer -Source https://github.com/wingtk/gvsbuild/releases/download/2026.2.0/GTK4_Gvsbuild_2026.2.0_x64.zip -Destination Gvsbuild.zip
|
||||||
|
|
||||||
- name: Extract Gvsbuild zip
|
- name: Extract Gvsbuild zip
|
||||||
if: steps.cache-gtk4.outputs.cache-hit != 'true'
|
if: steps.cache-gtk4.outputs.cache-hit != 'true'
|
||||||
@@ -41,12 +41,22 @@ jobs:
|
|||||||
- name: Build YAFI via Pip
|
- name: Build YAFI via Pip
|
||||||
run: pip install .
|
run: pip install .
|
||||||
|
|
||||||
- name: Build with PyInstaller
|
- name: Build with PyInstaller (ZIP)
|
||||||
run: python -m PyInstaller yafi.spec
|
run: python -m PyInstaller yafi.spec
|
||||||
working-directory: pyinstaller
|
working-directory: pyinstaller
|
||||||
|
|
||||||
- name: Upload PyInstaller Artifact
|
- name: Upload PyInstaller Artifact (ZIP)
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v6
|
||||||
|
with:
|
||||||
|
path: pyinstaller/dist/YAFI/*
|
||||||
|
name: yafi-windows-${{ github.sha }}
|
||||||
|
|
||||||
|
- name: Build with PyInstaller (Standalone)
|
||||||
|
run: python -m PyInstaller yafi.spec --noconfirm -- --onefile
|
||||||
|
working-directory: pyinstaller
|
||||||
|
|
||||||
|
- name: Upload PyInstaller Artifact (Standalone)
|
||||||
|
uses: actions/upload-artifact@v6
|
||||||
with:
|
with:
|
||||||
path: pyinstaller/dist/YAFI.exe
|
path: pyinstaller/dist/YAFI.exe
|
||||||
name: yafi-windows-${{ github.sha }}
|
name: yafi-windows-standalone-${{ github.sha }}
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
# CrOS_EC_Python udev rules
|
|
||||||
|
|
||||||
# LPC Access
|
|
||||||
KERNEL=="port", TAG+="uaccess"
|
|
||||||
|
|
||||||
# /dev/cros_ec Access
|
|
||||||
KERNEL=="cros_ec", TAG+="uaccess"
|
|
||||||
14
README.md
@@ -11,9 +11,13 @@ You can download the latest release from the [Releases page](https://github.com/
|
|||||||
|
|
||||||
There are builds for Flatpak, and PyInstaller for portable execution on Linux or Windows.
|
There are builds for Flatpak, and PyInstaller for portable execution on Linux or Windows.
|
||||||
|
|
||||||
|
YAFI is also available on [Flathub](https://flathub.org/en/apps/au.stevetech.yafi): `flatpak install flathub au.stevetech.yafi`.
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
To allow YAFI to communicate with the EC, you need to copy the [`60-cros_ec_python.rules`](60-cros_ec_python.rules) file to `/etc/udev/rules.d/` and reload the rules with `sudo udevadm control --reload-rules && sudo udevadm trigger`.
|
To allow YAFI to communicate with the EC, you will need to enable user access to the `/dev/cros_ec` device. You can do this by running `echo KERNEL==\"cros_ec\", TAG+=\"uaccess\" | sudo tee /etc/udev/rules.d/60-yafi.rules`, and then reload the rules with `sudo udevadm control --reload-rules && sudo udevadm trigger`.
|
||||||
|
|
||||||
|
You can also do this by running `curl -Lfs yafi.stevetech.au/udev.sh | sudo sh` which will run the [`add-udev-rules.sh`](add-udev-rules.sh) script.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
@@ -80,7 +84,7 @@ It is possible to run YAFI on Windows using [gvsbuild](https://github.com/wingtk
|
|||||||
|
|
||||||
### `[Errno 13] Permission denied: '/dev/cros_ec'`
|
### `[Errno 13] Permission denied: '/dev/cros_ec'`
|
||||||
|
|
||||||
This error occurs when the udev rules are not installed or not working. Make sure you have copied the `60-cros_ec_python.rules` file to `/etc/udev/rules.d/` and reloaded the rules with `sudo udevadm control --reload-rules && sudo udevadm trigger`.
|
This error occurs when the udev rules are not installed or not working. Make sure you have installed the udev rules as described in the [Linux Installation](#linux) section.
|
||||||
|
|
||||||
### `Could not auto detect device, check you have the required permissions, or specify manually.`
|
### `Could not auto detect device, check you have the required permissions, or specify manually.`
|
||||||
|
|
||||||
@@ -88,3 +92,9 @@ This error occurs when `/dev/cros_ec` is not found, and the `CrOS_EC_Python` lib
|
|||||||
You can either update your kernel to have a working `cros_ec_dev` driver, or run YAFI as root.
|
You can either update your kernel to have a working `cros_ec_dev` driver, or run YAFI as root.
|
||||||
|
|
||||||
It can also occur if you do not have a CrOS EC, like on non Framework laptops.
|
It can also occur if you do not have a CrOS EC, like on non Framework laptops.
|
||||||
|
|
||||||
|
## Disclaimer
|
||||||
|
|
||||||
|
YAFI is not affiliated with Framework Computer Inc. in any way.
|
||||||
|
|
||||||
|
YAFI is licensed under the [GPL-2.0-or-later license](COPYING), and comes with no warranty or guarantee of any kind. Use at your own risk.
|
||||||
|
|||||||
7
add-udev-rules.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
echo Installing udev rules for YAFI to /etc/udev/rules.d/60-yafi.rules
|
||||||
|
echo KERNEL==\"cros_ec\", TAG+=\"uaccess\" > /etc/udev/rules.d/60-yafi.rules
|
||||||
|
udevadm control --reload-rules
|
||||||
|
udevadm trigger
|
||||||
|
echo udev rules installed successfully.
|
||||||
@@ -1,13 +1,14 @@
|
|||||||
{
|
{
|
||||||
"id" : "au.stevetech.yafi",
|
"id" : "au.stevetech.yafi",
|
||||||
"runtime" : "org.gnome.Platform",
|
"runtime" : "org.gnome.Platform",
|
||||||
"runtime-version" : "48",
|
"runtime-version" : "49",
|
||||||
"sdk" : "org.gnome.Sdk",
|
"sdk" : "org.gnome.Sdk",
|
||||||
"command" : "yafi",
|
"command" : "yafi",
|
||||||
"finish-args" : [
|
"finish-args" : [
|
||||||
"--device=all",
|
"--device=all",
|
||||||
"--socket=fallback-x11",
|
"--socket=fallback-x11",
|
||||||
"--socket=wayland"
|
"--socket=wayland",
|
||||||
|
"--share=ipc"
|
||||||
],
|
],
|
||||||
"cleanup" : [
|
"cleanup" : [
|
||||||
"/include",
|
"/include",
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
"*.a"
|
"*.a"
|
||||||
],
|
],
|
||||||
"modules" : [
|
"modules" : [
|
||||||
|
"python3-cros_ec_python.json",
|
||||||
{
|
{
|
||||||
"name" : "yafi",
|
"name" : "yafi",
|
||||||
"builddir" : true,
|
"builddir" : true,
|
||||||
@@ -31,18 +33,6 @@
|
|||||||
"path" : "."
|
"path" : "."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "cros_ec_python",
|
|
||||||
"buildsystem": "simple",
|
|
||||||
"build-options": {
|
|
||||||
"build-args": [
|
|
||||||
"--share=network"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"build-commands": [
|
|
||||||
"pip3 install --prefix=${FLATPAK_DEST} --no-cache-dir \"cros_ec_python>=0.2.0\""
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ Comment=Yet Another Framework Interface
|
|||||||
Terminal=false
|
Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Utility;
|
Categories=Utility;
|
||||||
Keywords=GTK;
|
Keywords=Framework;EC;Embedded Controller;
|
||||||
StartupNotify=true
|
StartupNotify=true
|
||||||
DBusActivatable=true
|
DBusActivatable=true
|
||||||
|
|||||||
@@ -7,11 +7,25 @@
|
|||||||
<name>Yet Another Framework Interface</name>
|
<name>Yet Another Framework Interface</name>
|
||||||
<summary>YAFI is another GUI for the Framework Laptop Embedded Controller</summary>
|
<summary>YAFI is another GUI for the Framework Laptop Embedded Controller</summary>
|
||||||
<description>
|
<description>
|
||||||
<p>It is written in Python with a GTK3 theme, and uses the `CrOS_EC_Python` library to communicate with the EC.</p>
|
<p>It is written in Python with a GTK4 Adwaita theme, and uses the CrOS_EC_Python library to communicate with the EC.</p>
|
||||||
|
<p>YAFI has the capability for the following features:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Fan control and temperature monitoring</li>
|
||||||
|
<li>LED control</li>
|
||||||
|
<li>Battery statistics</li>
|
||||||
|
<li>Battery limiting</li>
|
||||||
|
<li>Hardware information</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>You will need to install the udev rules to allow non-root access to the EC device. See the README for more information.</p>
|
||||||
|
|
||||||
|
<p>Alternatively, you can run <code>curl -Lfs yafi.stevetech.au/udev.sh | sudo sh</code> to install the udev rules.</p>
|
||||||
|
|
||||||
|
<p>YAFI is not affiliated with Framework Computer Inc. in any way.</p>
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<developer id="au.stevetech">
|
<developer id="au.stevetech">
|
||||||
<name>Stephen Horvath</name>
|
<name translate="no">Stephen Horvath</name>
|
||||||
</developer>
|
</developer>
|
||||||
|
|
||||||
<!-- Required: Should be a link to the upstream homepage for the component -->
|
<!-- Required: Should be a link to the upstream homepage for the component -->
|
||||||
@@ -27,7 +41,7 @@
|
|||||||
<!-- Should provide a web link to an online user's reference, a software manual or help page -->
|
<!-- Should provide a web link to an online user's reference, a software manual or help page -->
|
||||||
<!-- <url type="help">https://example.org/help</url> -->
|
<!-- <url type="help">https://example.org/help</url> -->
|
||||||
<!-- URLs of this type should point to a webpage showing information on how to donate to the described software project -->
|
<!-- URLs of this type should point to a webpage showing information on how to donate to the described software project -->
|
||||||
<!-- <url type="donation">https://example.org/donate</url> -->
|
<url type="donation">https://github.com/sponsors/Steve-Tech</url>
|
||||||
<!-- This could for example be an HTTPS URL to an online form or a page describing how to contact the developer -->
|
<!-- This could for example be an HTTPS URL to an online form or a page describing how to contact the developer -->
|
||||||
<!-- <url type="contact">https://example.org/contact</url> -->
|
<!-- <url type="contact">https://example.org/contact</url> -->
|
||||||
<!-- URLs of this type should point to a webpage showing information on how to contribute to the described software project -->
|
<!-- URLs of this type should point to a webpage showing information on how to contribute to the described software project -->
|
||||||
@@ -42,42 +56,104 @@
|
|||||||
|
|
||||||
<!-- Applications should set a brand color in both light and dark variants like so -->
|
<!-- Applications should set a brand color in both light and dark variants like so -->
|
||||||
<branding>
|
<branding>
|
||||||
<color type="primary" scheme_preference="light">#ff00ff</color>
|
<color type="primary" scheme_preference="light">#7c916f</color>
|
||||||
<color type="primary" scheme_preference="dark">#993d3d</color>
|
<color type="primary" scheme_preference="dark">#282000</color>
|
||||||
</branding>
|
</branding>
|
||||||
|
|
||||||
<screenshots>
|
<screenshots>
|
||||||
<screenshot type="default">
|
<screenshot type="default">
|
||||||
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/1-thermal.png</image>
|
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/1-thermals.png</image>
|
||||||
<caption>The Thermal page</caption>
|
<caption>Fan Control and Temperature Monitoring</caption>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
<screenshot>
|
<screenshot>
|
||||||
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/2-leds.png</image>
|
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/2-leds.png</image>
|
||||||
<caption>The LED page</caption>
|
<caption>LED Control</caption>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
<screenshot>
|
<screenshot>
|
||||||
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/3-battery.png</image>
|
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/3-battery.png</image>
|
||||||
<caption>The Battery page</caption>
|
<caption>Battery Statistics</caption>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
<screenshot>
|
<screenshot>
|
||||||
<image>https://github.com/Steve-Tech/YAFI/blob/main/docs/4-hardware.png</image>
|
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/4-battery-limit.png</image>
|
||||||
<caption>The Hardware page</caption>
|
<caption>Battery Limiting</caption>
|
||||||
|
</screenshot>
|
||||||
|
<screenshot>
|
||||||
|
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/4a-battery-ext.png</image>
|
||||||
|
<caption>Battery Extender</caption>
|
||||||
|
</screenshot>
|
||||||
|
<screenshot>
|
||||||
|
<image>https://raw.githubusercontent.com/Steve-Tech/YAFI/refs/heads/main/docs/5-hardware.png</image>
|
||||||
|
<caption>Hardware Info</caption>
|
||||||
</screenshot>
|
</screenshot>
|
||||||
</screenshots>
|
</screenshots>
|
||||||
|
|
||||||
<releases>
|
<releases>
|
||||||
<release version="0.1.0" date="2025-03-20">
|
<release version="1.0" date="2026-03-21">
|
||||||
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.1.0</url>
|
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/1.0</url>
|
||||||
<description translate="no">
|
<description>
|
||||||
<p>First release</p>
|
<p>The following changes have been made:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Added Thermal page</li>
|
<li>New logo matching the GNOME style!</li>
|
||||||
<li>Added LED page</li>
|
<li>Errored temperature sensors will now show as 'Error'.</li>
|
||||||
<li>Added Battery page</li>
|
<li>Fix for battery page when battery isn't present.</li>
|
||||||
<li>Added Hardware page</li>
|
<li>Fix some minor UI bugs.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</description>
|
</description>
|
||||||
</release>
|
</release>
|
||||||
|
<release version="0.7" date="2025-12-25">
|
||||||
|
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.7</url>
|
||||||
|
<description>
|
||||||
|
<p>YAFI now supports modifying fan set points.</p>
|
||||||
|
</description>
|
||||||
|
</release>
|
||||||
|
<release version="0.6" date="2025-09-28">
|
||||||
|
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.6</url>
|
||||||
|
<description>
|
||||||
|
<p>The following changes have been made:</p>
|
||||||
|
<ul>
|
||||||
|
<li>YAFI now has a new logo!</li>
|
||||||
|
<li>The advanced LED settings now detect available LEDs.</li>
|
||||||
|
<li>The ALS and lid open sensor has been added.</li>
|
||||||
|
<li>Stuttering has been reduced when opening the about dialog.</li>
|
||||||
|
</ul>
|
||||||
|
</description>
|
||||||
|
</release>
|
||||||
|
<release version="0.5" date="2025-09-16">
|
||||||
|
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.5</url>
|
||||||
|
<description>
|
||||||
|
<p>The following bugs have been fixed:</p>
|
||||||
|
<ul>
|
||||||
|
<li>LED page crashing when encountering unsupported LEDs.</li>
|
||||||
|
<li>Scaling issues on Windows.</li>
|
||||||
|
<li>Minimum charge limiter doesn't work.</li>
|
||||||
|
</ul>
|
||||||
|
<p>This release also adds a traceback to the debug info, when there is an error during initialisation.</p>
|
||||||
|
</description>
|
||||||
|
</release>
|
||||||
|
<release version="0.4" date="2025-09-06">
|
||||||
|
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.4</url>
|
||||||
|
<description>
|
||||||
|
<p>This release also adds a new battery statistics page.</p>
|
||||||
|
</description>
|
||||||
|
</release>
|
||||||
|
<release version="0.3" date="2025-04-13">
|
||||||
|
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.3</url>
|
||||||
|
<description>
|
||||||
|
<p>YAFI now shows the battery limiter value.</p>
|
||||||
|
</description>
|
||||||
|
</release>
|
||||||
|
<release version="0.2" date="2025-03-24">
|
||||||
|
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.2</url>
|
||||||
|
<description>
|
||||||
|
<p>This fixes an LED list bug.</p>
|
||||||
|
</description>
|
||||||
|
</release>
|
||||||
|
<release version="0.1" date="2025-03-20">
|
||||||
|
<url type="details">https://github.com/Steve-Tech/YAFI/releases/tag/0.1</url>
|
||||||
|
<description>
|
||||||
|
<p>This is the first release of YAFI.</p>
|
||||||
|
</description>
|
||||||
|
</release>
|
||||||
</releases>
|
</releases>
|
||||||
|
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -1,36 +1,92 @@
|
|||||||
<?xml version="1.0" standalone="no"?>
|
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
<rect x="12" y="92" width="104" height="24" rx="8" fill="url(#paint0_linear_293_18)"/>
|
||||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
<rect x="12" y="88" width="104" height="24" rx="8" fill="#328361"/>
|
||||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
<rect x="12" y="88" width="104" height="24" rx="8" fill="url(#paint1_linear_293_18)" fill-opacity="0.5" style="mix-blend-mode:multiply"/>
|
||||||
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
<path d="M108 12H20C15.5817 12 12 15.5817 12 20V24V33V102C12 106.418 15.5817 110 20 110H108C112.418 110 116 106.418 116 102V20C116 15.5817 112.418 12 108 12Z" fill="#3FB182"/>
|
||||||
preserveAspectRatio="xMidYMid meet">
|
<path d="M34 25H38V18C38 17.4477 37.5523 17 37 17H35C34.4477 17 34 17.4477 34 18V25Z" fill="#FFE11D"/>
|
||||||
<metadata>
|
<path d="M42 25H46V18C46 17.4477 45.5523 17 45 17H43C42.4477 17 42 17.4477 42 18V25Z" fill="#FFE11D"/>
|
||||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
<path d="M50 25H54V18C54 17.4477 53.5523 17 53 17H51C50.4477 17 50 17.4477 50 18V25Z" fill="#FFE11D"/>
|
||||||
</metadata>
|
<path d="M58 25H62V18C62 17.4477 61.5523 17 61 17H59C58.4477 17 58 17.4477 58 18V25Z" fill="#FFE11D"/>
|
||||||
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
<path d="M66 25H70V18C70 17.4477 69.5523 17 69 17H67C66.4477 17 66 17.4477 66 18V25Z" fill="#FFE11D"/>
|
||||||
fill="#000000" stroke="none">
|
<path d="M74 25H78V18C78 17.4477 77.5523 17 77 17H75C74.4477 17 74 17.4477 74 18V25Z" fill="#FFE11D"/>
|
||||||
<path d="M1755 4883 c-120 -22 -418 -180 -609 -322 -118 -89 -148 -118 -177
|
<path d="M82 25H86V18C86 17.4477 85.5523 17 85 17H83C82.4477 17 82 17.4477 82 18V25Z" fill="#FFE11D"/>
|
||||||
-177 -23 -48 -24 -57 -27 -314 -1 -146 -7 -294 -13 -330 -18 -110 -78 -222
|
<path d="M90 25H94V18C94 17.4477 93.5523 17 93 17H91C90.4477 17 90 17.4477 90 18V25Z" fill="#FFE11D"/>
|
||||||
-163 -303 -46 -43 -69 -58 -305 -197 -191 -112 -222 -139 -257 -214 -33 -73
|
<rect x="24" y="27" width="80" height="74" rx="8" fill="url(#paint2_linear_293_18)"/>
|
||||||
-39 -145 -39 -461 0 -297 5 -360 33 -440 25 -73 77 -118 257 -224 88 -51 187
|
<rect x="24" y="27" width="80" height="74" rx="8" fill="black" fill-opacity="0.1"/>
|
||||||
-111 220 -132 123 -79 192 -169 245 -319 8 -21 14 -110 16 -230 8 -403 9 -423
|
<rect x="24" y="21" width="80" height="72" rx="8" fill="#EAEAEA"/>
|
||||||
29 -460 32 -61 56 -88 134 -148 234 -181 550 -347 676 -356 75 -5 116 12 306
|
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V105C38 105.552 37.5523 106 37 106H35C34.4477 106 34 105.552 34 105V98Z" fill="#939A00"/>
|
||||||
125 181 108 307 175 330 176 8 1 35 5 61 11 70 14 174 5 251 -23 38 -13 164
|
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V105C46 105.552 45.5523 106 45 106H43C42.4477 106 42 105.552 42 105V98Z" fill="#939A00"/>
|
||||||
-81 281 -149 286 -168 312 -173 494 -90 41 19 75 34 77 34 4 0 201 110 243
|
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V105C54 105.552 53.5523 106 53 106H51C50.4477 106 50 105.552 50 105V98Z" fill="#939A00"/>
|
||||||
135 45 27 147 100 213 153 51 40 83 75 104 113 l30 54 6 310 c5 280 8 315 27
|
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V105C62 105.552 61.5523 106 61 106H59C58.4477 106 58 105.552 58 105V98Z" fill="#939A00"/>
|
||||||
365 58 156 137 245 295 336 246 140 346 205 376 243 35 44 60 106 67 166 2 22
|
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V105C70 105.552 69.5523 106 69 106H67C66.4477 106 66 105.552 66 105V98Z" fill="#939A00"/>
|
||||||
8 74 13 115 9 78 7 442 -4 520 -12 97 -16 116 -27 150 -16 52 -61 113 -105
|
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V105C78 105.552 77.5523 106 77 106H75C74.4477 106 74 105.552 74 105V98Z" fill="#939A00"/>
|
||||||
142 -21 14 -126 78 -233 141 -107 64 -209 128 -225 144 -51 48 -101 115 -128
|
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V105C86 105.552 85.5523 106 85 106H83C82.4477 106 82 105.552 82 105V98Z" fill="#939A00"/>
|
||||||
173 -48 105 -56 163 -56 454 -1 262 -1 270 -25 321 -24 53 -65 100 -124 145
|
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V105C94 105.552 93.5523 106 93 106H91C90.4477 106 90 105.552 90 105V98Z" fill="#939A00"/>
|
||||||
-19 14 -46 34 -60 46 -42 32 -190 128 -257 164 -250 138 -384 177 -476 140
|
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V104H34V98Z" fill="#FFE11D"/>
|
||||||
-19 -8 -101 -54 -184 -104 -316 -188 -340 -198 -480 -199 -153 -1 -181 10
|
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V104H42V98Z" fill="#FFE11D"/>
|
||||||
-501 201 -178 106 -237 128 -309 115z m984 -848 c149 -19 308 -68 441 -135 68
|
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V104H50V98Z" fill="#FFE11D"/>
|
||||||
-34 181 -100 190 -110 3 -3 21 -17 40 -30 52 -37 75 -57 166 -148 150 -151
|
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V104H58V98Z" fill="#FFE11D"/>
|
||||||
281 -364 345 -562 33 -102 32 -99 56 -210 18 -86 26 -378 13 -455 -5 -27 -12
|
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V104H66V98Z" fill="#FFE11D"/>
|
||||||
-68 -15 -90 -16 -102 -64 -250 -117 -364 -211 -450 -634 -764 -1113 -828 -113
|
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V104H74V98Z" fill="#FFE11D"/>
|
||||||
-15 -425 -7 -455 12 -4 2 -22 7 -41 10 -150 26 -404 140 -531 239 -14 12 -41
|
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V104H82V98Z" fill="#FFE11D"/>
|
||||||
32 -59 46 -115 85 -291 299 -371 449 -78 148 -144 353 -165 516 -10 76 -10
|
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V104H90V98Z" fill="#FFE11D"/>
|
||||||
311 0 390 15 117 58 274 106 390 116 278 347 543 608 696 158 92 386 169 549
|
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98H34Z" fill="#808080"/>
|
||||||
184 38 4 70 8 72 9 5 6 229 -2 281 -9z"/>
|
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98H42Z" fill="#808080"/>
|
||||||
|
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98H50Z" fill="#808080"/>
|
||||||
|
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98H58Z" fill="#808080"/>
|
||||||
|
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98H66Z" fill="#808080"/>
|
||||||
|
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98H74Z" fill="#808080"/>
|
||||||
|
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98H82Z" fill="#808080"/>
|
||||||
|
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98H90Z" fill="#808080"/>
|
||||||
|
<g filter="url(#filter0_i_293_18)">
|
||||||
|
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#D9D9D9"/>
|
||||||
|
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#202020"/>
|
||||||
</g>
|
</g>
|
||||||
|
<g filter="url(#filter1_d_293_18)">
|
||||||
|
<path d="M64 70C56.8216 70 51 64.1761 51 57C51 49.8194 56.8216 44 64 44C71.1784 44 77 49.8239 77 57C77 64.1761 71.1784 70 64 70Z" fill="#EAEAEA"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_i_293_18" x="38.5264" y="34.6403" width="50.9473" height="45.4655" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="2"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
||||||
|
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_293_18"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d_293_18" x="51" y="44" width="26" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="2"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_293_18"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_293_18" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<linearGradient id="paint0_linear_293_18" x1="116" y1="116" x2="12" y2="116" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#404040"/>
|
||||||
|
<stop offset="0.03" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="0.06" stop-color="#606060"/>
|
||||||
|
<stop offset="0.94" stop-color="#606060"/>
|
||||||
|
<stop offset="0.97" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="1" stop-color="#404040"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_293_18" x1="116" y1="112" x2="12" y2="112" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#404040"/>
|
||||||
|
<stop offset="0.03" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="0.06" stop-color="#606060"/>
|
||||||
|
<stop offset="0.94" stop-color="#606060"/>
|
||||||
|
<stop offset="0.97" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="1" stop-color="#404040"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint2_linear_293_18" x1="24" y1="85.8476" x2="103.999" y2="85.6325" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#AFAFAF"/>
|
||||||
|
<stop offset="0.04" stop-color="#F6F5F4"/>
|
||||||
|
<stop offset="0.08" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="0.92" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="0.96" stop-color="#F6F5F4"/>
|
||||||
|
<stop offset="1" stop-color="#AFAFAF"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 8.6 KiB |
@@ -1,36 +1,4 @@
|
|||||||
<?xml version="1.0" standalone="no"?>
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
<path d="M8 10C6.89563 10 6 9.10402 6 8C6 6.8953 6.89563 6 8 6C9.10437 6 10 6.89598 10 8C10 9.10402 9.10437 10 8 10Z" fill="black"/>
|
||||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 2C0 0.895431 0.895431 0 2 0H3V1C3 1.55228 3.44772 2 4 2C4.55228 2 5 1.55228 5 1V0H7V1C7 1.55228 7.44772 2 8 2C8.55228 2 9 1.55228 9 1V0H11V1C11 1.55228 11.4477 2 12 2C12.5523 2 13 1.55228 13 1V0H14C15.1046 0 16 0.895431 16 2V14C16 15.1046 15.1046 16 14 16H13V15C13 14.4477 12.5523 14 12 14C11.4477 14 11 14.4477 11 15V16H9V15C9 14.4477 8.55228 14 8 14C7.44772 14 7 14.4477 7 15V16H5V15C5 14.4477 4.55228 14 4 14C3.44772 14 3 14.4477 3 15V16H2C0.895431 16 0 15.1046 0 14V2ZM5.23026 4.85673C5.04181 5.76259 4.56253 6.58395 3.86386 7.19836C3.37871 7.625 3.37871 8.375 3.86386 8.80164C4.56253 9.41605 5.04181 10.2374 5.23026 11.1433C5.36113 11.7723 6.01759 12.1473 6.6336 11.9449C7.52072 11.6535 8.47928 11.6535 9.3664 11.9449C9.98241 12.1473 10.6389 11.7723 10.7697 11.1433C10.9582 10.2374 11.4375 9.41605 12.1361 8.80164C12.6213 8.375 12.6213 7.625 12.1361 7.19836C11.4375 6.58395 10.9582 5.76259 10.7697 4.85673C10.6389 4.2277 9.98241 3.85271 9.3664 4.05509C8.47928 4.34654 7.52072 4.34654 6.6336 4.05509C6.01759 3.85271 5.36113 4.2277 5.23026 4.85673ZM8 10C6.89563 10 6 9.10402 6 8C6 6.8953 6.89563 6 8 6C9.10437 6 10 6.89598 10 8C10 9.10402 9.10437 10 8 10Z" fill="black"/>
|
||||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
|
||||||
preserveAspectRatio="xMidYMid meet">
|
|
||||||
<metadata>
|
|
||||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
|
||||||
</metadata>
|
|
||||||
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
|
||||||
fill="#000000" stroke="none">
|
|
||||||
<path d="M1755 4883 c-120 -22 -418 -180 -609 -322 -118 -89 -148 -118 -177
|
|
||||||
-177 -23 -48 -24 -57 -27 -314 -1 -146 -7 -294 -13 -330 -18 -110 -78 -222
|
|
||||||
-163 -303 -46 -43 -69 -58 -305 -197 -191 -112 -222 -139 -257 -214 -33 -73
|
|
||||||
-39 -145 -39 -461 0 -297 5 -360 33 -440 25 -73 77 -118 257 -224 88 -51 187
|
|
||||||
-111 220 -132 123 -79 192 -169 245 -319 8 -21 14 -110 16 -230 8 -403 9 -423
|
|
||||||
29 -460 32 -61 56 -88 134 -148 234 -181 550 -347 676 -356 75 -5 116 12 306
|
|
||||||
125 181 108 307 175 330 176 8 1 35 5 61 11 70 14 174 5 251 -23 38 -13 164
|
|
||||||
-81 281 -149 286 -168 312 -173 494 -90 41 19 75 34 77 34 4 0 201 110 243
|
|
||||||
135 45 27 147 100 213 153 51 40 83 75 104 113 l30 54 6 310 c5 280 8 315 27
|
|
||||||
365 58 156 137 245 295 336 246 140 346 205 376 243 35 44 60 106 67 166 2 22
|
|
||||||
8 74 13 115 9 78 7 442 -4 520 -12 97 -16 116 -27 150 -16 52 -61 113 -105
|
|
||||||
142 -21 14 -126 78 -233 141 -107 64 -209 128 -225 144 -51 48 -101 115 -128
|
|
||||||
173 -48 105 -56 163 -56 454 -1 262 -1 270 -25 321 -24 53 -65 100 -124 145
|
|
||||||
-19 14 -46 34 -60 46 -42 32 -190 128 -257 164 -250 138 -384 177 -476 140
|
|
||||||
-19 -8 -101 -54 -184 -104 -316 -188 -340 -198 -480 -199 -153 -1 -181 10
|
|
||||||
-501 201 -178 106 -237 128 -309 115z m984 -848 c149 -19 308 -68 441 -135 68
|
|
||||||
-34 181 -100 190 -110 3 -3 21 -17 40 -30 52 -37 75 -57 166 -148 150 -151
|
|
||||||
281 -364 345 -562 33 -102 32 -99 56 -210 18 -86 26 -378 13 -455 -5 -27 -12
|
|
||||||
-68 -15 -90 -16 -102 -64 -250 -117 -364 -211 -450 -634 -764 -1113 -828 -113
|
|
||||||
-15 -425 -7 -455 12 -4 2 -22 7 -41 10 -150 26 -404 140 -531 239 -14 12 -41
|
|
||||||
32 -59 46 -115 85 -291 299 -371 449 -78 148 -144 353 -165 516 -10 76 -10
|
|
||||||
311 0 390 15 117 58 274 106 390 116 278 347 543 608 696 158 92 386 169 549
|
|
||||||
184 38 4 70 8 72 9 5 6 229 -2 281 -9z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 160 KiB |
BIN
docs/2-leds.png
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 157 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 103 KiB |
3
flathub.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"only-arches": ["x86_64"]
|
||||||
|
}
|
||||||
92
logo.svg
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="12" y="92" width="104" height="24" rx="8" fill="url(#paint0_linear_293_18)"/>
|
||||||
|
<rect x="12" y="88" width="104" height="24" rx="8" fill="#328361"/>
|
||||||
|
<rect x="12" y="88" width="104" height="24" rx="8" fill="url(#paint1_linear_293_18)" fill-opacity="0.5" style="mix-blend-mode:multiply"/>
|
||||||
|
<path d="M108 12H20C15.5817 12 12 15.5817 12 20V24V33V102C12 106.418 15.5817 110 20 110H108C112.418 110 116 106.418 116 102V20C116 15.5817 112.418 12 108 12Z" fill="#3FB182"/>
|
||||||
|
<path d="M34 25H38V18C38 17.4477 37.5523 17 37 17H35C34.4477 17 34 17.4477 34 18V25Z" fill="#FFE11D"/>
|
||||||
|
<path d="M42 25H46V18C46 17.4477 45.5523 17 45 17H43C42.4477 17 42 17.4477 42 18V25Z" fill="#FFE11D"/>
|
||||||
|
<path d="M50 25H54V18C54 17.4477 53.5523 17 53 17H51C50.4477 17 50 17.4477 50 18V25Z" fill="#FFE11D"/>
|
||||||
|
<path d="M58 25H62V18C62 17.4477 61.5523 17 61 17H59C58.4477 17 58 17.4477 58 18V25Z" fill="#FFE11D"/>
|
||||||
|
<path d="M66 25H70V18C70 17.4477 69.5523 17 69 17H67C66.4477 17 66 17.4477 66 18V25Z" fill="#FFE11D"/>
|
||||||
|
<path d="M74 25H78V18C78 17.4477 77.5523 17 77 17H75C74.4477 17 74 17.4477 74 18V25Z" fill="#FFE11D"/>
|
||||||
|
<path d="M82 25H86V18C86 17.4477 85.5523 17 85 17H83C82.4477 17 82 17.4477 82 18V25Z" fill="#FFE11D"/>
|
||||||
|
<path d="M90 25H94V18C94 17.4477 93.5523 17 93 17H91C90.4477 17 90 17.4477 90 18V25Z" fill="#FFE11D"/>
|
||||||
|
<rect x="24" y="27" width="80" height="74" rx="8" fill="url(#paint2_linear_293_18)"/>
|
||||||
|
<rect x="24" y="27" width="80" height="74" rx="8" fill="black" fill-opacity="0.1"/>
|
||||||
|
<rect x="24" y="21" width="80" height="72" rx="8" fill="#EAEAEA"/>
|
||||||
|
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V105C38 105.552 37.5523 106 37 106H35C34.4477 106 34 105.552 34 105V98Z" fill="#939A00"/>
|
||||||
|
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V105C46 105.552 45.5523 106 45 106H43C42.4477 106 42 105.552 42 105V98Z" fill="#939A00"/>
|
||||||
|
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V105C54 105.552 53.5523 106 53 106H51C50.4477 106 50 105.552 50 105V98Z" fill="#939A00"/>
|
||||||
|
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V105C62 105.552 61.5523 106 61 106H59C58.4477 106 58 105.552 58 105V98Z" fill="#939A00"/>
|
||||||
|
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V105C70 105.552 69.5523 106 69 106H67C66.4477 106 66 105.552 66 105V98Z" fill="#939A00"/>
|
||||||
|
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V105C78 105.552 77.5523 106 77 106H75C74.4477 106 74 105.552 74 105V98Z" fill="#939A00"/>
|
||||||
|
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V105C86 105.552 85.5523 106 85 106H83C82.4477 106 82 105.552 82 105V98Z" fill="#939A00"/>
|
||||||
|
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V105C94 105.552 93.5523 106 93 106H91C90.4477 106 90 105.552 90 105V98Z" fill="#939A00"/>
|
||||||
|
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98V104H34V98Z" fill="#FFE11D"/>
|
||||||
|
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98V104H42V98Z" fill="#FFE11D"/>
|
||||||
|
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98V104H50V98Z" fill="#FFE11D"/>
|
||||||
|
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98V104H58V98Z" fill="#FFE11D"/>
|
||||||
|
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98V104H66V98Z" fill="#FFE11D"/>
|
||||||
|
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98V104H74V98Z" fill="#FFE11D"/>
|
||||||
|
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98V104H82V98Z" fill="#FFE11D"/>
|
||||||
|
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98V104H90V98Z" fill="#FFE11D"/>
|
||||||
|
<path d="M34 98C34 96.8954 34.8954 96 36 96C37.1046 96 38 96.8954 38 98H34Z" fill="#808080"/>
|
||||||
|
<path d="M42 98C42 96.8954 42.8954 96 44 96C45.1046 96 46 96.8954 46 98H42Z" fill="#808080"/>
|
||||||
|
<path d="M50 98C50 96.8954 50.8954 96 52 96C53.1046 96 54 96.8954 54 98H50Z" fill="#808080"/>
|
||||||
|
<path d="M58 98C58 96.8954 58.8954 96 60 96C61.1046 96 62 96.8954 62 98H58Z" fill="#808080"/>
|
||||||
|
<path d="M66 98C66 96.8954 66.8954 96 68 96C69.1046 96 70 96.8954 70 98H66Z" fill="#808080"/>
|
||||||
|
<path d="M74 98C74 96.8954 74.8954 96 76 96C77.1046 96 78 96.8954 78 98H74Z" fill="#808080"/>
|
||||||
|
<path d="M82 98C82 96.8954 82.8954 96 84 96C85.1046 96 86 96.8954 86 98H82Z" fill="#808080"/>
|
||||||
|
<path d="M90 98C90 96.8954 90.8954 96 92 96C93.1046 96 94 96.8954 94 98H90Z" fill="#808080"/>
|
||||||
|
<g filter="url(#filter0_i_293_18)">
|
||||||
|
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#D9D9D9"/>
|
||||||
|
<path d="M48.8658 38.6343C49.4695 35.7019 52.4974 33.9536 55.3388 34.8971L57.6974 35.6803C61.7893 37.039 66.2107 37.039 70.3026 35.6803L72.6612 34.8971C75.5026 33.9536 78.5305 35.7018 79.1342 38.6343L79.6352 41.0684C80.5045 45.2915 82.7152 49.1206 85.9378 51.9849L87.7953 53.6359C90.0331 55.6249 90.0331 59.1213 87.7953 61.1103L85.9378 62.7612C82.7152 65.6256 80.5045 69.4546 79.6352 73.6777L79.1342 76.1118C78.5305 79.0443 75.5026 80.7925 72.6612 79.849L70.3026 79.0659C66.2107 77.7071 61.7893 77.7071 57.6974 79.0659L55.3388 79.849C52.4974 80.7925 49.4695 79.0443 48.8658 76.1118L48.3648 73.6777C47.4955 69.4547 45.2848 65.6256 42.0622 62.7612L40.2047 61.1103C37.9669 59.1213 37.9669 55.6249 40.2047 53.6359L42.0622 51.9849C45.2848 49.1206 47.4955 45.2915 48.3648 41.0684L48.8658 38.6343Z" fill="#202020"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter1_d_293_18)">
|
||||||
|
<path d="M64 70C56.8216 70 51 64.1761 51 57C51 49.8194 56.8216 44 64 44C71.1784 44 77 49.8239 77 57C77 64.1761 71.1784 70 64 70Z" fill="#EAEAEA"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_i_293_18" x="38.5264" y="34.6403" width="50.9473" height="45.4655" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="2"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
||||||
|
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_293_18"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d_293_18" x="51" y="44" width="26" height="28" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dy="2"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="out"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 0 0.501961 0 0 0 1 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_293_18"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_293_18" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<linearGradient id="paint0_linear_293_18" x1="116" y1="116" x2="12" y2="116" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#404040"/>
|
||||||
|
<stop offset="0.03" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="0.06" stop-color="#606060"/>
|
||||||
|
<stop offset="0.94" stop-color="#606060"/>
|
||||||
|
<stop offset="0.97" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="1" stop-color="#404040"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint1_linear_293_18" x1="116" y1="112" x2="12" y2="112" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#404040"/>
|
||||||
|
<stop offset="0.03" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="0.06" stop-color="#606060"/>
|
||||||
|
<stop offset="0.94" stop-color="#606060"/>
|
||||||
|
<stop offset="0.97" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="1" stop-color="#404040"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint2_linear_293_18" x1="24" y1="85.8476" x2="103.999" y2="85.6325" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#AFAFAF"/>
|
||||||
|
<stop offset="0.04" stop-color="#F6F5F4"/>
|
||||||
|
<stop offset="0.08" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="0.92" stop-color="#D0D0D0"/>
|
||||||
|
<stop offset="0.96" stop-color="#F6F5F4"/>
|
||||||
|
<stop offset="1" stop-color="#AFAFAF"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 8.6 KiB |
@@ -1,5 +1,5 @@
|
|||||||
project('yafi',
|
project('yafi',
|
||||||
version: '0.1.0',
|
version: '1.0',
|
||||||
meson_version: '>= 1.0.0',
|
meson_version: '>= 1.0.0',
|
||||||
default_options: [ 'warning_level=2', 'werror=false', ],
|
default_options: [ 'warning_level=2', 'werror=false', ],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import os
|
|||||||
if os.name == 'nt' and os.environ.get('GDK_SCALE') is None:
|
if os.name == 'nt' and os.environ.get('GDK_SCALE') is None:
|
||||||
import ctypes
|
import ctypes
|
||||||
scale_factor = ctypes.windll.shcore.GetScaleFactorForDevice(0)
|
scale_factor = ctypes.windll.shcore.GetScaleFactorForDevice(0)
|
||||||
os.environ["GDK_SCALE"] = f"{scale_factor//100}"
|
os.environ["GDK_SCALE"] = f"{round(scale_factor, -2)//100}"
|
||||||
|
|
||||||
from yafi import main
|
from yafi import main
|
||||||
main()
|
main()
|
||||||
|
|||||||
BIN
pyinstaller/splash.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
301
pyinstaller/splash.svg
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
pyinstaller/yafi.ico
Executable file → Normal file
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 398 KiB |
@@ -1,11 +1,15 @@
|
|||||||
# -*- mode: python ; coding: utf-8 -*-
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
from PyInstaller.utils.hooks import collect_data_files
|
from PyInstaller.utils.hooks import collect_data_files
|
||||||
import os
|
import os
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--onefile", action="store_true")
|
||||||
|
options = parser.parse_args()
|
||||||
|
|
||||||
datas = [('LpcCrOSEC.bin', '.')] if os.name == 'nt' and os.path.exists('LpcCrOSEC.bin') else []
|
datas = [('LpcCrOSEC.bin', '.')] if os.name == 'nt' and os.path.exists('LpcCrOSEC.bin') else []
|
||||||
datas += collect_data_files('yafi')
|
datas += collect_data_files('yafi')
|
||||||
|
|
||||||
|
|
||||||
a = Analysis(
|
a = Analysis(
|
||||||
['entrypoint.py'],
|
['entrypoint.py'],
|
||||||
pathex=[],
|
pathex=[],
|
||||||
@@ -21,12 +25,34 @@ a = Analysis(
|
|||||||
)
|
)
|
||||||
pyz = PYZ(a.pure)
|
pyz = PYZ(a.pure)
|
||||||
|
|
||||||
|
if options.onefile:
|
||||||
|
splash = Splash(
|
||||||
|
'splash.png',
|
||||||
|
binaries=a.binaries,
|
||||||
|
datas=a.datas,
|
||||||
|
text_pos=(4, 480),
|
||||||
|
# Text doesn't scale on Linux, but does on Windows
|
||||||
|
text_size=12 if os.name == 'nt' else 6,
|
||||||
|
minify_script=True,
|
||||||
|
always_on_top=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
exe_args = (
|
||||||
|
[
|
||||||
|
a.scripts,
|
||||||
|
a.binaries,
|
||||||
|
a.datas,
|
||||||
|
splash,
|
||||||
|
splash.binaries,
|
||||||
|
]
|
||||||
|
if options.onefile
|
||||||
|
else [a.scripts]
|
||||||
|
)
|
||||||
|
|
||||||
exe = EXE(
|
exe = EXE(
|
||||||
pyz,
|
pyz,
|
||||||
a.scripts,
|
*exe_args,
|
||||||
a.binaries,
|
exclude_binaries=not options.onefile,
|
||||||
a.datas,
|
|
||||||
[],
|
|
||||||
name='YAFI',
|
name='YAFI',
|
||||||
debug=False,
|
debug=False,
|
||||||
bootloader_ignore_signals=False,
|
bootloader_ignore_signals=False,
|
||||||
@@ -42,3 +68,14 @@ exe = EXE(
|
|||||||
entitlements_file=None,
|
entitlements_file=None,
|
||||||
icon=['yafi.ico'],
|
icon=['yafi.ico'],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not options.onefile:
|
||||||
|
coll = COLLECT(
|
||||||
|
exe,
|
||||||
|
a.binaries,
|
||||||
|
a.datas,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
name='YAFI',
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "yafi"
|
name = "yafi"
|
||||||
version = "0.4"
|
version = "1.0"
|
||||||
authors = [
|
authors = [
|
||||||
{ name="Steve-Tech" }
|
{ name="Steve-Tech" }
|
||||||
]
|
]
|
||||||
@@ -8,11 +8,10 @@ description = "Yet Another Framework Interface"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cros_ec_python >= 0.2.0",
|
"cros_ec_python >= 0.4.0",
|
||||||
"PyGObject"
|
"PyGObject"
|
||||||
]
|
]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Development Status :: 3 - Alpha",
|
|
||||||
"Intended Audience :: End Users/Desktop",
|
"Intended Audience :: End Users/Desktop",
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Operating System :: POSIX :: Linux",
|
"Operating System :: POSIX :: Linux",
|
||||||
|
|||||||
14
python3-cros_ec_python.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"name": "python3-cros_ec_python",
|
||||||
|
"buildsystem": "simple",
|
||||||
|
"build-commands": [
|
||||||
|
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"cros_ec_python\" --no-build-isolation"
|
||||||
|
],
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"url": "https://files.pythonhosted.org/packages/6c/7a/10d978a02bbe37530490cfd14e0994c433dc29c81b3afcdbde453d512528/cros_ec_python-0.3.0-py3-none-any.whl",
|
||||||
|
"sha256": "aeb14ebdbd60ec6d6a4b11df1482a295466da4a908a468d168efd4cc141e7e3d"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -18,9 +18,7 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
from gi.repository import Adw
|
from gi.repository import Gtk, Adw, GLib
|
||||||
from gi.repository import Gtk
|
|
||||||
from gi.repository import GLib
|
|
||||||
|
|
||||||
import cros_ec_python.commands as ec_commands
|
import cros_ec_python.commands as ec_commands
|
||||||
import cros_ec_python.exceptions as ec_exceptions
|
import cros_ec_python.exceptions as ec_exceptions
|
||||||
@@ -52,6 +50,9 @@ class BatteryPage(Gtk.Box):
|
|||||||
|
|
||||||
def setup(self, app):
|
def setup(self, app):
|
||||||
battery = ec_commands.memmap.get_battery_values(app.cros_ec)
|
battery = ec_commands.memmap.get_battery_values(app.cros_ec)
|
||||||
|
if not battery:
|
||||||
|
self.batt_status.set_subtitle("No data")
|
||||||
|
return
|
||||||
self.batt_manu.set_subtitle(battery["manufacturer"])
|
self.batt_manu.set_subtitle(battery["manufacturer"])
|
||||||
self.batt_model.set_subtitle(battery["model"])
|
self.batt_model.set_subtitle(battery["model"])
|
||||||
self.batt_serial.set_subtitle(battery["serial"])
|
self.batt_serial.set_subtitle(battery["serial"])
|
||||||
|
|||||||
@@ -18,9 +18,7 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
from gi.repository import Adw
|
from gi.repository import Gtk, Adw, GLib
|
||||||
from gi.repository import Gtk
|
|
||||||
from gi.repository import GLib
|
|
||||||
|
|
||||||
import cros_ec_python.commands as ec_commands
|
import cros_ec_python.commands as ec_commands
|
||||||
import cros_ec_python.exceptions as ec_exceptions
|
import cros_ec_python.exceptions as ec_exceptions
|
||||||
@@ -36,8 +34,6 @@ class BatteryLimiterPage(Gtk.Box):
|
|||||||
bat_limit = Gtk.Template.Child()
|
bat_limit = Gtk.Template.Child()
|
||||||
bat_limit_label = Gtk.Template.Child()
|
bat_limit_label = Gtk.Template.Child()
|
||||||
bat_limit_scale = Gtk.Template.Child()
|
bat_limit_scale = Gtk.Template.Child()
|
||||||
chg_limit_override = Gtk.Template.Child()
|
|
||||||
chg_limit_override_btn = Gtk.Template.Child()
|
|
||||||
|
|
||||||
bat_ext_group = Gtk.Template.Child()
|
bat_ext_group = Gtk.Template.Child()
|
||||||
bat_ext_enable = Gtk.Template.Child()
|
bat_ext_enable = Gtk.Template.Child()
|
||||||
@@ -63,7 +59,6 @@ class BatteryLimiterPage(Gtk.Box):
|
|||||||
self.bat_limit_label.set_label(f"{ec_limit[1]}%")
|
self.bat_limit_label.set_label(f"{ec_limit[1]}%")
|
||||||
self.chg_limit.set_sensitive(True)
|
self.chg_limit.set_sensitive(True)
|
||||||
self.bat_limit.set_sensitive(True)
|
self.bat_limit.set_sensitive(True)
|
||||||
self.chg_limit_override.set_sensitive(True)
|
|
||||||
|
|
||||||
def handle_chg_limit_change(min, max):
|
def handle_chg_limit_change(min, max):
|
||||||
ec_commands.framework_laptop.set_charge_limit(
|
ec_commands.framework_laptop.set_charge_limit(
|
||||||
@@ -81,7 +76,6 @@ class BatteryLimiterPage(Gtk.Box):
|
|||||||
|
|
||||||
self.chg_limit.set_sensitive(active)
|
self.chg_limit.set_sensitive(active)
|
||||||
self.bat_limit.set_sensitive(active)
|
self.bat_limit.set_sensitive(active)
|
||||||
self.chg_limit_override.set_sensitive(active)
|
|
||||||
|
|
||||||
self.chg_limit_enable.connect(
|
self.chg_limit_enable.connect(
|
||||||
"notify::active", lambda switch, _: handle_chg_limit_enable(switch)
|
"notify::active", lambda switch, _: handle_chg_limit_enable(switch)
|
||||||
@@ -99,12 +93,6 @@ class BatteryLimiterPage(Gtk.Box):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
self.chg_limit_override_btn.connect(
|
|
||||||
"clicked",
|
|
||||||
lambda _: ec_commands.framework_laptop.override_charge_limit(
|
|
||||||
app.cros_ec
|
|
||||||
),
|
|
||||||
)
|
|
||||||
except ec_exceptions.ECError as e:
|
except ec_exceptions.ECError as e:
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||||
app.no_support.append(ec_commands.framework_laptop.EC_CMD_CHARGE_LIMIT_CONTROL)
|
app.no_support.append(ec_commands.framework_laptop.EC_CMD_CHARGE_LIMIT_CONTROL)
|
||||||
|
|||||||
@@ -18,9 +18,7 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
from gi.repository import Adw
|
from gi.repository import Gtk, Adw, GLib
|
||||||
from gi.repository import Gtk
|
|
||||||
from gi.repository import GLib
|
|
||||||
|
|
||||||
import cros_ec_python.commands as ec_commands
|
import cros_ec_python.commands as ec_commands
|
||||||
import cros_ec_python.exceptions as ec_exceptions
|
import cros_ec_python.exceptions as ec_exceptions
|
||||||
@@ -29,17 +27,24 @@ import cros_ec_python.exceptions as ec_exceptions
|
|||||||
class HardwarePage(Gtk.Box):
|
class HardwarePage(Gtk.Box):
|
||||||
__gtype_name__ = 'HardwarePage'
|
__gtype_name__ = 'HardwarePage'
|
||||||
|
|
||||||
|
hw_als = Gtk.Template.Child()
|
||||||
|
hw_als_label = Gtk.Template.Child()
|
||||||
|
|
||||||
hw_chassis = Gtk.Template.Child()
|
hw_chassis = Gtk.Template.Child()
|
||||||
hw_chassis_label = Gtk.Template.Child()
|
hw_chassis_label = Gtk.Template.Child()
|
||||||
|
|
||||||
|
hw_fp_pwr = Gtk.Template.Child()
|
||||||
|
hw_fp_pwr_en = Gtk.Template.Child()
|
||||||
|
hw_fp_pwr_dis = Gtk.Template.Child()
|
||||||
|
|
||||||
hw_priv_cam = Gtk.Template.Child()
|
hw_priv_cam = Gtk.Template.Child()
|
||||||
hw_priv_cam_sw = Gtk.Template.Child()
|
hw_priv_cam_sw = Gtk.Template.Child()
|
||||||
hw_priv_mic = Gtk.Template.Child()
|
hw_priv_mic = Gtk.Template.Child()
|
||||||
hw_priv_mic_sw = Gtk.Template.Child()
|
hw_priv_mic_sw = Gtk.Template.Child()
|
||||||
|
hw_lid_open = Gtk.Template.Child()
|
||||||
hw_fp_pwr = Gtk.Template.Child()
|
hw_lid_open_sw = Gtk.Template.Child()
|
||||||
hw_fp_pwr_en = Gtk.Template.Child()
|
hw_pwr_btn = Gtk.Template.Child()
|
||||||
hw_fp_pwr_dis = Gtk.Template.Child()
|
hw_pwr_btn_sw = Gtk.Template.Child()
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
@@ -68,7 +73,13 @@ class HardwarePage(Gtk.Box):
|
|||||||
GLib.timeout_add_seconds(1, self._update_hardware, app)
|
GLib.timeout_add_seconds(1, self._update_hardware, app)
|
||||||
|
|
||||||
def _update_hardware(self, app):
|
def _update_hardware(self, app):
|
||||||
success = False
|
# Memmap (ALS and Lid Open)
|
||||||
|
als = ec_commands.memmap.get_als(app.cros_ec)
|
||||||
|
self.hw_als_label.set_label(f"{als[0]} lux" if als[0] != 65535 else "MAX")
|
||||||
|
switches = ec_commands.memmap.get_switches(app.cros_ec)
|
||||||
|
self.hw_lid_open_sw.set_active(switches["lid_open"])
|
||||||
|
self.hw_pwr_btn_sw.set_active(switches["power_button_pressed"])
|
||||||
|
|
||||||
# Chassis
|
# Chassis
|
||||||
if not ec_commands.framework_laptop.EC_CMD_CHASSIS_INTRUSION in app.no_support:
|
if not ec_commands.framework_laptop.EC_CMD_CHASSIS_INTRUSION in app.no_support:
|
||||||
try:
|
try:
|
||||||
@@ -84,8 +95,6 @@ class HardwarePage(Gtk.Box):
|
|||||||
self.hw_chassis.set_subtitle(
|
self.hw_chassis.set_subtitle(
|
||||||
"Currently " + ("Open" if ec_chassis_open else "Closed")
|
"Currently " + ("Open" if ec_chassis_open else "Closed")
|
||||||
)
|
)
|
||||||
|
|
||||||
success = True
|
|
||||||
except ec_exceptions.ECError as e:
|
except ec_exceptions.ECError as e:
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||||
app.no_support.append(
|
app.no_support.append(
|
||||||
@@ -106,8 +115,6 @@ class HardwarePage(Gtk.Box):
|
|||||||
)
|
)
|
||||||
self.hw_priv_cam_sw.set_active(ec_privacy["camera"])
|
self.hw_priv_cam_sw.set_active(ec_privacy["camera"])
|
||||||
self.hw_priv_mic_sw.set_active(ec_privacy["microphone"])
|
self.hw_priv_mic_sw.set_active(ec_privacy["microphone"])
|
||||||
|
|
||||||
success = True
|
|
||||||
except ec_exceptions.ECError as e:
|
except ec_exceptions.ECError as e:
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||||
app.no_support.append(
|
app.no_support.append(
|
||||||
@@ -118,4 +125,4 @@ class HardwarePage(Gtk.Box):
|
|||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
return app.current_page == 4 and success
|
return app.current_page == 4
|
||||||
|
|||||||
111
yafi/leds.py
@@ -18,8 +18,7 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
from gi.repository import Adw
|
from gi.repository import Gtk, Adw, GLib
|
||||||
from gi.repository import Gtk
|
|
||||||
|
|
||||||
import cros_ec_python.commands as ec_commands
|
import cros_ec_python.commands as ec_commands
|
||||||
import cros_ec_python.exceptions as ec_exceptions
|
import cros_ec_python.exceptions as ec_exceptions
|
||||||
@@ -28,6 +27,8 @@ import cros_ec_python.exceptions as ec_exceptions
|
|||||||
class LedsPage(Gtk.Box):
|
class LedsPage(Gtk.Box):
|
||||||
__gtype_name__ = 'LedsPage'
|
__gtype_name__ = 'LedsPage'
|
||||||
|
|
||||||
|
first_run = True
|
||||||
|
|
||||||
led_pwr = Gtk.Template.Child()
|
led_pwr = Gtk.Template.Child()
|
||||||
led_pwr_scale = Gtk.Template.Child()
|
led_pwr_scale = Gtk.Template.Child()
|
||||||
|
|
||||||
@@ -36,27 +37,30 @@ class LedsPage(Gtk.Box):
|
|||||||
|
|
||||||
led_advanced = Gtk.Template.Child()
|
led_advanced = Gtk.Template.Child()
|
||||||
|
|
||||||
led_pwr_colour = Gtk.Template.Child()
|
|
||||||
|
|
||||||
led_chg_colour = Gtk.Template.Child()
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
def setup(self, app):
|
def setup(self, app):
|
||||||
# Power LED
|
# Power LED
|
||||||
try:
|
try:
|
||||||
|
|
||||||
def handle_led_pwr(scale):
|
def handle_led_pwr(scale):
|
||||||
value = int(abs(scale.get_value() - 2))
|
value = int(abs(scale.get_value() - 2))
|
||||||
ec_commands.framework_laptop.set_fp_led_level(app.cros_ec, value)
|
ec_commands.framework_laptop.set_fp_led_level(app.cros_ec, value)
|
||||||
self.led_pwr.set_subtitle(["High", "Medium", "Low"][value])
|
self.led_pwr.set_subtitle(["High", "Medium", "Low"][value])
|
||||||
|
|
||||||
current_fp_level = ec_commands.framework_laptop.get_fp_led_level(
|
try:
|
||||||
app.cros_ec
|
current_fp_level = ec_commands.framework_laptop.get_fp_led_level(
|
||||||
).value
|
app.cros_ec
|
||||||
self.led_pwr_scale.set_value(abs(current_fp_level - 2))
|
).value
|
||||||
self.led_pwr.set_subtitle(["High", "Medium", "Low"][current_fp_level])
|
self.led_pwr_scale.set_value(abs(current_fp_level - 2))
|
||||||
|
self.led_pwr.set_subtitle(["High", "Medium", "Low"][current_fp_level])
|
||||||
|
except ValueError:
|
||||||
|
# LED isn't a normal value
|
||||||
|
current_fp_level = ec_commands.framework_laptop.get_fp_led_level_int(
|
||||||
|
app.cros_ec
|
||||||
|
)
|
||||||
|
self.led_pwr.set_subtitle(f"Custom ({current_fp_level}%)")
|
||||||
|
|
||||||
self.led_pwr_scale.connect("value-changed", handle_led_pwr)
|
self.led_pwr_scale.connect("value-changed", handle_led_pwr)
|
||||||
except ec_exceptions.ECError as e:
|
except ec_exceptions.ECError as e:
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||||
@@ -85,28 +89,38 @@ class LedsPage(Gtk.Box):
|
|||||||
self.led_kbd.set_visible(False)
|
self.led_kbd.set_visible(False)
|
||||||
|
|
||||||
# Advanced options
|
# Advanced options
|
||||||
if ec_commands.general.get_cmd_versions(
|
if (
|
||||||
app.cros_ec, ec_commands.leds.EC_CMD_LED_CONTROL
|
ec_commands.general.get_cmd_versions(
|
||||||
|
app.cros_ec, ec_commands.leds.EC_CMD_LED_CONTROL
|
||||||
|
)
|
||||||
|
and self.first_run
|
||||||
):
|
):
|
||||||
|
|
||||||
# Advanced: Power LED
|
|
||||||
led_pwr_colour_strings = self.led_pwr_colour.get_model()
|
|
||||||
|
|
||||||
all_colours = ["Red", "Green", "Blue", "Yellow", "White", "Amber"]
|
all_colours = ["Red", "Green", "Blue", "Yellow", "White", "Amber"]
|
||||||
|
led_names = {
|
||||||
def add_colours(strings, led_id):
|
ec_commands.leds.EcLedId.EC_LED_ID_BATTERY_LED: "Battery LED",
|
||||||
# Auto and Off should already be present
|
ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED: "Power LED",
|
||||||
if strings.get_n_items() <= 2:
|
ec_commands.leds.EcLedId.EC_LED_ID_ADAPTER_LED: "Adapter LED",
|
||||||
supported_colours = ec_commands.leds.led_control_get_max_values(
|
ec_commands.leds.EcLedId.EC_LED_ID_LEFT_LED: "Left LED",
|
||||||
|
ec_commands.leds.EcLedId.EC_LED_ID_RIGHT_LED: "Right LED",
|
||||||
|
ec_commands.leds.EcLedId.EC_LED_ID_RECOVERY_HW_REINIT_LED: "Recovery LED",
|
||||||
|
ec_commands.leds.EcLedId.EC_LED_ID_SYSRQ_DEBUG_LED: "SysRq LED",
|
||||||
|
}
|
||||||
|
leds = {}
|
||||||
|
for i in range(ec_commands.leds.EcLedId.EC_LED_ID_COUNT.value):
|
||||||
|
try:
|
||||||
|
led_id = ec_commands.leds.EcLedId(i)
|
||||||
|
leds[led_id] = ec_commands.leds.led_control_get_max_values(
|
||||||
app.cros_ec, led_id
|
app.cros_ec, led_id
|
||||||
)
|
)
|
||||||
for i, colour in enumerate(all_colours):
|
except ec_exceptions.ECError as e:
|
||||||
if supported_colours[i]:
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_PARAM:
|
||||||
strings.append(colour)
|
continue
|
||||||
|
else:
|
||||||
add_colours(
|
raise e
|
||||||
led_pwr_colour_strings, ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED
|
|
||||||
)
|
# Power LED does not support Blue, even though Intel models think they do
|
||||||
|
leds[ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED][2] = 0
|
||||||
|
|
||||||
def handle_led_colour(combobox, led_id):
|
def handle_led_colour(combobox, led_id):
|
||||||
colour = combobox.get_selected() - 2
|
colour = combobox.get_selected() - 2
|
||||||
@@ -130,27 +144,20 @@ class LedsPage(Gtk.Box):
|
|||||||
100,
|
100,
|
||||||
ec_commands.leds.EcLedColors(colour_idx),
|
ec_commands.leds.EcLedColors(colour_idx),
|
||||||
)
|
)
|
||||||
|
for led_id, supported_colours in leds.items():
|
||||||
|
if any(supported_colours):
|
||||||
|
combo = Adw.ComboRow(title=led_names[led_id])
|
||||||
|
model = Gtk.StringList.new(["Auto", "Off"])
|
||||||
|
for i, colour in enumerate(all_colours):
|
||||||
|
if supported_colours[i]:
|
||||||
|
model.append(colour)
|
||||||
|
combo.set_model(model)
|
||||||
|
combo.connect(
|
||||||
|
"notify::selected",
|
||||||
|
lambda combobox, _, led_id=led_id: handle_led_colour(
|
||||||
|
combobox, led_id
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.led_advanced.add_row(combo)
|
||||||
|
|
||||||
self.led_pwr_colour.connect(
|
self.first_run = False
|
||||||
"notify::selected",
|
|
||||||
lambda combo, _: handle_led_colour(
|
|
||||||
combo, ec_commands.leds.EcLedId.EC_LED_ID_POWER_LED
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Advanced: Charging LED
|
|
||||||
led_chg_colour_strings = self.led_chg_colour.get_model()
|
|
||||||
|
|
||||||
add_colours(
|
|
||||||
led_chg_colour_strings,
|
|
||||||
ec_commands.leds.EcLedId.EC_LED_ID_BATTERY_LED,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.led_chg_colour.connect(
|
|
||||||
"notify::selected",
|
|
||||||
lambda combo, _: handle_led_colour(
|
|
||||||
combo, ec_commands.leds.EcLedId.EC_LED_ID_BATTERY_LED
|
|
||||||
),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.led_advanced.set_visible(False)
|
|
||||||
|
|||||||
55
yafi/main.py
@@ -18,15 +18,16 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
import threading
|
||||||
import gi
|
import gi
|
||||||
from gi.repository import Gio
|
|
||||||
|
|
||||||
gi.require_version('Gtk', '4.0')
|
gi.require_version('Gtk', '4.0')
|
||||||
gi.require_version('Adw', '1')
|
gi.require_version('Adw', '1')
|
||||||
|
|
||||||
from gi.repository import Gtk, Gio, Adw
|
from gi.repository import Gtk, Gio, Adw, GLib
|
||||||
from .window import YafiWindow
|
from .window import YafiWindow
|
||||||
from .thermals import ThermalsPage
|
from .thermals import ThermalsPage
|
||||||
from .leds import LedsPage
|
from .leds import LedsPage
|
||||||
@@ -66,6 +67,12 @@ class YafiApplication(Adw.Application):
|
|||||||
if not self.win:
|
if not self.win:
|
||||||
self.win = YafiWindow(application=self)
|
self.win = YafiWindow(application=self)
|
||||||
|
|
||||||
|
# Update the splash screen
|
||||||
|
splash = getattr(sys, 'frozen', False) and '_PYI_SPLASH_IPC' in os.environ
|
||||||
|
if splash:
|
||||||
|
import pyi_splash
|
||||||
|
pyi_splash.update_text("Detecting EC")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.cros_ec = get_cros_ec()
|
self.cros_ec = get_cros_ec()
|
||||||
pass
|
pass
|
||||||
@@ -81,9 +88,16 @@ class YafiApplication(Adw.Application):
|
|||||||
+ "If you are using a Framework Laptop, there are additional troubleshooting steps in the README."
|
+ "If you are using a Framework Laptop, there are additional troubleshooting steps in the README."
|
||||||
)
|
)
|
||||||
self.show_error("EC Initalisation Error", message)
|
self.show_error("EC Initalisation Error", message)
|
||||||
|
|
||||||
|
if splash:
|
||||||
|
pyi_splash.close()
|
||||||
|
|
||||||
self.win.present()
|
self.win.present()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if splash:
|
||||||
|
pyi_splash.update_text("Building Interface")
|
||||||
|
|
||||||
self.change_page(self.win.content, ThermalsPage())
|
self.change_page(self.win.content, ThermalsPage())
|
||||||
|
|
||||||
pages = (
|
pages = (
|
||||||
@@ -91,7 +105,7 @@ class YafiApplication(Adw.Application):
|
|||||||
("LEDs", LedsPage()),
|
("LEDs", LedsPage()),
|
||||||
("Battery", BatteryPage()),
|
("Battery", BatteryPage()),
|
||||||
("Battery Limiter", BatteryLimiterPage()),
|
("Battery Limiter", BatteryLimiterPage()),
|
||||||
("Hardware", HardwarePage()),
|
("Sensors", HardwarePage()),
|
||||||
("About", None),
|
("About", None),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -107,10 +121,14 @@ class YafiApplication(Adw.Application):
|
|||||||
self.current_page = page
|
self.current_page = page
|
||||||
self.change_page(self.win.content, pages[page][1])
|
self.change_page(self.win.content, pages[page][1])
|
||||||
else:
|
else:
|
||||||
|
self.win.navbar.select_row(self.win.navbar.get_row_at_index(self.current_page))
|
||||||
self.on_about_action()
|
self.on_about_action()
|
||||||
|
|
||||||
self.win.navbar.connect("row-activated", lambda box, row: switch_page(row.get_index()))
|
self.win.navbar.connect("row-activated", lambda box, row: switch_page(row.get_index()))
|
||||||
|
|
||||||
|
if splash:
|
||||||
|
pyi_splash.close()
|
||||||
|
|
||||||
self.win.present()
|
self.win.present()
|
||||||
|
|
||||||
def on_about_action(self, *args):
|
def on_about_action(self, *args):
|
||||||
@@ -118,20 +136,26 @@ class YafiApplication(Adw.Application):
|
|||||||
about = Adw.AboutDialog(
|
about = Adw.AboutDialog(
|
||||||
application_icon="au.stevetech.yafi",
|
application_icon="au.stevetech.yafi",
|
||||||
application_name="Yet Another Framework Interface",
|
application_name="Yet Another Framework Interface",
|
||||||
comments="YAFI is another GUI for the Framework Laptop Embedded Controller.\n"
|
comments="YAFI is another GUI for the Framework Laptop Embedded Controller.\n\n"
|
||||||
+ "It is written in Python with a GTK3 theme, and uses the `CrOS_EC_Python` library to communicate with the EC.",
|
+ "It is written in Python with a GTK4 Adwaita theme, and uses the CrOS_EC_Python library to communicate with the EC.\n\n"
|
||||||
copyright="© 2025 Stephen Horvath",
|
+ "YAFI is not affiliated with Framework Computer Inc. in any way.",
|
||||||
debug_info=self.generate_debug_info(),
|
copyright="© 2026 Stephen Horvath",
|
||||||
developer_name="Stephen Horvath",
|
developer_name="Stephen Horvath",
|
||||||
developers=["Stephen Horvath"],
|
developers=["Stephen Horvath https://github.com/Steve-Tech"],
|
||||||
|
artists=["Mirabelle SALLES https://github.com/oiimrosabel"],
|
||||||
issue_url="https://github.com/Steve-Tech/YAFI/issues",
|
issue_url="https://github.com/Steve-Tech/YAFI/issues",
|
||||||
license_type=Gtk.License.GPL_2_0,
|
license_type=Gtk.License.GPL_2_0,
|
||||||
version="0.4",
|
version="1.0",
|
||||||
website="https://github.com/Steve-Tech/YAFI",
|
website="https://github.com/Steve-Tech/YAFI",
|
||||||
)
|
)
|
||||||
about.add_acknowledgement_section(None, ["Framework Computer Inc. https://frame.work/"])
|
about.add_acknowledgement_section(None, ["Framework Computer Inc. https://frame.work/"])
|
||||||
about.present(self.props.active_window)
|
about.present(self.props.active_window)
|
||||||
|
|
||||||
|
if hasattr(self, 'debug_info'):
|
||||||
|
about.set_debug_info(self.debug_info)
|
||||||
|
else:
|
||||||
|
threading.Thread(target=lambda: GLib.idle_add(about.set_debug_info, self.generate_debug_info())).start()
|
||||||
|
|
||||||
def show_error(self, heading, message):
|
def show_error(self, heading, message):
|
||||||
dialog = Adw.AlertDialog(heading=heading, body=message)
|
dialog = Adw.AlertDialog(heading=heading, body=message)
|
||||||
dialog.add_response("exit", "Exit")
|
dialog.add_response("exit", "Exit")
|
||||||
@@ -149,6 +173,8 @@ class YafiApplication(Adw.Application):
|
|||||||
if hasattr(self, 'error'):
|
if hasattr(self, 'error'):
|
||||||
if isinstance(self.error, Exception):
|
if isinstance(self.error, Exception):
|
||||||
info += f"{type(self.error).__name__}: {self.error}\n\n"
|
info += f"{type(self.error).__name__}: {self.error}\n\n"
|
||||||
|
info += ''.join(traceback.format_exception(type(self.error), self.error, self.error.__traceback__))
|
||||||
|
info += "\n\n"
|
||||||
else:
|
else:
|
||||||
info += f"Error: {self.error}\n\n"
|
info += f"Error: {self.error}\n\n"
|
||||||
|
|
||||||
@@ -177,6 +203,8 @@ class YafiApplication(Adw.Application):
|
|||||||
info += f"Model: {f.read().strip()}\n"
|
info += f"Model: {f.read().strip()}\n"
|
||||||
with open('/sys/devices/virtual/dmi/id/product_sku', 'r') as f:
|
with open('/sys/devices/virtual/dmi/id/product_sku', 'r') as f:
|
||||||
info += f"SKU: {f.read().strip()}\n"
|
info += f"SKU: {f.read().strip()}\n"
|
||||||
|
with open('/sys/devices/virtual/dmi/id/board_name', 'r') as f:
|
||||||
|
info += f"Board: {f.read().strip()}\n"
|
||||||
with open('/sys/devices/virtual/dmi/id/bios_vendor', 'r') as f:
|
with open('/sys/devices/virtual/dmi/id/bios_vendor', 'r') as f:
|
||||||
info += f"BIOS Vendor: {f.read().strip()}\n"
|
info += f"BIOS Vendor: {f.read().strip()}\n"
|
||||||
with open('/sys/devices/virtual/dmi/id/bios_version', 'r') as f:
|
with open('/sys/devices/virtual/dmi/id/bios_version', 'r') as f:
|
||||||
@@ -188,10 +216,12 @@ class YafiApplication(Adw.Application):
|
|||||||
ps_cmd = (
|
ps_cmd = (
|
||||||
"powershell -Command "
|
"powershell -Command "
|
||||||
"\"$cs = Get-CimInstance -ClassName Win32_ComputerSystem; "
|
"\"$cs = Get-CimInstance -ClassName Win32_ComputerSystem; "
|
||||||
|
"$board = Get-CimInstance -ClassName Win32_BaseBoard; "
|
||||||
"$bios = Get-CimInstance -ClassName Win32_BIOS; "
|
"$bios = Get-CimInstance -ClassName Win32_BIOS; "
|
||||||
"Write-Output $cs.Manufacturer; "
|
"Write-Output $cs.Manufacturer; "
|
||||||
"Write-Output $cs.Model; "
|
"Write-Output $cs.Model; "
|
||||||
"Write-Output $cs.SystemSKUNumber; "
|
"Write-Output $cs.SystemSKUNumber; "
|
||||||
|
"Write-Output $board.Product; "
|
||||||
"Write-Output $bios.Manufacturer; "
|
"Write-Output $bios.Manufacturer; "
|
||||||
"Write-Output $bios.Name; "
|
"Write-Output $bios.Name; "
|
||||||
"Write-Output $bios.ReleaseDate\""
|
"Write-Output $bios.ReleaseDate\""
|
||||||
@@ -200,10 +230,11 @@ class YafiApplication(Adw.Application):
|
|||||||
info += f"Manufacturer: {output[0]}\n"
|
info += f"Manufacturer: {output[0]}\n"
|
||||||
info += f"Model: {output[1]}\n"
|
info += f"Model: {output[1]}\n"
|
||||||
info += f"SKU: {output[2]}\n"
|
info += f"SKU: {output[2]}\n"
|
||||||
info += f"BIOS Vendor: {output[3]}\n"
|
info += f"Board: {output[3]}\n"
|
||||||
info += f"BIOS Version: {output[4]}\n"
|
info += f"BIOS Vendor: {output[4]}\n"
|
||||||
|
info += f"BIOS Version: {output[5]}\n"
|
||||||
# Blank line in the output for some reason
|
# Blank line in the output for some reason
|
||||||
info += f"BIOS Date: {output[6]}\n"
|
info += f"BIOS Date: {output[7]}\n"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
info += f"System Info Error: {type(e).__name__}: {e}\n"
|
info += f"System Info Error: {type(e).__name__}: {e}\n"
|
||||||
|
|
||||||
|
|||||||
131
yafi/thermals.py
@@ -18,9 +18,7 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
from gi.repository import Adw
|
from gi.repository import Gtk, Adw, GLib
|
||||||
from gi.repository import Gtk
|
|
||||||
from gi.repository import GLib
|
|
||||||
|
|
||||||
import cros_ec_python.commands as ec_commands
|
import cros_ec_python.commands as ec_commands
|
||||||
import cros_ec_python.exceptions as ec_exceptions
|
import cros_ec_python.exceptions as ec_exceptions
|
||||||
@@ -29,11 +27,17 @@ import cros_ec_python.exceptions as ec_exceptions
|
|||||||
class ThermalsPage(Gtk.Box):
|
class ThermalsPage(Gtk.Box):
|
||||||
__gtype_name__ = 'ThermalsPage'
|
__gtype_name__ = 'ThermalsPage'
|
||||||
|
|
||||||
|
first_run = True
|
||||||
|
|
||||||
fan_rpm = Gtk.Template.Child()
|
fan_rpm = Gtk.Template.Child()
|
||||||
fan_mode = Gtk.Template.Child()
|
fan_mode = Gtk.Template.Child()
|
||||||
fan_set_rpm = Gtk.Template.Child()
|
fan_set_rpm = Gtk.Template.Child()
|
||||||
fan_set_percent = Gtk.Template.Child()
|
fan_set_percent = Gtk.Template.Child()
|
||||||
fan_percent_scale = Gtk.Template.Child()
|
fan_percent_scale = Gtk.Template.Child()
|
||||||
|
fan_set_points = Gtk.Template.Child()
|
||||||
|
set_points = []
|
||||||
|
ec_set_points_supported = False
|
||||||
|
ec_set_points = []
|
||||||
|
|
||||||
temperatures = Gtk.Template.Child()
|
temperatures = Gtk.Template.Child()
|
||||||
temp_items = []
|
temp_items = []
|
||||||
@@ -42,10 +46,40 @@ class ThermalsPage(Gtk.Box):
|
|||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
def setup(self, app):
|
def setup(self, app):
|
||||||
|
# Temperature sensors
|
||||||
|
while temp_child := self.temperatures.get_last_child():
|
||||||
|
self.temperatures.remove(temp_child)
|
||||||
|
self.temp_items.clear()
|
||||||
|
|
||||||
|
try:
|
||||||
|
ec_temp_sensors = ec_commands.thermal.get_temp_sensors(app.cros_ec)
|
||||||
|
except ec_exceptions.ECError as e:
|
||||||
|
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
||||||
|
# Generate some labels if the command is not supported
|
||||||
|
ec_temp_sensors = {}
|
||||||
|
temps = ec_commands.memmap.get_temps(app.cros_ec)
|
||||||
|
for i, temp in enumerate(temps):
|
||||||
|
ec_temp_sensors[f"Sensor {i}"] = (temp, None)
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
|
||||||
|
for key, value in ec_temp_sensors.items():
|
||||||
|
off_row = Adw.ActionRow(title=key, subtitle=f"{value[0]}°C" if value[0] is not None else "Error")
|
||||||
|
off_row.add_css_class("property")
|
||||||
|
self.temperatures.append(off_row)
|
||||||
|
self.temp_items.append(off_row)
|
||||||
|
|
||||||
|
self._update_thermals(app)
|
||||||
|
|
||||||
# Don't let the user change the fans if they can't get back to auto
|
# Don't let the user change the fans if they can't get back to auto
|
||||||
if ec_commands.general.get_cmd_versions(
|
if ec_commands.general.get_cmd_versions(
|
||||||
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_AUTO_FAN_CTRL
|
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_AUTO_FAN_CTRL
|
||||||
):
|
):
|
||||||
|
self.ec_set_points_supported = ec_commands.general.check_cmd_version(
|
||||||
|
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_GET_THRESHOLD, 1
|
||||||
|
) and ec_commands.general.check_cmd_version(
|
||||||
|
app.cros_ec, ec_commands.thermal.EC_CMD_THERMAL_SET_THRESHOLD, 1
|
||||||
|
)
|
||||||
|
|
||||||
def handle_fan_mode(mode):
|
def handle_fan_mode(mode):
|
||||||
match mode:
|
match mode:
|
||||||
@@ -53,13 +87,18 @@ class ThermalsPage(Gtk.Box):
|
|||||||
self.fan_set_rpm.set_visible(False)
|
self.fan_set_rpm.set_visible(False)
|
||||||
self.fan_set_percent.set_visible(False)
|
self.fan_set_percent.set_visible(False)
|
||||||
ec_commands.thermal.thermal_auto_fan_ctrl(app.cros_ec)
|
ec_commands.thermal.thermal_auto_fan_ctrl(app.cros_ec)
|
||||||
|
self.fan_set_points.set_visible(self.ec_set_points_supported)
|
||||||
case 1: # Percent
|
case 1: # Percent
|
||||||
|
self.fan_set_points.set_visible(False)
|
||||||
self.fan_set_rpm.set_visible(False)
|
self.fan_set_rpm.set_visible(False)
|
||||||
self.fan_set_percent.set_visible(True)
|
self.fan_set_percent.set_visible(True)
|
||||||
case 2: # RPM
|
case 2: # RPM
|
||||||
|
self.fan_set_points.set_visible(False)
|
||||||
self.fan_set_rpm.set_visible(True)
|
self.fan_set_rpm.set_visible(True)
|
||||||
self.fan_set_percent.set_visible(False)
|
self.fan_set_percent.set_visible(False)
|
||||||
|
|
||||||
|
handle_fan_mode(self.fan_mode.get_selected())
|
||||||
|
|
||||||
self.fan_mode.connect(
|
self.fan_mode.connect(
|
||||||
"notify::selected",
|
"notify::selected",
|
||||||
lambda combo, _: handle_fan_mode(combo.get_selected()),
|
lambda combo, _: handle_fan_mode(combo.get_selected()),
|
||||||
@@ -83,41 +122,77 @@ class ThermalsPage(Gtk.Box):
|
|||||||
):
|
):
|
||||||
|
|
||||||
def handle_fan_rpm(entry):
|
def handle_fan_rpm(entry):
|
||||||
rpm = int(entry.get_text())
|
rpm = int(entry.get_value())
|
||||||
ec_commands.pwm.pwm_set_fan_rpm(app.cros_ec, rpm)
|
ec_commands.pwm.pwm_set_fan_rpm(app.cros_ec, rpm)
|
||||||
|
|
||||||
self.fan_set_rpm.connect(
|
self.fan_set_rpm.connect(
|
||||||
"notify::text", lambda entry, _: handle_fan_rpm(entry)
|
"notify::value", lambda entry, _: handle_fan_rpm(entry)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.fan_set_rpm.set_sensitive(False)
|
self.fan_set_rpm.set_sensitive(False)
|
||||||
else:
|
else:
|
||||||
self.fan_mode.set_sensitive(False)
|
self.fan_mode.set_sensitive(False)
|
||||||
|
|
||||||
# Temperature sensors
|
# Set points
|
||||||
while temp_child := self.temperatures.get_last_child():
|
if self.ec_set_points_supported and self.first_run:
|
||||||
self.temperatures.remove(temp_child)
|
def handle_set_point(entry, key):
|
||||||
self.temp_items.clear()
|
index = entry.ec_index
|
||||||
|
temp = int(entry.get_value())
|
||||||
|
# Don't allow an off temp higher than max temp and vice versa
|
||||||
|
match key:
|
||||||
|
case "temp_fan_off":
|
||||||
|
if temp > self.ec_set_points[index]["temp_fan_max"]:
|
||||||
|
entry.set_value(self.ec_set_points[index]["temp_fan_off"])
|
||||||
|
return
|
||||||
|
case "temp_fan_max":
|
||||||
|
if temp < self.ec_set_points[index]["temp_fan_off"]:
|
||||||
|
entry.set_value(self.ec_set_points[index]["temp_fan_max"])
|
||||||
|
return
|
||||||
|
self.ec_set_points[entry.ec_index][key] = temp
|
||||||
|
ec_commands.thermal.thermal_set_thresholds(
|
||||||
|
app.cros_ec, index,
|
||||||
|
self.ec_set_points[index]
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
for i, sensor in enumerate(ec_temp_sensors):
|
||||||
ec_temp_sensors = ec_commands.thermal.get_temp_sensors(app.cros_ec)
|
ec_set_point = ec_commands.thermal.thermal_get_thresholds(app.cros_ec, i)
|
||||||
except ec_exceptions.ECError as e:
|
self.ec_set_points.append(ec_set_point)
|
||||||
if e.ec_status == ec_exceptions.EcStatus.EC_RES_INVALID_COMMAND:
|
off_row = Adw.SpinRow(
|
||||||
# Generate some labels if the command is not supported
|
title=f"Fan On - {sensor}",
|
||||||
ec_temp_sensors = {}
|
subtitle=f"Turn fan on when above temp (°C)",
|
||||||
temps = ec_commands.memmap.get_temps(app.cros_ec)
|
)
|
||||||
for i, temp in enumerate(temps):
|
off_row.ec_index = i
|
||||||
ec_temp_sensors[f"Sensor {i}"] = (temp, None)
|
# 0K to 65535K for 16bit unsigned range
|
||||||
else:
|
# Actually the EC takes 32bits, but let's keep it like this for sanity
|
||||||
raise e
|
off_row.set_adjustment(Gtk.Adjustment(
|
||||||
|
lower=-273,
|
||||||
|
upper=65_262,
|
||||||
|
page_increment=10,
|
||||||
|
step_increment=1,
|
||||||
|
value=ec_set_point["temp_fan_off"],
|
||||||
|
))
|
||||||
|
off_row.connect(
|
||||||
|
"notify::value", lambda entry, _: handle_set_point(entry, "temp_fan_off")
|
||||||
|
)
|
||||||
|
max_row = Adw.SpinRow(
|
||||||
|
title=f"Fan Max - {sensor}",
|
||||||
|
subtitle=f"Max fan speed when above temp (°C)",
|
||||||
|
)
|
||||||
|
max_row.ec_index = i
|
||||||
|
max_row.set_adjustment(Gtk.Adjustment(
|
||||||
|
lower=-273,
|
||||||
|
upper=65_262,
|
||||||
|
page_increment=10,
|
||||||
|
step_increment=1,
|
||||||
|
value=ec_set_point["temp_fan_max"],
|
||||||
|
))
|
||||||
|
max_row.connect(
|
||||||
|
"notify::value", lambda entry, _: handle_set_point(entry, "temp_fan_max")
|
||||||
|
)
|
||||||
|
self.fan_set_points.add_row(off_row)
|
||||||
|
self.fan_set_points.add_row(max_row)
|
||||||
|
|
||||||
for key, value in ec_temp_sensors.items():
|
self.first_run = False
|
||||||
new_row = Adw.ActionRow(title=key, subtitle=f"{value[0]}°C")
|
|
||||||
new_row.add_css_class("property")
|
|
||||||
self.temperatures.append(new_row)
|
|
||||||
self.temp_items.append(new_row)
|
|
||||||
|
|
||||||
self._update_thermals(app)
|
|
||||||
|
|
||||||
# Schedule _update_thermals to run every second
|
# Schedule _update_thermals to run every second
|
||||||
GLib.timeout_add_seconds(1, self._update_thermals, app)
|
GLib.timeout_add_seconds(1, self._update_thermals, app)
|
||||||
@@ -130,7 +205,7 @@ class ThermalsPage(Gtk.Box):
|
|||||||
ec_temp_sensors = ec_commands.memmap.get_temps(app.cros_ec)
|
ec_temp_sensors = ec_commands.memmap.get_temps(app.cros_ec)
|
||||||
# The temp sensors disappear sometimes, so we need to handle that
|
# The temp sensors disappear sometimes, so we need to handle that
|
||||||
for i in range(min(len(self.temp_items), len(ec_temp_sensors))):
|
for i in range(min(len(self.temp_items), len(ec_temp_sensors))):
|
||||||
self.temp_items[i].set_subtitle(f"{ec_temp_sensors[i]}°C")
|
self.temp_items[i].set_subtitle(f"{ec_temp_sensors[i]}°C" if ec_temp_sensors[i] is not None else "Error")
|
||||||
|
|
||||||
# Check if this has already failed and skip if it has
|
# Check if this has already failed and skip if it has
|
||||||
if not ec_commands.pwm.EC_CMD_PWM_GET_FAN_TARGET_RPM in app.no_support:
|
if not ec_commands.pwm.EC_CMD_PWM_GET_FAN_TARGET_RPM in app.no_support:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<!-- Created with Cambalache 0.96.1 -->
|
<!-- Created with Cambalache 0.96.3 -->
|
||||||
<interface>
|
<interface>
|
||||||
<!-- interface-name battery-limiter.ui -->
|
<!-- interface-name battery-limiter.ui -->
|
||||||
<!-- interface-description The Battery page for YAFI -->
|
<!-- interface-description The Battery page for YAFI -->
|
||||||
@@ -56,6 +56,7 @@
|
|||||||
<property name="sensitive">False</property>
|
<property name="sensitive">False</property>
|
||||||
<property name="subtitle">Limit the minimum charge</property>
|
<property name="subtitle">Limit the minimum charge</property>
|
||||||
<property name="title">Discharge Limit</property>
|
<property name="title">Discharge Limit</property>
|
||||||
|
<property name="visible">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<child>
|
<child>
|
||||||
@@ -78,25 +79,6 @@
|
|||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="AdwActionRow" id="chg_limit_override">
|
|
||||||
<property name="sensitive">False</property>
|
|
||||||
<property name="subtitle">Disables the limiter for one charge</property>
|
|
||||||
<property name="title">Override Charge Limiter</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkBox">
|
|
||||||
<property name="halign">end</property>
|
|
||||||
<property name="homogeneous">True</property>
|
|
||||||
<property name="valign">center</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="chg_limit_override_btn">
|
|
||||||
<property name="label">Override</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="AdwPreferencesGroup" id="bat_ext_group">
|
<object class="AdwPreferencesGroup" id="bat_ext_group">
|
||||||
<property name="description">Preserve the battery lifespan by gradually lowering battery charge voltage automatically if the system is connected to AC for more than the set day limit.</property>
|
<property name="description">Preserve the battery lifespan by gradually lowering battery charge voltage automatically if the system is connected to AC for more than the set day limit.</property>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<!-- Created with Cambalache 0.96.1 -->
|
<!-- Created with Cambalache 0.96.1 -->
|
||||||
<interface>
|
<interface>
|
||||||
<!-- interface-name hardware.ui -->
|
<!-- interface-name hardware.ui -->
|
||||||
<!-- interface-description The Hardware page for YAFI -->
|
<!-- interface-description The Sensors page for YAFI -->
|
||||||
<!-- interface-copyright Steve-Tech -->
|
<!-- interface-copyright Steve-Tech -->
|
||||||
<requires lib="gtk" version="4.0"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<requires lib="libadwaita" version="1.0"/>
|
<requires lib="libadwaita" version="1.0"/>
|
||||||
@@ -15,7 +15,15 @@
|
|||||||
<child>
|
<child>
|
||||||
<object class="AdwActionRow">
|
<object class="AdwActionRow">
|
||||||
<property name="selectable">False</property>
|
<property name="selectable">False</property>
|
||||||
<property name="title">Hardware Status</property>
|
<property name="title">Sensors</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="AdwActionRow" id="hw_als">
|
||||||
|
<property name="title">Ambient Light Sensor</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="hw_als_label"/>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@@ -26,6 +34,30 @@
|
|||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="AdwActionRow" id="hw_fp_pwr">
|
||||||
|
<property name="title">Fingerprint</property>
|
||||||
|
<property name="visible">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
<property name="spacing">5</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="hw_fp_pwr_en">
|
||||||
|
<property name="label">Enable</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="hw_fp_pwr_dis">
|
||||||
|
<property name="label">Disable</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="AdwActionRow" id="hw_priv_cam">
|
<object class="AdwActionRow" id="hw_priv_cam">
|
||||||
<property name="subtitle">Use Privacy Switch</property>
|
<property name="subtitle">Use Privacy Switch</property>
|
||||||
@@ -65,23 +97,35 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="AdwActionRow" id="hw_fp_pwr">
|
<object class="AdwActionRow" id="hw_lid_open">
|
||||||
<property name="title">Fingerprint</property>
|
<property name="title">Lid Open</property>
|
||||||
<property name="visible">False</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="homogeneous">True</property>
|
<property name="homogeneous">True</property>
|
||||||
<property name="spacing">5</property>
|
|
||||||
<property name="valign">center</property>
|
<property name="valign">center</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="hw_fp_pwr_en">
|
<object class="GtkSwitch" id="hw_lid_open_sw">
|
||||||
<property name="label">Enable</property>
|
<property name="active">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="AdwActionRow" id="hw_pwr_btn">
|
||||||
|
<property name="title">Power Button Pressed</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="homogeneous">True</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="hw_fp_pwr_dis">
|
<object class="GtkSwitch" id="hw_pwr_btn_sw">
|
||||||
<property name="label">Disable</property>
|
<property name="active">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
|||||||
@@ -69,52 +69,6 @@
|
|||||||
<property name="selectable">False</property>
|
<property name="selectable">False</property>
|
||||||
<property name="subtitle">These options break normal functionality</property>
|
<property name="subtitle">These options break normal functionality</property>
|
||||||
<property name="title">Advanced Options</property>
|
<property name="title">Advanced Options</property>
|
||||||
<child>
|
|
||||||
<object class="AdwPreferencesGroup">
|
|
||||||
<property name="description">When using these options, the power LED may not turn off with the computer.</property>
|
|
||||||
<property name="margin-bottom">5</property>
|
|
||||||
<property name="margin-end">5</property>
|
|
||||||
<property name="margin-start">5</property>
|
|
||||||
<property name="margin-top">5</property>
|
|
||||||
<property name="title">Power Button LED</property>
|
|
||||||
<child>
|
|
||||||
<object class="AdwComboRow" id="led_pwr_colour">
|
|
||||||
<property name="model">
|
|
||||||
<object class="GtkStringList">
|
|
||||||
<items>
|
|
||||||
<item>Auto</item>
|
|
||||||
<item>Off</item>
|
|
||||||
</items>
|
|
||||||
</object>
|
|
||||||
</property>
|
|
||||||
<property name="title">Colour</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="AdwPreferencesGroup">
|
|
||||||
<property name="description">When using these options, the charging indicator will no longer indicate charging.</property>
|
|
||||||
<property name="margin-bottom">5</property>
|
|
||||||
<property name="margin-end">5</property>
|
|
||||||
<property name="margin-start">5</property>
|
|
||||||
<property name="margin-top">5</property>
|
|
||||||
<property name="title">Charging Indicators</property>
|
|
||||||
<child>
|
|
||||||
<object class="AdwComboRow" id="led_chg_colour">
|
|
||||||
<property name="model">
|
|
||||||
<object class="GtkStringList">
|
|
||||||
<items>
|
|
||||||
<item>Auto</item>
|
|
||||||
<item>Off</item>
|
|
||||||
</items>
|
|
||||||
</object>
|
|
||||||
</property>
|
|
||||||
<property name="title">Colour</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<!-- Created with Cambalache 0.96.1 -->
|
<!-- Created with Cambalache 0.96.3 -->
|
||||||
<interface>
|
<interface>
|
||||||
<!-- interface-name thermals.ui -->
|
<!-- interface-name thermals.ui -->
|
||||||
<!-- interface-description The Thermals page for YAFI -->
|
<!-- interface-description The Thermals page for YAFI -->
|
||||||
@@ -92,6 +92,12 @@
|
|||||||
<property name="visible">False</property>
|
<property name="visible">False</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="AdwExpanderRow" id="fan_set_points">
|
||||||
|
<property name="selectable">False</property>
|
||||||
|
<property name="title">Fan Set Points</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
<style>
|
<style>
|
||||||
<class name="boxed-list"/>
|
<class name="boxed-list"/>
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||||
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
|
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
|
||||||
<!-- Created with Cambalache 0.96.1 -->
|
<!-- Created with Cambalache 0.96.3 -->
|
||||||
<cambalache-project version="0.96.0" target_tk="gtk-4.0">
|
<cambalache-project version="0.96.0" target_tk="gtk-4.0">
|
||||||
<ui template-class="YafiWindow" filename="yafi.ui" sha256="9d1b2f030e4a816eb0b1aa53ae1d80c5b50a2f4646e32c7a64803eb6f6ed3947"/>
|
<ui template-class="YafiWindow" filename="yafi.ui" sha256="9d1b2f030e4a816eb0b1aa53ae1d80c5b50a2f4646e32c7a64803eb6f6ed3947"/>
|
||||||
<ui template-class="ThermalsPage" filename="thermals.ui" sha256="e301e65649005315ff60d250b60a47f6250ad6feb27db104051fcf0143cde173"/>
|
<ui template-class="ThermalsPage" filename="thermals.ui" sha256="89f5b68da04abad587d8b949d18357cd956313680e663b10e5d42697f9bfbf6e"/>
|
||||||
<ui template-class="LedsPage" filename="leds.ui" sha256="0350d22d570de039d63602ba40925f17fff6680fd5909d2ebf19600f351eb0f2"/>
|
<ui template-class="LedsPage" filename="leds.ui" sha256="abc3ee759974a5c92feb48cc258dbe7271d0402facf71fd5e779f2bb1a277e16"/>
|
||||||
<ui template-class="BatteryLimiterPage" filename="battery-limiter.ui" sha256="656384cbc7dbfc0f2fd85b3f8c2d5e35066ec3368c5f464c31c8b82c5da334de"/>
|
<ui template-class="BatteryLimiterPage" filename="battery-limiter.ui" sha256="3a50b0dea08b9acbaa389d7d7a38bd94970fdc79207ef10638f722f52d9425cd"/>
|
||||||
<ui template-class="HardwarePage" filename="hardware.ui" sha256="f4deec4e38e683fde97656802dbfb2a638ab46a0e36af5c9a37f277f49e2aabb"/>
|
<ui template-class="HardwarePage" filename="hardware.ui" sha256="37ea282198d9f60435f80e4adf8256cd2249e590dcad4b63af634d828673f1bf"/>
|
||||||
<ui template-class="BatteryPage" filename="battery.ui" sha256="d495280cb543a26cdee1c2939e5af980d8d3878c326e360eeab4f05195cdbdc9"/>
|
<ui template-class="BatteryPage" filename="battery.ui" sha256="d495280cb543a26cdee1c2939e5af980d8d3878c326e360eeab4f05195cdbdc9"/>
|
||||||
</cambalache-project>
|
</cambalache-project>
|
||||||
|
|||||||
@@ -18,8 +18,7 @@
|
|||||||
#
|
#
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
from gi.repository import Adw
|
from gi.repository import Gtk, Adw
|
||||||
from gi.repository import Gtk
|
|
||||||
|
|
||||||
@Gtk.Template(resource_path='/au/stevetech/yafi/ui/yafi.ui')
|
@Gtk.Template(resource_path='/au/stevetech/yafi/ui/yafi.ui')
|
||||||
class YafiWindow(Adw.ApplicationWindow):
|
class YafiWindow(Adw.ApplicationWindow):
|
||||||
|
|||||||