mirror of https://github.com/davatorium/rofi.git
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.
This commit is contained in:
parent
7dccd805ef
commit
8c9b72f34e
|
@ -103,10 +103,7 @@ int find_arg ( const char * const key );
|
||||||
*
|
*
|
||||||
* @returns 1 when matches, 0 otherwise
|
* @returns 1 when matches, 0 otherwise
|
||||||
*/
|
*/
|
||||||
int token_match ( char **tokens, const char *input, int not_ascii, int case_sensitive,
|
int token_match ( char **tokens, const char *input, int not_ascii, int case_sensitive );
|
||||||
__attribute__( ( unused ) ) unsigned int index,
|
|
||||||
__attribute__( ( unused ) ) Switcher * data );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param cmd The command to execute.
|
* @param cmd The command to execute.
|
||||||
*
|
*
|
||||||
|
|
|
@ -42,7 +42,7 @@ typedef enum
|
||||||
typedef SwitcherMode ( *switcher_callback )( char **input, void *data );
|
typedef SwitcherMode ( *switcher_callback )( char **input, void *data );
|
||||||
typedef void ( *switcher_free )( Switcher *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.
|
* State returned by the rofi window.
|
||||||
*/
|
*/
|
||||||
|
@ -79,7 +79,7 @@ typedef enum
|
||||||
*
|
*
|
||||||
* @returns 1 when it matches, 0 if not.
|
* @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.
|
* @param sw the Switcher to show.
|
||||||
|
@ -288,7 +288,7 @@ struct _Switcher
|
||||||
* A switcher normally consists of the following parts:
|
* A switcher normally consists of the following parts:
|
||||||
*/
|
*/
|
||||||
void ( *init )( struct _Switcher *sw );
|
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 );
|
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 );
|
SwitcherMode ( *result )( int menu_retv, char **input, unsigned int selected_line, struct _Switcher *pd );
|
||||||
void ( *destroy )( struct _Switcher *pd );
|
void ( *destroy )( struct _Switcher *pd );
|
||||||
|
@ -297,6 +297,8 @@ struct _Switcher
|
||||||
|
|
||||||
get_display_value mgrv;
|
get_display_value mgrv;
|
||||||
|
|
||||||
|
int (*is_not_ascii)( struct _Switcher *sw, unsigned int index );
|
||||||
|
|
||||||
// Pointer to private data.
|
// Pointer to private data.
|
||||||
void *private_data;
|
void *private_data;
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
typedef struct _CombiModePrivateData
|
typedef struct _CombiModePrivateData
|
||||||
{
|
{
|
||||||
// List of (combined) entries.
|
// List of (combined) entries.
|
||||||
char **cmd_list;
|
|
||||||
unsigned int cmd_list_length;
|
unsigned int cmd_list_length;
|
||||||
// List to validate where each switcher starts.
|
// List to validate where each switcher starts.
|
||||||
unsigned int *starts;
|
unsigned int *starts;
|
||||||
|
@ -45,7 +44,6 @@ typedef struct _CombiModePrivateData
|
||||||
// List of switchers to combine.
|
// List of switchers to combine.
|
||||||
unsigned int num_switchers;
|
unsigned int num_switchers;
|
||||||
Switcher **switchers;
|
Switcher **switchers;
|
||||||
char *cache;
|
|
||||||
} CombiModePrivateData;
|
} CombiModePrivateData;
|
||||||
|
|
||||||
static void combi_mode_parse_switchers ( Switcher *sw )
|
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++ ) {
|
for ( unsigned int i = 0; i < pd->num_switchers; i++ ) {
|
||||||
pd->switchers[i]->init ( pd->switchers[i] );
|
pd->switchers[i]->init ( pd->switchers[i] );
|
||||||
}
|
}
|
||||||
}
|
if ( pd->cmd_list_length == 0 ) {
|
||||||
}
|
pd->cmd_list_length = 0;
|
||||||
static char ** combi_mode_get_data ( unsigned int *length, Switcher *sw )
|
for ( unsigned int i = 0; i < pd->num_switchers; i++ ) {
|
||||||
{
|
unsigned int length = pd->switchers[i]->get_num_entries ( pd->switchers[i] );;
|
||||||
CombiModePrivateData *pd = sw->private_data;
|
pd->starts[i] = pd->cmd_list_length;
|
||||||
if ( pd->cmd_list == NULL ) {
|
pd->lengths[i] = length;
|
||||||
pd->cmd_list_length = 0;
|
pd->cmd_list_length += length;
|
||||||
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;
|
static unsigned int combi_mode_get_num_entries ( Switcher *sw )
|
||||||
|
{
|
||||||
|
CombiModePrivateData *pd = sw->private_data;
|
||||||
|
return pd->cmd_list_length;
|
||||||
}
|
}
|
||||||
static void combi_mode_destroy ( Switcher *sw )
|
static void combi_mode_destroy ( Switcher *sw )
|
||||||
{
|
{
|
||||||
CombiModePrivateData *pd = (CombiModePrivateData *) sw->private_data;
|
CombiModePrivateData *pd = (CombiModePrivateData *) sw->private_data;
|
||||||
if ( pd != NULL ) {
|
if ( pd != NULL ) {
|
||||||
g_free ( pd->cmd_list );
|
|
||||||
g_free ( pd->starts );
|
g_free ( pd->starts );
|
||||||
g_free ( pd->lengths );
|
g_free ( pd->lengths );
|
||||||
// Cleanup switchers.
|
// Cleanup switchers.
|
||||||
|
@ -150,7 +136,6 @@ static void combi_mode_destroy ( Switcher *sw )
|
||||||
pd->switchers[i]->destroy ( pd->switchers[i] );
|
pd->switchers[i]->destroy ( pd->switchers[i] );
|
||||||
}
|
}
|
||||||
g_free ( pd->switchers );
|
g_free ( pd->switchers );
|
||||||
g_free ( pd->cache );
|
|
||||||
g_free ( pd );
|
g_free ( pd );
|
||||||
sw->private_data = NULL;
|
sw->private_data = NULL;
|
||||||
}
|
}
|
||||||
|
@ -188,22 +173,22 @@ static SwitcherMode combi_mode_result ( int mretv, char **input, unsigned int se
|
||||||
}
|
}
|
||||||
return MODE_EXIT;
|
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 )
|
int case_sensitive, unsigned int index, Switcher *sw )
|
||||||
{
|
{
|
||||||
CombiModePrivateData *pd = sw->private_data;
|
CombiModePrivateData *pd = sw->private_data;
|
||||||
|
|
||||||
for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
|
for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
|
||||||
if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[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] ) {
|
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] );
|
index - pd->starts[i], pd->switchers[i] );
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
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] );
|
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 ();
|
abort ();
|
||||||
return 0;
|
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++ ) {
|
for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
|
||||||
if ( selected_line >= pd->starts[i] && selected_line < ( pd->starts[i] + pd->lengths[i] ) ) {
|
if ( selected_line >= pd->starts[i] && selected_line < ( pd->starts[i] + pd->lengths[i] ) ) {
|
||||||
g_free ( pd->cache );
|
char * str = pd->switchers[i]->mgrv ( selected_line - pd->starts[i], (void *) pd->switchers[i], state, TRUE );
|
||||||
pd->cache = g_strdup_printf ( "(%s) %s", pd->switchers[i]->name,
|
char * retv = g_strdup_printf ( "(%s) %s", pd->switchers[i]->name, str );
|
||||||
pd->switchers[i]->mgrv ( selected_line - pd->starts[i],
|
g_free ( str );
|
||||||
(void *) pd->switchers[i], state ) );
|
return retv;
|
||||||
return pd->cache;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
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 =
|
Switcher combi_mode =
|
||||||
{
|
{
|
||||||
.name = "combi",
|
.name = "combi",
|
||||||
.keycfg = NULL,
|
.keycfg = NULL,
|
||||||
.keystr = NULL,
|
.keystr = NULL,
|
||||||
.modmask = AnyModifier,
|
.modmask = AnyModifier,
|
||||||
.init = combi_mode_init,
|
.init = combi_mode_init,
|
||||||
.get_data = combi_mode_get_data,
|
.get_num_entries = combi_mode_get_num_entries,
|
||||||
.result = combi_mode_result,
|
.result = combi_mode_result,
|
||||||
.destroy = combi_mode_destroy,
|
.destroy = combi_mode_destroy,
|
||||||
.token_match = combi_mode_match,
|
.token_match = combi_mode_match,
|
||||||
.mgrv = combi_mgrv,
|
.mgrv = combi_mgrv,
|
||||||
.private_data = NULL,
|
.is_not_ascii = combi_is_not_ascii,
|
||||||
.free = NULL
|
.private_data = NULL,
|
||||||
|
.free = NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -96,15 +96,10 @@ static char **get_dmenu ( unsigned int *length )
|
||||||
return retv;
|
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;
|
DmenuModePrivateData *rmpd = (DmenuModePrivateData *) sw->private_data;
|
||||||
if ( rmpd->cmd_list == NULL ) {
|
return rmpd->cmd_list_length;
|
||||||
rmpd->cmd_list_length = 0;
|
|
||||||
rmpd->cmd_list = get_dmenu ( &( rmpd->cmd_list_length ) );
|
|
||||||
}
|
|
||||||
*length = rmpd->cmd_list_length;
|
|
||||||
return rmpd->cmd_list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_pair ( char *input, struct range_pair *item )
|
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;
|
Switcher *sw = (Switcher *) data;
|
||||||
DmenuModePrivateData *pd = (DmenuModePrivateData *) sw->private_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;
|
*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 ) {
|
if ( find_arg ( "-i" ) >= 0 ) {
|
||||||
config.case_sensitive = FALSE;
|
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 =
|
Switcher dmenu_mode =
|
||||||
{
|
{
|
||||||
.name = "dmenu",
|
.name = "dmenu",
|
||||||
.keycfg = NULL,
|
.keycfg = NULL,
|
||||||
.keystr = NULL,
|
.keystr = NULL,
|
||||||
.modmask = AnyModifier,
|
.modmask = AnyModifier,
|
||||||
.init = dmenu_mode_init,
|
.init = dmenu_mode_init,
|
||||||
.get_data = dmenu_mode_get_data,
|
.get_num_entries = dmenu_mode_get_num_entries,
|
||||||
.result = NULL,
|
.result = NULL,
|
||||||
.destroy = dmenu_mode_free,
|
.destroy = dmenu_mode_free,
|
||||||
.token_match = token_match,
|
.token_match = dmenu_token_match,
|
||||||
.mgrv = get_display_data,
|
.mgrv = get_display_data,
|
||||||
.private_data = NULL,
|
.is_not_ascii = dmenu_is_not_ascii,
|
||||||
.free = NULL
|
.private_data = NULL,
|
||||||
|
.free = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
int dmenu_switcher_dialog ( void )
|
int dmenu_switcher_dialog ( void )
|
||||||
|
@ -306,8 +315,8 @@ int dmenu_switcher_dialog ( void )
|
||||||
char *input = NULL;
|
char *input = NULL;
|
||||||
int retv = FALSE;
|
int retv = FALSE;
|
||||||
int restart = FALSE;
|
int restart = FALSE;
|
||||||
unsigned int cmd_list_length = 0;
|
unsigned int cmd_list_length = pd->cmd_list_length;
|
||||||
char **cmd_list = dmenu_mode.get_data ( &( cmd_list_length ), &dmenu_mode );
|
char **cmd_list = pd->cmd_list;
|
||||||
|
|
||||||
int only_selected = FALSE;
|
int only_selected = FALSE;
|
||||||
if ( find_arg ( "-only-match" ) >= 0 || find_arg ( "-no-custom" ) >= 0 ) {
|
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 );
|
char **tokens = tokenize ( select, config.case_sensitive );
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for ( i = 0; i < cmd_list_length; i++ ) {
|
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;
|
pd->selected_line = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,13 +87,18 @@ static void exec_cmd ( const char *cmd, int run_in_term )
|
||||||
*/
|
*/
|
||||||
typedef struct _DRunModeEntry
|
typedef struct _DRunModeEntry
|
||||||
{
|
{
|
||||||
|
/* Executable */
|
||||||
char *exec;
|
char *exec;
|
||||||
|
/* Name of the Entry */
|
||||||
|
char *name;
|
||||||
|
/* Generic Name */
|
||||||
|
char *generic_name;
|
||||||
|
/* Application needs to be launched in terminal. */
|
||||||
unsigned int terminal;
|
unsigned int terminal;
|
||||||
} DRunModeEntry;
|
} DRunModeEntry;
|
||||||
|
|
||||||
typedef struct _DRunModePrivateData
|
typedef struct _DRunModePrivateData
|
||||||
{
|
{
|
||||||
char **cmd_list;
|
|
||||||
DRunModeEntry *entry_list;
|
DRunModeEntry *entry_list;
|
||||||
unsigned int cmd_list_length;
|
unsigned int cmd_list_length;
|
||||||
} DRunModePrivateData;
|
} 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 ) ) {
|
if ( g_key_file_has_key ( kf, "Desktop Entry", "Exec", NULL ) ) {
|
||||||
size_t nl = ( ( pd->cmd_list_length ) + 2 );
|
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 ) ) );
|
pd->entry_list = g_realloc ( pd->entry_list, nl * sizeof ( *( pd->entry_list ) ) );
|
||||||
if ( g_key_file_has_key ( kf, "Desktop Entry", "Name", NULL ) ) {
|
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 *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 );
|
gchar *gn = g_key_file_get_locale_string ( kf, "Desktop Entry", "GenericName", NULL, NULL );
|
||||||
if ( gn == NULL ) {
|
pd->entry_list[pd->cmd_list_length].name = n;
|
||||||
pd->cmd_list[pd->cmd_list_length] = g_markup_escape_text ( n, -1 );
|
pd->entry_list[pd->cmd_list_length].generic_name = gn;
|
||||||
}
|
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
else {
|
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 );
|
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 ) ) {
|
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->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 )++;
|
( pd->cmd_list_length )++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,22 +219,10 @@ static void drun_mode_init ( Switcher *sw )
|
||||||
if ( sw->private_data == NULL ) {
|
if ( sw->private_data == NULL ) {
|
||||||
DRunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
DRunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
||||||
sw->private_data = (void *) 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,
|
static SwitcherMode drun_mode_result ( int mretv, char **input, unsigned int selected_line,
|
||||||
Switcher *sw )
|
Switcher *sw )
|
||||||
{
|
{
|
||||||
|
@ -255,7 +240,7 @@ static SwitcherMode drun_mode_result ( int mretv, char **input, unsigned int sel
|
||||||
else if ( mretv & MENU_QUICK_SWITCH ) {
|
else if ( mretv & MENU_QUICK_SWITCH ) {
|
||||||
retv = ( mretv & MENU_LOWER_MASK );
|
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] ) );
|
exec_cmd_entry ( &( rmpd->entry_list[selected_line] ) );
|
||||||
}
|
}
|
||||||
else if ( ( mretv & MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] != '\0' ) {
|
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;
|
DRunModePrivateData *rmpd = (DRunModePrivateData *) sw->private_data;
|
||||||
if ( rmpd != NULL ) {
|
if ( rmpd != NULL ) {
|
||||||
g_strfreev ( rmpd->cmd_list );
|
|
||||||
for ( size_t i = 0; i < rmpd->cmd_list_length; i++ ) {
|
for ( size_t i = 0; i < rmpd->cmd_list_length; i++ ) {
|
||||||
g_free ( rmpd->entry_list[i].exec );
|
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->entry_list );
|
||||||
g_free ( rmpd );
|
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;
|
*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 =
|
Switcher drun_mode =
|
||||||
{
|
{
|
||||||
.name = "drun",
|
.name = "drun",
|
||||||
.keycfg = NULL,
|
.keycfg = NULL,
|
||||||
.keystr = NULL,
|
.keystr = NULL,
|
||||||
.modmask = AnyModifier,
|
.modmask = AnyModifier,
|
||||||
.init = drun_mode_init,
|
.init = drun_mode_init,
|
||||||
.get_data = drun_mode_get_data,
|
.get_num_entries = drun_mode_get_num_entries,
|
||||||
.result = drun_mode_result,
|
.result = drun_mode_result,
|
||||||
.destroy = drun_mode_destroy,
|
.destroy = drun_mode_destroy,
|
||||||
.token_match = token_match,
|
.token_match = drun_token_match,
|
||||||
.mgrv = mgrv,
|
.mgrv = mgrv,
|
||||||
.private_data = NULL,
|
.is_not_ascii = drun_is_not_ascii,
|
||||||
.free = NULL
|
.private_data = NULL,
|
||||||
|
.free = NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -272,20 +272,14 @@ static void run_mode_init ( Switcher *sw )
|
||||||
if ( sw->private_data == NULL ) {
|
if ( sw->private_data == NULL ) {
|
||||||
RunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
RunModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
||||||
sw->private_data = (void *) 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;
|
RunModePrivateData *rmpd = (RunModePrivateData *) sw->private_data;
|
||||||
if ( rmpd->cmd_list == NULL ) {
|
return rmpd->cmd_list_length;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SwitcherMode run_mode_result ( int mretv, char **input, unsigned int selected_line,
|
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 )
|
||||||
{
|
{
|
||||||
return run_mode_get_data ( NULL, sw )[selected_line];
|
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 )
|
||||||
|
{
|
||||||
|
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 =
|
Switcher run_mode =
|
||||||
{
|
{
|
||||||
.name = "run",
|
.name = "run",
|
||||||
.keycfg = NULL,
|
.keycfg = NULL,
|
||||||
.keystr = NULL,
|
.keystr = NULL,
|
||||||
.modmask = AnyModifier,
|
.modmask = AnyModifier,
|
||||||
.init = run_mode_init,
|
.init = run_mode_init,
|
||||||
.get_data = run_mode_get_data,
|
.get_num_entries = run_mode_get_num_entries,
|
||||||
.result = run_mode_result,
|
.result = run_mode_result,
|
||||||
.destroy = run_mode_destroy,
|
.destroy = run_mode_destroy,
|
||||||
.token_match = token_match,
|
.token_match = run_token_match,
|
||||||
.mgrv = mgrv,
|
.mgrv = mgrv,
|
||||||
.private_data = NULL,
|
.is_not_ascii = run_is_not_ascii,
|
||||||
.free = NULL
|
.private_data = NULL,
|
||||||
|
.free = NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -102,17 +102,13 @@ static void script_mode_init ( Switcher *sw )
|
||||||
if ( sw->private_data == NULL ) {
|
if ( sw->private_data == NULL ) {
|
||||||
ScriptModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
ScriptModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
||||||
sw->private_data = (void *) 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;
|
ScriptModePrivateData *rmpd = (ScriptModePrivateData *) sw->private_data;
|
||||||
if ( rmpd->cmd_list == NULL ) {
|
return rmpd->cmd_list_length;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SwitcherMode script_mode_result ( int mretv, char **input, unsigned int selected_line,
|
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;
|
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 = ( (Switcher *) sw )->private_data;
|
ScriptModePrivateData *rmpd = sw->private_data;
|
||||||
return rmpd->cmd_list[selected_line];
|
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 = sw->private_data;
|
||||||
|
return is_not_ascii ( rmpd->cmd_list[index] );
|
||||||
}
|
}
|
||||||
|
|
||||||
Switcher *script_switcher_parse_setup ( const char *str )
|
Switcher *script_switcher_parse_setup ( const char *str )
|
||||||
|
@ -184,15 +192,16 @@ Switcher *script_switcher_parse_setup ( const char *str )
|
||||||
}
|
}
|
||||||
g_free ( parse );
|
g_free ( parse );
|
||||||
if ( index == 2 ) {
|
if ( index == 2 ) {
|
||||||
sw->free = script_switcher_free;
|
sw->free = script_switcher_free;
|
||||||
sw->keysym = None;
|
sw->keysym = None;
|
||||||
sw->modmask = AnyModifier;
|
sw->modmask = AnyModifier;
|
||||||
sw->init = script_mode_init;
|
sw->init = script_mode_init;
|
||||||
sw->get_data = script_mode_get_data;
|
sw->get_num_entries = script_mode_get_num_entries;
|
||||||
sw->result = script_mode_result;
|
sw->result = script_mode_result;
|
||||||
sw->destroy = script_mode_destroy;
|
sw->destroy = script_mode_destroy;
|
||||||
sw->token_match = token_match;
|
sw->token_match = script_token_match;
|
||||||
sw->mgrv = mgrv;
|
sw->mgrv = mgrv;
|
||||||
|
sw->is_not_ascii = script_is_not_ascii;
|
||||||
|
|
||||||
return sw;
|
return sw;
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,20 +327,14 @@ static void ssh_mode_init ( Switcher *sw )
|
||||||
if ( sw->private_data == NULL ) {
|
if ( sw->private_data == NULL ) {
|
||||||
SSHModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
SSHModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
||||||
sw->private_data = (void *) 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;
|
SSHModePrivateData *rmpd = (SSHModePrivateData *) sw->private_data;
|
||||||
if ( rmpd->cmd_list == NULL ) {
|
return rmpd->cmd_list_length;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
static SwitcherMode ssh_mode_result ( int mretv, char **input, unsigned int selected_line,
|
static SwitcherMode ssh_mode_result ( int mretv, char **input, unsigned int selected_line,
|
||||||
Switcher *sw )
|
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 )
|
||||||
{
|
{
|
||||||
return ssh_mode_get_data ( NULL, sw )[selected_line];
|
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 )
|
||||||
|
{
|
||||||
|
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 =
|
Switcher ssh_mode =
|
||||||
{
|
{
|
||||||
.name = "ssh",
|
.name = "ssh",
|
||||||
.keycfg = NULL,
|
.keycfg = NULL,
|
||||||
.keystr = NULL,
|
.keystr = NULL,
|
||||||
.modmask = AnyModifier,
|
.modmask = AnyModifier,
|
||||||
.init = ssh_mode_init,
|
.init = ssh_mode_init,
|
||||||
.get_data = ssh_mode_get_data,
|
.get_num_entries = ssh_mode_get_num_entries,
|
||||||
.result = ssh_mode_result,
|
.result = ssh_mode_result,
|
||||||
.destroy = ssh_mode_destroy,
|
.destroy = ssh_mode_destroy,
|
||||||
.token_match = token_match,
|
.token_match = ssh_token_match,
|
||||||
.mgrv = mgrv,
|
.mgrv = mgrv,
|
||||||
.private_data = NULL,
|
.is_not_ascii = ssh_is_not_ascii,
|
||||||
.free = NULL
|
.private_data = NULL,
|
||||||
|
.free = NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -315,13 +315,12 @@ typedef struct _SwitcherModePrivateData
|
||||||
unsigned int cmd_list_length;
|
unsigned int cmd_list_length;
|
||||||
winlist *ids;
|
winlist *ids;
|
||||||
int config_i3_mode;
|
int config_i3_mode;
|
||||||
int init;
|
|
||||||
// Current window.
|
// Current window.
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
char *cache;
|
char *cache;
|
||||||
} SwitcherModePrivateData;
|
} SwitcherModePrivateData;
|
||||||
|
|
||||||
static int window_match ( char **tokens, __attribute__( ( unused ) ) const char *input,
|
static int window_match ( char **tokens,
|
||||||
__attribute__( ( unused ) ) int not_ascii,
|
__attribute__( ( unused ) ) int not_ascii,
|
||||||
int case_sensitive, unsigned int index, Switcher *sw )
|
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'
|
// e.g. when searching 'title element' and 'class element'
|
||||||
char *ftokens[2] = { tokens[j], NULL };
|
char *ftokens[2] = { tokens[j], NULL };
|
||||||
if ( !test && c->title[0] != '\0' ) {
|
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' ) {
|
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' ) {
|
if ( !test && c->role[0] != '\0' ) {
|
||||||
test = token_match ( ftokens, c->role, is_not_ascii ( c->role ), case_sensitive, 0, NULL );
|
test = token_match ( ftokens, c->role, not_ascii, case_sensitive );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !test && c->name[0] != '\0' ) {
|
if ( !test && c->name[0] != '\0' ) {
|
||||||
test = token_match ( ftokens, c->name, is_not_ascii ( c->name ), case_sensitive, 0, NULL );
|
test = token_match ( ftokens, c->name, not_ascii, case_sensitive );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( test == 0 ) {
|
if ( test == 0 ) {
|
||||||
|
@ -362,151 +361,151 @@ static int window_match ( char **tokens, __attribute__( ( unused ) ) const char
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int window_mode_get_num_entries ( Switcher *sw )
|
||||||
|
{
|
||||||
|
SwitcherModePrivateData *pd = (SwitcherModePrivateData *) sw->private_data;
|
||||||
|
return pd->cmd_list_length;
|
||||||
|
}
|
||||||
|
static void _window_mode_load_data ( Switcher *sw, unsigned int cd )
|
||||||
|
{
|
||||||
|
SwitcherModePrivateData *pd = (SwitcherModePrivateData *) sw->private_data;
|
||||||
|
Screen *screen = DefaultScreenOfDisplay ( display );
|
||||||
|
Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) );
|
||||||
|
// find window list
|
||||||
|
Atom type;
|
||||||
|
int nwins = 0;
|
||||||
|
Window wins[100];
|
||||||
|
int count = 0;
|
||||||
|
Window curr_win_id = 0;
|
||||||
|
// Create cache
|
||||||
|
|
||||||
|
x11_cache_create ();
|
||||||
|
// Check for i3
|
||||||
|
pd->config_i3_mode = i3_support_initialize ( display );
|
||||||
|
|
||||||
|
// Get the active window so we can highlight this.
|
||||||
|
if ( !( window_get_prop ( display, root, netatoms[_NET_ACTIVE_WINDOW], &type, &count, &curr_win_id, sizeof ( Window ) )
|
||||||
|
&& type == XA_WINDOW && count > 0 ) ) {
|
||||||
|
curr_win_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current desktop.
|
||||||
|
unsigned long current_desktop = 0;
|
||||||
|
if ( !window_get_cardinal_prop ( display, root, netatoms[_NET_CURRENT_DESKTOP], ¤t_desktop, 1 ) ) {
|
||||||
|
current_desktop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int nw = 100 * sizeof ( Window );
|
||||||
|
// First try Stacking order.. If this fails.
|
||||||
|
if ( !( window_get_prop ( display, root, netatoms[_NET_CLIENT_LIST_STACKING], &type, &nwins, wins, nw )
|
||||||
|
&& type == XA_WINDOW ) ) {
|
||||||
|
// Try to get order by age.
|
||||||
|
if ( !( window_get_prop ( display, root, netatoms[_NET_CLIENT_LIST], &type, &nwins, wins, nw )
|
||||||
|
&& type == XA_WINDOW ) ) {
|
||||||
|
nwins = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( nwins > 0 ) {
|
||||||
|
char pattern[50];
|
||||||
|
int i;
|
||||||
|
unsigned int classfield = 0;
|
||||||
|
unsigned long desktops = 0;
|
||||||
|
// windows we actually display. May be slightly different to _NET_CLIENT_LIST_STACKING
|
||||||
|
// if we happen to have a window destroyed while we're working...
|
||||||
|
pd->ids = winlist_new ();
|
||||||
|
|
||||||
|
// calc widths of fields
|
||||||
|
for ( i = nwins - 1; i > -1; i-- ) {
|
||||||
|
client *c;
|
||||||
|
|
||||||
|
if ( ( c = window_client ( display, wins[i] ) )
|
||||||
|
&& !c->xattr.override_redirect
|
||||||
|
&& !client_has_window_type ( c, netatoms[_NET_WM_WINDOW_TYPE_DOCK] )
|
||||||
|
&& !client_has_window_type ( c, netatoms[_NET_WM_WINDOW_TYPE_DESKTOP] )
|
||||||
|
&& !client_has_state ( c, netatoms[_NET_WM_STATE_SKIP_PAGER] )
|
||||||
|
&& !client_has_state ( c, netatoms[_NET_WM_STATE_SKIP_TASKBAR] ) ) {
|
||||||
|
classfield = MAX ( classfield, strlen ( c->class ) );
|
||||||
|
|
||||||
|
if ( client_has_state ( c, netatoms[_NET_WM_STATE_DEMANDS_ATTENTION] ) ) {
|
||||||
|
c->demands = TRUE;
|
||||||
|
}
|
||||||
|
if ( ( c->hint_flags & XUrgencyHint ) == XUrgencyHint ) {
|
||||||
|
c->demands = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( c->window == curr_win_id ) {
|
||||||
|
c->active = TRUE;
|
||||||
|
}
|
||||||
|
winlist_append ( pd->ids, c->window, NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create pattern for printing the line.
|
||||||
|
if ( !window_get_cardinal_prop ( display, root, netatoms[_NET_NUMBER_OF_DESKTOPS], &desktops, 1 ) ) {
|
||||||
|
desktops = 1;
|
||||||
|
}
|
||||||
|
if ( pd->config_i3_mode ) {
|
||||||
|
sprintf ( pattern, "%%-%ds %%s", MAX ( 5, classfield ) );
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sprintf ( pattern, "%%-%ds %%-%ds %%s", desktops < 10 ? 1 : 2,
|
||||||
|
MAX ( 5, classfield ) );
|
||||||
|
}
|
||||||
|
pd->cmd_list = g_malloc0_n ( ( pd->ids->len + 1 ), sizeof ( char* ) );
|
||||||
|
|
||||||
|
// build the actual list
|
||||||
|
for ( i = 0; i < ( pd->ids->len ); i++ ) {
|
||||||
|
Window w = pd->ids->array[i];
|
||||||
|
client *c;
|
||||||
|
|
||||||
|
if ( ( c = window_client ( display, w ) ) ) {
|
||||||
|
// final line format
|
||||||
|
unsigned long wmdesktop;
|
||||||
|
char desktop[5];
|
||||||
|
desktop[0] = 0;
|
||||||
|
char *line = g_malloc ( strlen ( c->title ) + strlen ( c->class ) + classfield + 50 );
|
||||||
|
if ( !pd->config_i3_mode ) {
|
||||||
|
// find client's desktop.
|
||||||
|
if ( !window_get_cardinal_prop ( display, c->window, netatoms[_NET_WM_DESKTOP], &wmdesktop, 1 ) ) {
|
||||||
|
// Assume the client is on all desktops.
|
||||||
|
wmdesktop = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
else if ( cd && wmdesktop != current_desktop ) {
|
||||||
|
g_free ( line );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( wmdesktop < 0xFFFFFFFF ) {
|
||||||
|
sprintf ( desktop, "%d", (int) wmdesktop );
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf ( line, pattern, desktop, c->class, c->title );
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
sprintf ( line, pattern, c->class, c->title );
|
||||||
|
}
|
||||||
|
|
||||||
|
pd->cmd_list[pd->cmd_list_length++] = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
static void window_mode_init ( Switcher *sw )
|
static void window_mode_init ( Switcher *sw )
|
||||||
{
|
{
|
||||||
if ( sw->private_data == NULL ) {
|
if ( sw->private_data == NULL ) {
|
||||||
SwitcherModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
SwitcherModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
||||||
sw->private_data = (void *) pd;
|
sw->private_data = (void *) pd;
|
||||||
pd->init = FALSE;
|
_window_mode_load_data ( sw, FALSE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static void window_mode_init_cd ( Switcher *sw )
|
||||||
static char ** _window_mode_get_data ( unsigned int *length, Switcher *sw, unsigned int cd )
|
|
||||||
{
|
{
|
||||||
SwitcherModePrivateData *pd = (SwitcherModePrivateData *) sw->private_data;
|
if ( sw->private_data == NULL ) {
|
||||||
if ( !pd->init ) {
|
SwitcherModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
||||||
Screen *screen = DefaultScreenOfDisplay ( display );
|
sw->private_data = (void *) pd;
|
||||||
Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) );
|
_window_mode_load_data ( sw, TRUE );
|
||||||
// find window list
|
|
||||||
Atom type;
|
|
||||||
int nwins = 0;
|
|
||||||
Window wins[100];
|
|
||||||
int count = 0;
|
|
||||||
Window curr_win_id = 0;
|
|
||||||
// Create cache
|
|
||||||
|
|
||||||
x11_cache_create ();
|
|
||||||
// Check for i3
|
|
||||||
pd->config_i3_mode = i3_support_initialize ( display );
|
|
||||||
|
|
||||||
// Get the active window so we can highlight this.
|
|
||||||
if ( !( window_get_prop ( display, root, netatoms[_NET_ACTIVE_WINDOW], &type, &count, &curr_win_id, sizeof ( Window ) )
|
|
||||||
&& type == XA_WINDOW && count > 0 ) ) {
|
|
||||||
curr_win_id = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the current desktop.
|
|
||||||
unsigned long current_desktop = 0;
|
|
||||||
if ( !window_get_cardinal_prop ( display, root, netatoms[_NET_CURRENT_DESKTOP], ¤t_desktop, 1 ) ) {
|
|
||||||
current_desktop = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int nw = 100 * sizeof ( Window );
|
|
||||||
// First try Stacking order.. If this fails.
|
|
||||||
if ( !( window_get_prop ( display, root, netatoms[_NET_CLIENT_LIST_STACKING], &type, &nwins, wins, nw )
|
|
||||||
&& type == XA_WINDOW ) ) {
|
|
||||||
// Try to get order by age.
|
|
||||||
if ( !( window_get_prop ( display, root, netatoms[_NET_CLIENT_LIST], &type, &nwins, wins, nw )
|
|
||||||
&& type == XA_WINDOW ) ) {
|
|
||||||
nwins = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( nwins > 0 ) {
|
|
||||||
char pattern[50];
|
|
||||||
int i;
|
|
||||||
unsigned int classfield = 0;
|
|
||||||
unsigned long desktops = 0;
|
|
||||||
// windows we actually display. May be slightly different to _NET_CLIENT_LIST_STACKING
|
|
||||||
// if we happen to have a window destroyed while we're working...
|
|
||||||
pd->ids = winlist_new ();
|
|
||||||
|
|
||||||
// calc widths of fields
|
|
||||||
for ( i = nwins - 1; i > -1; i-- ) {
|
|
||||||
client *c;
|
|
||||||
|
|
||||||
if ( ( c = window_client ( display, wins[i] ) )
|
|
||||||
&& !c->xattr.override_redirect
|
|
||||||
&& !client_has_window_type ( c, netatoms[_NET_WM_WINDOW_TYPE_DOCK] )
|
|
||||||
&& !client_has_window_type ( c, netatoms[_NET_WM_WINDOW_TYPE_DESKTOP] )
|
|
||||||
&& !client_has_state ( c, netatoms[_NET_WM_STATE_SKIP_PAGER] )
|
|
||||||
&& !client_has_state ( c, netatoms[_NET_WM_STATE_SKIP_TASKBAR] ) ) {
|
|
||||||
classfield = MAX ( classfield, strlen ( c->class ) );
|
|
||||||
|
|
||||||
if ( client_has_state ( c, netatoms[_NET_WM_STATE_DEMANDS_ATTENTION] ) ) {
|
|
||||||
c->demands = TRUE;
|
|
||||||
}
|
|
||||||
if ( ( c->hint_flags & XUrgencyHint ) == XUrgencyHint ) {
|
|
||||||
c->demands = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( c->window == curr_win_id ) {
|
|
||||||
c->active = TRUE;
|
|
||||||
}
|
|
||||||
winlist_append ( pd->ids, c->window, NULL );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create pattern for printing the line.
|
|
||||||
if ( !window_get_cardinal_prop ( display, root, netatoms[_NET_NUMBER_OF_DESKTOPS], &desktops, 1 ) ) {
|
|
||||||
desktops = 1;
|
|
||||||
}
|
|
||||||
if ( pd->config_i3_mode ) {
|
|
||||||
sprintf ( pattern, "%%-%ds %%s", MAX ( 5, classfield ) );
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
sprintf ( pattern, "%%-%ds %%-%ds %%s", desktops < 10 ? 1 : 2,
|
|
||||||
MAX ( 5, classfield ) );
|
|
||||||
}
|
|
||||||
pd->cmd_list = g_malloc0_n ( ( pd->ids->len + 1 ), sizeof ( char* ) );
|
|
||||||
|
|
||||||
// build the actual list
|
|
||||||
for ( i = 0; i < ( pd->ids->len ); i++ ) {
|
|
||||||
Window w = pd->ids->array[i];
|
|
||||||
client *c;
|
|
||||||
|
|
||||||
if ( ( c = window_client ( display, w ) ) ) {
|
|
||||||
// final line format
|
|
||||||
unsigned long wmdesktop;
|
|
||||||
char desktop[5];
|
|
||||||
desktop[0] = 0;
|
|
||||||
char *line = g_malloc ( strlen ( c->title ) + strlen ( c->class ) + classfield + 50 );
|
|
||||||
if ( !pd->config_i3_mode ) {
|
|
||||||
// find client's desktop.
|
|
||||||
if ( !window_get_cardinal_prop ( display, c->window, netatoms[_NET_WM_DESKTOP], &wmdesktop, 1 ) ) {
|
|
||||||
// Assume the client is on all desktops.
|
|
||||||
wmdesktop = 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
else if ( cd && wmdesktop != current_desktop ) {
|
|
||||||
g_free ( line );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( wmdesktop < 0xFFFFFFFF ) {
|
|
||||||
sprintf ( desktop, "%d", (int) wmdesktop );
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf ( line, pattern, desktop, c->class, c->title );
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
sprintf ( line, pattern, c->class, c->title );
|
|
||||||
}
|
|
||||||
|
|
||||||
pd->cmd_list[pd->cmd_list_length++] = line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pd->init = TRUE;
|
|
||||||
}
|
}
|
||||||
*length = pd->cmd_list_length;
|
|
||||||
return pd->cmd_list;
|
|
||||||
}
|
|
||||||
static char ** window_mode_get_data_cd ( unsigned int *length, Switcher *sw )
|
|
||||||
{
|
|
||||||
return _window_mode_get_data ( length, sw, TRUE );
|
|
||||||
}
|
|
||||||
static char ** window_mode_get_data ( unsigned int *length, Switcher *sw )
|
|
||||||
{
|
|
||||||
return _window_mode_get_data ( length, sw, FALSE );
|
|
||||||
}
|
}
|
||||||
static SwitcherMode window_mode_result ( int mretv, G_GNUC_UNUSED char **input,
|
static SwitcherMode window_mode_result ( int mretv, G_GNUC_UNUSED char **input,
|
||||||
unsigned int selected_line,
|
unsigned int selected_line,
|
||||||
|
@ -558,47 +557,57 @@ static void window_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 )
|
||||||
{
|
{
|
||||||
SwitcherModePrivateData *rmpd = ( (Switcher *) sw )->private_data;
|
SwitcherModePrivateData *rmpd = sw->private_data;
|
||||||
if ( window_client ( display, rmpd->ids->array[selected_line] )->demands ) {
|
if ( window_client ( display, rmpd->ids->array[selected_line] )->demands ) {
|
||||||
*state |= URGENT;
|
*state |= URGENT;
|
||||||
}
|
}
|
||||||
if ( window_client ( display, rmpd->ids->array[selected_line] )->active ) {
|
if ( window_client ( display, rmpd->ids->array[selected_line] )->active ) {
|
||||||
*state |= ACTIVE;
|
*state |= ACTIVE;
|
||||||
}
|
}
|
||||||
return rmpd->cmd_list[selected_line];
|
return get_entry ? g_strdup ( rmpd->cmd_list[selected_line] ) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int window_is_not_ascii ( Switcher *sw, unsigned int index )
|
||||||
|
{
|
||||||
|
SwitcherModePrivateData *rmpd = sw->private_data;
|
||||||
|
winlist *ids = ( winlist * ) rmpd->ids;
|
||||||
|
client *c = window_client ( display, ids->array[index] );
|
||||||
|
return is_not_ascii ( c->role ) || is_not_ascii ( c->class ) || is_not_ascii ( c->title ) || is_not_ascii ( c->name );
|
||||||
}
|
}
|
||||||
|
|
||||||
Switcher window_mode =
|
Switcher window_mode =
|
||||||
{
|
{
|
||||||
.name = "window",
|
.name = "window",
|
||||||
.keycfg = NULL,
|
.keycfg = NULL,
|
||||||
.keystr = NULL,
|
.keystr = NULL,
|
||||||
.modmask = AnyModifier,
|
.modmask = AnyModifier,
|
||||||
.init = window_mode_init,
|
.init = window_mode_init,
|
||||||
.get_data = window_mode_get_data,
|
.get_num_entries = window_mode_get_num_entries,
|
||||||
.result = window_mode_result,
|
.result = window_mode_result,
|
||||||
.destroy = window_mode_destroy,
|
.destroy = window_mode_destroy,
|
||||||
.token_match = window_match,
|
.token_match = window_match,
|
||||||
.mgrv = mgrv,
|
.mgrv = mgrv,
|
||||||
.private_data = NULL,
|
.is_not_ascii = window_is_not_ascii,
|
||||||
.free = NULL
|
.private_data = NULL,
|
||||||
|
.free = NULL
|
||||||
};
|
};
|
||||||
Switcher window_mode_cd =
|
Switcher window_mode_cd =
|
||||||
{
|
{
|
||||||
.name = "windowcd",
|
.name = "windowcd",
|
||||||
.keycfg = NULL,
|
.keycfg = NULL,
|
||||||
.keystr = NULL,
|
.keystr = NULL,
|
||||||
.modmask = AnyModifier,
|
.modmask = AnyModifier,
|
||||||
.init = window_mode_init,
|
.init = window_mode_init_cd,
|
||||||
.get_data = window_mode_get_data_cd,
|
.get_num_entries = window_mode_get_num_entries,
|
||||||
.result = window_mode_result,
|
.result = window_mode_result,
|
||||||
.destroy = window_mode_destroy,
|
.destroy = window_mode_destroy,
|
||||||
.token_match = window_match,
|
.token_match = window_match,
|
||||||
.mgrv = mgrv,
|
.mgrv = mgrv,
|
||||||
.private_data = NULL,
|
.is_not_ascii = window_is_not_ascii,
|
||||||
.free = NULL
|
.private_data = NULL,
|
||||||
|
.free = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WINDOW_MODE
|
#endif // WINDOW_MODE
|
||||||
|
|
|
@ -472,9 +472,7 @@ static int glob_token_match ( char **tokens, const char *input, int not_ascii, i
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
int token_match ( char **tokens, const char *input, int not_ascii, int case_sensitive,
|
int token_match ( char **tokens, const char *input, int not_ascii, int case_sensitive )
|
||||||
__attribute__( ( unused ) ) unsigned int index,
|
|
||||||
__attribute__( ( unused ) ) Switcher *data )
|
|
||||||
{
|
{
|
||||||
if ( config.glob ) {
|
if ( config.glob ) {
|
||||||
return glob_token_match ( tokens, input, not_ascii, case_sensitive );
|
return glob_token_match ( tokens, input, not_ascii, case_sensitive );
|
||||||
|
|
|
@ -154,7 +154,7 @@ static int lev_sort ( const void *p1, const void *p2, void *arg )
|
||||||
|
|
||||||
#define MIN3( a, b, c ) ( ( a ) < ( b ) ? ( ( a ) < ( c ) ? ( a ) : ( c ) ) : ( ( b ) < ( c ) ? ( b ) : ( c ) ) )
|
#define MIN3( a, b, c ) ( ( a ) < ( b ) ? ( ( a ) < ( c ) ? ( a ) : ( c ) ) : ( ( b ) < ( c ) ? ( b ) : ( c ) ) )
|
||||||
|
|
||||||
static int levenshtein ( char *s1, char *s2 )
|
static int levenshtein ( const char *s1, const char *s2 )
|
||||||
{
|
{
|
||||||
unsigned int x, y, lastdiag, olddiag;
|
unsigned int x, y, lastdiag, olddiag;
|
||||||
size_t s1len = strlen ( s1 );
|
size_t s1len = strlen ( s1 );
|
||||||
|
@ -222,7 +222,6 @@ typedef struct MenuState
|
||||||
// Return state
|
// Return state
|
||||||
unsigned int *selected_line;
|
unsigned int *selected_line;
|
||||||
MenuReturn retv;
|
MenuReturn retv;
|
||||||
char **lines;
|
|
||||||
int *lines_not_ascii;
|
int *lines_not_ascii;
|
||||||
int line_height;
|
int line_height;
|
||||||
unsigned int border;
|
unsigned int border;
|
||||||
|
@ -643,7 +642,10 @@ static int menu_keyboard_navigation ( MenuState *state, KeySym key, unsigned int
|
||||||
else if ( abe_test_action ( ROW_SELECT, modstate, key ) ) {
|
else if ( abe_test_action ( ROW_SELECT, modstate, key ) ) {
|
||||||
// If a valid item is selected, return that..
|
// If a valid item is selected, return that..
|
||||||
if ( state->selected < state->filtered_lines ) {
|
if ( state->selected < state->filtered_lines ) {
|
||||||
textbox_text ( state->text, state->lines[state->line_map[state->selected]] );
|
int st;
|
||||||
|
char * str = state->sw->mgrv ( state->line_map[state->selected], state->sw, &st, TRUE );
|
||||||
|
textbox_text ( state->text, str );
|
||||||
|
g_free ( str );
|
||||||
textbox_cursor_end ( state->text );
|
textbox_cursor_end ( state->text );
|
||||||
state->update = TRUE;
|
state->update = TRUE;
|
||||||
state->refilter = TRUE;
|
state->refilter = TRUE;
|
||||||
|
@ -752,18 +754,20 @@ static void filter_elements ( thread_state *t, G_GNUC_UNUSED gpointer user_data
|
||||||
{
|
{
|
||||||
// input changed
|
// input changed
|
||||||
for ( unsigned int i = t->start; i < t->stop; i++ ) {
|
for ( unsigned int i = t->start; i < t->stop; i++ ) {
|
||||||
|
int st;
|
||||||
int match = t->state->sw->token_match ( t->tokens,
|
int match = t->state->sw->token_match ( t->tokens,
|
||||||
t->state->lines[i],
|
|
||||||
t->state->lines_not_ascii[i],
|
t->state->lines_not_ascii[i],
|
||||||
config.case_sensitive,
|
config.case_sensitive,
|
||||||
i,
|
i,
|
||||||
t->state->sw );
|
t->state->sw );
|
||||||
|
|
||||||
// If each token was matched, add it to list.
|
// If each token was matched, add it to list.
|
||||||
if ( match ) {
|
if ( match ) {
|
||||||
t->state->line_map[t->start + t->count] = i;
|
t->state->line_map[t->start + t->count] = i;
|
||||||
if ( config.levenshtein_sort ) {
|
if ( config.levenshtein_sort ) {
|
||||||
t->state->distance[i] = levenshtein ( t->state->text->text, t->state->lines[i] );
|
// This is inefficient, need to fix it.
|
||||||
|
char * str = t->state->sw->mgrv ( i, t->state->sw, &st, TRUE );
|
||||||
|
t->state->distance[i] = levenshtein ( t->state->text->text, str );
|
||||||
|
g_free ( str );
|
||||||
}
|
}
|
||||||
t->count++;
|
t->count++;
|
||||||
}
|
}
|
||||||
|
@ -776,7 +780,7 @@ static void filter_elements ( thread_state *t, G_GNUC_UNUSED gpointer user_data
|
||||||
static void check_is_ascii ( thread_state *t, G_GNUC_UNUSED gpointer user_data )
|
static void check_is_ascii ( thread_state *t, G_GNUC_UNUSED gpointer user_data )
|
||||||
{
|
{
|
||||||
for ( unsigned int i = t->start; i < t->stop; i++ ) {
|
for ( unsigned int i = t->start; i < t->stop; i++ ) {
|
||||||
t->state->lines_not_ascii[i] = is_not_ascii ( t->state->lines[i] );
|
t->state->lines_not_ascii[i] = t->state->sw->is_not_ascii ( t->state->sw, i );
|
||||||
}
|
}
|
||||||
g_mutex_lock ( t->mutex );
|
g_mutex_lock ( t->mutex );
|
||||||
( *( t->acount ) )--;
|
( *( t->acount ) )--;
|
||||||
|
@ -933,10 +937,11 @@ static void menu_draw ( MenuState *state, cairo_t *d )
|
||||||
{
|
{
|
||||||
TextBoxFontType type = ( ( ( i % state->max_rows ) & 1 ) == 0 ) ? NORMAL : ALT;
|
TextBoxFontType type = ( ( ( i % state->max_rows ) & 1 ) == 0 ) ? NORMAL : ALT;
|
||||||
int fstate = 0;
|
int fstate = 0;
|
||||||
const char *text = state->sw->mgrv ( state->line_map[i + offset], state->sw, &fstate );
|
char *text = state->sw->mgrv ( state->line_map[i + offset], state->sw, &fstate, TRUE );
|
||||||
TextBoxFontType tbft = fstate | ( ( i + offset ) == state->selected ? HIGHLIGHT : type );
|
TextBoxFontType tbft = fstate | ( ( i + offset ) == state->selected ? HIGHLIGHT : type );
|
||||||
textbox_font ( state->boxes[i], tbft );
|
textbox_font ( state->boxes[i], tbft );
|
||||||
textbox_text ( state->boxes[i], text );
|
textbox_text ( state->boxes[i], text );
|
||||||
|
g_free ( text );
|
||||||
}
|
}
|
||||||
textbox_draw ( state->boxes[i], d );
|
textbox_draw ( state->boxes[i], d );
|
||||||
}
|
}
|
||||||
|
@ -947,7 +952,7 @@ static void menu_draw ( MenuState *state, cairo_t *d )
|
||||||
for ( i = 0; i < max_elements; i++ ) {
|
for ( i = 0; i < max_elements; i++ ) {
|
||||||
TextBoxFontType type = ( ( ( i % state->max_rows ) & 1 ) == 0 ) ? NORMAL : ALT;
|
TextBoxFontType type = ( ( ( i % state->max_rows ) & 1 ) == 0 ) ? NORMAL : ALT;
|
||||||
int fstate = 0;
|
int fstate = 0;
|
||||||
state->sw->mgrv ( state->line_map[i + offset], state->sw, &fstate );
|
state->sw->mgrv ( state->line_map[i + offset], state->sw, &fstate, FALSE );
|
||||||
TextBoxFontType tbft = fstate | ( ( i + offset ) == state->selected ? HIGHLIGHT : type );
|
TextBoxFontType tbft = fstate | ( ( i + offset ) == state->selected ? HIGHLIGHT : type );
|
||||||
textbox_font ( state->boxes[i], tbft );
|
textbox_font ( state->boxes[i], tbft );
|
||||||
textbox_draw ( state->boxes[i], d );
|
textbox_draw ( state->boxes[i], d );
|
||||||
|
@ -1186,11 +1191,11 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, unsigned int *select
|
||||||
.border = config.padding + config.menu_bw
|
.border = config.padding + config.menu_bw
|
||||||
};
|
};
|
||||||
// Request the lines to show.
|
// Request the lines to show.
|
||||||
state.lines = sw->get_data ( &( state.num_lines ), sw );
|
state.num_lines = sw->get_num_entries ( sw );
|
||||||
state.lines_not_ascii = g_malloc0_n ( state.num_lines, sizeof ( int ) );
|
state.lines_not_ascii = g_malloc0_n ( state.num_lines, sizeof ( int ) );
|
||||||
|
|
||||||
// find out which lines contain non-ascii codepoints, so we can be faster in some cases.
|
// find out which lines contain non-ascii codepoints, so we can be faster in some cases.
|
||||||
if ( state.lines != NULL ) {
|
if ( state.num_lines > 0 ) {
|
||||||
TICK_N ( "Is ASCII start" )
|
TICK_N ( "Is ASCII start" )
|
||||||
unsigned int nt = MAX ( 1, state.num_lines / 5000 );
|
unsigned int nt = MAX ( 1, state.num_lines / 5000 );
|
||||||
thread_state states[nt];
|
thread_state states[nt];
|
||||||
|
@ -1487,7 +1492,7 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, unsigned int *select
|
||||||
}
|
}
|
||||||
Status stat;
|
Status stat;
|
||||||
char pad[32];
|
char pad[32];
|
||||||
KeySym key;// = XkbKeycodeToKeysym ( display, ev.xkey.keycode, 0, 0 );
|
KeySym key; // = XkbKeycodeToKeysym ( display, ev.xkey.keycode, 0, 0 );
|
||||||
int len = Xutf8LookupString ( xic, &( ev.xkey ), pad, sizeof ( pad ), &key, &stat );
|
int len = Xutf8LookupString ( xic, &( ev.xkey ), pad, sizeof ( pad ), &key, &stat );
|
||||||
pad[len] = 0;
|
pad[len] = 0;
|
||||||
|
|
||||||
|
@ -1525,6 +1530,7 @@ MenuReturn menu ( Switcher *sw, char **input, char *prompt, unsigned int *select
|
||||||
else {
|
else {
|
||||||
textbox_text ( state.case_indicator, " " );
|
textbox_text ( state.case_indicator, " " );
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// Special delete entry command.
|
// Special delete entry command.
|
||||||
else if ( abe_test_action ( DELETE_ENTRY, ev.xkey.state, key ) ) {
|
else if ( abe_test_action ( DELETE_ENTRY, ev.xkey.state, key ) ) {
|
||||||
|
|
Loading…
Reference in New Issue