Replace the custom GJS/GTK4 @agi/gtk3 setup with AGS v3 on GTK3 using Astal services (Hyprland, Brightness). Updates README installation instructions, package scripts, and rewrites main.js to use AGS JSX widgets and reactive state bindings. Adds a minimal package-lock.json.
6.8 KiB
PineNote Shell Widget
A fullscreen GTK widget designed for Pine64 PineNote running Arch Linux with Hyprland, controllable via hyprgrass gestures.
Overview
This Astal-based GTK application provides:
- Screen rotation (portrait/landscape)
- Display brightness control (100%, 75%, 25%, 0% steps)
- Power operations (suspend, shutdown, reboot)
- Quick launch shortcuts for terminal, browser, and e-reader
- Display refresh functionality
- Audio waveform switching
Requirements
- OS: Arch Linux with Hyprland
- Desktop Environment: AGS (Aylur's GTK Shell) v3 / Astal
- Dependencies: GJS, GTK 3, Astal (
libastal-*-git),ags, hyprgrass - Display: Pine64 PineNote (or any compatible monitor)
Installation
Prerequisites
Astal and AGS are not distributed via npm. Install the system packages from the AUR:
# Install AGS and Astal core libraries (GTK3 + GJS bindings)
yay -S ags libastal-meta libastal-gjs-git libastal-hyprland-git libastal-brightness-git
# Base GTK/Layer-Shell support
sudo pacman -S gjs gtk3 gtk-layer-shell
Clone and Setup
cd ~/projects/pineNoteShell
# Project already set up in pinenote-shell/
# No npm dependencies are required
cd pinenote-shell
# Make widget executable
chmod +x ./src/main.js
Note:
npm installis not needed for this project. The previouspackage.jsonreferenced a package (@agi/gtk3) that does not exist on the npm registry.
Running
The entry point uses an ags run shebang, so you can start it directly:
./src/main.js
Or use the ags CLI explicitly:
ags run ./src/main.js
You can toggle the window from another terminal:
ags toggle pinenote-fullscreen -i pinenote-shell
Hyprland Configuration
Add the following to your ~/.config/hypr/hyprgrass.conf:
Note: AGS v3 uses
ags toggle/ags requestinstead of the old--js-evaluateflag.
[gesture:toggle_widget]
hotkeys = [Mod1, T]
shorthand = "pinch open"
actions = [
{
command = "exec ags toggle pinenote-fullscreen -i pinenote-shell",
timeout = 300,
target = "window:pinenote-fullscreen"
}
]
[gesture:brightness_up]
hotkeys = [Mod1, B]
shorthand = "swipe up"
actions = [
{
command = "exec ags request 'brightness 100' -i pinenote-shell",
timeout = 300,
target = "window:pinenote-fullscreen"
}
]
[gesture:brightness_down]
hotkeys = [Mod1, V]
shorthand = "swipe down"
actions = [
{
command = "exec ags request 'brightness 0' -i pinenote-shell",
timeout = 300,
target = "window:pinenote-fullscreen"
}
]
If you want the brightness requests to actually work, add a requestHandler to app.start in src/main.js, for example:
app.start({
instanceName: "pinenote-shell",
css: readFile(cssPath),
requestHandler(argv, response) {
if (argv[0] === "brightness") {
const level = parseInt(argv[1], 10)
brightness.set(level)
response(`brightness set to ${level}`)
}
response("unknown command")
},
main() {
PinenoteShell()
},
})
(You'll need to lift the brightness manager out of the component scope for this.)
Additional Gestures
Add more gestures for other controls:
[gesture:rotate_landscape]
hotkeys = [Mod1, R]
shorthand = "swipe left"
actions = [
{
command = "exec ags request 'rotate landscape' -i pinenote-shell",
timeout = 300,
target = "window:pinenote-fullscreen"
}
]
[gesture:launch_terminal]
hotkeys = [Mod1, T]
shorthand = "double tap left"
actions = [
{
command = "exec ags request 'launch terminal' -i pinenote-shell",
timeout = 300,
target = "window:pinenote-fullscreen"
}
]
Usage
Basic Controls
- Open/Close: Activate with hyprgrass gesture (see configuration)
- Screen Rotation: Tap landscape/portrait icons to rotate display
- Brightness: Click brightness level buttons or use gestures in config
- System Actions: Use suspend/shutdown buttons for power operations
- Launch Apps: Click terminal, browser, or e-reader shortcuts
Advanced Features
- Waveform Switching: Use the waveform control to switch between audio output modes
- Display Refresh: Force display refresh with the refresh button
- Status Display: Monitor rotation and brightness levels in footer
Configuration
Custom Applications
Edit src/main.js and modify the LauncherManager.launch() method:
const launchers = {
terminal: "alacritty", // Your preferred terminal
browser: "brave-browser", // Or chromium/firefox/edge
"e-reader": "calibre", // Your e-reader application
};
Hyprland Integration
The widget uses hyprctl and the AstalHyprland library to communicate with Hyprland:
- Screen rotation: Monitors the focused monitor's
transformproperty - Display refresh: Uses
pdlc-cli --refreshfor PineNote e-ink refresh - Brightness: Uses
AstalBrightness(/sys/class/backlight/)
Styling
The widget uses CSS styling loaded from $HOME/.config/ags/style.css. The style.css file in this directory is the source of truth; copy or symlink it there before running:
mkdir -p ~/.config/ags
cp ./style.css ~/.config/ags/style.css
Common customization options:
background-color: Change widget backgroundborder-radius,margin: Adjust widget borders and spacing- Icon sets: Use different icon themes for better visual consistency
Troubleshooting
Widget Won't Appear
- Check Astal/AGS installation: Ensure
ags,gjs, and the Astal libraries are installed correctly - Verify CSS path: Make sure
~/.config/ags/style.cssexists; otherwise the app will crash on start - Verify hyprgrass config: Make sure your gesture bindings are correct
- Debug output: Run with
ags run ./src/main.jsin a terminal to see console errors
Controls Not Working
- Permission issues: Some operations may require appropriate permissions
- Missing applications: Ensure your preferred terminal/browser exist
- Hyprland compatibility: Test basic
hyprctlcommands manually first
Performance Issues
- The widget is designed to be lightweight and efficient
- For best performance on PineNote, consider reducing animation frequency
- Monitor system resources with
htopor similar tools
Future Enhancements
Potential features for future development:
- Multi-monitor support
- Advanced brightness curves (not just discrete steps)
- Custom app launcher configuration
- Audio waveform visualization
- System monitoring widgets
- Integration with PineNote-specific settings
License
This project is provided as-is for your PineNote setup. Use responsibly and test changes before deploying to production hardware.