Beetroot

Beetroot v1.6.1 — The Keyboard Rewrite Nobody Saw

A complete rewrite of how Beetroot handles keyboard input in no-focus mode. Plus a refreshed preview panel with arrow navigation, and fixes for every bug users reported in v1.6.0.

Two days after releasing v1.6.0 with the no-focus window, users started reporting problems. Arrows didn't work right away. Notes couldn't be edited. Switching filters took 2-3 seconds. Alt+T only worked sometimes.

All of it traced back to the same thing: the keyboard system wasn't designed for a window that never has focus.

At a glance:

  • Keyboard hook rewrite — three layers replace the fragile single-hook approach
  • Preview panel overhaul — dynamic header, collapsible notes, arrow navigation between clips
  • Performance fix — filter switching is instant again
  • Note editing works — the hook no longer eats your keystrokes

The keyboard problem

v1.6.0's no-focus mode had a single keyboard hook that intercepted keys and sent them to the UI through Tauri events. Two things went wrong:

Tauri drops events when the window has no focus. The whole point of no-focus mode is that Beetroot doesn't have focus. So keys were intercepted from other apps but never arrived in Beetroot. Users saw this as "arrows don't work until I click."

The hook intercepted everything. Trying to type in the note field? Space opened preview. Enter triggered paste. Arrows navigated the list instead of moving your cursor.

The fix: split keyboard handling into three layers — a low-level hook for navigation keys, RegisterHotKey for modifier combos (the proper Windows API instead of the timing-sensitive GetAsyncKeyState), and direct JS injection via win.eval() to bypass Tauri's event system entirely.

The hook also reinstalls itself every time the window opens. Windows 11 silently removes low-level hooks if their callbacks take too long — this was behind the intermittent "keyboard stops working" reports.

Preview panel, refreshed

The preview header now shows useful context instead of just "Preview" — source app icon, content type, and a key stat like "Chrome · Text · 178 chars". You can press Up/Down to flip through clips without closing and reopening preview. Notes are collapsed by default with a pencil icon — click to expand, they save automatically when you navigate away.

The 2-second filter switch

The most-reported v1.6.0 bug. Switching from "All" to "Images" froze for 2-3 seconds with ~1000 items.

The cause: the Rust search engine returned full content for every item — including raw HTML from browser copies. At 1000 items, the JSON payload crossing the IPC bridge was megabytes. The fix: search results now return only the first 200 characters (enough for the list view). Full content is fetched on demand when you actually need it — paste, preview, or transform.

Other fixes

  • Note editing — clicking the note field now activates the window, so the hook steps aside
  • Key-up leak — the old hook caught presses but let releases through, causing erratic Explorer behavior
  • First keypress ignored — startup race where React wasn't ready yet. Fixed with a retry
  • Remove spaces — now handles non-breaking spaces (U+00A0). Your IBAN paste actually works
  • Source app race — source is captured at the exact moment of clipboard change, not 50-200ms later

How to update

Beetroot will offer to update automatically. Or download v1.6.1 from GitHub.

Discussion

No comment section here — all discussions happen on X.

Max Nardit

Max Nardit

@mnardit

More articles

Beetroot v1.6.2 — The Truncation Bug

A hotfix for v1.6.1's content truncation — AI transforms, preview, and copy were silently working with partial text. Plus Alt+T toggle and filter count fixes.