Skip to content

Ctrl+P Closes Search Palette Instead of Navigating Up #938

Description

@uNyanda
  • Type: Bug
  • Severity: Medium

Environment

  • OS: Linux
  • WM: Niri
  • Compositor: Wayland
  • Software version: 2.69.0

Description

In the Search Notes palette, Ctrl+P is documented as an alternative to ArrowUp for moving the selection to the previous result. It instead closes the palette.

The same chord closes the palette from inside the New note form that the palette's create row opens. That form holds the typed name, folder, and tags in component state, so pressing Ctrl+P while filling it in discards everything that was typed.

The palette's own footer advertises this chord, reading ↑↓ Ctrl+N/P move, so the interface promises exactly the behaviour that does not happen.

This is not a preference local to Search Notes. Ctrl+P moving the selection up is an established convention backed by one shared helper. Open Notes (Space+O) is the clearest case: the same chord moves the selection up there, which is exactly the behaviour missing here. Command Palette, Templates (New from Template, Insert Template into Note), Search text in vault and Settings search share it too. Search Notes is the only palette that closes instead, and it does so only because of a collision with its own opening shortcut.

One surface imports the same helper without navigating on it, and it is worth naming so the convention is not over-read. Quick capture does not, but for an unrelated reason: it renders as its own window root rather than the main app, so it has no list driven by this helper. Its Ctrl+P toggles that window's own note picker, which is separate behaviour and not part of this defect.

Ctrl+N, Ctrl+J and Ctrl+K navigate correctly wherever there is a list to move through: the result list, and the folder and tag lists of the New note form. None of the four does anything in the form's Name field, which has no list to move through. That is correct, and it is a separate matter. Among the surfaces that do have a list, Ctrl+P alone is affected.

Steps to Reproduce

  1. Open the Search Notes palette with Ctrl+P.
  2. Type a query that returns more than one result.
  3. Press Ctrl+P.
  4. Observe that the palette closes instead of the selection moving up.

On the second surface:

  1. Open the Search Notes palette with Ctrl+P.
  2. Type a query that matches no existing note.
  3. Move to the create row and press Enter to open the New note form.
  4. Type a name and a partial folder path.
  5. Press Ctrl+P.
  6. Observe that the palette closes and the typed name and folder are gone.

Expected Behaviour

Ctrl+P should move the selection to the previous item, as ArrowUp does, and leave the palette open.

From inside the New note form it should move the selection within the folder or tag list under the focused field, and leave the form open with its contents intact.

Actual Behaviour

Ctrl+P closes the entire Search Notes palette in every case. Typed input in the New note form is lost.

Why Ctrl+P Never Reaches the Palette

Palettes accept three flavours of "move selection": the arrow keys, the Emacs pair Ctrl+N / Ctrl+P, and the vim pair Ctrl+J / Ctrl+K. Ctrl+P is recognised by isPalettePreviousKey() in packages/app-core/src/lib/palette-nav.ts, and SearchPalette consumes it to move up.

It is intercepted before it can get there. The shortcut that opens and toggles Search Notes is Mod+P, which resolves to Ctrl+P on Linux and Windows and Cmd+P on macOS. The toggle is handled by focusPaneHandler in packages/app-core/src/App.tsx, which is registered on window in the capture phase.

Its first job is to close the palette when its own shortcut is pressed again, and it does so by calling both preventDefault() and stopImmediatePropagation().

A capture-phase listener on window runs before the event reaches React's delegated root listener, and stopImmediatePropagation() stops it entirely. The palette's own key handler therefore never observes the event, and the Ctrl+P branch of isPalettePreviousKey() is unreachable for as long as the palette is open.

Winning over Vim's Ctrl+P (cursor up) on Linux and Windows is intentional, and is the reason the handler sits in the capture phase. The defect is that the toggle claims the chord unconditionally, without yielding to a palette that is already open and already consumes it.

Ctrl+N, Ctrl+J and Ctrl+K have no global binding, so they pass through the capture handler untouched and navigate as intended.

Affected Surfaces

  • The Search Notes result list, where Ctrl+P closes the palette.
  • The New note form's folder and tag lists, where Ctrl+P closes the palette and discards typed input.

The toggle consults a set of modal selectors before acting, which is how the Ctrl+D trash confirmation keeps Ctrl+P to itself. The New note form carries data-search-create-form, which is not in that set, so the toggle does not treat it as a modal and does not defer to it.

Suggested Behaviour

Make Ctrl+P mean one thing at a time: it opens the palette when the palette is closed, and navigates the selection when it is open.

Removing the toggle-close is preferable to making it yield to the palette. The toggle is the sole cause of the collision, so deleting it fixes this bug and removes the whole class, any future global binding that overlaps one of the palette-nav chords becomes safe by default, rather than needing to be special-cased. A guard would only ever patch the one instance that exists today.

The end state is the one the rest of the app already has: Ctrl+P navigates the selection up while a palette holds focus, and opens Search Notes when no palette is open.

The other palette surfaces must not change. Ctrl+P has to keep moving the selection up in Open Notes and the eleven other consumers of the shared helper. They are unaffected today, because the toggle only fires while Search Notes is open, and they stay unaffected afterwards, the overlay guard that stops a global shortcut from firing over an open palette already covers them. This is the constraint a narrower fix could plausibly break, so it belongs in the verification.

Nothing is lost by dropping it:

  • esc is the documented dismiss key, and the palette footer already says so.
  • The app's own reference material describes Mod+P as opening the palette. Neither the keymap description nor the in-app manual claims it toggles, so removing the toggle aligns the code with the documented contract rather than the other way round.
  • Opening a note and clicking outside both dismiss the palette already.

The cost is losing press-again-to-dismiss, which every other Ctrl+P palette trains users to expect. A user pressing Ctrl+P a second time expecting dismissal will move the selection up instead. That is a small, learnable surprise, and it is the same chord the footer tells them moves.

Additional Notes

Activity

  1. uNyanda commented on Oct 13, 2026

    @uNyanda
    ContributorAuthor

    Fixed in #939

  2. added
    bugSomething isn't working
    searchSearch palettes, vault text search, indexing
    keymapsShortcuts, rebinding, leader sequences, conflicts
    on Oct 13, 2026
  3. added theissue type on Oct 13, 2026
  4. adibhanna commented on Oct 13, 2026

    @adibhanna
    Contributor

    Thanks @uNyanda, a precise report. Confirmed on main: the Search Notes toggle in focusPaneHandler (App.tsx) runs in the capture phase and stops the event, so on Linux and Windows, where Mod+P is Ctrl+P, the palette never sees the key it uses to move up, in the result list or in the New note form. Closing this in favor of your #939, which carries the fix and will be reviewed for the next release.

  5. added a commit that references this issue on Oct 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingkeymapsShortcuts, rebinding, leader sequences, conflictslinuxLinuxsearchSearch palettes, vault text search, indexingwindowsWindows

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions