Skip to content

Add keybinding support for fuzzel#130

Open
psyclyx wants to merge 1 commit intofdw:mainfrom
psyclyx:psyclyx/feat-fuzzel-keybindings
Open

Add keybinding support for fuzzel#130
psyclyx wants to merge 1 commit intofdw:mainfrom
psyclyx:psyclyx/feat-fuzzel-keybindings

Conversation

@psyclyx
Copy link
Copy Markdown

@psyclyx psyclyx commented Mar 10, 2026

Add keybinding support for fuzzel

Fuzzel supports custom keybindings via custom-1 through custom-19 in its config, returning exit codes 10+ when triggered. This wires that up so --keybindings and --menu-keybindings work with fuzzel.

Approach

Fuzzel doesn't accept keybinding config via CLI flags (unlike rofi's -kb-custom-N), so we generate a temporary config file at runtime. The config is generated once per keybinding list and cached for the lifetime of the process, cleaned up via atexit.

The generated config contains:

  • The user's existing fuzzel config copied inline (not via include= — fuzzel doesn't support nested includes)
  • A [dmenu] section forcing exit-immediately-if-empty=no so the target submenu behaves correctly for entries with no fields
  • A [key-bindings] section mapping shortcuts to custom-N, with unused slots set to none

Entry selection uses fuzzel's --index mode, outputting the selected line number rather than text. This avoids fuzzel's trailing whitespace stripping breaking entry lookup for entries with empty usernames.

Other details

  • --fuzzel-config is a dedicated flag (rather than using --selector-args) because we read and transform the config file contents rather than just forwarding it to fuzzel
  • Shortcut format conversion (Alt+Mod1+, Super+Mod4+) in __convert_shortcut so users can use the same format as rofi
    • Unsure how i feel about this - on the one hand, this does mean that users can just replace rofi with fuzzel and it'll Just Work ™️, but it does obfuscate keybind handling a bit. Native fuzzel keybinds aren't mangled, so nothing prevents users from using wayland-style binds if they so choose.
  • Help message shown via --mesg when show_help_message is set
  • README updated: bemenu (not fuzzel) doesn't support keybindings

AI

Assisted by Claude Code. I worked on, reviewed, and tested these changes throughout.

@fdw
Copy link
Copy Markdown
Owner

fdw commented Mar 10, 2026

Thank you, sounds interesting! 🙂

Could you maybe extract the feature for --index mode as a separate PR? That should make discussions (and merges) easier.

Regarding the config file, I find the approach interesting, but it also feels a bit complicated. Do you think it would also be viable if rofimoji simply understands the other exit codes from fuzzel, but the user has to create their own config file?

@psyclyx
Copy link
Copy Markdown
Author

psyclyx commented Mar 19, 2026

Apologies for the delay, have been traveling.

re: --index - absolutely, I'll get that separated and PR'd.

re: config file - I'm still thinking this through, sharing my notes below. FWIW - This config dance is a bit unfortunate, but I don't know that it's that complicated. We're just appending to the existing config, we don't have to do any complex rewriting. I don't write much python - is there some other way this could be structured to keep it clean? I think there are real benefits to having rofi-rbw manage it - --mesg will always be accurate and complete, and updates to rofi-rbw won't risk user keybinding config falling out of date.

notes
  • rofi-rbw has 2 menus with keybinds.
--- Main Menu
alt-c copy password copy field
alt-t type password type field
  • rofi-rbw needs to match these to exit codes to perform an action
    • In this PR, rofi-rbw controls the exit code -> action mapping by setting the keybindings in the generated config
    • If users managed the config files, those files would have to assign those binds to exit codes rofi-rbw knows about
      • rofi-rbw could have a predefined set of exit codes
      • rofi-rbw could expose options to map exit codes to actions
      • maybe we overload --keybindings for this?
        • exit 2::menu, or something?
      • --exit-codes?
  • rofi-rbw uses --keybindings to construct the help message
    • if we have an exit code mapping instead of just keybindings, then we can't construct that string accurately
      • we could construct a template string, and pass it as an env var?
        • user would need to write a shell script to wrap fuzzel, i don't think there's a way to specify this today, short of manipulating PATH before calling rofi-rbw? unsure
  • we could just not pass --mesg
    • as a user, i get a lot of value out of it
    • we can pass extra args to selectors already, but we have different --mesgs depending on main view / menu
  • rofi-rbw needs to support both the main view as well as the menu view
    • these have different binds
    • could solve this with 2 config files
      • bleh
      • how do we get rofi-rbw to use the right one?
        • cli arg to pass this mapping?
        • pass a config file prefix, and rofi-rbw adds a suffix for each view?
    • or could have all binds for both views, and only handle some of them
      • seems fine
  • what if rofi-rbw adds new menus, or new binds?
    • user config would fall out of date
      • users could be unaware of new binds
    • hardcoded --mesgs would miss these binds
    • if rofi-rbw has a hardedcoded set of exit codes, they could be bound to other custom keybinds in the user's fuzzel config
      • i don't think custom binds really make sense in a generic config, though - probably a non-issue
        • this is also an argument for just doing the generated config dance though - it's just an append, and won't clobber anything that makes sense to be in a user config anyways
    • i don't know how likely rofi-rbw is to add new binds or menus - this could just be a non-issue
  • fuzzel has a limit of 20 custom binds
    • deal with it if/when we approach 20 binds, not a problem for now
    • less of an issue if we have a config per menu, or if rofi-rbw manages the configs

@fdw
Copy link
Copy Markdown
Owner

fdw commented Mar 22, 2026

We're just appending to the existing config, we don't have to do any complex rewriting.

But what happens if the user has already some keybindings defined? We probably can't simply append, we need to parse the file and filter them out. Can we use the same names or do we need some translation? What happens when fuzzel changes their config syntax? Do relative includes still work if the config file is now in /tmp?

Suddenly, rofi-rbw does not simply depend on fuzzel's API any more, but on its config file support. And we have to do the dance to create the file.

I'm not convinced yet ;)

What I can definitely see is to add understand hotkeys received from fuzzel, but the user has to configure them themselves.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants