Sync omarchy-air's handoff work: pointer patch, firewall, case fix
Everything from the air side of lan-mouse that was living only on that machine, plus corrections to what this repo already said. New: handoff/patch/ is a two-line source patch making the daemon forward the ACCELERATED pointer deltas. Upstream 0.11.0 forwards dx_unaccel and discards the accelerated pair in the same event, and the wlr receiver applies no curve either, so remote motion arrives with the sender's acceleration stripped and nothing replacing it -- and sensitivity / accel_profile are inert on both ends, so no config can fix it. The patch also adds LAN_MOUSE_POINTER_SCALE for the residual logical-ppi gap (0.7 for air's 140.1ppi against the LG's ~95.8). install.sh builds it per-machine; the unit now runs the result. This laptop is still unpatched, so its forwarded motion is still wrong until the handoff step runs here. New: install.sh --handoff opens 4242/udp for the peer in ufw. ufw is default-deny inbound and a dropped inbound packet presents IDENTICALLY to a bad certificate; this cost a day. Nothing in the repo covered it. Fixed: cmd_restart bypassed the systemd unit with pkill + uwsm-app, which races Restart=on-failure and can leave two daemons on 4242. It now prefers the unit, matching what cmd_log already assumed, and keeps the hand-start path only for when no unit exists. Documented, and this was the actual root cause of a day of dead crossings: fingerprints are CASE-SENSITIVE. lan-mouse generates them lowercase and compares with a plain map lookup, while openssl prints uppercase and cli authorize-key stores what it is handed. An uppercase digest is the right digest, valid TOML, non-empty, passes every guard, and never matches -- the handshake dies bad_certificate. Also documented: authorization is receiver-side only (connect.rs sets insecure_skip_verify), so each direction depends solely on the receiver's list and a sender cannot tell whether it is talking to the real peer. Corrected: README claimed the unknown-device* accel rule was needed because the receiver double-accelerates already-accelerated deltas. That is backwards and the rule is a measured no-op -- the device matches, but sensitivity and accel_profile are libinput settings and a wlr-virtual-pointer is not a libinput device. Measured on both machines: 398x198px travel at sensitivity 0 and identical at -0.9, exactly 1:1. Lines kept (harmless, and the naming note is worth having) with the real mechanism written down. ~/.config/lan-mouse/ stays out of the repo as before; handoff/config/ holds example configs carrying the backend, edge and lowercase rules instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LrgrMhPG8CTo9XZF326rjZ
This commit is contained in:
+61
-1
@@ -16,7 +16,13 @@ set -uo pipefail
|
||||
REPO="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
STAMP="$(date +%s)"
|
||||
DRY=0
|
||||
STEPS=(packages config themes plugins bin services system)
|
||||
STEPS=(packages config themes plugins bin handoff services system)
|
||||
|
||||
# omarchy-handoff peer addresses to open the firewall for. The peer is dual-homed
|
||||
# (Wi-Fi + dock NIC) and the dock address disappears on undock, so list both.
|
||||
if [[ -z ${HANDOFF_PEER_IPS+x} ]]; then
|
||||
HANDOFF_PEER_IPS=(192.168.1.24 192.168.1.86)
|
||||
fi
|
||||
|
||||
c_ok=$'\033[32m'; c_skip=$'\033[2m'; c_warn=$'\033[33m'; c_err=$'\033[31m'; c_hd=$'\033[1m'; c_off=$'\033[0m'
|
||||
[[ -t 1 ]] || { c_ok=; c_skip=; c_warn=; c_err=; c_hd=; c_off=; }
|
||||
@@ -264,6 +270,60 @@ step_services() {
|
||||
say " rather than now. 'systemctl --user start <unit>' to bring one up early."
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- handoff
|
||||
step_handoff() {
|
||||
head_ "omarchy-handoff (lan-mouse)"
|
||||
|
||||
# 1. The patched daemon. systemd/user/lan-mouse.service points at this path, so
|
||||
# it has to exist before the services step enables the unit. Per-architecture:
|
||||
# this laptop is x86_64 and omarchy-air is aarch64, so each builds its own.
|
||||
if [[ -x $HOME/.local/bin/lan-mouse-patched ]]; then
|
||||
skip "~/.local/bin/lan-mouse-patched (delete it to force a rebuild)"
|
||||
elif ! command -v cargo >/dev/null; then
|
||||
warn "cargo missing - run the packages step first, or: omarchy pkg add rust"
|
||||
elif (( DRY )); then
|
||||
printf ' %s? would build ~/.local/bin/lan-mouse-patched from handoff/patch/%s\n' "$c_skip" "$c_off"
|
||||
else
|
||||
say " building patched daemon from handoff/patch/ (~1 min; see handoff/patch/REBUILD.md for why)"
|
||||
if "$REPO/handoff/patch/build.sh"; then ok "~/.local/bin/lan-mouse-patched"
|
||||
else err "build failed - the unit will not start until this succeeds"; fi
|
||||
fi
|
||||
|
||||
# 2. The firewall. THE bug that cost a full day: ufw is default-deny inbound, so
|
||||
# the peer's DTLS handshake dies at the wire and presents EXACTLY like a bad
|
||||
# certificate. Authorization is receiver-side only (connect.rs sets
|
||||
# insecure_skip_verify), so the RECEIVER's firewall must allow 4242/udp or
|
||||
# that direction is silently dead.
|
||||
if ! command -v ufw >/dev/null; then
|
||||
skip "ufw not installed - nothing to open"
|
||||
else
|
||||
local ip rules=""
|
||||
# Reading the ruleset needs root, so don't probe it on a dry run.
|
||||
(( DRY )) || rules=$(sudo ufw status 2>/dev/null || true)
|
||||
for ip in "${HANDOFF_PEER_IPS[@]}"; do
|
||||
if [[ $rules == *"4242"*"$ip"* ]]; then
|
||||
skip "ufw allows 4242/udp from $ip"
|
||||
elif (( DRY )); then
|
||||
printf ' %s? would allow 4242/udp from %s%s\n' "$c_skip" "$ip" "$c_off"
|
||||
else
|
||||
sudo ufw allow from "$ip" to any port 4242 proto udp \
|
||||
comment "lan-mouse peer $ip" >/dev/null && ok "ufw: 4242/udp from $ip"
|
||||
fi
|
||||
done
|
||||
say ""
|
||||
say " Verify a blocked handshake with: journalctl -k -g 'UFW BLOCK'"
|
||||
fi
|
||||
|
||||
say ""
|
||||
say " ~/.config/lan-mouse/ is NOT in this repo (private key + per-machine"
|
||||
say " fingerprints). Start from handoff/config/config.toml.example-* and:"
|
||||
say " omarchy-handoff fingerprint # give it to the peer, LOWERCASE"
|
||||
say " omarchy-handoff pair <peer> <lowercase-sha256>"
|
||||
say " omarchy-handoff doctor # must pass before arming"
|
||||
say " omarchy-handoff on"
|
||||
say " A fresh install regenerates the cert, so the PEER must re-pair."
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- system
|
||||
step_system() {
|
||||
head_ "System drop-ins (needs sudo)"
|
||||
|
||||
Reference in New Issue
Block a user