mirror of
https://github.com/davatorium/rofi.git
synced 2025-04-14 17:43:01 -04:00
Add combi viewer, where (selected) modi can be combined.
- Add active window highlighter.
This commit is contained in:
parent
56a888da6f
commit
0d87cf12a3
13 changed files with 220 additions and 102 deletions
|
@ -1,6 +1,8 @@
|
|||
0.15.3: (unreleased)
|
||||
0.15.4: (unreleased)
|
||||
New feature:
|
||||
- Number mode for dmenu. allows user to get index back instead of content.
|
||||
- Combi mode. Combine multiple views into one.
|
||||
- Highlight current window.
|
||||
Bug fixes:
|
||||
- On a single item in list disable auto-select.
|
||||
Improvements:
|
||||
|
@ -13,6 +15,7 @@
|
|||
- Fix modi switcher boxes size+layout.
|
||||
- Reduce work on redraws (do not always calculate new size/position), set text, etc.
|
||||
- OO-ify the switchers.
|
||||
- Remove unneeded filtered array.
|
||||
Cleanup:
|
||||
- Do not lug argc,argv around everywhere.
|
||||
|
||||
|
|
|
@ -104,7 +104,10 @@ Settings config = {
|
|||
/** Lazy mode setting */
|
||||
.lazy_filter_limit = 5000,
|
||||
/** auto select */
|
||||
.auto_select = FALSE,
|
||||
.parse_hosts = FALSE
|
||||
.auto_select = FALSE,
|
||||
/** Parse /etc/hosts file in ssh view. */
|
||||
.parse_hosts = FALSE,
|
||||
/** Modi to combine into one view. */
|
||||
.combi_modi = "window,run"
|
||||
};
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ 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 );
|
||||
/**
|
||||
* State returned by the rofi window.
|
||||
*/
|
||||
|
@ -90,7 +92,7 @@ typedef int ( *menu_match_cb )( char **tokens, const char *input, int case_sensi
|
|||
*/
|
||||
MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prompt,
|
||||
menu_match_cb mmc, void *mmc_data,
|
||||
int *selected_line, int sorting ) __attribute__ ( ( nonnull ( 1, 3, 4, 7 ) ) );
|
||||
int *selected_line, int sorting, get_display_value mgrv, void *mgrv_data ) __attribute__ ( ( nonnull ( 1, 3, 4, 7 ) ) );
|
||||
/**
|
||||
* @param sig The caught signal
|
||||
*
|
||||
|
@ -203,6 +205,8 @@ typedef struct _Settings
|
|||
unsigned int auto_select;
|
||||
/** Hosts file parsing */
|
||||
unsigned int parse_hosts;
|
||||
/** Combi Switchers */
|
||||
char *combi_modi;
|
||||
} Settings;
|
||||
|
||||
/** Global Settings structure. */
|
||||
|
@ -236,21 +240,23 @@ struct _Switcher
|
|||
/**
|
||||
* A switcher normally consists of the following parts:
|
||||
*/
|
||||
void ( *init )( struct _Switcher *sw );
|
||||
char ** ( *get_data )( unsigned int *length, struct _Switcher *pd );
|
||||
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 );
|
||||
void ( *init )( struct _Switcher *sw );
|
||||
char ** ( *get_data )( unsigned int *length, struct _Switcher *pd );
|
||||
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 );
|
||||
// Token match.
|
||||
menu_match_cb token_match;
|
||||
menu_match_cb token_match;
|
||||
|
||||
get_display_value mgrv;
|
||||
|
||||
// Pointer to private data.
|
||||
void *private_data;
|
||||
void *private_data;
|
||||
|
||||
// Extra fields for script
|
||||
void *ed;
|
||||
void *ed;
|
||||
// Free SWitcher
|
||||
switcher_free free;
|
||||
switcher_free free;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,7 @@ typedef struct
|
|||
XIM xim;
|
||||
XIC xic;
|
||||
PangoLayout *layout;
|
||||
int tbft;
|
||||
} textbox;
|
||||
|
||||
|
||||
|
@ -34,11 +35,15 @@ typedef enum
|
|||
typedef enum
|
||||
{
|
||||
// Render font normally
|
||||
NORMAL,
|
||||
NORMAL = 1,
|
||||
// Alternating row.
|
||||
ALT,
|
||||
ALT = 2,
|
||||
// Render font highlighted (inverted colors.)
|
||||
HIGHLIGHT,
|
||||
HIGHLIGHT = 4,
|
||||
|
||||
STATE_MASK = ( NORMAL | ALT | HIGHLIGHT ),
|
||||
|
||||
BOLD = 8,
|
||||
} TextBoxFontType;
|
||||
|
||||
textbox* textbox_create ( Window parent,
|
||||
|
|
|
@ -29,8 +29,11 @@
|
|||
#include <stdio.h>
|
||||
#include <rofi.h>
|
||||
|
||||
extern unsigned int num_switchers;
|
||||
extern Switcher **switchers;
|
||||
#include <dialogs/run.h>
|
||||
#include <dialogs/ssh.h>
|
||||
#include <dialogs/window.h>
|
||||
#include <dialogs/script.h>
|
||||
|
||||
/**
|
||||
* Combi Switcher
|
||||
*/
|
||||
|
@ -45,28 +48,64 @@ typedef struct _CombiModePrivateData
|
|||
// List of switchers to combine.
|
||||
unsigned int num_switchers;
|
||||
Switcher **switchers;
|
||||
char *cache;
|
||||
} CombiModePrivateData;
|
||||
|
||||
static void combi_add_switcher ( Switcher *sw, Switcher *m )
|
||||
static void combi_mode_parse_switchers ( Switcher *sw )
|
||||
{
|
||||
CombiModePrivateData *pd = sw->private_data;
|
||||
pd->switchers = g_realloc ( pd->switchers, ( pd->num_switchers + 2 ) * sizeof ( Switcher * ) );
|
||||
pd->switchers[pd->num_switchers] = m;
|
||||
pd->switchers[pd->num_switchers + 1] = NULL;
|
||||
pd->num_switchers++;
|
||||
CombiModePrivateData *pd = sw->private_data;
|
||||
char *savept = NULL;
|
||||
// Make a copy, as strtok will modify it.
|
||||
char *switcher_str = g_strdup ( config.combi_modi );
|
||||
// Split token on ','. This modifies switcher_str.
|
||||
for ( char *token = strtok_r ( switcher_str, ",", &savept );
|
||||
token != NULL;
|
||||
token = strtok_r ( NULL, ",", &savept ) ) {
|
||||
// Resize and add entry.
|
||||
pd->switchers = (Switcher * *) g_realloc ( pd->switchers,
|
||||
sizeof ( Switcher* ) * ( pd->num_switchers + 1 ) );
|
||||
|
||||
// Window switcher.
|
||||
if ( strcasecmp ( token, "window" ) == 0 ) {
|
||||
pd->switchers[pd->num_switchers++] = &window_mode;
|
||||
}
|
||||
// SSh dialog
|
||||
else if ( strcasecmp ( token, "ssh" ) == 0 ) {
|
||||
pd->switchers[pd->num_switchers++] = &ssh_mode;
|
||||
}
|
||||
// Run dialog
|
||||
else if ( strcasecmp ( token, "run" ) == 0 ) {
|
||||
pd->switchers[pd->num_switchers++] = &run_mode;
|
||||
}
|
||||
else {
|
||||
// If not build in, use custom switchers.
|
||||
Switcher *sw = script_switcher_parse_setup ( token );
|
||||
if ( sw != NULL ) {
|
||||
pd->switchers[pd->num_switchers++] = sw;
|
||||
}
|
||||
else{
|
||||
// Report error, don't continue.
|
||||
fprintf ( stderr, "Invalid script switcher: %s\n", token );
|
||||
token = NULL;
|
||||
}
|
||||
}
|
||||
// Keybinding.
|
||||
}
|
||||
// Free string that was modified by strtok_r
|
||||
g_free ( switcher_str );
|
||||
}
|
||||
|
||||
static void combi_mode_init ( Switcher *sw )
|
||||
{
|
||||
if ( sw->private_data == NULL ) {
|
||||
CombiModePrivateData *pd = g_malloc0 ( sizeof ( *pd ) );
|
||||
sw->private_data = (void *) pd;
|
||||
for ( unsigned int i = 0; i < num_switchers; i++ ) {
|
||||
if ( switchers[i] != sw ) {
|
||||
combi_add_switcher ( sw, switchers[i] );
|
||||
}
|
||||
}
|
||||
combi_mode_parse_switchers ( sw );
|
||||
pd->starts = g_malloc0 ( sizeof ( int ) * pd->num_switchers );
|
||||
pd->lengths = g_malloc0 ( sizeof ( int ) * pd->num_switchers );
|
||||
for ( unsigned int i = 0; i < pd->num_switchers; i++ ) {
|
||||
pd->switchers[i]->init ( pd->switchers[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
static char ** combi_mode_get_data ( unsigned int *length, Switcher *sw )
|
||||
|
@ -101,8 +140,13 @@ static void combi_mode_destroy ( Switcher *sw )
|
|||
g_free ( pd->cmd_list );
|
||||
g_free ( pd->starts );
|
||||
g_free ( pd->lengths );
|
||||
// Cleanup switchers.
|
||||
for ( unsigned int i = 0; i < pd->num_switchers; i++ ) {
|
||||
pd->switchers[i]->destroy ( pd->switchers[i] );
|
||||
}
|
||||
g_free ( pd->switchers );
|
||||
g_free ( pd );
|
||||
g_free ( pd->cache );
|
||||
sw->private_data = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -138,6 +182,21 @@ static int combi_mode_match ( char **tokens, const char *input,
|
|||
abort ();
|
||||
return 0;
|
||||
}
|
||||
static const char * combi_mgrv ( unsigned int selected_line, void *sw, int *state )
|
||||
{
|
||||
CombiModePrivateData *pd = ( (Switcher *) sw )->private_data;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Switcher combi_mode =
|
||||
{
|
||||
|
@ -151,6 +210,7 @@ Switcher combi_mode =
|
|||
.result = combi_mode_result,
|
||||
.destroy = combi_mode_destroy,
|
||||
.token_match = combi_mode_match,
|
||||
.mgrv = combi_mgrv,
|
||||
.private_data = NULL,
|
||||
.free = NULL
|
||||
};
|
||||
|
|
|
@ -64,6 +64,12 @@ static char **get_dmenu ( int *length )
|
|||
return retv;
|
||||
}
|
||||
|
||||
static const char *get_display_data ( unsigned int index, void *data, G_GNUC_UNUSED int *state )
|
||||
{
|
||||
char **retv = (char * *) data;
|
||||
return retv[index];
|
||||
}
|
||||
|
||||
int dmenu_switcher_dialog ( char **input )
|
||||
{
|
||||
char *dmenu_prompt = "dmenu ";
|
||||
|
@ -84,7 +90,7 @@ int dmenu_switcher_dialog ( char **input )
|
|||
|
||||
do {
|
||||
int mretv = menu ( list, length, input, dmenu_prompt,
|
||||
token_match, NULL, &selected_line, FALSE );
|
||||
token_match, NULL, &selected_line, FALSE, get_display_data, list );
|
||||
|
||||
// We normally do not want to restart the loop.
|
||||
restart = FALSE;
|
||||
|
|
|
@ -331,6 +331,12 @@ static void run_mode_destroy ( Switcher *sw )
|
|||
}
|
||||
}
|
||||
|
||||
static const char *mgrv ( unsigned int selected_line, void *sw, G_GNUC_UNUSED int *state )
|
||||
{
|
||||
RunModePrivateData *rmpd = ( (Switcher *) sw )->private_data;
|
||||
return rmpd->cmd_list[selected_line];
|
||||
}
|
||||
|
||||
Switcher run_mode =
|
||||
{
|
||||
.name = "run",
|
||||
|
@ -343,6 +349,7 @@ Switcher run_mode =
|
|||
.result = run_mode_result,
|
||||
.destroy = run_mode_destroy,
|
||||
.token_match = token_match,
|
||||
.mgrv = mgrv,
|
||||
.private_data = NULL,
|
||||
.free = NULL
|
||||
};
|
||||
|
|
|
@ -163,6 +163,11 @@ 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 )
|
||||
{
|
||||
ScriptModePrivateData *rmpd = ( (Switcher *) sw )->private_data;
|
||||
return rmpd->cmd_list[selected_line];
|
||||
}
|
||||
|
||||
Switcher *script_switcher_parse_setup ( const char *str )
|
||||
{
|
||||
|
@ -189,6 +194,7 @@ Switcher *script_switcher_parse_setup ( const char *str )
|
|||
sw->result = script_mode_result;
|
||||
sw->destroy = script_mode_destroy;
|
||||
sw->token_match = token_match;
|
||||
sw->mgrv = mgrv;
|
||||
|
||||
return sw;
|
||||
}
|
||||
|
|
|
@ -321,6 +321,12 @@ static void ssh_mode_destroy ( Switcher *sw )
|
|||
}
|
||||
}
|
||||
|
||||
static const char *mgrv ( unsigned int selected_line, void *sw, G_GNUC_UNUSED int *state )
|
||||
{
|
||||
SSHModePrivateData *rmpd = ( (Switcher *) sw )->private_data;
|
||||
return rmpd->cmd_list[selected_line];
|
||||
}
|
||||
|
||||
Switcher ssh_mode =
|
||||
{
|
||||
.name = "ssh",
|
||||
|
@ -333,6 +339,7 @@ Switcher ssh_mode =
|
|||
.result = ssh_mode_result,
|
||||
.destroy = ssh_mode_destroy,
|
||||
.token_match = token_match,
|
||||
.mgrv = mgrv,
|
||||
.private_data = NULL,
|
||||
.free = NULL
|
||||
};
|
||||
|
|
|
@ -286,6 +286,9 @@ typedef struct _SwitcherModePrivateData
|
|||
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,
|
||||
|
@ -496,11 +499,21 @@ static void window_mode_destroy ( Switcher *sw )
|
|||
winlist_free ( rmpd->ids );
|
||||
i3_support_free_internals ();
|
||||
x11_cache_free ();
|
||||
g_free ( rmpd->cache );
|
||||
g_free ( rmpd );
|
||||
sw->private_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *mgrv ( unsigned int selected_line, void *sw, G_GNUC_UNUSED int *state )
|
||||
{
|
||||
SwitcherModePrivateData *rmpd = ( (Switcher *) sw )->private_data;
|
||||
if ( window_client ( display, rmpd->ids->array[selected_line] )->active ) {
|
||||
*state = BOLD;
|
||||
}
|
||||
return rmpd->cmd_list[selected_line];
|
||||
}
|
||||
|
||||
Switcher window_mode =
|
||||
{
|
||||
.name = "window",
|
||||
|
@ -513,6 +526,7 @@ Switcher window_mode =
|
|||
.result = window_mode_result,
|
||||
.destroy = window_mode_destroy,
|
||||
.token_match = window_match,
|
||||
.mgrv = mgrv,
|
||||
.private_data = NULL,
|
||||
.free = NULL
|
||||
};
|
||||
|
|
125
source/rofi.c
125
source/rofi.c
|
@ -272,51 +272,52 @@ static Window create_window ( Display *display )
|
|||
|
||||
typedef struct MenuState
|
||||
{
|
||||
unsigned int menu_lines;
|
||||
unsigned int max_elements;
|
||||
unsigned int max_rows;
|
||||
unsigned int columns;
|
||||
unsigned int menu_lines;
|
||||
unsigned int max_elements;
|
||||
unsigned int max_rows;
|
||||
unsigned int columns;
|
||||
|
||||
// window width,height
|
||||
unsigned int w, h;
|
||||
int x, y;
|
||||
unsigned int element_width;
|
||||
unsigned int w, h;
|
||||
int x, y;
|
||||
unsigned int element_width;
|
||||
|
||||
// Update/Refilter list.
|
||||
int update;
|
||||
int refilter;
|
||||
int rchanged;
|
||||
int cur_page;
|
||||
int update;
|
||||
int refilter;
|
||||
int rchanged;
|
||||
int cur_page;
|
||||
|
||||
// Entries
|
||||
textbox *text;
|
||||
textbox *prompt_tb;
|
||||
textbox *case_indicator;
|
||||
textbox *arrowbox_top;
|
||||
textbox *arrowbox_bottom;
|
||||
textbox **boxes;
|
||||
char **filtered;
|
||||
int *distance;
|
||||
int *line_map;
|
||||
textbox *text;
|
||||
textbox *prompt_tb;
|
||||
textbox *case_indicator;
|
||||
textbox *arrowbox_top;
|
||||
textbox *arrowbox_bottom;
|
||||
textbox **boxes;
|
||||
int *distance;
|
||||
int *line_map;
|
||||
|
||||
unsigned int num_lines;
|
||||
unsigned int num_lines;
|
||||
|
||||
// Selected element.
|
||||
unsigned int selected;
|
||||
unsigned int filtered_lines;
|
||||
unsigned int selected;
|
||||
unsigned int filtered_lines;
|
||||
// Last offset in paginating.
|
||||
unsigned int last_offset;
|
||||
unsigned int last_offset;
|
||||
|
||||
KeySym prev_key;
|
||||
Time last_button_press;
|
||||
KeySym prev_key;
|
||||
Time last_button_press;
|
||||
|
||||
int quit;
|
||||
int init;
|
||||
int quit;
|
||||
int init;
|
||||
// Return state
|
||||
int *selected_line;
|
||||
MenuReturn retv;
|
||||
char **lines;
|
||||
int line_height;
|
||||
int *selected_line;
|
||||
MenuReturn retv;
|
||||
char **lines;
|
||||
int line_height;
|
||||
get_display_value mgrv;
|
||||
void *mgrv_data;
|
||||
}MenuState;
|
||||
|
||||
/**
|
||||
|
@ -337,7 +338,6 @@ static void menu_free_state ( MenuState *state )
|
|||
}
|
||||
|
||||
g_free ( state->boxes );
|
||||
g_free ( state->filtered );
|
||||
g_free ( state->line_map );
|
||||
g_free ( state->distance );
|
||||
}
|
||||
|
@ -575,15 +575,9 @@ static void menu_keyboard_navigation ( MenuState *state, KeySym key, unsigned in
|
|||
}
|
||||
else if ( key == XK_Tab ) {
|
||||
if ( state->filtered_lines == 1 ) {
|
||||
if ( state->filtered[state->selected] ) {
|
||||
state->retv = MENU_OK;
|
||||
*( state->selected_line ) = state->line_map[state->selected];
|
||||
state->quit = 1;
|
||||
}
|
||||
else{
|
||||
fprintf ( stderr, "We should never hit this." );
|
||||
abort ();
|
||||
}
|
||||
state->retv = MENU_OK;
|
||||
*( state->selected_line ) = state->line_map[state->selected];
|
||||
state->quit = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -636,7 +630,7 @@ static void menu_keyboard_navigation ( MenuState *state, KeySym key, unsigned in
|
|||
}
|
||||
else if ( key == XK_space && ( modstate & ControlMask ) == ControlMask ) {
|
||||
// If a valid item is selected, return that..
|
||||
if ( state->selected < state->filtered_lines && state->filtered[state->selected] != NULL ) {
|
||||
if ( state->selected < state->filtered_lines ) {
|
||||
textbox_text ( state->text, state->lines[state->line_map[state->selected]] );
|
||||
textbox_cursor_end ( state->text );
|
||||
state->update = TRUE;
|
||||
|
@ -753,13 +747,6 @@ static void menu_refilter ( MenuState *state, char **lines, menu_match_cb mmc, v
|
|||
if ( sorting ) {
|
||||
qsort_r ( state->line_map, j, sizeof ( int ), lev_sort, state->distance );
|
||||
}
|
||||
// Update the filtered list.
|
||||
for ( unsigned int i = 0; i < j; i++ ) {
|
||||
state->filtered[i] = lines[state->line_map[i]];
|
||||
}
|
||||
for ( unsigned int i = j; i < state->num_lines; i++ ) {
|
||||
state->filtered[i] = NULL;
|
||||
}
|
||||
|
||||
// Cleanup + bookkeeping.
|
||||
state->filtered_lines = j;
|
||||
|
@ -767,7 +754,6 @@ static void menu_refilter ( MenuState *state, char **lines, menu_match_cb mmc, v
|
|||
}
|
||||
else{
|
||||
for ( unsigned int i = 0; i < state->num_lines; i++ ) {
|
||||
state->filtered[i] = lines[i];
|
||||
state->line_map[i] = i;
|
||||
}
|
||||
state->filtered_lines = state->num_lines;
|
||||
|
@ -841,9 +827,10 @@ static void menu_draw ( MenuState *state )
|
|||
ex + x_offset, ey + y_offset,
|
||||
element_width, element_height );
|
||||
{
|
||||
TextBoxFontType type = ( ( ( i % state->max_rows ) & 1 ) == 0 ) ? NORMAL : ALT;
|
||||
char *text = state->filtered[i + offset];
|
||||
TextBoxFontType tbft = ( i + offset ) == state->selected ? HIGHLIGHT : type;
|
||||
TextBoxFontType type = ( ( ( i % state->max_rows ) & 1 ) == 0 ) ? NORMAL : ALT;
|
||||
int fstate = 0;
|
||||
const char *text = state->mgrv ( state->line_map[i + offset], state->mgrv_data, &fstate );
|
||||
TextBoxFontType tbft = fstate | ( ( i + offset ) == state->selected ? HIGHLIGHT : type );
|
||||
textbox_font ( state->boxes[i], tbft );
|
||||
textbox_text ( state->boxes[i], text );
|
||||
}
|
||||
|
@ -855,8 +842,10 @@ static void menu_draw ( MenuState *state )
|
|||
else{
|
||||
// Only do basic redrawing + highlight of row.
|
||||
for ( i = 0; i < max_elements; i++ ) {
|
||||
TextBoxFontType type = ( ( ( i % state->max_rows ) & 1 ) == 0 ) ? NORMAL : ALT;
|
||||
TextBoxFontType tbft = ( i + offset ) == state->selected ? HIGHLIGHT : type;
|
||||
TextBoxFontType type = ( ( ( i % state->max_rows ) & 1 ) == 0 ) ? NORMAL : ALT;
|
||||
int fstate = 0;
|
||||
state->mgrv ( state->line_map[i + offset], state->mgrv_data, &fstate );
|
||||
TextBoxFontType tbft = fstate | ( ( i + offset ) == state->selected ? HIGHLIGHT : type );
|
||||
textbox_font ( state->boxes[i], tbft );
|
||||
textbox_draw ( state->boxes[i] );
|
||||
}
|
||||
|
@ -924,7 +913,8 @@ static void menu_paste ( MenuState *state, XSelectionEvent *xse )
|
|||
}
|
||||
|
||||
MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prompt,
|
||||
menu_match_cb mmc, void *mmc_data, int *selected_line, int sorting )
|
||||
menu_match_cb mmc, void *mmc_data, int *selected_line, int sorting,
|
||||
get_display_value mgrv, void *mgrv_data )
|
||||
{
|
||||
int shift = FALSE;
|
||||
MenuState state = {
|
||||
|
@ -940,11 +930,13 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
|||
.filtered_lines = 0,
|
||||
.max_elements = 0,
|
||||
// We want to filter on the first run.
|
||||
.refilter = TRUE,
|
||||
.update = FALSE,
|
||||
.rchanged = TRUE,
|
||||
.cur_page = -1,
|
||||
.lines = lines
|
||||
.refilter = TRUE,
|
||||
.update = FALSE,
|
||||
.rchanged = TRUE,
|
||||
.cur_page = -1,
|
||||
.lines = lines,
|
||||
.mgrv = mgrv,
|
||||
.mgrv_data = mgrv_data
|
||||
};
|
||||
unsigned int i;
|
||||
workarea mon;
|
||||
|
@ -1036,7 +1028,6 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
|||
config.padding + state.max_rows * element_height + LINE_MARGIN );
|
||||
|
||||
// filtered list
|
||||
state.filtered = (char * *) g_malloc0_n ( state.num_lines, sizeof ( char* ) );
|
||||
state.line_map = g_malloc0_n ( state.num_lines, sizeof ( int ) );
|
||||
if ( sorting ) {
|
||||
state.distance = (int *) g_malloc0_n ( state.num_lines, sizeof ( int ) );
|
||||
|
@ -1212,7 +1203,7 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
|||
// Special delete entry command.
|
||||
else if ( ( ( ev.xkey.state & ShiftMask ) == ShiftMask ) &&
|
||||
key == XK_Delete ) {
|
||||
if ( state.filtered[state.selected] != NULL ) {
|
||||
if ( state.selected < state.filtered_lines ) {
|
||||
*( state.selected_line ) = state.line_map[state.selected];
|
||||
state.retv = MENU_ENTRY_DELETE;
|
||||
state.quit = TRUE;
|
||||
|
@ -1226,7 +1217,7 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
|||
shift = ( ( ev.xkey.state & ShiftMask ) == ShiftMask );
|
||||
|
||||
// If a valid item is selected, return that..
|
||||
if ( state.selected < state.filtered_lines && state.filtered[state.selected] != NULL ) {
|
||||
if ( state.selected < state.filtered_lines ) {
|
||||
*( state.selected_line ) = state.line_map[state.selected];
|
||||
if ( strlen ( state.text->text ) > 0 && rc == -2 ) {
|
||||
state.retv = MENU_CUSTOM_INPUT;
|
||||
|
@ -1836,7 +1827,9 @@ SwitcherMode switcher_run ( char **input, Switcher *sw )
|
|||
input, prompt,
|
||||
sw->token_match, sw,
|
||||
&selected_line,
|
||||
config.levenshtein_sort );
|
||||
config.levenshtein_sort,
|
||||
sw->mgrv,
|
||||
sw );
|
||||
|
||||
SwitcherMode retv = sw->result ( mretv, input, selected_line, sw );
|
||||
|
||||
|
|
|
@ -78,10 +78,6 @@ textbox* textbox_create ( Window parent,
|
|||
|
||||
tb->layout = pango_layout_new ( p_context );
|
||||
|
||||
PangoFontDescription *pfd = pango_font_description_from_string ( config.menu_font );
|
||||
pango_layout_set_font_description ( tb->layout, pfd );
|
||||
pango_font_description_free ( pfd );
|
||||
|
||||
unsigned int cp;
|
||||
switch ( tbft )
|
||||
{
|
||||
|
@ -104,6 +100,8 @@ textbox* textbox_create ( Window parent,
|
|||
InputOutput, vinfo->visual, CWColormap | CWBorderPixel | CWBackPixel, &attr );
|
||||
|
||||
// need to preload the font to calc line height
|
||||
// Force update of font descriptor.
|
||||
tb->tbft = ~tbft;
|
||||
textbox_font ( tb, tbft );
|
||||
|
||||
textbox_text ( tb, text ? text : "" );
|
||||
|
@ -129,7 +127,15 @@ textbox* textbox_create ( Window parent,
|
|||
// set an Xft font by name
|
||||
void textbox_font ( textbox *tb, TextBoxFontType tbft )
|
||||
{
|
||||
switch ( tbft )
|
||||
if ( ( tbft & BOLD ) != ( tb->tbft & BOLD ) ) {
|
||||
PangoFontDescription *pfd = pango_font_description_from_string ( config.menu_font );
|
||||
if ( ( tbft & BOLD ) == BOLD ) {
|
||||
pango_font_description_set_weight ( pfd, PANGO_WEIGHT_BOLD );
|
||||
}
|
||||
pango_layout_set_font_description ( tb->layout, pfd );
|
||||
pango_font_description_free ( pfd );
|
||||
}
|
||||
switch ( ( tbft & STATE_MASK ) )
|
||||
{
|
||||
case HIGHLIGHT:
|
||||
tb->color_bg = color_hlbg;
|
||||
|
@ -145,6 +151,7 @@ void textbox_font ( textbox *tb, TextBoxFontType tbft )
|
|||
tb->color_fg = color_fg;
|
||||
break;
|
||||
}
|
||||
tb->tbft = tbft;
|
||||
}
|
||||
|
||||
// set the default text to display
|
||||
|
|
|
@ -105,7 +105,8 @@ static XrmOption xrmOptions[] = {
|
|||
{ xrm_Number, "lazy-filter-limit", { .num = &config.lazy_filter_limit }, NULL },
|
||||
{ xrm_SNumber, "eh", { .snum = &config.element_height }, NULL },
|
||||
{ xrm_Boolean, "auto-select", { .num = &config.auto_select }, NULL },
|
||||
{ xrm_Boolean, "parse-hosts", { .num = &config.parse_hosts }, NULL }
|
||||
{ xrm_Boolean, "parse-hosts", { .num = &config.parse_hosts }, NULL },
|
||||
{ xrm_String, "combi-modi", { .str = &config.combi_modi }, NULL }
|
||||
};
|
||||
|
||||
// Dynamic options.
|
||||
|
|
Loading…
Add table
Reference in a new issue