summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/dialogs/combi.c12
-rw-r--r--source/dialogs/dmenu.c172
-rw-r--r--source/dialogs/drun.c246
-rw-r--r--source/dialogs/help-keys.c2
-rw-r--r--source/dialogs/run.c2
-rw-r--r--source/dialogs/script.c138
-rw-r--r--source/dialogs/ssh.c2
-rw-r--r--source/dialogs/window.c90
-rw-r--r--source/helper.c135
-rw-r--r--source/history.c68
-rw-r--r--source/keyb.c2
-rw-r--r--source/mode.c2
-rw-r--r--source/rofi.c53
-rw-r--r--source/theme.c74
-rw-r--r--source/view.c33
-rw-r--r--source/widgets/container.c2
-rw-r--r--source/widgets/listview.c12
-rw-r--r--source/widgets/textbox.c7
-rw-r--r--source/xcb.c14
-rw-r--r--source/xrmoptions.c122
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