Skip to content

Option to execute command instead of keybind for buttons - #2327

Open
seg-faulty wants to merge 4 commits into
davatorium:nextfrom
seg-faulty:button-exec-command
Open

seg-faulty wants to merge 4 commits into
davatorium:nextfrom
seg-faulty:button-exec-command

Conversation

@seg-faulty

@seg-faulty seg-faulty commented Aug 31, 2026

Copy link
Copy Markdown

Currently, you can only have Rofi perform functions using buttons by setting them to perform a specific keybind, e.g. a button to paste the contents of the keyboard would have the action property set to kb-primary-paste. When clicked, it would perform the same function as the keybind it was set to.

In dmenu mode, custom keybinds (kb-custom-X) terminate Rofi and return a value when pressed, starting from 10. For example, when "ALT-1" (the default keybind for kb-custom-1) is pressed when in dmenu, a value of 10 is returned. This allows for the creation of scripts that execute commands on pressing these keybinds, e.g.

#!/bin/bash
rofi -dmenu
output=$?
if [[ $output -eq 10  ]]; then
  echo "Custom keybind 1"
elif [[ $output -eq 11 ]]; then
  echo "Custom keybind 2"
else 
  "Something else"
fi

In the above script, if you press ALT-1 you would get the output "Custom keybind 1", ALT-2 "Custom keybind 2", and any other keybind "Something else". You can map a button to a keybind using the action property and then make a script that executes a command on that keybind, and hence when the button is clicked that command will be run.

However, this does not seem to be the case in drun mode. When I press ALT-1 in drun, it just switches to window mode and ALT-2 takes me back to drun mode. This means those who want to add custom buttons to their drun menus, e.g. a lock button or a power off button, cannot do so.

My commit fixes this by adding a new string property for buttons, known as exec. If action is not set on a button, Rofi instead looks for the exec property which contains a command, such as a program or shell script. When the button is clicked, Rofi will run the command using stdlib's system function.

An optional boolean property (default set to false) exit-after-command, if true, will close Rofi upon the command's completion.

For example:

button-terminal {
	content: "Terminal";
	exec: "xterm &";
	exit-after-command: true;
}

When the button is clicked, xterm is launched in the background and Rofi will close.

@DaveDavenport

Copy link
Copy Markdown
Collaborator

I need to discuss if this is something we want to add, but a few remarks looking at the patch:

  • Don't use system but use the helper_execute_command* methods rofi provide for launching.
  • Handle errors and check for NULL pointers.
  • Update documentation.

@seg-faulty

Copy link
Copy Markdown
Author

I need to discuss if this is something we want to add, but a few remarks looking at the patch:

* Don't use `system` but use the `helper_execute_command*` methods rofi provide for launching.

* Handle errors and check for NULL pointers.

* Update documentation.

Hi, thanks for your response, I have updated my patch to use helper_execute_command instead of system and added relevant documentation to doc/rofi-theme.5.markdown.

What do you mean by "handle errors" and "check for NULL pointers"? If you attempt to run a non-existent command using helper_execute_command, it already shows an error in the Rofi window. Unless you mean I should display any non-zero exit code in Rofi.

Failed to execute child process nonexistent-command (no such file or directory)

I've added a check in the textbox_button_trigger_action function that the value of exec is not NULL before attempting to execute.

@DaveDavenport

Copy link
Copy Markdown
Collaborator

yeah, helper_* does a lot of the error handling for free 😄

This branch has not been deployed

No deployments
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