final changes
This commit is contained in:
1 parent
42bca37ed8
commit
2028a9aaa7
8 files changed
+24
-91
No files matched your search
@@ -7,7 +7,6 @@
|
|||||||
!/Cargo.lock
|
!/Cargo.lock
|
||||||
!/nix/
|
!/nix/
|
||||||
!/src/
|
!/src/
|
||||||
!/docs/
|
|
||||||
!/assets/
|
!/assets/
|
||||||
!/noctalia-plugin/
|
!/noctalia-plugin/
|
||||||
!/README.md
|
!/README.md
|
||||||
+13
-4
@@ -2,7 +2,7 @@
|
|||||||
name = "valw"
|
name = "valw"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
description = "macOS-style screenshots for niri"
|
description = "desktop helper"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -10,7 +10,11 @@ ab_glyph = "0.2.32"
|
|||||||
anyhow = "1.0.104"
|
anyhow = "1.0.104"
|
||||||
chrono = "0.4.45"
|
chrono = "0.4.45"
|
||||||
clap = { version = "4.6.7", features = ["derive"] }
|
clap = { version = "4.6.7", features = ["derive"] }
|
||||||
eframe = { version = "0.36.2", default-features = false, features = ["default_fonts", "glow", "wayland"] }
|
eframe = { version = "0.36.2", default-features = false, features = [
|
||||||
|
"default_fonts",
|
||||||
|
"glow",
|
||||||
|
"wayland",
|
||||||
|
] }
|
||||||
glow = "0.18.0"
|
glow = "0.18.0"
|
||||||
image = { version = "0.25.10", default-features = false, features = ["png"] }
|
image = { version = "0.25.10", default-features = false, features = ["png"] }
|
||||||
khronos-egl = { version = "6.0.0", features = ["dynamic"] }
|
khronos-egl = { version = "6.0.0", features = ["dynamic"] }
|
||||||
@@ -18,7 +22,13 @@ libc = "0.2.189"
|
|||||||
libloading = "0.8"
|
libloading = "0.8"
|
||||||
resvg = "0.48.1"
|
resvg = "0.48.1"
|
||||||
niri-ipc = "=26.4.0"
|
niri-ipc = "=26.4.0"
|
||||||
rustix = { version = "1.1.5", features = ["event", "fs", "pipe", "process", "stdio"] }
|
rustix = { version = "1.1.5", features = [
|
||||||
|
"event",
|
||||||
|
"fs",
|
||||||
|
"pipe",
|
||||||
|
"process",
|
||||||
|
"stdio",
|
||||||
|
] }
|
||||||
serde = { version = "1.0.229", features = ["derive"] }
|
serde = { version = "1.0.229", features = ["derive"] }
|
||||||
serde_ignored = "0.1.14"
|
serde_ignored = "0.1.14"
|
||||||
serde_json = "1.0.151"
|
serde_json = "1.0.151"
|
||||||
@@ -37,6 +47,5 @@ wl-clipboard-rs = "0.9.4"
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3.27.0"
|
tempfile = "3.27.0"
|
||||||
|
|
||||||
# Image encoding is painfully slow unoptimised; keep dev builds usable.
|
|
||||||
[profile.dev.package."*"]
|
[profile.dev.package."*"]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
@@ -1,19 +1,16 @@
|
|||||||
# valw
|
# valw
|
||||||
|
|
||||||
macOS-style screenshots for [niri](https://github.com/YaLTeR/niri) on
|
valw is desktop helper for 3N' [nixos] (https://nixos.org/) [niri](https://github.com/YaLTeR/niri) [noctalia](https://github.com/noctalia-dev/noctalia)
|
||||||
Wayland: the whole screen, a region, a window, a zoomable freeze-frame, a
|
|
||||||
Cmd+Shift+5-style toolbar, a floating preview you can drag into other apps,
|
|
||||||
and a built-in markup editor. Written in Rust, packaged with Nix.
|
|
||||||
|
|
||||||
## Install
|
## installation
|
||||||
|
|
||||||
Run it once:
|
run first:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
nix run git+https://git.userevolt.app/elars/valw -- doctor
|
nix run git+https://git.userevolt.app/elars/valw -- doctor
|
||||||
```
|
```
|
||||||
|
|
||||||
As a package from the flake (`packages.<system>.default`), or with the
|
use as package from the flake (`packages.<system>.default`), or with the
|
||||||
home-manager module:
|
home-manager module:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
@@ -35,13 +32,7 @@ inputs.valw.url = "git+https://git.userevolt.app/elars/valw";
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
## binding on niri
|
||||||
`settings` becomes `~/.config/valw/config.toml`. valw checks it while the
|
|
||||||
configuration is built, so a typo or a bad value fails the rebuild instead
|
|
||||||
of surprising you later. The toolbar's remembered choices live in
|
|
||||||
`~/.local/state/valw/toolbar.toml` and stay writable.
|
|
||||||
|
|
||||||
## Bind it in niri
|
|
||||||
|
|
||||||
```kdl
|
```kdl
|
||||||
binds {
|
binds {
|
||||||
@@ -53,7 +44,7 @@ binds {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Commands
|
## commands
|
||||||
|
|
||||||
| Command | What it does |
|
| Command | What it does |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -69,45 +60,8 @@ binds {
|
|||||||
Capture commands take `--clipboard-only`, `-o PATH` (`-` for stdout),
|
Capture commands take `--clipboard-only`, `-o PATH` (`-` for stdout),
|
||||||
`--delay SECS`, `--cursor` and `--no-preview`.
|
`--delay SECS`, `--cursor` and `--no-preview`.
|
||||||
|
|
||||||
## The overview backdrop
|
|
||||||
|
|
||||||
`valw backdrop` draws a slow liquid-paint background, coloured from the
|
## configuration
|
||||||
wallpaper (via Noctalia, if it runs), behind niri's overview. It only draws
|
|
||||||
while the overview shows it. Start it with niri and place it in the
|
|
||||||
backdrop:
|
|
||||||
|
|
||||||
```kdl
|
|
||||||
spawn-at-startup "valw" "backdrop"
|
|
||||||
|
|
||||||
layer-rule {
|
|
||||||
match namespace="^valw-backdrop$"
|
|
||||||
place-within-backdrop true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
With Noctalia, turn its own backdrop off (`[backdrop] enabled = false`).
|
|
||||||
Colours elsewhere (the region dim, the window picker's fallback) follow
|
|
||||||
Noctalia's current community palette when there is one.
|
|
||||||
|
|
||||||
## Noctalia
|
|
||||||
|
|
||||||
With [Noctalia](https://noctalia.dev), valw comes as a plugin: a camera
|
|
||||||
button on the bar (left click: the toolbar, right click: a region shot),
|
|
||||||
the toolbar as a Noctalia panel and a control-center tile. Noctalia draws
|
|
||||||
them, so they follow your Noctalia theme.
|
|
||||||
|
|
||||||
```nix
|
|
||||||
programs.valw.noctalia.enable = true;
|
|
||||||
```
|
|
||||||
|
|
||||||
Then enable `elars/valw` in Noctalia, add a widget of type `elars/valw:bar`
|
|
||||||
to a bar, and bind the toolbar:
|
|
||||||
|
|
||||||
```kdl
|
|
||||||
Mod+Shift+T { spawn "noctalia" "msg" "panel-toggle" "elars/valw:toolbar"; }
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
Every key is optional; these are the defaults.
|
Every key is optional; these are the defaults.
|
||||||
|
|
||||||
@@ -130,7 +84,7 @@ scroll_step = 1.15
|
|||||||
flashlight_radius = 180
|
flashlight_radius = 180
|
||||||
|
|
||||||
[editor]
|
[editor]
|
||||||
backend = "builtin" # or "satty", or "noctalia" (its annotator)
|
backend = "builtin" # or "satty","noctalia" choose which one is for you.
|
||||||
|
|
||||||
[sound]
|
[sound]
|
||||||
enabled = true
|
enabled = true
|
||||||
@@ -138,4 +92,4 @@ volume = 0.9
|
|||||||
combo_reset_secs = 5
|
combo_reset_secs = 5
|
||||||
```
|
```
|
||||||
|
|
||||||
Logs are in `~/.local/state/valw/logs/`.
|
logs are in `~/.local/state/valw/logs/`.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
description = "valw, macOS-style screenshots for niri";
|
description = "valw desktop helper";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
|
|||||||
@@ -9,9 +9,6 @@
|
|||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
valw = self'.packages.default;
|
valw = self'.packages.default;
|
||||||
|
|
||||||
# The home-manager module, evaluated with stand-ins for the two
|
|
||||||
# home-manager options it sets (no home-manager input needed).
|
|
||||||
homeModule =
|
homeModule =
|
||||||
valwConfig:
|
valwConfig:
|
||||||
(lib.evalModules {
|
(lib.evalModules {
|
||||||
@@ -44,7 +41,6 @@
|
|||||||
];
|
];
|
||||||
}).config;
|
}).config;
|
||||||
|
|
||||||
# Reuses the package's vendored dependencies, runs `cmd` instead of the build.
|
|
||||||
cargoCheck =
|
cargoCheck =
|
||||||
name: tools: cmd:
|
name: tools: cmd:
|
||||||
valw.overrideAttrs (old: {
|
valw.overrideAttrs (old: {
|
||||||
@@ -52,7 +48,6 @@
|
|||||||
nativeBuildInputs = old.nativeBuildInputs ++ tools;
|
nativeBuildInputs = old.nativeBuildInputs ++ tools;
|
||||||
buildPhase = cmd;
|
buildPhase = cmd;
|
||||||
installPhase = "touch $out";
|
installPhase = "touch $out";
|
||||||
# The package patches its binary's RUNPATH; a check has no binary.
|
|
||||||
postFixup = "";
|
postFixup = "";
|
||||||
});
|
});
|
||||||
in
|
in
|
||||||
@@ -100,9 +95,6 @@
|
|||||||
}/testBuildFailure.log
|
}/testBuildFailure.log
|
||||||
touch $out
|
touch $out
|
||||||
'';
|
'';
|
||||||
# The plugin as packaged: manifest, every entry present, Luau that
|
|
||||||
# compiles, translations that parse; and its logic against stubbed
|
|
||||||
# Noctalia globals.
|
|
||||||
noctalia-plugin =
|
noctalia-plugin =
|
||||||
pkgs.runCommand "valw-noctalia-plugin"
|
pkgs.runCommand "valw-noctalia-plugin"
|
||||||
{
|
{
|
||||||
@@ -135,8 +127,6 @@
|
|||||||
touch $out
|
touch $out
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Runs the real screencopy path against a headless sway. This is
|
|
||||||
# wlroots, not niri, but it catches capture and format bugs on every build.
|
|
||||||
headless =
|
headless =
|
||||||
pkgs.runCommand "valw-headless"
|
pkgs.runCommand "valw-headless"
|
||||||
{
|
{
|
||||||
@@ -168,15 +158,10 @@
|
|||||||
valw doctor | tee doctor.txt
|
valw doctor | tee doctor.txt
|
||||||
! grep -q '^fail' doctor.txt
|
! grep -q '^fail' doctor.txt
|
||||||
|
|
||||||
# Through a pipe: the clipboard child must not keep it open.
|
|
||||||
# The timeout covers the reader too; the child is in its own
|
|
||||||
# session, so bounding valw alone would not catch a leak.
|
|
||||||
timeout 10 sh -c 'valw screen -o - | cat > shot.png'
|
timeout 10 sh -c 'valw screen -o - | cat > shot.png'
|
||||||
file shot.png | tee file.txt
|
file shot.png | tee file.txt
|
||||||
grep -q 'PNG image data, 1280 x 720' file.txt
|
grep -q 'PNG image data, 1280 x 720' file.txt
|
||||||
|
|
||||||
# Preview. The background is solid black, so a thumbnail in the
|
|
||||||
# bottom-right corner shows up as more than one colour there.
|
|
||||||
mkdir -p $HOME/.config/valw
|
mkdir -p $HOME/.config/valw
|
||||||
printf '[preview]\ntimeout_secs = 2\n' > $HOME/.config/valw/config.toml
|
printf '[preview]\ntimeout_secs = 2\n' > $HOME/.config/valw/config.toml
|
||||||
socket=$XDG_RUNTIME_DIR/valw.sock
|
socket=$XDG_RUNTIME_DIR/valw.sock
|
||||||
|
|||||||
@@ -16,21 +16,17 @@
|
|||||||
clippy
|
clippy
|
||||||
rust-analyzer
|
rust-analyzer
|
||||||
rustfmt
|
rustfmt
|
||||||
# Manual verification: grim is the pixel oracle, magick compares.
|
|
||||||
grim
|
grim
|
||||||
imagemagick
|
imagemagick
|
||||||
wayland-utils
|
wayland-utils
|
||||||
];
|
];
|
||||||
|
|
||||||
# What the package gets through its RUNPATH, for `cargo run`.
|
|
||||||
LD_LIBRARY_PATH = lib.makeLibraryPath [
|
LD_LIBRARY_PATH = lib.makeLibraryPath [
|
||||||
pkgs.wayland
|
pkgs.wayland
|
||||||
pkgs.libxkbcommon
|
pkgs.libxkbcommon
|
||||||
pkgs.libglvnd
|
pkgs.libglvnd
|
||||||
];
|
];
|
||||||
|
|
||||||
# The repo is a path: flake, so Nix copies the whole tree on every
|
|
||||||
# evaluation. Keep the multi-gigabyte target dir out of it.
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
export CARGO_TARGET_DIR="''${XDG_CACHE_HOME:-$HOME/.cache}/valw/target"
|
export CARGO_TARGET_DIR="''${XDG_CACHE_HOME:-$HOME/.cache}/valw/target"
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
let
|
let
|
||||||
cfg = config.programs.valw;
|
cfg = config.programs.valw;
|
||||||
toml = pkgs.formats.toml { };
|
toml = pkgs.formats.toml { };
|
||||||
# valw checks its own config: a typo or a bad value fails the build.
|
|
||||||
checked =
|
checked =
|
||||||
settings:
|
settings:
|
||||||
let
|
let
|
||||||
|
|||||||
+1
-10
@@ -14,9 +14,7 @@
|
|||||||
!(builtins.elem (baseNameOf path) [
|
!(builtins.elem (baseNameOf path) [
|
||||||
".direnv"
|
".direnv"
|
||||||
".jj"
|
".jj"
|
||||||
# Plan ledgers and review notes; not part of the build.
|
|
||||||
".superpowers"
|
".superpowers"
|
||||||
# Documentation: a doc change shouldn't rebuild the binary.
|
|
||||||
"docs"
|
"docs"
|
||||||
"README.md"
|
"README.md"
|
||||||
"result"
|
"result"
|
||||||
@@ -35,11 +33,7 @@
|
|||||||
pkgs.wayland
|
pkgs.wayland
|
||||||
];
|
];
|
||||||
|
|
||||||
# Tests run through `nix flake check` instead.
|
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
|
|
||||||
# Clicking a preview opens Satty if configured. --suffix keeps a user's own Satty first.
|
|
||||||
# The editor embeds DejaVu Sans Bold; its licence wants the notice shipped.
|
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
wrapProgram $out/bin/valw --suffix PATH : ${
|
wrapProgram $out/bin/valw --suffix PATH : ${
|
||||||
lib.makeBinPath [
|
lib.makeBinPath [
|
||||||
@@ -48,14 +42,11 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
install -Dm644 assets/fonts/LICENSE-DejaVu $out/share/licenses/valw/LICENSE-DejaVu
|
install -Dm644 assets/fonts/LICENSE-DejaVu $out/share/licenses/valw/LICENSE-DejaVu
|
||||||
# The Noctalia plugin (programs.valw.noctalia), without its tests.
|
|
||||||
mkdir -p $out/share/valw
|
mkdir -p $out/share/valw
|
||||||
cp -r noctalia-plugin $out/share/valw/noctalia-plugin
|
cp -r noctalia-plugin $out/share/valw/noctalia-plugin
|
||||||
rm -r $out/share/valw/noctalia-plugin/tests
|
rm -r $out/share/valw/noctalia-plugin/tests
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# dlopen()ed at run time: libwayland (winit, valw), libxkbcommon (winit),
|
|
||||||
# libEGL (zoom, editor; Mesa's drivers come from the system).
|
|
||||||
postFixup = ''
|
postFixup = ''
|
||||||
patchelf --add-rpath ${
|
patchelf --add-rpath ${
|
||||||
lib.makeLibraryPath [
|
lib.makeLibraryPath [
|
||||||
@@ -67,7 +58,7 @@
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
description = "macOS-style screenshots for niri";
|
description = "desktop helper";
|
||||||
mainProgram = "valw";
|
mainProgram = "valw";
|
||||||
platforms = lib.platforms.linux;
|
platforms = lib.platforms.linux;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in new issue
Block a user