fix(niri): move the example toggle off Mod+Shift+D
Mod+Shift+D is Move Column Right in Dank Material Shell's niri binds (dms/binds.kdl), so the shipped example competed with it silently. The toggle moves to Mod+Shift+M, which is free in niri's stock binds and in DMS's binds. The start and stop examples move off Mod+Shift+E, which is stock niri's quit, to Mod+Shift+S and Mod+Shift+X. niri validate rejects a key bound twice in one binds block but not across blocks, so validation cannot show a conflict. The docs now give a grep over the config tree and niri's embedded stock binds for checking a key before binding it. The overlay pointer is corrected to Mod+Shift+Slash. A test pins the doc and the include to one toggle key that is not Mod+Shift+D. Fixes #45
This commit is contained in:
+31
-4
@@ -39,7 +39,7 @@ The shipped bind:
|
||||
|
||||
```kdl
|
||||
binds {
|
||||
Mod+Shift+D repeat=false hotkey-overlay-title="Toggle Voculinux dictation" {
|
||||
Mod+Shift+M repeat=false hotkey-overlay-title="Toggle Voculinux dictation" {
|
||||
spawn "voculinux" "--toggle";
|
||||
}
|
||||
}
|
||||
@@ -47,9 +47,11 @@ binds {
|
||||
|
||||
`repeat=false` is what makes it toggle once per press: without it, holding
|
||||
the key repeats the spawn and toggles dictation back off before you let go.
|
||||
Pick any key you like (the overlay title keeps it discoverable under
|
||||
`Mod+H`), and uncomment the `--start` / `--stop` variants in the include
|
||||
file if you want dedicated keys.
|
||||
`Mod+Shift+M` was free in niri's stock binds and in Dank Material Shell's
|
||||
binds when this was written. To use another key, check it first (below).
|
||||
The bind's title shows in niri's hotkey overlay (`Mod+Shift+Slash`). The
|
||||
include file's commented `--start` / `--stop` variants use `Mod+Shift+S` and
|
||||
`Mod+Shift+X`, which were free in the same way.
|
||||
|
||||
A key is either a compositor bind or an in-app Voculinux shortcut —
|
||||
never both. With External Activation on, do not keep the same key configured
|
||||
@@ -57,6 +59,31 @@ under **Settings → Shortcuts**; with it off, remove the niri bind. A key
|
||||
claimed on both sides fires twice: the compositor toggles over D-Bus while
|
||||
the internal listener fires on its own.
|
||||
|
||||
## Check a key before you bind it
|
||||
|
||||
`niri validate` rejects a key bound twice inside one `binds {}` block, but
|
||||
not a key bound in two blocks: a bind in your include file and one in
|
||||
`dms/binds.kdl` both pass validation with no warning. So validation cannot
|
||||
tell you whether a key is free. Check with grep, against your own config and
|
||||
niri's stock binds. Run this before you copy the include file, or your own
|
||||
toggle bind will match:
|
||||
|
||||
```bash
|
||||
KEY_RE='(Mod|Super)\+Shift\+M([[:space:]{]|$)' # the key you want to check
|
||||
grep -rnE --include='*.kdl' "$KEY_RE" ~/.config/niri/
|
||||
strings "$(command -v niri)" | grep -E "^[[:space:]]*(//[[:space:]]*)?$KEY_RE"
|
||||
```
|
||||
|
||||
The first command searches your config. `~/.config/niri/` holds
|
||||
`config.kdl` and the DMS-managed `dms/binds.kdl`, which `config.kdl`
|
||||
includes. `--include='*.kdl'` skips the `binds.kdl.pre-*` backups. If you
|
||||
include files from elsewhere, add their paths. The second command searches
|
||||
the stock defaults embedded in the niri binary. Commented lines match too, so
|
||||
a hit can be a bind you have commented out. No output from either command
|
||||
means the key is free. For a hit, remove or move the other bind, because niri does not warn
|
||||
about a key bound in two places. `Mod` and `Super` are both checked because
|
||||
niri reads `Mod` as Super on a TTY.
|
||||
|
||||
## First dictation
|
||||
|
||||
There is no permission prompt on niri. The RemoteDesktop portal is never
|
||||
|
||||
@@ -11,12 +11,16 @@
|
||||
//
|
||||
// One key is either a compositor bind or an in-app Voculinux shortcut,
|
||||
// never both: do not keep this key configured under Settings → Shortcuts.
|
||||
//
|
||||
// The keys below were free in niri's stock binds and in Dank Material Shell's
|
||||
// binds when this file was written. Before you use one, check it against your
|
||||
// own config: docs/NIRI.md, "Check a key before you bind it".
|
||||
|
||||
binds {
|
||||
// Toggle dictation, exactly once per press. repeat=false stops key
|
||||
// repeat from firing the spawn again while the key is held (which
|
||||
// would toggle dictation back off before you let go).
|
||||
Mod+Shift+D repeat=false hotkey-overlay-title="Toggle Voculinux dictation" {
|
||||
Mod+Shift+M repeat=false hotkey-overlay-title="Toggle Voculinux dictation" {
|
||||
spawn "voculinux" "--toggle";
|
||||
}
|
||||
|
||||
@@ -24,13 +28,13 @@ binds {
|
||||
// Mod+Shift+S repeat=false hotkey-overlay-title="Start Voculinux dictation" {
|
||||
// spawn "voculinux" "--start";
|
||||
// }
|
||||
// Mod+Shift+E repeat=false hotkey-overlay-title="Stop Voculinux dictation" {
|
||||
// Mod+Shift+X repeat=false hotkey-overlay-title="Stop Voculinux dictation" {
|
||||
// spawn "voculinux" "--stop";
|
||||
// }
|
||||
|
||||
// Flatpak installs: voculinux is not on the host PATH, so bind the
|
||||
// host D-Bus call instead (same toggle, no extra sandbox per press).
|
||||
// Mod+Shift+D repeat=false hotkey-overlay-title="Toggle Voculinux dictation" {
|
||||
// Mod+Shift+M repeat=false hotkey-overlay-title="Toggle Voculinux dictation" {
|
||||
// spawn "gdbus" "call" "--session" "--dest" "com.voculinux.Voculinux" "--object-path" "/com/voculinux/Voculinux" "--method" "com.voculinux.Voculinux.Toggle";
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ widening fails loudly. When #32 records DMS evidence, update the doc and
|
||||
this assertion together.
|
||||
"""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
@@ -18,6 +19,9 @@ USER_GUIDE = REPO_ROOT / "docs" / "USER_GUIDE.md"
|
||||
TRAY_INDICATOR = REPO_ROOT / "src" / "vocalinux" / "ui" / "tray_indicator.py"
|
||||
|
||||
TOGGLE_SPAWN = 'spawn "voculinux" "--toggle"'
|
||||
TOGGLE_HEADER = re.compile(r"^(\S+) repeat=false")
|
||||
#: Move Column Right in Dank Material Shell's binds; the shipped key must not reuse it (#45).
|
||||
DMS_MOVE_COLUMN_RIGHT_KEY = "Mod+Shift+D"
|
||||
CURRENT_WATCHER = "org.kde.StatusNotifierWatcher"
|
||||
|
||||
|
||||
@@ -45,6 +49,19 @@ def test_include_bind_is_non_repeating() -> None:
|
||||
assert "repeat=false" in _read(NIRI_INCLUDE)
|
||||
|
||||
|
||||
def test_doc_and_include_share_a_toggle_key_not_taken_by_dms() -> None:
|
||||
"""The doc's example key is the include file's toggle key, and it is not in use (#45)."""
|
||||
keys = [
|
||||
match.group(1)
|
||||
for match in (TOGGLE_HEADER.match(line) for line in _active_lines(_read(NIRI_INCLUDE)))
|
||||
if match
|
||||
]
|
||||
assert len(keys) == 1, "the include file should ship exactly one toggle bind"
|
||||
key = keys[0]
|
||||
assert key != DMS_MOVE_COLUMN_RIGHT_KEY
|
||||
assert f"{key} repeat=false" in _read(NIRI_DOC)
|
||||
|
||||
|
||||
def test_include_file_uses_no_compositor_internals() -> None:
|
||||
"""Only plain spawn actions; no compositor message APIs."""
|
||||
assert "niri msg" not in _read(NIRI_INCLUDE).lower()
|
||||
|
||||
Reference in New Issue
Block a user