github y3owk1n/neru v1.49.0

latest release: nightly
4 hours ago

1.49.0 (2026-07-27)

Overview

This release is mostly about making runtime config stick and making the Linux and Windows ports behave like first-class citizens. neru config set is now persistent, the recursive grid can jump straight to a depth, Linux/Wayland input handling got a large stability pass (hotplug, suspend/resume, stuck keys, XKB options), and Windows finally ships a single binary that works as both CLI and daemon — with a proper uninstaller on all three platforms.

Migration Guide

Warning

This release changes Linux default hotkeys and the Windows binary layout. Both need a one-time action.

Linux: default global hotkeys are now empty (breaking)
Neru no longer ships default global hotkeys on Linux, because the old defaults collided with terminal and application shortcuts (Ctrl+Shift+C / copy, Ctrl+Shift+V / paste, …). neru config init no longer writes them either. You now have two options:

  • Recommended — bind neru hints, neru grid, etc. in your desktop environment / window manager keybindings
  • Or explicitly add a [hotkeys] section back to your own config

Windows: reinstall to get the unified binary (breaking)
Windows previously shipped a GUI-subsystem binary, so no subcommand could print to the terminal it was typed in. It is now built for the console subsystem and releases the console when launched from a shortcut, so a single binary serves as both CLI and daemon. Re-run the installer to pick this up — typing neru now works, while the Start Menu and autostart entries still open no window.

New: persistent config set writes an override file
neru config set now persists across restarts by writing to a *.override.toml file next to your active config (config.tomlconfig.override.toml). The new load order is:

Defaults → config.toml → config.override.toml → Runtime (in-memory)

Nothing to do if you don't use neru config set — but if you have been using it, be aware that changes now survive restarts. Undo them with neru config reset <key>, or delete the override file.


Configuration & CLI

  • Persistent neru config set — runtime config changes are now written to a *.override.toml file alongside your config, so they survive daemon restarts. Your hand-written config is never touched
  • neru config reset <key> — new command that removes a key from the override file, restoring your configured (or default) value
  • --no-reload for both set and reset — defer the reload when you are changing several fields that validate against each other, then commit all of them at once:
    neru config set --no-reload recursive_grid.grid_cols 3
    neru config set --no-reload recursive_grid.grid_rows 3
    neru config set recursive_grid.keys gcrhtnmwv   # commits and reloads
    This makes toggleable grid layouts a single hotkey:
    [hotkeys]
    "Cmd+8" = [
        "config set recursive_grid.grid_cols 3 --no-reload",
        "config set recursive_grid.grid_rows 3 --no-reload",
        "config set recursive_grid.keys gcrhtnmwv",
    ]
    "Cmd+9" = [
        "config reset recursive_grid.grid_cols --no-reload",
        "config reset recursive_grid.grid_rows --no-reload",
        "config reset recursive_grid.keys",
    ]
  • Friendlier startup notice — the scary Linux/Windows startup warning is replaced by a short, dynamic capability line, e.g. ⚠️ Neru is running on linux/wayland-wlroots. Run 'neru doctor' for platform capabilities.

Recursive Grid

  • --zoom-to-depth flag — drill straight down to a given depth at the current cursor position instead of stepping there key by key. Zero-based (0 is the root), negative values are rejected, and values beyond the maximum depth are clamped instead of erroring:
    neru recursive_grid --zoom-to-depth 2
    To bind it from inside the recursive grid, idle first:
    [recursive_grid.hotkeys]
    "Cmd+1" = [ "idle", "recursive_grid --zoom-to-depth 2" ]

Linux

Note

