mirror of https://github.com/davatorium/rofi.git
Compare commits
10 Commits
bf4f8303ec
...
ce3a393bfc
Author | SHA1 | Date |
---|---|---|
djvs | ce3a393bfc | |
Dave Davenport | 839ee0d7d9 | |
Dave Davenport | 76154cc1ff | |
Dave Davenport | 1063b6ec05 | |
Dave Davenport | 04f16052a9 | |
lbonn | 9cae4a9b61 | |
Dave Davenport | af6fb83a51 | |
Dave Davenport | 0bf0c51827 | |
djvs | a382dd03c1 | |
djvs | 0b3f7f7bb8 |
|
@ -13,7 +13,7 @@ body:
|
|||
consider you’re wrong and still fill the full report. Any report
|
||||
missing required informations will be labeled as “Incomplete Report -
|
||||
Please follow the guidelines” and will be closed. If you ask a
|
||||
question, enter dummy information in required fields to get passed the
|
||||
question, enter dummy information in required fields to get past the
|
||||
checks or in general completely ignore the guidelines, the issue will
|
||||
be closed and locked as spam.
|
||||
|
||||
|
@ -37,21 +37,26 @@ body:
|
|||
- type: input
|
||||
attributes:
|
||||
label: "Configuration"
|
||||
description: "Please use https://gist.github.com and include output of `rofi -dump-config`."
|
||||
description: |
|
||||
Please use https://gist.github.com and include output of `rofi -dump-config`.
|
||||
n/a is not a valid config.
|
||||
placeholder: "Gist URL"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Theme"
|
||||
description: "Please use https://gist.github.com and include output of `rofi -dump-theme`."
|
||||
description: |
|
||||
Please use https://gist.github.com and include output of `rofi -dump-theme`.
|
||||
n/a is not a valid theme.
|
||||
placeholder: "Gist URL"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Timing report"
|
||||
description: "Please use https://gist.github.com and include output of your command with G_MESSAGES_DEBUG=Timings set."
|
||||
description: |
|
||||
Please use https://gist.github.com and include output of your command with G_MESSAGES_DEBUG=Timings set.
|
||||
placeholder: "Gist URL"
|
||||
validations:
|
||||
required: false
|
||||
|
|
|
@ -49,7 +49,7 @@ jobs:
|
|||
build-autotools-gcc-no-window:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: ./.github/actions/setup
|
||||
|
|
|
@ -123,6 +123,8 @@ Settings config = {
|
|||
.window_match_fields = "all",
|
||||
/** Monitor */
|
||||
.monitor = "-5",
|
||||
/** Multiply scrolling amount **/
|
||||
.scroll_multiplier = 1,
|
||||
/** Set filter */
|
||||
.filter = NULL,
|
||||
.dpi = -1,
|
||||
|
|
|
@ -95,6 +95,8 @@ typedef struct {
|
|||
/** Toggle to enable sorting. */
|
||||
unsigned int sort;
|
||||
/** Sorting method. */
|
||||
unsigned int scroll_multiplier;
|
||||
/** Sorting method. */
|
||||
SortingMethod sorting_method_enum;
|
||||
/** Sorting method. */
|
||||
char *sorting_method;
|
||||
|
|
|
@ -129,6 +129,21 @@ void listview_set_selected(listview *lv, unsigned int selected);
|
|||
*/
|
||||
unsigned int listview_get_selected(listview *lv);
|
||||
|
||||
|
||||
/**
|
||||
* @param lv The listview handle
|
||||
*
|
||||
* Move the selection one row up.
|
||||
* - Wrap around.
|
||||
*/
|
||||
void listview_scroll_prev(listview *lv);
|
||||
/**
|
||||
* @param lv listview handle.
|
||||
*
|
||||
* Alternate, potentially multi-row alternative to listview_nav_up
|
||||
* - Wrap around.
|
||||
*/
|
||||
void listview_scroll_next(listview *lv);
|
||||
/**
|
||||
* @param lv The listview handle
|
||||
*
|
||||
|
@ -143,12 +158,12 @@ void listview_nav_next(listview *lv);
|
|||
* - Wrap around.
|
||||
*/
|
||||
void listview_nav_prev(listview *lv);
|
||||
|
||||
/**
|
||||
* @param lv The listview handle
|
||||
*
|
||||
* Move the selection one row up.
|
||||
* - Wrap around.
|
||||
* Alternate, potentially multi-row alternative to listview_nav_down
|
||||
* - No wrap around.
|
||||
* - Do not move to top row when at start.
|
||||
*/
|
||||
void listview_nav_up(listview *lv);
|
||||
/**
|
||||
|
|
|
@ -473,13 +473,7 @@ static ModeMode file_browser_mode_result(Mode *sw, int mretv, char **input,
|
|||
}
|
||||
gboolean special_command =
|
||||
((mretv & MENU_CUSTOM_ACTION) == MENU_CUSTOM_ACTION);
|
||||
if (mretv & MENU_NEXT) {
|
||||
retv = NEXT_DIALOG;
|
||||
} else if (mretv & MENU_PREVIOUS) {
|
||||
retv = PREVIOUS_DIALOG;
|
||||
} else if (mretv & MENU_QUICK_SWITCH) {
|
||||
retv = (mretv & MENU_LOWER_MASK);
|
||||
} else if (mretv & MENU_CUSTOM_COMMAND) {
|
||||
if (mretv & MENU_CUSTOM_COMMAND) {
|
||||
retv = (mretv & MENU_LOWER_MASK);
|
||||
} else if ((mretv & MENU_OK)) {
|
||||
if (selected_line < pd->array_length) {
|
||||
|
@ -657,13 +651,7 @@ ModeMode file_browser_mode_completer(Mode *sw, int mretv, char **input,
|
|||
ModeMode retv = MODE_EXIT;
|
||||
FileBrowserModePrivateData *pd =
|
||||
(FileBrowserModePrivateData *)mode_get_private_data(sw);
|
||||
if (mretv & MENU_NEXT) {
|
||||
retv = NEXT_DIALOG;
|
||||
} else if (mretv & MENU_PREVIOUS) {
|
||||
retv = PREVIOUS_DIALOG;
|
||||
} else if (mretv & MENU_QUICK_SWITCH) {
|
||||
retv = (mretv & MENU_LOWER_MASK);
|
||||
} else if ((mretv & MENU_OK)) {
|
||||
if ((mretv & MENU_OK)) {
|
||||
if (selected_line < pd->array_length) {
|
||||
if (pd->array[selected_line].type == UP) {
|
||||
GFile *new = g_file_get_parent(pd->current_dir);
|
||||
|
|
|
@ -351,13 +351,7 @@ static ModeMode recursive_browser_mode_result(Mode *sw, int mretv, G_GNUC_UNUSED
|
|||
|
||||
return MODE_EXIT;
|
||||
}
|
||||
if (mretv & MENU_NEXT) {
|
||||
retv = NEXT_DIALOG;
|
||||
} else if (mretv & MENU_PREVIOUS) {
|
||||
retv = PREVIOUS_DIALOG;
|
||||
} else if (mretv & MENU_QUICK_SWITCH) {
|
||||
retv = (mretv & MENU_LOWER_MASK);
|
||||
} else if (mretv & MENU_CUSTOM_COMMAND) {
|
||||
if (mretv & MENU_CUSTOM_COMMAND) {
|
||||
retv = (mretv & MENU_LOWER_MASK);
|
||||
} else if ((mretv & MENU_OK)) {
|
||||
if (selected_line < pd->array_length) {
|
||||
|
@ -495,13 +489,7 @@ ModeMode recursive_browser_mode_completer(Mode *sw, int mretv, char **input,
|
|||
ModeMode retv = MODE_EXIT;
|
||||
FileBrowserModePrivateData *pd =
|
||||
(FileBrowserModePrivateData *)mode_get_private_data(sw);
|
||||
if (mretv & MENU_NEXT) {
|
||||
retv = NEXT_DIALOG;
|
||||
} else if (mretv & MENU_PREVIOUS) {
|
||||
retv = PREVIOUS_DIALOG;
|
||||
} else if (mretv & MENU_QUICK_SWITCH) {
|
||||
retv = (mretv & MENU_LOWER_MASK);
|
||||
} else if ((mretv & MENU_OK)) {
|
||||
if ((mretv & MENU_OK)) {
|
||||
if (selected_line < pd->array_length) {
|
||||
if (pd->array[selected_line].type == RFILE) {
|
||||
*path = g_strescape(pd->array[selected_line].path, NULL);
|
||||
|
|
|
@ -60,12 +60,14 @@
|
|||
/**
|
||||
* Name of the history file where previously chosen commands are stored.
|
||||
*/
|
||||
#define RUN_CACHE_FILE "rofi-3.runcache"
|
||||
#define RUN_CACHE_FILE "rofi-4.runcache"
|
||||
|
||||
typedef struct {
|
||||
char *entry;
|
||||
char *exec;
|
||||
uint32_t icon_fetch_uid;
|
||||
uint32_t icon_fetch_size;
|
||||
gboolean from_history;
|
||||
/* Surface holding the icon. */
|
||||
cairo_surface_t *icon;
|
||||
} RunEntry;
|
||||
|
@ -113,6 +115,7 @@ static gboolean exec_cmd(const char *cmd, int run_in_term, const char *orig) {
|
|||
|
||||
char *path = g_build_filename(cache_dir, RUN_CACHE_FILE, NULL);
|
||||
RofiHelperExecuteContext context = {.name = NULL};
|
||||
char *hist = g_strdup_printf("%s\x1f%s", orig, cmd);
|
||||
// FIXME: assume startup notification support for terminals
|
||||
if (helper_execute_command(NULL, lf_cmd, run_in_term,
|
||||
run_in_term ? &context : NULL)) {
|
||||
|
@ -121,12 +124,14 @@ static gboolean exec_cmd(const char *cmd, int run_in_term, const char *orig) {
|
|||
* It is allowed to be a bit slower.
|
||||
*/
|
||||
|
||||
history_set(path, orig);
|
||||
history_set(path, hist);
|
||||
g_free(path);
|
||||
g_free(lf_cmd);
|
||||
g_free(hist);
|
||||
return TRUE;
|
||||
}
|
||||
history_remove(path, orig);
|
||||
history_remove(path, hist);
|
||||
g_free(hist);
|
||||
g_free(path);
|
||||
g_free(lf_cmd);
|
||||
return FALSE;
|
||||
|
@ -140,8 +145,9 @@ static gboolean exec_cmd(const char *cmd, int run_in_term, const char *orig) {
|
|||
static void delete_entry(const RunEntry *cmd) {
|
||||
char *path = g_build_filename(cache_dir, RUN_CACHE_FILE, NULL);
|
||||
|
||||
history_remove(path, cmd->entry);
|
||||
|
||||
char *hist = g_strdup_printf("%s\x1f%s", cmd->entry, cmd->exec);
|
||||
history_remove(path, hist);
|
||||
g_free(hist);
|
||||
g_free(path);
|
||||
}
|
||||
|
||||
|
@ -205,6 +211,8 @@ static RunEntry *get_apps_external(RunEntry *retv, unsigned int *length,
|
|||
// No duplicate, add it.
|
||||
retv = g_realloc(retv, ((*length) + 2) * sizeof(RunEntry));
|
||||
retv[(*length)].entry = g_strdup(buffer);
|
||||
retv[(*length)].exec = g_shell_quote(buffer);
|
||||
retv[(*length)].from_history = FALSE;
|
||||
retv[(*length)].icon = NULL;
|
||||
retv[(*length)].icon_fetch_uid = 0;
|
||||
retv[(*length)].icon_fetch_size = 0;
|
||||
|
@ -221,6 +229,8 @@ static RunEntry *get_apps_external(RunEntry *retv, unsigned int *length,
|
|||
}
|
||||
}
|
||||
retv[(*length)].entry = NULL;
|
||||
retv[(*length)].exec = NULL;
|
||||
retv[(*length)].from_history = FALSE;
|
||||
retv[(*length)].icon = NULL;
|
||||
retv[(*length)].icon_fetch_uid = 0;
|
||||
retv[(*length)].icon_fetch_size = 0;
|
||||
|
@ -244,7 +254,14 @@ static RunEntry *get_apps(unsigned int *length) {
|
|||
char **hretv = history_get_list(path, length);
|
||||
retv = (RunEntry *)g_malloc0((*length + 1) * sizeof(RunEntry));
|
||||
for (unsigned int i = 0; i < *length; i++) {
|
||||
retv[i].entry = hretv[i];
|
||||
gchar **rs = g_strsplit(hretv[i], "\x1f", 2);
|
||||
retv[i].entry = rs[0];
|
||||
retv[i].exec = rs[1];
|
||||
if (retv[i].exec == NULL) {
|
||||
retv[i].exec = g_strdup(rs[0]);
|
||||
}
|
||||
retv[i].from_history = TRUE;
|
||||
g_free(rs);
|
||||
}
|
||||
g_free(hretv);
|
||||
g_free(path);
|
||||
|
@ -259,6 +276,7 @@ static RunEntry *get_apps(unsigned int *length) {
|
|||
g_debug("Failed to convert homedir to UTF-8: %s", error->message);
|
||||
for (unsigned int i = 0; retv[i].entry != NULL; i++) {
|
||||
g_free(retv[i].entry);
|
||||
g_free(retv[i].exec);
|
||||
}
|
||||
g_free(retv);
|
||||
g_clear_error(&error);
|
||||
|
@ -332,10 +350,14 @@ static RunEntry *get_apps(unsigned int *length) {
|
|||
|
||||
retv = g_realloc(retv, ((*length) + 2) * sizeof(RunEntry));
|
||||
retv[(*length)].entry = name;
|
||||
retv[(*length)].exec = g_shell_quote(name);
|
||||
retv[(*length)].from_history = FALSE;
|
||||
retv[(*length)].icon = NULL;
|
||||
retv[(*length)].icon_fetch_uid = 0;
|
||||
retv[(*length)].icon_fetch_size = 0;
|
||||
retv[(*length) + 1].entry = NULL;
|
||||
retv[(*length) + 1].exec = NULL;
|
||||
retv[(*length) + 1].from_history = FALSE;
|
||||
retv[(*length) + 1].icon = NULL;
|
||||
retv[(*length) + 1].icon_fetch_uid = 0;
|
||||
retv[(*length) + 1].icon_fetch_size = 0;
|
||||
|
@ -367,6 +389,8 @@ static RunEntry *get_apps(unsigned int *length) {
|
|||
if (g_strcmp0(retv[index].entry, retv[index + 1].entry) == 0) {
|
||||
g_free(retv[index].entry);
|
||||
retv[index].entry = NULL;
|
||||
g_free(retv[index].exec);
|
||||
retv[index].exec = NULL;
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
|
@ -397,6 +421,7 @@ static void run_mode_destroy(Mode *sw) {
|
|||
if (rmpd != NULL) {
|
||||
for (unsigned int i = 0; i < rmpd->cmd_list_length; i++) {
|
||||
g_free(rmpd->cmd_list[i].entry);
|
||||
g_free(rmpd->cmd_list[i].exec);
|
||||
if (rmpd->cmd_list[i].icon != NULL) {
|
||||
cairo_surface_destroy(rmpd->cmd_list[i].icon);
|
||||
}
|
||||
|
@ -447,16 +472,14 @@ static ModeMode run_mode_result(Mode *sw, int mretv, char **input,
|
|||
&path);
|
||||
if (retv == MODE_EXIT) {
|
||||
if (path == NULL) {
|
||||
char *arg = g_shell_quote(rmpd->cmd_list[rmpd->selected_line].entry);
|
||||
char *arg = rmpd->cmd_list[rmpd->selected_line].exec;
|
||||
exec_cmd(arg, run_in_term, rmpd->cmd_list[rmpd->selected_line].entry);
|
||||
g_free(arg);
|
||||
} else {
|
||||
char *earg = g_shell_quote(rmpd->cmd_list[rmpd->selected_line].entry);
|
||||
char *earg = rmpd->cmd_list[rmpd->selected_line].exec;
|
||||
char *epath = g_shell_quote(path);
|
||||
char *arg = g_strdup_printf("%s %s", earg, epath);
|
||||
exec_cmd(arg, run_in_term, arg);
|
||||
g_free(arg);
|
||||
g_free(earg);
|
||||
g_free(epath);
|
||||
}
|
||||
}
|
||||
|
@ -466,11 +489,11 @@ static ModeMode run_mode_result(Mode *sw, int mretv, char **input,
|
|||
}
|
||||
|
||||
if ((mretv & MENU_OK) && rmpd->cmd_list[selected_line].entry != NULL) {
|
||||
char *earg = g_shell_quote(rmpd->cmd_list[selected_line].entry);
|
||||
char *earg = NULL;
|
||||
earg = rmpd->cmd_list[selected_line].exec;
|
||||
if (!exec_cmd(earg, run_in_term, rmpd->cmd_list[selected_line].entry)) {
|
||||
retv = RELOAD_DIALOG;
|
||||
}
|
||||
g_free(earg);
|
||||
} else if ((mretv & MENU_CUSTOM_INPUT) && *input != NULL &&
|
||||
*input[0] != '\0') {
|
||||
if (!exec_cmd(*input, run_in_term, *input)) {
|
||||
|
|
|
@ -94,7 +94,7 @@ static void rofi_icon_fetch_entry_free(gpointer data);
|
|||
IconFetcher *rofi_icon_fetcher_data = NULL;
|
||||
|
||||
static void rofi_icon_fetch_thread_pool_entry_remove(gpointer data) {
|
||||
IconFetcherNameEntry *entry = (IconFetcherNameEntry *)data;
|
||||
IconFetcherEntry *entry = (IconFetcherEntry *)data;
|
||||
// Mark it in a way it should be re-fetched on next query?
|
||||
}
|
||||
static void rofi_icon_fetch_entry_free(gpointer data) {
|
||||
|
|
|
@ -2653,6 +2653,15 @@ static int rofi_thread_workers_sort(gconstpointer a, gconstpointer b,
|
|||
|
||||
static void rofi_thread_pool_state_free(gpointer data) {
|
||||
if (data) {
|
||||
// This is a weirdness from glib that should not happen.
|
||||
// It pushes in a 1 to msg sleeping threads to wake up.
|
||||
// This should be removed from queue to avoid hitting this method.
|
||||
// In practice, we still hit it (and crash)
|
||||
if (GPOINTER_TO_UINT(data) == 1) {
|
||||
// Ignore this entry.
|
||||
g_debug("Glib thread-pool bug, received pointer with value 1.");
|
||||
return;
|
||||
}
|
||||
thread_state *ts = (thread_state *)data;
|
||||
if (ts->free) {
|
||||
ts->free(data);
|
||||
|
|
|
@ -693,10 +693,10 @@ listview_trigger_action(widget *wid, MouseBindingListviewAction action,
|
|||
listview_nav_right(lv);
|
||||
break;
|
||||
case SCROLL_DOWN:
|
||||
listview_nav_down(lv);
|
||||
listview_scroll_next(lv);
|
||||
break;
|
||||
case SCROLL_UP:
|
||||
listview_nav_up(lv);
|
||||
listview_scroll_prev(lv);
|
||||
break;
|
||||
}
|
||||
return WIDGET_TRIGGER_ACTION_RESULT_HANDLED;
|
||||
|
@ -863,6 +863,67 @@ void listview_nav_prev(listview *lv) {
|
|||
listview_nav_up_int(lv);
|
||||
}
|
||||
|
||||
|
||||
static void listview_scroll_up_int(listview *lv) {
|
||||
if (lv == NULL) {
|
||||
return;
|
||||
}
|
||||
unsigned int mult = 1;
|
||||
if (config.scroll_multiplier){
|
||||
mult = config.scroll_multiplier;
|
||||
}
|
||||
for (unsigned int i=0; i < mult; i++) {
|
||||
if (lv->req_elements == 0 || (lv->selected == 0 && !lv->cycle)) {
|
||||
return;
|
||||
}
|
||||
if (lv->selected == 0) {
|
||||
lv->selected = lv->req_elements;
|
||||
}
|
||||
lv->selected--;
|
||||
}
|
||||
lv->barview.direction = RIGHT_TO_LEFT;
|
||||
|
||||
if (lv->sc_callback) {
|
||||
lv->sc_callback(lv, lv->selected, lv->sc_udata);
|
||||
}
|
||||
widget_queue_redraw(WIDGET(lv));
|
||||
}
|
||||
static void listview_scroll_down_int(listview *lv) {
|
||||
if (lv == NULL) {
|
||||
return;
|
||||
}
|
||||
unsigned int mult = 1;
|
||||
if (config.scroll_multiplier){
|
||||
mult = config.scroll_multiplier;
|
||||
}
|
||||
for (unsigned int i=0; i < mult; i++) {
|
||||
if (lv->req_elements == 0 ||
|
||||
(lv->selected == (lv->req_elements - 1) && !lv->cycle)) {
|
||||
return;
|
||||
}
|
||||
lv->selected = lv->selected < lv->req_elements - 1
|
||||
? MIN(lv->req_elements - 1, lv->selected + 1)
|
||||
: 0;
|
||||
}
|
||||
lv->barview.direction = LEFT_TO_RIGHT;
|
||||
if (lv->sc_callback) {
|
||||
lv->sc_callback(lv, lv->selected, lv->sc_udata);
|
||||
}
|
||||
widget_queue_redraw(WIDGET(lv));
|
||||
}
|
||||
void listview_scroll_next(listview *lv) {
|
||||
if (lv == NULL) {
|
||||
return;
|
||||
}
|
||||
listview_scroll_down_int(lv);
|
||||
}
|
||||
void listview_scroll_prev(listview *lv) {
|
||||
if (lv == NULL) {
|
||||
return;
|
||||
}
|
||||
listview_scroll_up_int(lv);
|
||||
}
|
||||
|
||||
static void listview_nav_column_left_int(listview *lv) {
|
||||
if (lv->selected >= lv->cur_columns) {
|
||||
lv->selected -= lv->cur_columns;
|
||||
|
|
|
@ -333,6 +333,12 @@ static XrmOption xrmOptions[] = {
|
|||
NULL,
|
||||
"Threads to use for string matching",
|
||||
CONFIG_DEFAULT},
|
||||
{xrm_Number,
|
||||
"scroll-multiplier",
|
||||
{.num = &config.scroll_multiplier},
|
||||
NULL,
|
||||
"Scrolling multiplier (how many times as many lines to scroll)",
|
||||
CONFIG_DEFAULT},
|
||||
{xrm_Number,
|
||||
"scroll-method",
|
||||
{.num = &config.scroll_method},
|
||||
|
|
Loading…
Reference in New Issue