05b18bdade
- Add `einkRefresh()` helper calling `pdlc-cli --refresh` after rotation, brightness changes, waveform changes, and when the widget opens - Disable CSS transitions and animations globally to reduce ghosting - Remove button hover transform and transition effects - Update README with e-ink-specific guidance and tuning notes
256 lines
7.3 KiB
Markdown
256 lines
7.3 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
|
|
|
|
Add the following to your `~/.config/hypr/hyprgrass.conf`:
|
|
|
|
> **Note:** AGS v3 uses `ags toggle` / `ags request` instead of the old `--js-evaluate` flag.
|
|
|
|
```ini
|
|
[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:
|
|
|
|
```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
|
|
|
|
Add more gestures for other controls:
|
|
|
|
```ini
|
|
[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:
|
|
|
|
```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 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
|
|
|
|
### 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. |