diff options
author | Dave Davenport <qball@gmpclient.org> | 2015-11-21 23:59:59 +0100 |
---|---|---|
committer | Dave Davenport <qball@gmpclient.org> | 2015-11-21 23:59:59 +0100 |
commit | 8c9b72f34edb6cf2f3e8bd1b3d0efa36b0c05fff (patch) | |
tree | d2b001311d138a55af38e5c79d14b98ba72ef3da | |
parent | 7dccd805eff65db75c5eb5b8767549a6728c379d (diff) |
Start at fixing Issue 273, this might break some things.
* Only use get_display_data for displaying. (Except the select complete (ctrl-space), this needs fixing).
* Fix possible race condition in parallelization.
* Fix small bug in case-sensitive handling. (beware for collision in keybinding)
* Keep less lists around.
-rw-r--r-- | include/helper.h | 5 | ||||
-rw-r--r-- | include/rofi.h | 8 | ||||
-rw-r--r-- | source/dialogs/combi.c | 102 | ||||
-rw-r--r-- | source/dialogs/dmenu.c | 57 | ||||
-rw-r--r-- | source/dialogs/drun.c | 120 | ||||
-rw-r--r-- | source/dialogs/run.c | 52 | ||||
-rw-r--r-- | source/dialogs/script.c | 47 | ||||
-rw-r--r-- | source/dialogs/ssh.c | 53 | ||||
-rw-r--r-- | source/dialogs/window.c | 323 | ||||
-rw-r--r-- | source/helper.c | 4 | ||||
-rw-r--r-- | source/rofi.c | 30 |
11 files changed, 442 insertions, 359 deletions
diff --git a/include/helper.h b/include/helper.h index 305e6d61..db9d684f 100644 --- a/include/helper.h +++ b/include/helper.h @@ -103,10 +103,7 @@ int find_arg ( const char * const key ); * * @returns 1 when matches, 0 otherwise */ -int token_match ( char **tokens, const char *input, int not_ascii, int case_sensitive, - __attribute__( ( unused ) ) unsigned int index, - __attribute__( ( unused ) ) Switcher * data ); - +int token_match ( char **tokens, const char *input, int not_ascii, int case_sensitive ); /** * @param cmd The command to execute. * diff --git a/include/rofi.h b/include/rofi.h index 05883004..28b66197 100644 --- a/include/rofi.h +++ b/include/rofi.h @@ -42,7 +42,7 @@ typedef enum typedef SwitcherMode ( *switcher_callback )( char **input, void *data ); typedef void ( *switcher_free )( Switcher *data ); -typedef const char * ( *get_display_value )( unsigned int selected_line, void *data, int *state ); +typedef char * ( *get_display_value )( unsigned int selected_line, struct _Switcher *data, int *state, int get_entry ); /** * State returned by the rofi window. */ @@ -79,7 +79,7 @@ typedef enum * * @returns 1 when it matches, 0 if not. */ -typedef int ( *menu_match_cb )( char **tokens, const char *input, int not_ascii, int case_sensitive, unsigned int index, Switcher *data ); +typedef int ( *menu_match_cb )( char **tokens, int not_ascii, int case_sensitive, unsigned int index, Switcher *data ); /** * @param sw the Switcher to show. @@ -288,7 +288,7 @@ struct _Switcher * A switcher normally consists of the following parts: */ void ( *init )( struct _Switcher *sw ); - char ** ( *get_data )( unsigned int *length, struct _Switcher *pd ); + unsigned int ( *get_num_entries )( struct _Switcher *sw ); int ( *match )( char **tokens, const char *input, int case_sensitive, int index, struct _Switcher *data ); SwitcherMode ( *result )( int menu_retv, char **input, unsigned int selected_line, struct _Switcher *pd ); void ( *destroy )( struct _Switcher *pd ); @@ -297,6 +297,8 @@ struct _Switcher get_display_value mgrv; + int (*is_not_ascii)( struct _Switcher *sw, unsigned int index ); + // Pointer to private data. void *private_data; diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c index 8a38fb8c..c7ed3632 100644 --- a/source/dialogs/combi.c +++ b/source/dialogs/combi.c @@ -37,7 +37,6 @@ typedef struct _CombiModePrivateData { // List of (combined) entries. - char **cmd_list; unsigned int cmd_list_length; // List to validate where each switcher starts. unsigned int *starts; @@ -45,7 +44,6 @@ typedef struct _CombiModePrivateData // List of switchers to combine. unsigned int num_switchers; Switcher **switchers; - char *cache; } CombiModePrivateData; static void combi_mode_parse_switchers ( Switcher *sw ) @@ -111,38 +109,26 @@ static void combi_mode_init ( Switcher *sw ) for ( unsigned int i = 0; i < pd->num_switchers; i++ ) { pd->switchers[i]->init ( pd->switchers[i] ); } + if ( pd->cmd_list_length == 0 ) { + pd->cmd_list_length = 0; + for ( unsigned int i = 0; i < pd->num_switchers; i++ ) { + unsigned int length = pd->switchers[i]->get_num_entries ( pd->switchers[i] );; + pd->starts[i] = pd->cmd_list_length; + pd->lengths[i] = length; + pd->cmd_list_length += length; + } + } } } -static char ** combi_mode_get_data ( unsigned int *length, Switcher *sw ) +static unsigned int combi_mode_get_num_entries ( Switcher *sw ) { CombiModePrivateData *pd = sw->private_data; - if ( pd->cmd_list == NULL ) { - pd->cmd_list_length = 0; - for ( unsigned int i = 0; i < pd->num_switchers; i++ ) { - unsigned int length = 0; - pd->switchers[i]->get_data ( &length, pd->switchers[i] ); - pd->starts[i] = pd->cmd_list_length; - pd->lengths[i] = length; - pd->cmd_list_length += length; - } - // Fill the list. - pd->cmd_list = g_malloc0 ( ( pd->cmd_list_length + 1 ) * sizeof ( char* ) ); - for ( unsigned i = 0; i < pd->num_switchers; i++ ) { - unsigned int length = 0; - char **retv = pd->switchers[i]->get_data ( &length, pd->switchers[i] ); - for ( unsigned int j = 0; j < length; j++ ) { - pd->cmd_list[j + pd->starts[i]] = retv[j]; - } - } - } - *length = pd->cmd_list_length; - return pd->cmd_list; + return pd->cmd_list_length; } static void combi_mode_destroy ( Switcher *sw ) { CombiModePrivateData *pd = (CombiModePrivateData *) sw->private_data; if ( pd != NULL ) { - g_free ( pd->cmd_list ); g_free ( pd->starts ); g_free ( pd->lengths ); // Cleanup switchers. @@ -150,7 +136,6 @@ static void combi_mode_destroy ( Switcher *sw ) pd->switchers[i]->destroy ( pd->switchers[i] ); } g_free ( pd->switchers ); - g_free ( pd->cache ); g_free ( pd ); sw->private_data = NULL; } @@ -188,22 +173,22 @@ static SwitcherMode combi_mode_result ( int mretv, char **input, unsigned int se } return MODE_EXIT; } -static int combi_mode_match ( char **tokens, const char *input, int not_ascii, +static int combi_mode_match ( char **tokens, int not_ascii, int case_sensitive, unsigned int index, Switcher *sw ) { CombiModePrivateData *pd = sw->private_data; for ( unsigned i = 0; i < pd->num_switchers; i++ ) { if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[i] ) ) { - if ( tokens && input[0] && tokens[0][0] == '!' ) { + if ( tokens && tokens[0][0] == '!' ) { if ( tokens[0][1] == pd->switchers[i]->name[0] ) { - return pd->switchers[i]->token_match ( &tokens[1], input, not_ascii, case_sensitive, + return pd->switchers[i]->token_match ( &tokens[1], not_ascii, case_sensitive, index - pd->starts[i], pd->switchers[i] ); } return 0; } else { - return pd->switchers[i]->token_match ( tokens, input, not_ascii, case_sensitive, + return pd->switchers[i]->token_match ( tokens, not_ascii, case_sensitive, index - pd->starts[i], pd->switchers[i] ); } } @@ -211,34 +196,53 @@ static int combi_mode_match ( char **tokens, const char *input, int not_ascii, abort (); return 0; } -static const char * combi_mgrv ( unsigned int selected_line, void *sw, int *state ) +static char * combi_mgrv ( unsigned int selected_line, Switcher *sw, int *state, int get_entry ) { - CombiModePrivateData *pd = ( (Switcher *) sw )->private_data; + CombiModePrivateData *pd = sw->private_data; + if ( !get_entry ) { + for ( unsigned i = 0; i < pd->num_switchers; i++ ) { + if ( selected_line >= pd->starts[i] && selected_line < ( pd->starts[i] + pd->lengths[i] ) ) { + pd->switchers[i]->mgrv ( selected_line - pd->starts[i], (void *) pd->switchers[i], state, FALSE ); + return NULL; + } + } + return NULL; + } for ( unsigned i = 0; i < pd->num_switchers; i++ ) { if ( selected_line >= pd->starts[i] && selected_line < ( pd->starts[i] + pd->lengths[i] ) ) { - g_free ( pd->cache ); - pd->cache = g_strdup_printf ( "(%s) %s", pd->switchers[i]->name, - pd->switchers[i]->mgrv ( selected_line - pd->starts[i], - (void *) pd->switchers[i], state ) ); - return pd->cache; + char * str = pd->switchers[i]->mgrv ( selected_line - pd->starts[i], (void *) pd->switchers[i], state, TRUE ); + char * retv = g_strdup_printf ( "(%s) %s", pd->switchers[i]->name, str ); + g_free ( str ); + return retv; } } return NULL; } +static int combi_is_not_ascii ( Switcher *sw, unsigned int index ) +{ + CombiModePrivateData *pd = sw->private_data; + for ( unsigned i = 0; i < pd->num_switchers; i++ ) { + if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[i] ) ) { + return pd->switchers[i]->is_not_ascii ( pd->switchers[i], index - pd->starts[i] ); + } + } + return FALSE; +} Switcher combi_mode = { - .name = "combi", - .keycfg = NULL, - .keystr = NULL, - .modmask = AnyModifier, - .init = combi_mode_init, - .get_data = combi_mode_get_data, - .result = combi_mode_result, - .destroy = combi_mode_destroy, - .token_match = combi_mode_match, - .mgrv = combi_mgrv, - .private_data = NULL, - .free = NULL + .name = "combi", + .keycfg = NULL, + .keystr = NULL, + .modmask = AnyModifier, + .init = combi_mode_init, + .get_num_entries = combi_mode_get_num_entries, + .result = combi_mode_result, + .destroy = combi_mode_destroy, + .token_match = combi_mode_match, + .mgrv = combi_mgrv, + .is_not_ascii = combi_is_not_ascii, + .private_data = NULL, + .free = NULL }; diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c index 0bdae156..eeecef52 100644 --- a/source/dialogs/dmenu.c +++ b/source/dialogs/dmenu.c @@ -96,15 +96,10 @@ static char **get_dmenu ( unsigned int *length ) return retv; } -static char ** dmenu_mode_get_data ( unsigned int *length, Switcher *sw ) +static unsigned int dmenu_mode_get_num_entries ( Switcher *sw ) { DmenuModePrivateData *rmpd = (DmenuModePrivateData *) sw->private_data; - if ( rmpd->cmd_list == NULL ) { - rmpd->cmd_list_length = 0; - rmpd->cmd_list = get_dmenu ( &( rmpd->cmd_list_length ) ); - } - *length = rmpd->cmd_list_length; - return rmpd->cmd_list; + return rmpd->cmd_list_length; } static void parse_pair ( char *input, struct range_pair *item ) @@ -142,7 +137,7 @@ static void parse_ranges ( char *input, struct range_pair **list, unsigned int * } } -static const char *get_display_data ( unsigned int index, void *data, G_GNUC_UNUSED int *state ) +static char *get_display_data ( unsigned int index, Switcher *data, int *state, int get_entry ) { Switcher *sw = (Switcher *) data; DmenuModePrivateData *pd = (DmenuModePrivateData *) sw->private_data; @@ -157,7 +152,7 @@ static const char *get_display_data ( unsigned int index, void *data, G_GNUC_UNU *state |= URGENT; } } - return retv[index]; + return get_entry ? g_strdup ( retv[index] ) : NULL; } /** @@ -281,22 +276,36 @@ static void dmenu_mode_init ( Switcher *sw ) if ( find_arg ( "-i" ) >= 0 ) { config.case_sensitive = FALSE; } + pd->cmd_list = get_dmenu ( &( pd->cmd_list_length ) ); +} + +static int dmenu_token_match ( char **tokens, int not_ascii, int case_sensitive, unsigned int index, Switcher *sw ) +{ + DmenuModePrivateData *rmpd = (DmenuModePrivateData *) sw->private_data; + return token_match ( tokens, rmpd->cmd_list[index], not_ascii, case_sensitive ); +} + +static int dmenu_is_not_ascii ( Switcher *sw, unsigned int index ) +{ + DmenuModePrivateData *rmpd = (DmenuModePrivateData *) sw->private_data; + return is_not_ascii ( rmpd->cmd_list[index] ); } Switcher dmenu_mode = { - .name = "dmenu", - .keycfg = NULL, - .keystr = NULL, - .modmask = AnyModifier, - .init = dmenu_mode_init, - .get_data = dmenu_mode_get_data, - .result = NULL, - .destroy = dmenu_mode_free, - .token_match = token_match, - .mgrv = get_display_data, - .private_data = NULL, - .free = NULL + .name = "dmenu", + .keycfg = NULL, + .keystr = NULL, + .modmask = AnyModifier, + .init = dmenu_mode_init, + .get_num_entries = dmenu_mode_get_num_entries, + .result = NULL, + .destroy = dmenu_mode_free, + .token_match = dmenu_token_match, + .mgrv = get_display_data, + .is_not_ascii = dmenu_is_not_ascii, + .private_data = NULL, + .free = NULL }; int dmenu_switcher_dialog ( void ) @@ -306,8 +315,8 @@ int dmenu_switcher_dialog ( void ) char *input = NULL; int retv = FALSE; int restart = FALSE; - unsigned int cmd_list_length = 0; - char **cmd_list = dmenu_mode.get_data ( &( cmd_list_length ), &dmenu_mode ); + unsigned int cmd_list_length = pd->cmd_list_length; + char **cmd_list = pd->cmd_list; int only_selected = FALSE; if ( find_arg ( "-only-match" ) >= 0 || find_arg ( "-no-custom" ) >= 0 ) { @@ -325,7 +334,7 @@ int dmenu_switcher_dialog ( void ) char **tokens = tokenize ( select, config.case_sensitive ); unsigned int i = 0; for ( i = 0; i < cmd_list_length; i++ ) { - if ( token_match ( tokens, cmd_list[i], is_not_ascii ( cmd_list[i] ), config.case_sensitive, 0, NULL ) ) { + if ( token_match ( tokens, cmd_list[i], is_not_ascii ( cmd_list[i] ), config.case_sensitive ) ) { pd->selected_line = i; break; } diff --git a/source/dialogs/drun.c b/source/dialogs/drun.c index 95f073b4..85d0ecf5 100644 --- a/source/dialogs/drun.c +++ b/source/dialogs/drun.c @@ -87,13 +87,18 @@ static void exec_cmd ( const char *cmd, int run_in_term ) */ typedef struct _DRunModeEntry { + /* Executable */ char *exec; + /* Name of the Entry */ + char *name; + /* Generic Name */ + char *generic_name; + /* Application needs to be launched in terminal. */ unsigned int terminal; } DRunModeEntry; typedef struct _DRunModePrivateData { - char **cmd_list; DRunModeEntry *entry_list; unsigned int cmd_list_length; } DRunModePrivateData; @@ -151,29 +156,21 @@ static void get_apps_dir ( DRunModePrivateData *pd, const char *bp ) } if ( g_key_file_has_key ( kf, "Desktop Entry", "Exec", NULL ) ) { size_t nl = ( ( pd->cmd_list_length ) + 2 ); - pd->cmd_list = g_realloc ( pd->cmd_list, nl * sizeof ( *( pd->cmd_list ) ) ); pd->entry_list = g_realloc ( pd->entry_list, nl * sizeof ( *( pd->entry_list ) ) ); if ( g_key_file_has_key ( kf, "Desktop Entry", "Name", NULL ) ) { gchar *n = g_key_file_get_locale_string ( kf, "Desktop Entry", "Name", NULL, NULL ); gchar *gn = g_key_file_get_locale_string ( kf, "Desktop Entry", "GenericName", NULL, NULL ); - if ( gn == NULL ) { - pd->cmd_list[pd->cmd_list_length] = g_markup_escape_text ( n, -1 ); - } - else { - ( pd->cmd_list )[( pd->cmd_list_length )] = g_markup_printf_escaped ( - "%s <span weight='light' size='small'><i>(%s)</i></span>", - n, gn ? gn : "" ); - } - g_free ( n ); g_free ( gn ); + pd->entry_list[pd->cmd_list_length].name = n; + pd->entry_list[pd->cmd_list_length].generic_name = gn; } else { - ( pd->cmd_list )[( pd->cmd_list_length )] = g_strdup ( dent->d_name ); + pd->entry_list[pd->cmd_list_length].name = g_strdup ( dent->d_name ); + pd->entry_list[pd->cmd_list_length].generic_name = NULL; } pd->entry_list[pd->cmd_list_length].exec = g_key_file_get_string ( kf, "Desktop Entry", "Exec", NULL ); if ( g_key_file_has_key ( kf, "Desktop Entry", "Terminal", NULL ) ) { pd->entry_list[pd->cmd_list_length].terminal = g_key_file_get_boolean ( kf, "Desktop Entry", "Terminal", NULL ); } - ( pd->cmd_list )[( pd->cmd_list_length ) + 1] = NULL; ( pd->cmd_list_length )++; } @@ -222,22 +219,10 @@ static void drun_mode_init ( Switcher *sw ) if ( sw->private_data == NULL ) { DRunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); sw->private_data = (void *) pd; + get_apps ( pd ); } } -static char ** drun_mode_get_data ( unsigned int *length, Switcher *sw ) -{ - DRunModePrivateData *rmpd = (DRunModePrivateData *) sw->private_data; - if ( rmpd->cmd_list == NULL ) { - rmpd->cmd_list_length = 0; - get_apps ( rmpd ); - } - if ( length != NULL ) { - *length = rmpd->cmd_list_length; - } - return rmpd->cmd_list; -} - static SwitcherMode drun_mode_result ( int mretv, char **input, unsigned int selected_line, Switcher *sw ) { @@ -255,7 +240,7 @@ static SwitcherMode drun_mode_result ( int mretv, char **input, unsigned int sel else if ( mretv & MENU_QUICK_SWITCH ) { retv = ( mretv & MENU_LOWER_MASK ); } - else if ( ( mretv & MENU_OK ) && rmpd->cmd_list[selected_line] != NULL ) { + else if ( ( mretv & MENU_OK ) ) { exec_cmd_entry ( &( rmpd->entry_list[selected_line] ) ); } else if ( ( mretv & MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] != '\0' ) { @@ -268,9 +253,10 @@ static void drun_mode_destroy ( Switcher *sw ) { DRunModePrivateData *rmpd = (DRunModePrivateData *) sw->private_data; if ( rmpd != NULL ) { - g_strfreev ( rmpd->cmd_list ); for ( size_t i = 0; i < rmpd->cmd_list_length; i++ ) { g_free ( rmpd->entry_list[i].exec ); + g_free ( rmpd->entry_list[i].name ); + g_free ( rmpd->entry_list[i].generic_name ); } g_free ( rmpd->entry_list ); g_free ( rmpd ); @@ -278,24 +264,74 @@ static void drun_mode_destroy ( Switcher *sw ) } } -static const char *mgrv ( unsigned int selected_line, void *sw, int *state ) +static char *mgrv ( unsigned int selected_line, Switcher *sw, int *state, int get_entry ) { + DRunModePrivateData *pd = (DRunModePrivateData *) sw->private_data; *state |= MARKUP; - return drun_mode_get_data ( NULL, sw )[selected_line]; + if ( !get_entry ) { + return NULL; + } + if ( pd->entry_list == NULL ) { + // Should never get here. + return g_strdup ( "Failed" ); + } + /* Free temp storage. */ + DRunModeEntry *dr = &( pd->entry_list[selected_line] ); + if ( dr->generic_name == NULL ) { + return g_markup_escape_text ( dr->name, -1 ); + } + else { + return g_markup_printf_escaped ( "%s <span weight='light' size='small'><i>(%s)</i></span>", dr->name, + dr->generic_name ); + } +} + +static int drun_token_match ( char **tokens, + int not_ascii, + int case_sensitive, + unsigned int index, + Switcher *data ) +{ + DRunModePrivateData *rmpd = (DRunModePrivateData *) data->private_data; + if ( rmpd->entry_list[index].name && + token_match ( tokens, rmpd->entry_list[index].name, not_ascii, case_sensitive ) ) { + return 1; + } + if ( rmpd->entry_list[index].generic_name && + token_match ( tokens, rmpd->entry_list[index].generic_name, not_ascii, case_sensitive ) ) { + return 1; + } + + return 0; +} + +static unsigned int drun_mode_get_num_entries ( Switcher *sw ) +{ + DRunModePrivateData *pd = (DRunModePrivateData *) sw->private_data; + return pd->cmd_list_length; +} +static int drun_is_not_ascii ( Switcher *sw, unsigned int index ) +{ + DRunModePrivateData *pd = (DRunModePrivateData *) sw->private_data; + if ( pd->entry_list[index].generic_name ) { + return is_not_ascii ( pd->entry_list[index].name ) || is_not_ascii ( pd->entry_list[index].generic_name ); + } + return is_not_ascii ( pd->entry_list[index].name ); } Switcher drun_mode = { - .name = "drun", - .keycfg = NULL, - .keystr = NULL, - .modmask = AnyModifier, - .init = drun_mode_init, - .get_data = drun_mode_get_data, - .result = drun_mode_result, - .destroy = drun_mode_destroy, - .token_match = token_match, - .mgrv = mgrv, - .private_data = NULL, - .free = NULL + .name = "drun", + .keycfg = NULL, + .keystr = NULL, + .modmask = AnyModifier, + .init = drun_mode_init, + .get_num_entries = drun_mode_get_num_entries, + .result = drun_mode_result, + .destroy = drun_mode_destroy, + .token_match = drun_token_match, + .mgrv = mgrv, + .is_not_ascii = drun_is_not_ascii, + .private_data = NULL, + .free = NULL }; diff --git a/source/dialogs/run.c b/source/dialogs/run.c index 9653dce4..75fe7722 100644 --- a/source/dialogs/run.c +++ b/source/dialogs/run.c @@ -272,20 +272,14 @@ static void run_mode_init ( Switcher *sw ) if ( sw->private_data == NULL ) { RunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); sw->private_data = (void *) pd; + pd->cmd_list = get_apps ( &( pd->cmd_list_length ) ); } } -static char ** run_mode_get_data ( unsigned int *length, Switcher *sw ) +static unsigned int run_mode_get_num_entries ( Switcher *sw ) { RunModePrivateData *rmpd = (RunModePrivateData *) sw->private_data; - if ( rmpd->cmd_list == NULL ) { - rmpd->cmd_list_length = 0; - rmpd->cmd_list = get_apps ( &( rmpd->cmd_list_length ) ); - } - if ( length != NULL ) { - *length = rmpd->cmd_list_length; - } - return rmpd->cmd_list; + return rmpd->cmd_list_length; } static SwitcherMode run_mode_result ( int mretv, char **input, unsigned int selected_line, @@ -333,23 +327,35 @@ static void run_mode_destroy ( Switcher *sw ) } } -static const char *mgrv ( unsigned int selected_line, void *sw, G_GNUC_UNUSED int *state ) +static char *mgrv ( unsigned int selected_line, Switcher *sw, G_GNUC_UNUSED int *state, int get_entry ) +{ + RunModePrivateData *rmpd = (RunModePrivateData *) sw->private_data; + return get_entry ? g_strdup ( rmpd->cmd_list[selected_line] ) : NULL; +} +static int run_token_match ( char **tokens, int not_ascii, int case_sensitive, unsigned int index, Switcher *sw ) { - return run_mode_get_data ( NULL, sw )[selected_line]; + RunModePrivateData *rmpd = (RunModePrivateData *) sw->private_data; + return token_match ( tokens, rmpd->cmd_list[index], not_ascii, case_sensitive ); } +static int run_is_not_ascii ( Switcher *sw, unsigned int index ) +{ + RunModePrivateData *rmpd = (RunModePrivateData *) sw->private_data; + return is_not_ascii ( rmpd->cmd_list[index] ); +} Switcher run_mode = { - .name = "run", - .keycfg = NULL, - .keystr = NULL, - .modmask = AnyModifier, - .init = run_mode_init, - .get_data = run_mode_get_data, - .result = run_mode_result, - .destroy = run_mode_destroy, - .token_match = token_match, - .mgrv = mgrv, - .private_data = NULL, - .free = NULL + .name = "run", + .keycfg = NULL, + .keystr = NULL, + .modmask = AnyModifier, + .init = run_mode_init, + .get_num_entries = run_mode_get_num_entries, + .result = run_mode_result, + .destroy = run_mode_destroy, + .token_match = run_token_match, + .mgrv = mgrv, + .is_not_ascii = run_is_not_ascii, + .private_data = NULL, + .free = NULL }; diff --git a/source/dialogs/script.c b/source/dialogs/script.c index 915fc602..b67d5be8 100644 --- a/source/dialogs/script.c +++ b/source/dialogs/script.c @@ -102,17 +102,13 @@ static void script_mode_init ( Switcher *sw ) if ( sw->private_data == NULL ) { ScriptModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); sw->private_data = (void *) pd; + pd->cmd_list = get_script_output ( (const char *) sw->ed, &( pd->cmd_list_length ) ); } } -static char ** script_mode_get_data ( unsigned int *length, Switcher *sw ) +static unsigned int script_mode_get_num_entries ( Switcher *sw ) { ScriptModePrivateData *rmpd = (ScriptModePrivateData *) sw->private_data; - if ( rmpd->cmd_list == NULL ) { - rmpd->cmd_list_length = 0; - rmpd->cmd_list = get_script_output ( (const char *) sw->ed, &( rmpd->cmd_list_length ) ); - } - *length = rmpd->cmd_list_length; - return rmpd->cmd_list; + return rmpd->cmd_list_length; } static SwitcherMode script_mode_result ( int mretv, char **input, unsigned int selected_line, @@ -161,10 +157,22 @@ static void script_mode_destroy ( Switcher *sw ) sw->private_data = NULL; } } -static const char *mgrv ( unsigned int selected_line, void *sw, G_GNUC_UNUSED int *state ) +static char *mgrv ( unsigned int selected_line, Switcher *sw, G_GNUC_UNUSED int *state, int get_entry ) +{ + ScriptModePrivateData *rmpd = sw->private_data; + return get_entry ? g_strdup ( rmpd->cmd_list[selected_line] ) : NULL; +} + +static int script_token_match ( char **tokens, int not_ascii, int case_sensitive, unsigned int index, Switcher *sw ) +{ + ScriptModePrivateData *rmpd = sw->private_data; + return token_match ( tokens, rmpd->cmd_list[index], not_ascii, case_sensitive ); +} + +static int script_is_not_ascii ( Switcher *sw, unsigned int index ) { - ScriptModePrivateData *rmpd = ( (Switcher *) sw )->private_data; - return rmpd->cmd_list[selected_line]; + ScriptModePrivateData *rmpd = sw->private_data; + return is_not_ascii ( rmpd->cmd_list[index] ); } Switcher *script_switcher_parse_setup ( const char *str ) @@ -184,15 +192,16 @@ Switcher *script_switcher_parse_setup ( const char *str ) } g_free ( parse ); if ( index == 2 ) { - sw->free = script_switcher_free; - sw->keysym = None; - sw->modmask = AnyModifier; - sw->init = script_mode_init; - sw->get_data = script_mode_get_data; - sw->result = script_mode_result; - sw->destroy = script_mode_destroy; - sw->token_match = token_match; - sw->mgrv = mgrv; + sw->free = script_switcher_free; + sw->keysym = None; + sw->modmask = AnyModifier; + sw->init = script_mode_init; + sw->get_num_entries = script_mode_get_num_entries; + sw->result = script_mode_result; + sw->destroy = script_mode_destroy; + sw->token_match = script_token_match; + sw->mgrv = mgrv; + sw->is_not_ascii = script_is_not_ascii; return sw; } diff --git a/source/dialogs/ssh.c b/source/dialogs/ssh.c index 9bf610b1..7b870c0f 100644 --- a/source/dialogs/ssh.c +++ b/source/dialogs/ssh.c @@ -327,20 +327,14 @@ static void ssh_mode_init ( Switcher *sw ) if ( sw->private_data == NULL ) { SSHModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) ); sw->private_data = (void *) pd; + pd->cmd_list = get_ssh ( &( pd->cmd_list_length ) ); } } -static char ** ssh_mode_get_data ( unsigned int *length, Switcher *sw ) +static unsigned int ssh_mode_get_num_entries ( Switcher *sw ) { SSHModePrivateData *rmpd = (SSHModePrivateData *) sw->private_data; - if ( rmpd->cmd_list == NULL ) { - rmpd->cmd_list_length = 0; - rmpd->cmd_list = get_ssh ( &( rmpd->cmd_list_length ) ); - } - if ( length != NULL ) { - *length = rmpd->cmd_list_length; - } - return rmpd->cmd_list; + return rmpd->cmd_list_length; } static SwitcherMode ssh_mode_result ( int mretv, char **input, unsigned int selected_line, Switcher *sw ) @@ -383,23 +377,36 @@ static void ssh_mode_destroy ( Switcher *sw ) } } -static const char *mgrv ( unsigned int selected_line, void *sw, G_GNUC_UNUSED int *state ) +static char *mgrv ( unsigned int selected_line, Switcher *sw, G_GNUC_UNUSED int *state, int get_entry ) +{ + SSHModePrivateData *rmpd = (SSHModePrivateData *) sw->private_data; + return get_entry ? g_strdup ( rmpd->cmd_list[selected_line] ) : NULL; +} +static int ssh_token_match ( char **tokens, int not_ascii, int case_sensitive, unsigned int index, Switcher *sw ) { - return ssh_mode_get_data ( NULL, sw )[selected_line]; + SSHModePrivateData *rmpd = (SSHModePrivateData *) sw->private_data; + return token_match ( tokens, rmpd->cmd_list[index], not_ascii, case_sensitive ); +} + +static int ssh_is_not_ascii ( Switcher *sw, unsigned int index ) +{ + SSHModePrivateData *rmpd = (SSHModePrivateData *) sw->private_data; + return is_not_ascii ( rmpd->cmd_list[index] ); } Switcher ssh_mode = { - .name = "ssh", - .keycfg = NULL, - .keystr = NULL, - .modmask = AnyModifier, - .init = ssh_mode_init, - .get_data = ssh_mode_get_data, - .result = ssh_mode_result, - .destroy = ssh_mode_destroy, - .token_match = token_match, - .mgrv = mgrv, - .private_data = NULL, - .free = NULL + .name = "ssh", + .keycfg = NULL, + .keystr = NULL, + .modmask = AnyModifier, + .init = ssh_mode_init, + .get_num_entries = ssh_mode_get_num_entries, + .result = ssh_mode_result, + .destroy = ssh_mode_destroy, + .token_match = ssh_token_match, + .mgrv = mgrv, + .is_not_ascii = ssh_is_not_ascii, + .private_data = NULL, + .free = NULL }; diff --git a/source/dialogs/window.c b/source/dialogs/window.c index 1a30bf11..a922cd9f 100644 --- a/source/dialogs/window.c +++ b/source/dialogs/window.c @@ -315,13 +315,12 @@ typedef struct _SwitcherModePrivateData unsigned int cmd_list_length; winlist *ids; int config_i3_mode; - int init; // Current window. unsigned int index; char *cache; } SwitcherModePrivateData; -static int window_match ( char **tokens, __attribute__( ( unused ) ) const char *input, +static int window_match ( char **tokens, __attribute__( ( unused ) ) int not_ascii, int case_sensitive, unsigned int index, Switcher *sw ) { @@ -339,19 +338,19 @@ static int window_match ( char **tokens, __attribute__( ( unused ) ) const char // e.g. when searching 'title element' and 'class element' char *ftokens[2] = { tokens[j], NULL }; if ( !test && c->title[0] != '\0' ) { - test = token_match ( ftokens, c->title, is_not_ascii ( c->title ), case_sensitive, 0, NULL ); + test = token_match ( ftokens, c->title, not_ascii, case_sensitive ); } if ( !test && c->class[0] != '\0' ) { - test = token_match ( ftokens, c->class, is_not_ascii ( c->class ), case_sensitive, 0, NULL ); + test = token_match ( ftokens, c->class, not_ascii, case_sensitive ); } if ( !test && c->role[0] != '\0' ) { - |