Linux implementations are mainly contributor driven, feel free to help improving it!

  • Recursive grid animations — transition animations are now implemented on Linux for both Wayland and X11, matching the macOS behavior
  • Persistent evdev capture with hotplug support — devices under /dev/input/event* were being re-scanned on every mode activation, adding roughly 0.5s of input delay. The capture is now created once and reused, with an inotify watcher on /dev/input/ keeping the device list in sync when keyboards are plugged or unplugged
  • No more stuck keys after grab — keys held across a grab could split their state between file descriptors, leaving libinput permanently convinced a key was down. Neru now waits (up to 5s) for held keys to be released before grabbing, suppresses the replayed press events for keys still held, and injects synthetic releases on disable
  • XKB options respected — evdev scan codes are resolved through the compositor's libxkbcommon keymap instead of a hardcoded table, so options like caps:swapescape configured in your compositor are honored
  • Global hotkeys recover after sleep — hotkeys could become permanently unresponsive after suspend, because /dev/input/event* had not been re-enumerated at the moment PrepareForSleep(false) fired. Capture creation now succeeds with zero devices so the hotplug watcher can pick them up as udev populates them, wake-up retries are bounded (5 attempts, 500ms backoff), and the health check no longer reports a failed listener as healthy
  • No more hangs or repeated permission prompts on resume — hotkey teardown now times out and recovers instead of hanging the daemon after deep sleep, and the RemoteDesktop session is no longer reset on every sleep cycle, so you are not re-prompted for Remote Control permission (input actions retry once if they hit a stale connection)
  • 100% CPU busy-loop fixed — the evdev hotplug inotify watcher was created with IN_NONBLOCK, so reads returned EAGAIN immediately and spun the loop
  • Cursor synced before mode activation — the Wayland cursor-position cache is refreshed before a mode activates, so overlays and indicators anchor to the real pointer position instead of a stale one (often screen center) after you move the mouse manually
  • AT-SPI init is now gated — accessibility activation is conditional on your hints configuration, and the state is always reset on startup and shutdown

Windows

  • One binary for CLI and daemon — built for the console subsystem, releasing the console when started from a shortcut rather than a terminal. neru <subcommand> now prints to the terminal you typed it in, while the Start Menu and autostart entries still open no window. The embedded icon is preserved
  • Proper Windows paths everywhere — PATH entries, shortcuts and registry values are now real Windows paths instead of mixed or POSIX-style ones
  • PATH written through the registry — replaces setx, which truncates at 1024 characters and flattens other tools' expandable entries
  • Optional Start Menu shortcut — what actually makes the app searchable from the taskbar; PATH alone does not
  • ~/.config/neru is now discovered — in addition to %APPDATA% and XDG_CONFIG_HOME, so a config carried over from a Unix dotfiles repo works unchanged. %APPDATA% remains the write location

Install & Uninstall

  • just uninstall on all three platforms — undoes each install step in reverse. Config and logs are kept unless --purge is passed, so -y alone can never delete a hand-tuned config; --purge lists the fully resolved directories before deleting anything. It deliberately leaves alone what it did not install — a binary on PATH that is not our symlink, and the Linux input group, which other tools may depend on

Docs & Internals

  • Cross-platform feature parity tablesdocs/CROSS_PLATFORM.md now spells out per-feature support across macOS, Linux (X11 / Wayland variants) and Windows in much more detail
  • macOS integration tests — the main run loop is now serviced during integration tests, fixing flakiness in run-loop-dependent tests

Features

  • config: add --no-reload for set and add reset (#1083) (2920864)
  • config: persistent config set via override files (#1082) (6398fa5)
  • install: unify the Windows binary, add cross-platform uninstall (#1103) (fc8e1f0)
  • linux: support animation for recursive grid (#1089) (b800247)
  • recursive_grid: add --zoom-to-depth flag (#1077) (3dfe895)

Bug Fixes

  • linux,wayland: make evdev capture persistent with kb hotplug support (#1086) (e345661)
  • linux,wayland: prevent hotpulgLoop busy wait (#1088) (c519875)
  • linux,wayland: prevent stale evdev state from causing stuck keys after grab (#1087) (cdd466a)
  • linux,wayland: sync cursor before mode activation (#1091) (f94f72a)
  • linux,wayland: use compositor keymap to respect XKB options (#1097) (fb4fe8e)
  • linux: disable default global hotkeys to avoid collisions (#1081) (3625f39)
  • linux: gate AT-SPI accessibility init and ensure reset on quit (#1085) (986f064)
  • linux: recover evdev global hotkeys post-sleep and fix health check (#1092) (154ae6c)
  • linux: resolve evdev hotkey deadlock post-suspend and preserve RemoteDesktop session (#1094) (16be957)
  • replace startup warning on launch with dynamic capability notice (#1084) (03b2d5c)

Documentation

  • update cross platform feature parity with details (#1095) (6a9842b)

Don't miss a new neru release

NewReleases is sending notifications on new releases.