Skip to content

Commit

Permalink
Merge branch 'next' into feat/smartcase
Browse files Browse the repository at this point in the history
  • Loading branch information
phanen authored Jan 27, 2025
2 parents 3021eb4 + 3724b4d commit 177f677
Show file tree
Hide file tree
Showing 14 changed files with 298 additions and 23 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ if FOUND_PANDOC
generate-manpage: doc/rofi.1\
doc/rofi-sensible-terminal.1\
doc/rofi-theme-selector.1\
doc/rofi-actions.5\
doc/rofi-debugging.5\
doc/rofi-dmenu.5\
doc/rofi-keys.5\
Expand Down
12 changes: 12 additions & 0 deletions config/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ Settings config = {
/** Custom command to generate preview icons */
.preview_cmd = NULL,

/** Custom command to call when menu selection changes */
.on_selection_changed = NULL,
/** Custom command to call when menu mode changes */
.on_mode_changed = NULL,
/** Custom command to call when menu entry is accepted */
.on_entry_accepted = NULL,
/** Custom command to call when menu is canceled */
.on_menu_canceled = NULL,
/** Custom command to call when menu finds errors */
.on_menu_error = NULL,
/** Custom command to call when menu screenshot is taken */
.on_screenshot_taken = NULL,
/** Terminal to use. (for ssh and open in terminal) */
.terminal_emulator = "rofi-sensible-terminal",
.ssh_client = "ssh",
Expand Down
1 change: 1 addition & 0 deletions doc/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ man_files = [
'rofi.1',
'rofi-sensible-terminal.1',
'rofi-theme-selector.1',
'rofi-actions.5',
'rofi-debugging.5',
'rofi-dmenu.5',
'rofi-keys.5',
Expand Down
89 changes: 89 additions & 0 deletions doc/rofi-actions.5.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# rofi-actions(5)

## NAME

**rofi-actions** - Custom commands following interaction with rofi menus

## DESCRIPTION

**rofi** allows to set custom commands or scripts to be executed when some actions are performed in the menu, such as changing selection, accepting an entry or canceling.

This makes it possible for example to play sound effects or read aloud menu entries on selection.

## USAGE

Following is the list of rofi flags for specifying custom commands or scripts to execute on supported actions:

`-on-selection-changed` *cmd*

Command or script to run when the current selection changes. Selected text is forwarded to the command replacing the pattern *{entry}*.

`-on-entry-accepted` *cmd*

Command or script to run when a menu entry is accepted. Accepted text is forwarded to the command replacing the pattern *{entry}*.

`-on-mode-changed` *cmd*

Command or script to run when the menu mode (e.g. drun,window,ssh...) is changed.

`-on-menu-canceled` *cmd*

Command or script to run when the menu is canceled.

`-on-menu-error` *cmd*

Command or script to run when an error menu is shown (e.g. `rofi -e "error message"`). Error text is forwarded to the command replacing the pattern *{error}*.

`-on-screenshot-taken` *cmd*

Command or script to run when a screenshot of rofi is taken. Screenshot path is forwarded to the command replacing the pattern *{path}*.

### Example usage

Rofi command line:

```bash
rofi -on-selection-changed "/path/to/select.sh {entry}" \
-on-entry-accepted "/path/to/accept.sh {entry}" \
-on-menu-canceled "/path/to/exit.sh" \
-on-mode-changed "/path/to/change.sh" \
-on-menu-error "/path/to/error.sh {error}" \
-on-screenshot-taken "/path/to/camera.sh {path}" \
-show drun
```

Rofi config file:

```css
configuration {
on-selection-changed: "/path/to/select.sh {entry}";
on-entry-accepted: "/path/to/accept.sh {entry}";
on-menu-canceled: "/path/to/exit.sh";
on-mode-changed: "/path/to/change.sh";
on-menu-error: "/path/to/error.sh {error}";
on-screenshot-taken: "/path/to/camera.sh {path}";
}
```

### Play sound effects

Here's an example bash script that plays a sound effect using `aplay` when the current selection is changed:

```bash
#!/bin/bash

coproc aplay -q $HOME/Music/selecting_an_item.wav
```

The use of `coproc` for playing sounds is suggested, otherwise the rofi process will wait for sounds to end playback before exiting.

### Read aloud

Here's an example bash script that reads aloud currently selected entries using `espeak`:

```bash
#!/bin/bash

killall espeak
echo "selected: $@" | espeak
```
3 changes: 2 additions & 1 deletion doc/rofi-script.5.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ An integer number with the current state:
- **0**: Initial call of script.
- **1**: Selected an entry.
- **2**: Selected a custom entry.
- **3**: Deleted an entry.
- **10-28**: Custom keybinding 1-19 ( need to be explicitly enabled by script ).

### `ROFI_INFO`
Expand Down Expand Up @@ -109,7 +110,7 @@ The following extra options exists:
- **keep-selection**: If set, the selection is not moved to the first entry,
but the current position is maintained. The filter is cleared.

- **keep-filter**: If set, the filter is not cleared.
- **keep-filter**: If set, the filter is not cleared.

- **new-selection**: If `keep-selection` is set, this allows you to override
the selected entry (absolute position).
Expand Down
3 changes: 0 additions & 3 deletions include/mode-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@
#include <gmodule.h>
G_BEGIN_DECLS

/** ABI version to check if loaded plugin is compatible. */
#define ABI_VERSION 7u

/**
* Indicator what type of mode this is.
* For now it can be the classic switcher, or also implement a completer.
Expand Down
27 changes: 27 additions & 0 deletions include/mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@
#define ROFI_MODE_H
#include "rofi-types.h"
#include <cairo.h>
#include <gmodule.h>
G_BEGIN_DECLS

/** ABI version to check if loaded plugin is compatible. */
#define ABI_VERSION 7u

/**
* @defgroup MODE Mode
*
Expand Down Expand Up @@ -277,6 +282,28 @@ ModeMode mode_completer_result(Mode *sw, int menu_retv, char **input,
* @returns TRUE if mode can be used as completer.
*/
gboolean mode_is_completer(const Mode *sw);

/**
* @param mode The mode to query
*
* @returns the modes ABI version.
*/
int mode_get_abi_version(Mode *const mode);

/**
* @param mode The mode to query
* @param mod The GModule used to load the mode
*
* Set GModule used to load this plugin, this is used to
* unload it on shutdown.
*/
void mode_plugin_set_module(Mode *mode, GModule *mod);
/**
* @param mode The mode to query
*
* @returns the GModule used to load this plugin. NULL if not a plugin.
*/
GModule *mode_plugin_get_module(Mode *mode);
/**@}*/
G_END_DECLS
#endif
12 changes: 12 additions & 0 deletions include/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ typedef struct {
/** Custom command to generate preview icons */
char *preview_cmd;

/** Custom command to call when menu selection changes */
char *on_selection_changed;
/** Custom command to call when menu mode changes */
char *on_mode_changed;
/** Custom command to call when menu entry is accepted */
char *on_entry_accepted;
/** Custom command to call when menu is canceled */
char *on_menu_canceled;
/** Custom command to call when menu finds errors */
char *on_menu_error;
/** Custom command to call when menu screenshot is taken */
char *on_screenshot_taken;
/** Terminal to use */
char *terminal_emulator;
/** SSH client to use */
Expand Down
2 changes: 2 additions & 0 deletions include/view-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ struct RofiViewState {
int skip_absorb;
/** The selected line (in the unfiltered list) */
unsigned int selected_line;
/** The previously selected line (in the unfiltered list) */
unsigned int previous_line;
/** The return state of the view */
MenuReturn retv;
/** Monitor #workarea the view is displayed on */
Expand Down
11 changes: 11 additions & 0 deletions source/mode.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ const char *mode_get_name(const Mode *mode) {
return mode->name;
}

int mode_get_abi_version(Mode *const mode) {
g_assert(mode != NULL);
return mode->abi_version;
}

void mode_free(Mode **mode) {
g_assert(mode != NULL);
g_assert((*mode) != NULL);
Expand Down Expand Up @@ -245,4 +250,10 @@ gboolean mode_is_completer(const Mode *mode) {
return FALSE;
}

void mode_plugin_set_module(Mode *mode, GModule *mod){
mode->module = mod;
}
GModule *mode_plugin_get_module(Mode *mode){
return mode->module;
}
/**@}*/
4 changes: 4 additions & 0 deletions source/modes/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ static ModeMode script_mode_result(Mode *sw, int mretv, char **input,
retv = (mretv & MENU_LOWER_MASK);
return retv;
}
} else if ((mretv & MENU_ENTRY_DELETE) && selected_line != UINT32_MAX) {
script_mode_reset_highlight(sw);
new_list = execute_executor(sw, rmpd->cmd_list[selected_line].entry, &new_length,
3, &(rmpd->cmd_list[selected_line]));
} else if ((mretv & MENU_OK) && rmpd->cmd_list[selected_line].entry != NULL) {
if (rmpd->cmd_list[selected_line].nonselectable) {
return RELOAD_DIALOG;
Expand Down
32 changes: 15 additions & 17 deletions source/rofi.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,6 @@

#include "timings.h"

// Plugin abi version.
// TODO: move this check to mode.c
#include "mode-private.h"

/** Location of pidfile for this instance. */
char *pidfile = NULL;
/** Location of Cache directory. */
Expand Down Expand Up @@ -205,7 +201,7 @@ static void run_mode_index(ModeMode mode) {
for (unsigned int i = 0; i < num_modes; i++) {
if (!mode_init(modes[i])) {
GString *str = g_string_new("Failed to initialize the mode: ");
g_string_append(str, modes[i]->name);
g_string_append(str, mode_get_name(modes[i]));
g_string_append(str, "\n");

rofi_view_error_dialog(str->str, ERROR_MSG_MARKUP);
Expand Down Expand Up @@ -306,7 +302,7 @@ static void print_list_of_modes(int is_term) {
}
printf(" • %s%s%s%s\n", active ? "+" : "",
is_term ? (active ? color_green : color_red) : "",
available_modes[i]->name, is_term ? color_reset : "");
mode_get_name(available_modes[i]), is_term ? color_reset : "");
}
}
static void print_main_application_options(int is_term) {
Expand Down Expand Up @@ -473,7 +469,7 @@ static void help_print_mode_not_found(const char *mode) {
}
}
g_string_append_printf(str, " * %s%s\n", active ? "+" : "",
available_modes[i]->name);
mode_get_name(available_modes[i]));
}
rofi_add_error_message(str);
}
Expand All @@ -487,7 +483,7 @@ static void help_print_no_arguments(void) {
g_string_append(emesg, "The following modes are enabled:\n");
for (unsigned int j = 0; j < num_modes; j++) {
g_string_append_printf(emesg, " • <span color=\"green\">%s</span>\n",
modes[j]->name);
mode_get_name(modes[j]));
}
g_string_append(emesg, "\nThe following modes can be enabled:\n");
for (unsigned int i = 0; i < num_available_modes; i++) {
Expand All @@ -500,7 +496,7 @@ static void help_print_no_arguments(void) {
}
if (!active) {
g_string_append_printf(emesg, " • <span color=\"red\">%s</span>\n",
available_modes[i]->name);
mode_get_name(available_modes[i]));
}
}
g_string_append(emesg, "\nTo activate a mode, add it to the list in "
Expand Down Expand Up @@ -563,7 +559,7 @@ static void cleanup(void) {

Mode *rofi_collect_modes_search(const char *name) {
for (unsigned int i = 0; i < num_available_modes; i++) {
if (g_strcmp0(name, available_modes[i]->name) == 0) {
if (g_strcmp0(name, mode_get_name(available_modes[i])) == 0) {
return available_modes[i];
}
}
Expand All @@ -575,7 +571,7 @@ Mode *rofi_collect_modes_search(const char *name) {
* @returns TRUE when success.
*/
static gboolean rofi_collectmodes_add(Mode *mode) {
Mode *m = rofi_collect_modes_search(mode->name);
Mode *m = rofi_collect_modes_search(mode_get_name(mode));
if (m == NULL) {
available_modes =
g_realloc(available_modes, sizeof(Mode *) * (num_available_modes + 1));
Expand Down Expand Up @@ -603,13 +599,13 @@ static void rofi_collectmodes_dir(const char *base_dir) {
if (mod) {
Mode *m = NULL;
if (g_module_symbol(mod, "mode", (gpointer *)&m)) {
if (m->abi_version != ABI_VERSION) {
if (mode_get_abi_version(m) != ABI_VERSION) {
g_warning("ABI version of plugin: '%s' does not match: %08X "
"expecting: %08X",
dn, m->abi_version, ABI_VERSION);
dn, mode_get_abi_version(m), ABI_VERSION);
g_module_close(mod);
} else {
m->module = mod;
mode_plugin_set_module(m, mod);
if (!rofi_collectmodes_add(m)) {
g_module_close(mod);
}
Expand Down Expand Up @@ -673,8 +669,8 @@ static void rofi_collectmodes_setup(void) {
}
static void rofi_collectmodes_destroy(void) {
for (unsigned int i = 0; i < num_available_modes; i++) {
if (available_modes[i]->module) {
GModule *mod = available_modes[i]->module;
if (mode_plugin_get_module(available_modes[i])) {
GModule *mod = mode_plugin_get_module(available_modes[i]);
available_modes[i] = NULL;
g_module_close(mod);
}
Expand Down Expand Up @@ -1073,7 +1069,9 @@ int main(int argc, char *argv[]) {
extern const char *rasi_theme_file_extensions[];
char *file2 =
helper_get_theme_path(config_path, rasi_theme_file_extensions, NULL);
char *filename = rofi_theme_parse_prepare_file(file2);
GFile *gf = g_file_new_for_path(file2);
char *filename = g_file_get_path(gf);
g_object_unref(gf);
g_free(file2);
if (filename && g_file_test(filename, G_FILE_TEST_EXISTS)) {
if (rofi_theme_parse_file(filename)) {
Expand Down
Loading

0 comments on commit 177f677

Please sign in to comment.