`cargo release patch --execute` now does what the last three releases
did by hand: bump Cargo.toml/Cargo.lock, rewrite PKGBUILD's pkgver,
stamp the "## Unreleased" changelog section with version and date,
commit as "release X.Y.Z", tag vX.Y.Z and push commit and tag to the
gitea remote (not `origin`, which is the GitHub upstream). The tag then
triggers .gitea/workflows/release.yml as before. No crates.io publish.
CHANGELOG.md gets a standing "## Unreleased" section to collect entries
between releases; README documents the flow.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A config carrying a !backlight widget on a machine with nothing under
/sys/class/backlight (a laptop config on a desktop) hit
expect("did not find backlight device") in Backlight::new, which with
panic = "abort" killed wldash before a window appeared.
The device path is now Option<PathBuf>. A missing device, or a
configured `device` name that does not exist, prints one line on stderr
and leaves the widget in place so layout indices stay aligned: it
renders empty, skips sysfs reads and writes, and ignores clicks.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A config generated on one machine pinned
/usr/share/fonts/google-noto/NotoSans-Regular.ttf; on another host the
same package installs under fonts/noto, so the shared config made the
fontloader thread panic ("Font file not found") and, with panic =
"abort", kill wldash before a window appeared.
resolve_font_path() now uses a pinned path only if the file exists,
otherwise asks fontconfig for the name (what fc-match does) and says so
on stderr. find_font() and FontLoader::from_path() return errors
instead of unwrapping, and an unresolvable font exits with one clear
line. Generated configs leave font_paths unset so names resolve per
machine; pinning remains possible by hand.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The desktop-entry cache lived in $XDG_CACHE_HOME/wldash/desktop.json.
On an NFS-shared home that is a remote read and write on every start
(unless the session happens to export a machine-local XDG_CACHE_HOME),
and it went stale whenever a package was installed until someone ran
--desktop-refresh. Scanning the applications directories takes a few
milliseconds over local /usr/share and already happened on a background
thread, so the cache bought nothing: drop it, along with simd-json and
the serde derives on Desktop. --desktop-refresh stays as a no-op so old
key bindings keep working.
Calculator history and the prompt saved on Escape are state, not cache:
they move to $XDG_STATE_HOME/wldash (~/.local/state), written only on
Enter/Escape, and the old cache location is still read as a fallback.
With the serde derives gone, two Desktop fields were unused; use them:
Type=Link entries now open their URL with xdg-open, and Terminal=true
entries run under $TERMINAL -e when it is set.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Same shape as uhhm/gdo: a v* tag runs makepkg on the x86_64 (ergo,
"bare") and aarch64 (klokka) runners, uploads to the [uhhm] Arch
registry under namespace bl, and creates a release with the changelog
section as notes. The tag must agree with PKGBUILD's pkgver and
Cargo.toml's version. Without a REGISTRY_TOKEN secret the publish step
warns and skips so the build is still verified.
Version jumps to 0.4.0 because upstream already tagged v0.2.1 and
v0.3.0 on this history before the rewrite reset Cargo.toml to 0.2.0.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Mostly `cargo clippy --fix`: needless borrows, redundant field names,
match -> if let, io::Error::other, Option::filter/map, let chains, c""
literals. By hand: drop unused impl lifetimes, a type alias for the
font preload map, Iterator::find in next_buffer, contains_key, and
allow new_ret_no_self where constructors intentionally return the
boxed/generic wrapper type.
No functional change; tests and release build unchanged.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Missing/invalid config, unwritable config target, failed Wayland connect
and bad arguments now print one line to stderr and exit 1 rather than
panicking with "uh" or a serde backtrace.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- wl_keyboard.repeat_info with rate 0 means "no repeat"; we divided by it.
- an unknown keymap format hit unreachable!() instead of being ignored.
- raw keycode 1 (Escape) returned before widgets were dispatched, so the
launcher's Escape handler (which saves the prompt for Ctrl+R) never ran.
Dispatch first, then fall back to quitting.
- always lay out on the first layer-surface configure, even when the
compositor hands us exactly the placeholder dimensions.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The bounding-box height was computed from other.height + other.height
instead of other.height + other.y, so the combined damage rectangle sent
to the compositor was wrong whenever a widget's drawn area changed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
memmap 0.7 is unmaintained (RUSTSEC-2020-0077); memmap2 is a drop-in
replacement. Drop the unused shlex dependency.
Each resize created a new wl_shm_pool that was never destroyed; keep the
pool on the buffer and destroy it with it. A wl_buffer.release for a
buffer we didn't consider acquired used to underflow refcnt and wedge
rendering. Fix the lifetime-elision warnings while here.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The release profile builds with panic = "abort", so a panic in any helper
thread took the whole dashboard down:
- backlight: WalkDir yields /sys/class/backlight itself, so detect() was
always true and new() picked the class dir as the device, then panicked
reading brightness. Use min_depth(1) and tolerate read errors.
- battery: detect() only checked that UPower's DisplayDevice answered,
which it does on every machine; use IsPresent. The monitor thread now
returns an error instead of unwrapping, and publishes its first reading.
- pulseaudio: a failed connection panicked ("damn"); clicks before the
first sink query unwrapped a None channel map. Both are now handled, and
the connect loop no longer busy-spins.
- bar widget: don't underflow when narrower than the label column.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Desktop derived Hash over every field but PartialEq compared only the
name, violating the Hash/Eq contract the launcher's HashMap relies on
(clippy denies this by default, so `cargo clippy` failed to build).
Also skip directories and files without a .desktop extension (mimeinfo
cache, .directory files, ...) and stop unwrapping non-UTF-8 paths.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
set(), end() and move_cursor() used the byte length of the input as the
cursor bound while append/backspace/delete/clear_* index a grapheme table.
Any non-ASCII input (æøå, emoji) followed by End or typing past the end
indexed out of bounds and, with panic = "abort" in release, killed wldash.
While here:
- clamp Up so the selection can't run past the last row (every widget now
reports its row count), and make mouse selection underflow-safe
- strip all desktop-entry field codes from Exec (%i %c %k ... and %% -> %),
not just %f/%F/%u/%U
- report a failed spawn instead of panicking
- size the highlight colour table by chars, matching the drawing code
Adds unit tests for the prompt and the field-code stripping.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
On a shared (NFS-roamed) home, ~/.config/wldash/config.yml is identical on
every machine. Prefer a host-specific /etc/wldash/config.yml when it exists so
each machine can keep its own layout without conflicting; --config still
overrides both. Enables the 'factor host-specific config to /etc' pattern for
shared-home fleets.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ensure ~/.config/wldash and ~/.cache/wldash exist.
Provide hints when no configuration exists.
Signed-off-by: Alejandro Visiedo <alejandro.visiedo@gmail.com>
This implementation is a rewrite of wldash, implemented from scratch.
This also means that it is an unrelated history, hence the history now
having two initial commits.
wldash was originally written to expect server-side shm buffer
optimizations, which make it so only a single buffer has to be in use.
This simplifies damage tracking and repaint needs.
Support for using multiple buffers was added to support e.g., jay, but
the damage handling was not in place for this to work. Fix that by
tracking damage per buffer.
The calloop timer is only responsible for ensuring wakeup at the right
time, but we can also be woken up before time so we need to check the
deadline.
At the same time, We may end up being significantly delayed past the
deadline if something else was slow. If we are too far behind, reset the
base of the repeat timer by just offsetting from the current time.