Files
pineNoteShell/pinenote-shell/README.md
T
fegger 851aad6452 Update Hyprland gesture examples to Lua syntax in README
The documentation previously showed the legacy `hyprland.conf` INI format. Since users now configure Hyprgrass via
Hyprland's Lua config, rewrite all gesture examples as Lua and update the troubleshooting note accordingly.
2026-07-13 13:54:11 +02:00

266 lines
8.0 KiB
Markdown

# 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:
```bash
# 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
```bash
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:
```bash
./src/main.js
```
Or use the `ags` CLI explicitly:
```bash
ags run ./src/main.js
```
You can toggle the window from another terminal:
```bash
ags toggle pinenote-fullscreen -i pinenote-shell
```
### Hyprland Configuration (Lua)
The examples below use **Hyprland's Lua configuration format**. If you use the classic `hyprland.conf` syntax, translate the tables/keys accordingly.
Add the gesture bindings to your Hyprland Lua config (often `~/.config/hypr/hyprland.lua` or wherever your `hyprland.conf` sources):
> **Note:** AGS v3 uses `ags toggle` / `ags request` instead of the old `--js-evaluate` flag.
```lua
-- Load hyprgrass helpers if needed; adjust to your setup
local hyprgrass = require("hyprgrass") -- or however you import it
hyprgrass.gesture("toggle_widget", {
hotkeys = { "MOD1", "T" }, -- Mod1+T
shorthand = "pinch open",
actions = {
{
command = "ags toggle pinenote-fullscreen -i pinenote-shell",
timeout = 300,
target = "window:pinenote-fullscreen",
},
},
})
hyprgrass.gesture("brightness_up", {
hotkeys = { "MOD1", "B" },
shorthand = "swipe up",
actions = {
{
command = "ags request 'brightness 100' -i pinenote-shell",
timeout = 300,
target = "window:pinenote-fullscreen",
},
},
})
hyprgrass.gesture("brightness_down", {
hotkeys = { "MOD1", "V" },
shorthand = "swipe down",
actions = {
{
command = "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:
```js
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 (Lua)
Add more gestures for other controls:
```lua
hyprgrass.gesture("rotate_landscape", {
hotkeys = { "MOD1", "R" },
shorthand = "swipe left",
actions = {
{
command = "ags request 'rotate landscape' -i pinenote-shell",
timeout = 300,
target = "window:pinenote-fullscreen",
},
},
})
hyprgrass.gesture("launch_terminal", {
hotkeys = { "MOD1", "T" },
shorthand = "double tap left",
actions = {
{
command = "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:
```javascript
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:
```bash
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 Lua config**: Make sure your gesture bindings are correct and the Lua file is sourced by Hyprland
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
### E-ink / PineNote-specific Tweaks
The code and CSS are already tuned for e-ink:
- **No CSS transitions or animations** in `style.css` to avoid ghosting.
- **E-ink refreshes are triggered automatically** after rotation, brightness changes, waveform changes, and when the widget opens.
- If you still see ghosting, increase the refresh frequency or add `einkRefresh()` after other interactive actions in `src/main.js`.
### Performance Issues
- The widget is designed to be lightweight and efficient
- For best performance on PineNote, avoid animations and continuous polling
- E-ink displays update slowly; the app uses GObject signals instead of polling wherever possible
- 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.