From 1aa83f7ca47f3070ada2a29248d165023ee7d08d Mon Sep 17 00:00:00 2001 From: Josh Guice Date: Sat, 9 May 2026 17:05:36 -0700 Subject: [PATCH 1/2] Fix Ubuntu/Debian install: add ydotoold dep, correct set-key docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Debian/Ubuntu the ydotool client and ydotoold daemon ship as separate packages. Without the daemon installed and running, utter's keystroke injection silently fails — the postinstall systemctl enable of ydotool.service errors with "Unit file ydotool.service does not exist" because no ydotoold is present to provide it. Fedora/RHEL bundle both in a single ydotool package, so this only needs to apply to the deb build. Also fix install-release.sh's final message: it told users to `systemctl --user edit utter-watcher` and override ExecStart to change the PTT key, which is the manual systemd path. The supported flow is `utter set-key` — the watcher restarts itself and the change persists via the config file rather than a unit drop-in. --- packaging/nfpm.yaml | 1 + scripts/install-release.sh | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packaging/nfpm.yaml b/packaging/nfpm.yaml index f0a426a..14f7061 100644 --- a/packaging/nfpm.yaml +++ b/packaging/nfpm.yaml @@ -80,6 +80,7 @@ overrides: deb: depends: - ydotool + - ydotoold - alsa-utils - wl-clipboard - libnotify-bin diff --git a/scripts/install-release.sh b/scripts/install-release.sh index aedd06a..f21822f 100755 --- a/scripts/install-release.sh +++ b/scripts/install-release.sh @@ -13,7 +13,9 @@ # 2. Fetch the latest utter release from GitHub. # 3. Download the right .rpm or .deb for your distro+arch. # 4. Install it via dnf / apt (pulls in ydotool, alsa-utils, wl-clipboard, -# libnotify as deps; drops udev + systemd files; enables ydotool). +# libnotify as deps — plus ydotoold on Debian/Ubuntu, where the daemon +# ships in a separate package; drops udev + systemd files; enables +# ydotool). # 5. Download the Parakeet model (~640 MB) as your user. # 6. Start utter-daemon and utter-watcher in your current session. @@ -112,9 +114,9 @@ Verify anytime with: systemctl --user status utter-daemon utter-watcher journalctl --user -u utter-daemon -f -To change the key (default: rightmeta), edit: - systemctl --user edit utter-watcher +To change the PTT key (default: rightmeta), run: + utter set-key -…and override ExecStart with e.g. --key capslock, --key f13, etc. -See /usr/share/doc/utter/README.md for the full list. +…then press and hold the key you want and release. The watcher restarts +automatically. See /usr/share/doc/utter/README.md for details. EOM From 9325b78b5309eb37155ba073200a5e0cdee7ea05 Mon Sep 17 00:00:00 2001 From: Josh Guice Date: Sat, 9 May 2026 18:32:24 -0700 Subject: [PATCH 2/2] Ship ydotool.service on deb, fall back to input group, mention set-key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding ydotoold to deps (previous commit) gets the daemon installed but doesn't help on Debian/Ubuntu, where the ydotoold package strips the systemd unit. The postinstall's `systemctl enable ydotool.service` then fails with "Unit file ydotool.service does not exist" and ydotoold never starts. Ship a minimal base unit ourselves on deb only (Fedora's ydotool package already provides one — shipping ours there would conflict). The existing ydotool.service.d/owner.conf drop-in keeps working unchanged. Add the installing user to the `input` group as a permission fallback. The shipped udev rule grants ACL access via systemd-logind's `uaccess` tag — preferred when it works, since it scopes access to the active seat — but it silently does nothing in some session configurations (no local seat, certain compositor setups, headless installs). Group membership requires a re-login but is reliable. Trigger udev with `--action=change` so logind re-evaluates ACLs on already-plugged devices instead of only firing on new adds. Postinstall message now also tells users to run `utter set-key` to change the PTT key, matching install-release.sh. --- packaging/nfpm.yaml | 10 ++++++++ packaging/scripts/postinstall.sh | 40 ++++++++++++++++++++++++++++++- packaging/systemd/ydotool.service | 12 ++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 packaging/systemd/ydotool.service diff --git a/packaging/nfpm.yaml b/packaging/nfpm.yaml index 14f7061..fbc4204 100644 --- a/packaging/nfpm.yaml +++ b/packaging/nfpm.yaml @@ -54,6 +54,16 @@ contents: file_info: mode: 0644 + # Ubuntu/Debian's ydotool & ydotoold packages ship the binaries but not a + # systemd unit, so the drop-in above has nothing to drop into. Ship a base + # ydotool.service ourselves on deb only — Fedora's ydotool package already + # provides one (we'd conflict if we shipped it on rpm too). + - src: ./systemd/ydotool.service + dst: /usr/lib/systemd/system/ydotool.service + file_info: + mode: 0644 + packager: deb + - src: ../scripts/download-model.sh dst: /usr/share/utter/download-model.sh file_info: diff --git a/packaging/scripts/postinstall.sh b/packaging/scripts/postinstall.sh index 6fab277..cf5d638 100755 --- a/packaging/scripts/postinstall.sh +++ b/packaging/scripts/postinstall.sh @@ -6,7 +6,28 @@ set -e # get added after install. if command -v udevadm >/dev/null 2>&1; then udevadm control --reload-rules || true - udevadm trigger --subsystem-match=input || true + # `change` action so logind re-evaluates ACLs on already-plugged devices + # rather than only firing for new device adds. + udevadm trigger --subsystem-match=input --action=change || true +fi + +# Belt-and-suspenders: the udev/uaccess rule above grants ACL access to +# the active-seat user without requiring `input` group membership, which +# is great when it works — but on some session configurations (no local +# seat assigned, headless, certain Wayland compositors) logind never +# applies the ACL. Add the installing user to `input` as a fallback so +# utter-watcher works after a re-login even when uaccess silently fails. +INSTALL_USER="${SUDO_USER:-}" +if [ -z "$INSTALL_USER" ] && [ -n "${PKEXEC_UID:-}" ]; then + INSTALL_USER="$(getent passwd "$PKEXEC_UID" | cut -d: -f1 || true)" +fi +if [ -n "$INSTALL_USER" ] && [ "$INSTALL_USER" != "root" ] \ + && getent group input >/dev/null 2>&1 \ + && ! id -nG "$INSTALL_USER" 2>/dev/null | tr ' ' '\n' | grep -qx input +then + if usermod -aG input "$INSTALL_USER" 2>/dev/null; then + ADDED_INPUT_GROUP=1 + fi fi # Install & start ydotool (the system service that drives /dev/uinput). @@ -43,6 +64,23 @@ To start the services in your current session without logging out: Then hold Right Cmd (or the key you configured) and speak. +To change the PTT key (default: rightmeta), run: + + utter set-key + +…then press and hold the key you want and release. The watcher restarts +automatically. + EOM +if [ "${ADDED_INPUT_GROUP:-0}" = "1" ]; then + cat <