851aad6452
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.
266 lines
8.0 KiB
Markdown
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. |