Files
pineNoteShell/pinenote-shell/README.md
T
fegger 4938bb472b Migrate pinenote-shell to AGS v3/Astal framework
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.
2026-07-13 13:31:57 +02:00

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 install is not needed for this project. The previous package.json referenced 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 request instead of the old --js-evaluate flag.

[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

  1. Open/Close: Activate with hyprgrass gesture (see configuration)
  2. Screen Rotation: Tap landscape/portrait icons to rotate display
  3. Brightness: Click brightness level buttons or use gestures in config
  4. System Actions: Use suspend/shutdown buttons for power operations
  5. 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 transform property
  • Display refresh: Uses pdlc-cli --refresh for 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 background
  • border-radius, margin: Adjust widget borders and spacing
  • Icon sets: Use different icon themes for better visual consistency

Troubleshooting

Widget Won't Appear

  1. Check Astal/AGS installation: Ensure ags, gjs, and the Astal libraries are installed correctly
  2. Verify CSS path: Make sure ~/.config/ags/style.css exists; otherwise the app will crash on start
  3. Verify hyprgrass config: Make sure your gesture bindings are correct
  4. Debug output: Run with ags run ./src/main.js in a terminal to see console errors

Controls Not Working

  1. Permission issues: Some operations may require appropriate permissions
  2. Missing applications: Ensure your preferred terminal/browser exist
  3. Hyprland compatibility: Test basic hyprctl commands 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 htop or 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.