diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/dialogs/combi.c | 12 | ||||
-rw-r--r-- | source/dialogs/dmenu.c | 172 | ||||
-rw-r--r-- | source/dialogs/drun.c | 246 | ||||
-rw-r--r-- | source/dialogs/help-keys.c | 2 | ||||
-rw-r--r-- | source/dialogs/run.c | 2 | ||||
-rw-r--r-- | source/dialogs/script.c | 138 | ||||
-rw-r--r-- | source/dialogs/ssh.c | 2 | ||||
-rw-r--r-- | source/dialogs/window.c | 90 | ||||
-rw-r--r-- | source/helper.c | 135 | ||||
-rw-r--r-- | source/history.c | 68 | ||||
-rw-r--r-- | source/keyb.c | 2 | ||||
-rw-r--r-- | source/mode.c | 2 | ||||
-rw-r--r-- | source/rofi.c | 53 | ||||
-rw-r--r-- | source/theme.c | 74 | ||||
-rw-r--r-- | source/view.c | 33 | ||||
-rw-r--r-- | source/widgets/container.c | 2 | ||||
-rw-r--r-- | source/widgets/listview.c | 12 | ||||
-rw-r--r-- | source/widgets/textbox.c | 7 | ||||
-rw-r--r-- | source/xcb.c | 14 | ||||
-rw-r--r-- | source/xrmoptions.c | 122 |
20 files changed, 771 insertions, 417 deletions
diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c index a41e54e6..077527e2 100644 --- a/source/dialogs/combi.c +++ b/source/dialogs/combi.c @@ -124,13 +124,13 @@ static int combi_mode_init ( Mode *sw ) } static unsigned int combi_mode_get_num_entries ( const Mode *sw ) { - const CombiModePrivateData *pd = (const CombiModePrivateData *) mode_get_private_data ( sw ); - unsigned int length = 0; + const CombiModePrivateData *pd = (const CombiModePrivateData *) mode_get_private_data ( sw ); + unsigned int length = 0; for ( unsigned int i = 0; i < pd->num_switchers; i++ ) { unsigned int entries = mode_get_num_entries ( pd->switchers[i].mode ); - pd->starts[i] = length; - pd->lengths[i] = entries; - length+=entries; + pd->starts[i] = length; + pd->lengths[i] = entries; + length += entries; } return length; } @@ -187,7 +187,7 @@ static ModeMode combi_mode_result ( Mode *sw, int mretv, char **input, unsigned } return MODE_EXIT; } -static int combi_mode_match ( const Mode *sw, GRegex **tokens, unsigned int index ) +static int combi_mode_match ( const Mode *sw, rofi_int_matcher **tokens, unsigned int index ) { CombiModePrivateData *pd = mode_get_private_data ( sw ); for ( unsigned i = 0; i < pd->num_switchers; i++ ) { diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c index 691b79b9..13b07a84 100644 --- a/source/dialogs/dmenu.c +++ b/source/dialogs/dmenu.c @@ -49,12 +49,6 @@ #include "xrmoptions.h" #include "view.h" -struct range_pair -{ - unsigned int start; - unsigned int stop; -}; - static inline unsigned int bitget ( uint32_t *array, unsigned int index ) { uint32_t bit = index % 32; @@ -73,33 +67,33 @@ typedef struct { /** Settings */ // Separator. - char separator; - - unsigned int selected_line; - char *message; - char *format; - struct range_pair * urgent_list; - unsigned int num_urgent_list; - struct range_pair * active_list; - unsigned int num_active_list; - uint32_t *selected_list; - unsigned int num_selected_list; - unsigned int do_markup; + char separator; + + unsigned int selected_line; + char *message; + char *format; + struct rofi_range_pair * urgent_list; + unsigned int num_urgent_list; + struct rofi_range_pair * active_list; + unsigned int num_active_list; + uint32_t *selected_list; + unsigned int num_selected_list; + unsigned int do_markup; // List with entries. - char **cmd_list; - unsigned int cmd_list_real_length; - unsigned int cmd_list_length; - unsigned int only_selected; - unsigned int selected_count; - - gchar **columns; - gchar *column_separator; - gboolean multi_select; - - GCancellable *cancel; - gulong cancel_source; - GInputStream *input_stream; - GDataInputStream *data_input_stream; + char **cmd_list; + unsigned int cmd_list_real_length; + unsigned int cmd_list_length; + unsigned int only_selected; + unsigned int selected_count; + + gchar **columns; + gchar *column_separator; + gboolean multi_select; + + GCancellable *cancel; + gulong cancel_source; + GInputStream *input_stream; + GDataInputStream *data_input_stream; } DmenuModePrivateData; static void async_close_callback ( GObject *source_object, GAsyncResult *res, G_GNUC_UNUSED gpointer user_data ) @@ -206,43 +200,6 @@ static unsigned int dmenu_mode_get_num_entries ( const Mode *sw ) return rmpd->cmd_list_length; } -static void parse_pair ( char *input, struct range_pair *item ) -{ - int index = 0; - const char * const sep = "-"; - for ( char *token = strsep ( &input, sep ); token != NULL; token = strsep ( &input, sep ) ) { - if ( index == 0 ) { - item->start = item->stop = (unsigned int) strtoul ( token, NULL, 10 ); - index++; - } - else { - if ( token[0] == '\0' ) { - item->stop = 0xFFFFFFFF; - } - else{ - item->stop = (unsigned int) strtoul ( token, NULL, 10 ); - } - } - } -} - -static void parse_ranges ( char *input, struct range_pair **list, unsigned int *length ) -{ - char *endp; - if ( input == NULL ) { - return; - } - const char *const sep = ","; - for ( char *token = strtok_r ( input, sep, &endp ); token != NULL; token = strtok_r ( NULL, sep, &endp ) ) { - // Make space. - *list = g_realloc ( ( *list ), ( ( *length ) + 1 ) * sizeof ( struct range_pair ) ); - // Parse a single pair. - parse_pair ( token, &( ( *list )[*length] ) ); - - ( *length )++; - } -} - static gchar * dmenu_format_output_string ( const DmenuModePrivateData *pd, const char *input ) { if ( pd->columns == NULL ) { @@ -295,61 +252,6 @@ static char *get_display_data ( const Mode *data, unsigned int index, int *state return get_entry ? dmenu_format_output_string ( pd, retv[index] ) : NULL; } -/** - * @param format The format string used. See below for possible syntax. - * @param string The selected entry. - * @param selected_line The selected line index. - * @param filter The entered filter. - * - * Function that outputs the selected line in the user-specified format. - * Currently the following formats are supported: - * * i: Print the index (0-(N-1)) - * * d: Print the index (1-N) - * * s: Print input string. - * * q: Print quoted input string. - * * f: Print the entered filter. - * * F: Print the entered filter, quoted - * - * This functions outputs the formatted string to stdout, appends a newline (\n) character and - * calls flush on the file descriptor. - */ -static void dmenu_output_formatted_line ( const char *format, const char *string, int selected_line, - const char *filter ) -{ - for ( int i = 0; format && format[i]; i++ ) { - if ( format[i] == 'i' ) { - fprintf ( stdout, "%d", selected_line ); - } - else if ( format[i] == 'd' ) { - fprintf ( stdout, "%d", ( selected_line + 1 ) ); - } - else if ( format[i] == 's' ) { - fputs ( string, stdout ); - } - else if ( format[i] == 'q' ) { - char *quote = g_shell_quote ( string ); - fputs ( quote, stdout ); - g_free ( quote ); - } - else if ( format[i] == 'f' ) { - if ( filter ) { - fputs ( filter, stdout ); - } - } - else if ( format[i] == 'F' ) { - if ( filter ) { - char *quote = g_shell_quote ( filter ); - fputs ( quote, stdout ); - g_free ( quote ); - } - } - else { - fputc ( format[i], stdout ); - } - } - fputc ( '\n', stdout ); - fflush ( stdout ); -} static void dmenu_mode_free ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { @@ -467,7 +369,7 @@ static int dmenu_mode_init ( Mode *sw ) return TRUE; } -static int dmenu_token_match ( const Mode *sw, GRegex **tokens, unsigned int index ) +static int dmenu_token_match ( const Mode *sw, rofi_int_matcher **tokens, unsigned int index ) { DmenuModePrivateData *rmpd = (DmenuModePrivateData *) mode_get_private_data ( sw ); return helper_token_match ( tokens, rmpd->cmd_list[index] ); @@ -525,7 +427,7 @@ static void dmenu_print_results ( DmenuModePrivateData *pd, const char *input ) for ( unsigned int st = 0; st < pd->cmd_list_length; st++ ) { if ( bitget ( pd->selected_list, st ) ) { seen = TRUE; - dmenu_output_formatted_line ( pd->format, cmd_list[st], st, input ); + rofi_output_formatted_line ( pd->format, cmd_list[st], st, input ); } } } @@ -534,7 +436,7 @@ static void dmenu_print_results ( DmenuModePrivateData *pd, const char *input ) if ( pd->selected_line != UINT32_MAX ) { cmd = cmd_list[pd->selected_line]; } - dmenu_output_formatted_line ( pd->format, cmd, pd->selected_line, input ); + rofi_output_formatted_line ( pd->format, cmd, pd->selected_line, input ); } } @@ -696,7 +598,7 @@ int dmenu_switcher_dialog ( void ) } } if ( config.auto_select && cmd_list_length == 1 ) { - dmenu_output_formatted_line ( pd->format, cmd_list[0], 0, config.filter ); + rofi_output_formatted_line ( pd->format, cmd_list[0], 0, config.filter ); return TRUE; } if ( find_arg ( "-password" ) >= 0 ) { @@ -708,25 +610,25 @@ int dmenu_switcher_dialog ( void ) char *select = NULL; find_arg_str ( "-select", &select ); if ( select != NULL ) { - GRegex **tokens = tokenize ( select, config.case_sensitive ); - unsigned int i = 0; + rofi_int_matcher **tokens = helper_tokenize ( select, config.case_sensitive ); + unsigned int i = 0; for ( i = 0; i < cmd_list_length; i++ ) { if ( helper_token_match ( tokens, cmd_list[i] ) ) { pd->selected_line = i; break; } } - tokenize_free ( tokens ); + helper_tokenize_free ( tokens ); } if ( find_arg ( "-dump" ) >= 0 ) { - GRegex **tokens = tokenize ( config.filter ? config.filter : "", config.case_sensitive ); - unsigned int i = 0; + rofi_int_matcher **tokens = helper_tokenize ( config.filter ? config.filter : "", config.case_sensitive ); + unsigned int i = 0; for ( i = 0; i < cmd_list_length; i++ ) { if ( tokens == NULL || helper_token_match ( tokens, cmd_list[i] ) ) { - dmenu_output_formatted_line ( pd->format, cmd_list[i], i, config.filter ); + rofi_output_formatted_line ( pd->format, cmd_list[i], i, config.filter ); } } - tokenize_free ( tokens ); + helper_tokenize_free ( tokens ); dmenu_mode_free ( &dmenu_mode ); g_free ( input ); return TRUE; diff --git a/source/dialogs/drun.c b/source/dialogs/drun.c index c891429b..961b0e2f 100644 --- a/source/dialogs/drun.c +++ b/source/dialogs/drun.c @@ -31,6 +31,7 @@ #ifdef ENABLE_DRUN #include <stdlib.h> #include <stdio.h> +#include <limits.h> #include <unistd.h> #include <limits.h> @@ -52,7 +53,7 @@ #include "nkutils-xdg-theme.h" #include "xcb.h" -#define DRUN_CACHE_FILE "rofi2.druncache" +#define DRUN_CACHE_FILE "rofi3.druncache" /** * Store extra information about the entry. @@ -66,6 +67,8 @@ typedef struct char *path; /* Application id (.desktop filename) */ char *app_id; + /* Desktop id */ + char *desktop_id; /* Icon stuff */ char *icon_name; /* Icon size is used to indicate what size is requested by the gui. @@ -83,24 +86,49 @@ typedef struct char **categories; GKeyFile *key_file; + + gint sort_index; } DRunModeEntry; typedef struct { + const char *entry_field_name; + gboolean enabled; +} DRunEntryField; + +typedef enum +{ + DRUN_MATCH_FIELD_NAME, + DRUN_MATCH_FIELD_GENERIC, + DRUN_MATCH_FIELD_EXEC, + DRUN_MATCH_FIELD_CATEGORIES, + DRUN_MATCH_NUM_FIELDS, +} DRunMatchingFields; + +static DRunEntryField matching_entry_fields[DRUN_MATCH_NUM_FIELDS] = { + { .entry_field_name = "name", .enabled = TRUE, }, + { .entry_field_name = "generic", .enabled = TRUE, }, + { .entry_field_name = "exec", .enabled = TRUE, }, + { .entry_field_name = "categories", .enabled = TRUE, } +}; + +typedef struct +{ NkXdgThemeContext *xdg_context; DRunModeEntry *entry_list; unsigned int cmd_list_length; unsigned int cmd_list_length_actual; - unsigned int history_length; // List of disabled entries. GHashTable *disabled_entries; unsigned int disabled_entries_length; GThreadPool *pool; - unsigned int expected_line_height; DRunModeEntry quit_entry; + // Theme const gchar *icon_theme; + // DE + gchar **current_desktop_list; } DRunModePrivateData; struct RegexEvalArg @@ -108,6 +136,7 @@ struct RegexEvalArg DRunModeEntry *e; gboolean success; }; + static gboolean drun_helper_eval_cb ( const GMatchInfo *info, GString *res, gpointer data ) { // TODO quoting is not right? Find description not very clear, need to check. @@ -207,9 +236,8 @@ static void exec_cmd_entry ( DRunModeEntry *e ) gboolean terminal = g_key_file_get_boolean ( e->key_file, "Desktop Entry", "Terminal", NULL ); if ( helper_execute_command ( exec_path, fp, terminal, sn ? &context : NULL ) ) { char *path = g_build_filename ( cache_dir, DRUN_CACHE_FILE, NULL ); - char *key = g_strdup_printf ( "%s:::%s", e->root, e->path ); - history_set ( path, key ); - g_free ( key ); + // Store it based on the unique identifiers (desktop_id). + history_set ( path, e->desktop_id ); g_free ( path ); } g_free ( wmclass ); @@ -277,6 +305,42 @@ static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, c g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) ); return FALSE; } + if ( pd->current_desktop_list ) { + gboolean show = TRUE; + // If the DE is set, check the keys. + if ( g_key_file_has_key ( kf, "Desktop Entry", "OnlyShowIn", NULL ) ) { + gsize llength = 0; + show = FALSE; + gchar **list = g_key_file_get_string_list ( kf, "Desktop Entry", "OnlyShowIn", &llength, NULL); + if ( list ) { + for ( gsize lcd = 0; !show && pd->current_desktop_list[lcd]; lcd++ ) { + for ( gsize lle = 0; !show && lle < llength; lle++ ) { + show = ( g_strcmp0 ( pd->current_desktop_list[lcd], list[lle] ) == 0 ); + } + } + g_strfreev ( list ); + } + } + if ( show && g_key_file_has_key ( kf, "Desktop Entry", "NotShowIn", NULL )) { + gsize llength = 0; + gchar **list = g_key_file_get_string_list ( kf, "Desktop Entry", "NotShowIn", &llength, NULL); + if ( list ) { + for ( gsize lcd = 0; show && pd->current_desktop_list[lcd]; lcd++ ) { + for ( gsize lle = 0; show && lle < llength; lle++ ) { + show = ! ( g_strcmp0 ( pd->current_desktop_list[lcd], list[lle] ) == 0 ); + } + } + g_strfreev ( list ); + } + } + + if ( ! show ) { + g_debug ( "Adding desktop file: %s to disabled list because: OnlyShowIn/NotShowIn", path ); + g_key_file_free ( kf ); + g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) ); + return FALSE; + } + } // Skip entries that have NoDisplay set. if ( g_key_file_get_boolean ( kf, "Desktop Entry", "NoDisplay", NULL ) ) { g_debug ( "Adding desktop file: %s to disabled list because: NoDisplay", path ); @@ -317,10 +381,20 @@ static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, c pd->cmd_list_length_actual += 256; pd->entry_list = g_realloc ( pd->entry_list, pd->cmd_list_length_actual * sizeof ( *( pd->entry_list ) ) ); } - pd->entry_list[pd->cmd_list_length].icon_size = 0; - pd->entry_list[pd->cmd_list_length].root = g_strdup ( root ); - pd->entry_list[pd->cmd_list_length].path = g_strdup ( path ); - pd->entry_list[pd->cmd_list_length].app_id = g_strndup ( basename, strlen ( basename ) - strlen ( ".desktop" ) ); + // Make sure order is preserved, this will break when cmd_list_length is bigger then INT_MAX. + // This is not likely to happen. + if ( G_UNLIKELY ( pd->cmd_list_length > INT_MAX ) ) { + // Default to smallest value. + pd->entry_list[pd->cmd_list_length].sort_index = INT_MIN; + } + else { + pd->entry_list[pd->cmd_list_length].sort_index = -pd->cmd_list_length; + } + pd->entry_list[pd->cmd_list_length].icon_size = 0; + pd->entry_list[pd->cmd_list_length].root = g_strdup ( root ); + pd->entry_list[pd->cmd_list_length].path = g_strdup ( path ); + pd->entry_list[pd->cmd_list_length].desktop_id = g_strdup ( id ); + pd->entry_list[pd->cmd_list_length].app_id = g_strndup ( basename, strlen ( basename ) - strlen ( ".desktop" ) ); gchar *n = g_key_file_get_locale_string ( kf, "Desktop Entry", "Name", NULL, NULL ); pd->entry_list[pd->cmd_list_length].name = n; gchar *gn = g_key_file_get_locale_string ( kf, "Desktop Entry", "GenericName", NULL, NULL ); @@ -416,36 +490,46 @@ static void walk_dir ( DRunModePrivateData *pd, const char *root, const char *di static void delete_entry_history ( const DRunModeEntry *entry ) { char *path = g_build_filename ( cache_dir, DRUN_CACHE_FILE, NULL ); - char *key = g_strdup_printf ( "%s:::%s", entry->root, entry->path ); - history_remove ( path, key ); - g_free ( key ); + history_remove ( path, entry->desktop_id ); g_free ( path ); } static void get_apps_history ( DRunModePrivateData *pd ) { + TICK_N ( "Start drun history" ); unsigned int length = 0; gchar *path = g_build_filename ( cache_dir, DRUN_CACHE_FILE, NULL ); gchar **retv = history_get_list ( path, &length ); for ( unsigned int index = 0; index < length; index++ ) { - char **st = g_strsplit ( retv[index], ":::", 2 ); - if ( st && st[0] && st[1] ) { - const gchar *basename = g_utf8_strrchr ( st[1], -1, G_DIR_SEPARATOR ); - if ( basename == NULL || !read_desktop_file ( pd, st[0], st[1], ++basename ) ) { - history_remove ( path, retv[index] ); + for ( size_t i = 0; i < pd->cmd_list_length; i++ ) { + if ( g_strcmp0 ( pd->entry_list[i].desktop_id, retv[index] ) == 0 ) { + unsigned int sort_index = length - index; + if ( G_LIKELY ( sort_index < INT_MAX ) ) { + pd->entry_list[i].sort_index = sort_index; + } + else { + // This won't sort right anymore, but never gonna hit it anyway. + pd->entry_list[i].sort_index = INT_MAX; + } } } - g_strfreev ( st ); } g_strfreev ( retv ); g_free ( path ); - pd->history_length = pd->cmd_list_length; + TICK_N ( "Stop drun history" ); +} + +static gint drun_int_sort_list ( gconstpointer a, gconstpointer b, G_GNUC_UNUSED gpointer user_data ) +{ + DRunModeEntry *da = (DRunModeEntry *) a; + DRunModeEntry *db = (DRunModeEntry *) b; + + return db->sort_index - da->sort_index; } static void get_apps ( DRunModePrivateData *pd ) { TICK_N ( "Get Desktop apps (start)" ); - get_apps_history ( pd ); gchar *dir; // First read the user directory. @@ -471,6 +555,11 @@ static void get_apps ( DRunModePrivateData *pd ) } } TICK_N ( "Get Desktop apps (system dirs)" ); + get_apps_history ( pd ); + + g_qsort_with_data ( pd->entry_list, pd->cmd_list_length, sizeof ( DRunModeEntry ), drun_int_sort_list, NULL ); + + TICK_N ( "Sorting done." ); } static void drun_icon_fetch ( gpointer data, gpointer user_data ) @@ -488,13 +577,20 @@ static void drun_icon_fetch ( gpointer data, gpointer user_data ) if ( dr->icon_name == NULL ) { return; } - gchar *icon_path = nk_xdg_theme_get_icon ( pd->xdg_context, themes, NULL, dr->icon_name, dr->icon_size, 1, TRUE ); - if ( icon_path == NULL ) { - g_debug ( "Failed to get Icon %s(%d): n/a", dr->icon_name, dr->icon_size ); - return; - } - else{ - g_debug ( "Found Icon %s(%d): %s", dr->icon_name, dr->icon_size, icon_path ); + const gchar *icon_path; + gchar *icon_path_ = NULL; + + if ( g_path_is_absolute ( dr->icon_name ) ) + icon_path = dr->icon_name; + else { + icon_path = icon_path_ = nk_xdg_theme_get_icon ( pd->xdg_context, themes, NULL, dr->icon_name, dr->icon_size, 1, TRUE ); + if ( icon_path_ == NULL ) { + g_debug ( "Failed to get Icon %s(%d): n/a", dr->icon_name, dr->icon_size ); + return; + } + else{ + g_debug ( "Found Icon %s(%d): %s", dr->icon_name, dr->icon_size, icon_path ); + } } cairo_surface_t *icon_surf = NULL; if ( g_str_has_suffix ( icon_path, ".png" ) ) { @@ -515,10 +611,46 @@ static void drun_icon_fetch ( gpointer data, gpointer user_data ) } dr->icon = icon_surf; } - g_free ( icon_path ); + g_free ( icon_path_ ); rofi_view_reload (); } +static void drun_mode_parse_entry_fields () +{ + char *savept = NULL; + // Make a copy, as strtok will modify it. + char *switcher_str = g_strdup ( config.drun_match_fields ); + const char * const sep = ",#"; + // Split token on ','. This modifies switcher_str. + for ( unsigned int i = 0; i < DRUN_MATCH_NUM_FIELDS; i++ ) { + matching_entry_fields[i].enabled = FALSE; + } + for ( char *token = strtok_r ( switcher_str, sep, &savept ); token != NULL; + token = strtok_r ( NULL, sep, &savept ) ) { + if ( strcmp ( token, "all" ) == 0 ) { + for ( unsigned int i = 0; i < DRUN_MATCH_NUM_FIELDS; i++ ) { + matching_entry_fields[i].enabled = TRUE; + } + break; + } + else { + gboolean matched = FALSE; + for ( unsigned int i = 0; i < DRUN_MATCH_NUM_FIELDS; i++ ) { + const char * entry_name = matching_entry_fields[i].entry_field_name; + if ( strcmp ( token, entry_name ) == 0 ) { + matching_entry_fields[i].enabled = TRUE; + matched = TRUE; + } + } + if ( !matched ) { + g_warning ( "Invalid entry name :%s", token ); + } + } + } + // Free string that was modified by strtok_r + g_free ( switcher_str ); +} + static int drun_mode_init ( Mode *sw ) { if ( mode_get_private_data ( sw ) == NULL ) { @@ -534,9 +666,16 @@ static int drun_mode_init ( Mode *sw ) DRunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); pd->disabled_entries = g_hash_table_new_full ( g_str_hash, g_str_equal, g_free, NULL ); mode_set_private_data ( sw, (void *) pd ); + // current destkop + const char *current_desktop = g_getenv ( "XDG_CURRENT_DESKTOP" ); + pd->current_desktop_list = current_desktop? g_strsplit(current_desktop, ":", 0) : NULL; + + + // Theme pd->xdg_context = nk_xdg_theme_context_new ( drun_icon_fallback_themes, NULL ); nk_xdg_theme_preload_themes_icon ( pd->xdg_context, themes ); get_apps ( pd ); + drun_mode_parse_entry_fields (); } return TRUE; } @@ -545,6 +684,7 @@ static void drun_entry_clear ( DRunModeEntry *e ) g_free ( e->root ); g_free ( e->path ); g_free ( e->app_id ); + g_free ( e->desktop_id ); if ( e->icon != NULL ) { cairo_surface_destroy ( e->icon ); } @@ -581,7 +721,8 @@ static ModeMode drun_mode_result ( Mode *sw, int mretv, char **input, unsigned i helper_execute_command ( NULL, *input, run_in_term, run_in_term ? &context : NULL ); } else if ( ( mretv & MENU_ENTRY_DELETE ) && selected_line < rmpd->cmd_list_length ) { - if ( selected_line < rmpd->history_length ) { + // Possitive sort index means it is in history. + if ( rmpd->entry_list[selected_line].sort_index >= 0 ) { if ( rmpd->pool ) { g_thread_pool_free ( rmpd->pool, TRUE, TRUE ); rmpd->pool = NULL; @@ -610,6 +751,8 @@ static void drun_mode_destroy ( Mode *sw ) g_hash_table_destroy ( rmpd->disabled_entries ); g_free ( rmpd->entry_list ); nk_xdg_theme_context_free ( rmpd->xdg_context ); + + g_strfreev ( rmpd->current_desktop_list ); g_free ( rmpd ); mode_set_private_data ( sw, NULL ); } @@ -667,33 +810,39 @@ static char *drun_get_completion ( const Mode *sw, unsigned int index ) } } -static int drun_token_match ( const Mode *data, GRegex **tokens, unsigned int index ) +static int drun_token_match ( const Mode *data, rofi_int_matcher **tokens, unsigned int index ) { DRunModePrivateData *rmpd = (DRunModePrivateData *) mode_get_private_data ( data ); int match = 1; if ( tokens ) { for ( int j = 0; match && tokens != NULL && tokens[j] != NULL; j++ ) { - int test = 0; - GRegex *ftokens[2] = { tokens[j], NULL }; + int test = 0; + rofi_int_matcher *ftokens[2] = { tokens[j], NULL }; // Match name - if ( rmpd->entry_list[index].name && - helper_token_match ( ftokens, rmpd->entry_list[index].name ) ) { - test = 1; + if ( matching_entry_fields[DRUN_MATCH_FIELD_NAME].enabled ) { + if ( rmpd->entry_list[index].name ) { + test = helper_token_match ( ftokens, rmpd->entry_list[index].name ); + } } - // Match generic name - if ( !test && rmpd->entry_list[index].generic_name && - helper_token_match ( ftokens, rmpd->entry_list[index].generic_name ) ) { - test = 1; + if ( matching_entry_fields[DRUN_MATCH_FIELD_GENERIC].enabled ) { + // Match generic name + if ( test == tokens[j]->invert && rmpd->entry_list[index].generic_name ) { + test = helper_token_match ( ftokens, rmpd->entry_list[index].generic_name ); + } } - // Match executable name. - if ( !test && helper_token_match ( ftokens, rmpd->entry_list[index].exec ) ) { - test = 1; + if ( matching_entry_fields[DRUN_MATCH_FIELD_EXEC].enabled ) { + // Match executable name. + if ( test == tokens[j]->invert ) { + test = helper_token_match ( ftokens, rmpd->entry_list[index].exec ); + } } - // Match against category. - if ( !test ) { - gchar **list = rmpd->entry_list[index].categories; - for ( int iter = 0; !test && list && list[iter]; iter++ ) { - test = helper_token_match ( ftokens, list[iter] ); + if ( matching_entry_fields[DRUN_MATCH_FIELD_CATEGORIES].enabled ) { + // Match against category. + if ( test == tokens[j]->invert ) { + gchar **list = rmpd->entry_list[index].categories; + for ( int iter = 0; test == tokens[j]->invert && list && list[iter]; iter++ ) { + test = helper_token_match ( ftokens, list[iter] ); + } } } if ( test == 0 ) { @@ -701,6 +850,7 @@ static int drun_token_match ( const Mode *data, GRegex **tokens, unsigned int in } } } + return match; } diff --git a/source/dialogs/help-keys.c b/source/dialogs/help-keys.c index e7de6dee..25d5e041 100644 --- a/source/dialogs/help-keys.c +++ b/source/dialogs/help-keys.c @@ -104,7 +104,7 @@ static char *_get_display_value ( const Mode *sw, unsigned int selected_line, in return g_strdup ( pd->messages[selected_line] ); } static int help_keys_token_match ( const Mode *data, - GRegex **tokens, + rofi_int_matcher **tokens, unsigned int index ) { diff --git a/source/dialogs/run.c b/source/dialogs/run.c index 561d02a3..8d7070ec 100644 --- a/source/dialogs/run.c +++ b/source/dialogs/run.c @@ -400,7 +400,7 @@ static char *_get_display_value ( const Mode *sw, unsigned int selected_line, G_ const RunModePrivateData *rmpd = (const RunModePrivateData *) sw->private_data; return get_entry ? g_strdup ( rmpd->cmd_list[selected_line] ) : NULL; } -static int run_token_match ( const Mode *sw, GRegex **tokens, unsigned int index ) +static int run_token_match ( const Mode *sw, rofi_int_matcher **tokens, unsigned int index ) { const RunModePrivateData *rmpd = (const RunModePrivateData *) sw->private_data; return helper_token_match ( tokens, rmpd->cmd_list[index] ); diff --git a/source/dialogs/script.c b/source/dialogs/script.c index 6e0bdd48..05cfcb29 100644 --- a/source/dialogs/script.c +++ b/source/dialogs/script.c @@ -40,14 +40,71 @@ #include "dialogs/script.h" #include "helper.h" +#include "widgets/textbox.h" + #include "mode-private.h" -static char **get_script_output ( char *command, char *arg, unsigned int *length ) + +typedef struct +{ + /** ID of the current script. */ + unsigned int id; + /** List of visible items. */ + char **cmd_list; + /** length list of visible items. */ + unsigned int cmd_list_length; + + /** Urgent list */ + struct rofi_range_pair * urgent_list; + unsigned int |