mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-25 13:55:34 -05:00
Add support for msg string with pango markup.
This commit is contained in:
parent
48d8d09831
commit
a93aec02bd
7 changed files with 117 additions and 18 deletions
|
@ -529,6 +529,10 @@ The following options are further explained in the theming section:
|
||||||
|
|
||||||
Preset user filter to *filter* in the entry box and pre-filter the list.
|
Preset user filter to *filter* in the entry box and pre-filter the list.
|
||||||
|
|
||||||
|
`-mesg` *str*
|
||||||
|
|
||||||
|
Add a message line beneath filter. Supports pango markdown.
|
||||||
|
|
||||||
### Message dialog
|
### Message dialog
|
||||||
|
|
||||||
`-e` *message*
|
`-e` *message*
|
||||||
|
|
|
@ -695,6 +695,14 @@ Default: 's'
|
||||||
Preset user filter to *filter* in the entry box and pre\-filter the list.
|
Preset user filter to *filter* in the entry box and pre\-filter the list.
|
||||||
.fi
|
.fi
|
||||||
.RE
|
.RE
|
||||||
|
.PP
|
||||||
|
\fB\fC\-mesg\fR \fIstr\fP
|
||||||
|
.PP
|
||||||
|
.RS
|
||||||
|
.nf
|
||||||
|
Add a message line beneath filter. Supports pango markdown.
|
||||||
|
.fi
|
||||||
|
.RE
|
||||||
.SS Message dialog
|
.SS Message dialog
|
||||||
.PP
|
.PP
|
||||||
\fB\fC\-e\fR \fImessage\fP
|
\fB\fC\-e\fR \fImessage\fP
|
||||||
|
|
|
@ -87,6 +87,7 @@ typedef int ( *menu_match_cb )( char **tokens, const char *input, int case_sensi
|
||||||
* @param mmc Menu menu match callback, used for matching user input.
|
* @param mmc Menu menu match callback, used for matching user input.
|
||||||
* @param mmc_data data to pass to mmc.
|
* @param mmc_data data to pass to mmc.
|
||||||
* @param selected_line pointer to integer holding the selected line.
|
* @param selected_line pointer to integer holding the selected line.
|
||||||
|
* @param message Extra message to display.
|
||||||
*
|
*
|
||||||
* Main menu callback.
|
* Main menu callback.
|
||||||
*
|
*
|
||||||
|
@ -94,8 +95,8 @@ 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,
|
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 *next_pos ) __attribute__ ( ( nonnull ( 1, 3,
|
get_display_value mgrv, void *mgrv_data, int *next_pos, const char *message ) __attribute__ ( ( nonnull ( 1, 3,
|
||||||
4, 7 ) ) );
|
4, 7 ) ) );
|
||||||
/**
|
/**
|
||||||
* @param sig The caught signal
|
* @param sig The caught signal
|
||||||
*
|
*
|
||||||
|
|
|
@ -18,6 +18,8 @@ typedef struct
|
||||||
XIC xic;
|
XIC xic;
|
||||||
PangoLayout *layout;
|
PangoLayout *layout;
|
||||||
int tbft;
|
int tbft;
|
||||||
|
int markup;
|
||||||
|
int changed;
|
||||||
} textbox;
|
} textbox;
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +31,7 @@ typedef enum
|
||||||
TB_RIGHT = 1 << 17,
|
TB_RIGHT = 1 << 17,
|
||||||
TB_CENTER = 1 << 18,
|
TB_CENTER = 1 << 18,
|
||||||
TB_EDITABLE = 1 << 19,
|
TB_EDITABLE = 1 << 19,
|
||||||
|
TB_MARKUP = 1 << 20,
|
||||||
} TextboxFlags;
|
} TextboxFlags;
|
||||||
|
|
||||||
|
|
||||||
|
@ -240,4 +243,7 @@ void textbox_delete ( textbox *tb, int pos, int dlen );
|
||||||
|
|
||||||
void textbox_moveresize ( textbox *tb, int x, int y, int w, int h );
|
void textbox_moveresize ( textbox *tb, int x, int y, int w, int h );
|
||||||
int textbox_get_estimated_char_height ( void );
|
int textbox_get_estimated_char_height ( void );
|
||||||
|
|
||||||
|
|
||||||
|
void textbox_text_markup ( textbox *tb, const char *text );
|
||||||
#endif //__TEXTBOX_H__
|
#endif //__TEXTBOX_H__
|
||||||
|
|
|
@ -186,6 +186,10 @@ int dmenu_switcher_dialog ( char **input )
|
||||||
int length = 0;
|
int length = 0;
|
||||||
char **list = get_dmenu ( &length );
|
char **list = get_dmenu ( &length );
|
||||||
int restart = FALSE;
|
int restart = FALSE;
|
||||||
|
char *message = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
find_arg_str ( "-mesg", &message );
|
||||||
|
|
||||||
// By default we print the unescaped line back.
|
// By default we print the unescaped line back.
|
||||||
char *format = "s";
|
char *format = "s";
|
||||||
|
@ -238,7 +242,7 @@ int dmenu_switcher_dialog ( char **input )
|
||||||
do {
|
do {
|
||||||
int next_pos = selected_line;
|
int next_pos = selected_line;
|
||||||
int mretv = menu ( list, length, input, dmenu_prompt,
|
int mretv = menu ( list, length, input, dmenu_prompt,
|
||||||
token_match, NULL, &selected_line, config.levenshtein_sort, get_display_data, list, &next_pos );
|
token_match, NULL, &selected_line, config.levenshtein_sort, get_display_data, list, &next_pos, message );
|
||||||
// Special behavior.
|
// Special behavior.
|
||||||
if ( only_selected ) {
|
if ( only_selected ) {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -280,6 +280,7 @@ typedef struct MenuState
|
||||||
unsigned int w, h;
|
unsigned int w, h;
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned int element_width;
|
unsigned int element_width;
|
||||||
|
int top_offset;
|
||||||
|
|
||||||
// Update/Refilter list.
|
// Update/Refilter list.
|
||||||
int update;
|
int update;
|
||||||
|
@ -290,6 +291,7 @@ typedef struct MenuState
|
||||||
// Entries
|
// Entries
|
||||||
textbox *text;
|
textbox *text;
|
||||||
textbox *prompt_tb;
|
textbox *prompt_tb;
|
||||||
|
textbox *message_tb;
|
||||||
textbox *case_indicator;
|
textbox *case_indicator;
|
||||||
textbox *arrowbox_top;
|
textbox *arrowbox_top;
|
||||||
textbox *arrowbox_bottom;
|
textbox *arrowbox_bottom;
|
||||||
|
@ -798,7 +800,7 @@ static void menu_draw ( MenuState *state )
|
||||||
}
|
}
|
||||||
|
|
||||||
int element_height = state->line_height * config.element_height;
|
int element_height = state->line_height * config.element_height;
|
||||||
int y_offset = config.padding + state->line_height;
|
int y_offset = state->top_offset;
|
||||||
int x_offset = config.padding;
|
int x_offset = config.padding;
|
||||||
// Calculate number of visible rows.
|
// Calculate number of visible rows.
|
||||||
unsigned int max_elements = MIN ( a_lines, state->max_rows * columns );
|
unsigned int max_elements = MIN ( a_lines, state->max_rows * columns );
|
||||||
|
@ -850,6 +852,9 @@ static void menu_update ( MenuState *state )
|
||||||
textbox_draw ( state->case_indicator );
|
textbox_draw ( state->case_indicator );
|
||||||
textbox_draw ( state->prompt_tb );
|
textbox_draw ( state->prompt_tb );
|
||||||
textbox_draw ( state->text );
|
textbox_draw ( state->text );
|
||||||
|
if ( state->message_tb ) {
|
||||||
|
textbox_draw ( state->message_tb );
|
||||||
|
}
|
||||||
menu_draw ( state );
|
menu_draw ( state );
|
||||||
menu_set_arrow_text ( state->filtered_lines, state->selected,
|
menu_set_arrow_text ( state->filtered_lines, state->selected,
|
||||||
state->max_elements, state->arrowbox_top,
|
state->max_elements, state->arrowbox_top,
|
||||||
|
@ -859,6 +864,13 @@ static void menu_update ( MenuState *state )
|
||||||
state->line_height + ( config.padding ) + ( LINE_MARGIN ) / 2,
|
state->line_height + ( config.padding ) + ( LINE_MARGIN ) / 2,
|
||||||
state->w - ( ( config.padding ) ) - 1,
|
state->w - ( ( config.padding ) ) - 1,
|
||||||
state->line_height + ( config.padding ) + ( LINE_MARGIN ) / 2 );
|
state->line_height + ( config.padding ) + ( LINE_MARGIN ) / 2 );
|
||||||
|
if ( state->message_tb ) {
|
||||||
|
XDrawLine ( display, main_window, gc,
|
||||||
|
( config.padding ),
|
||||||
|
state->top_offset + ( LINE_MARGIN ) / 2,
|
||||||
|
state->w - ( ( config.padding ) ) - 1,
|
||||||
|
state->top_offset + ( LINE_MARGIN ) / 2 );
|
||||||
|
}
|
||||||
|
|
||||||
if ( config.sidebar_mode == TRUE ) {
|
if ( config.sidebar_mode == TRUE ) {
|
||||||
XDrawLine ( display, main_window, gc,
|
XDrawLine ( display, main_window, gc,
|
||||||
|
@ -904,7 +916,7 @@ static void menu_paste ( MenuState *state, XSelectionEvent *xse )
|
||||||
|
|
||||||
MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prompt,
|
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 *next_pos )
|
get_display_value mgrv, void *mgrv_data, int *next_pos, const char *message )
|
||||||
{
|
{
|
||||||
int shift = FALSE;
|
int shift = FALSE;
|
||||||
MenuState state = {
|
MenuState state = {
|
||||||
|
@ -919,13 +931,14 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
||||||
.filtered_lines = 0,
|
.filtered_lines = 0,
|
||||||
.max_elements = 0,
|
.max_elements = 0,
|
||||||
// We want to filter on the first run.
|
// We want to filter on the first run.
|
||||||
.refilter = TRUE,
|
.refilter = TRUE,
|
||||||
.update = FALSE,
|
.update = FALSE,
|
||||||
.rchanged = TRUE,
|
.rchanged = TRUE,
|
||||||
.cur_page = -1,
|
.cur_page = -1,
|
||||||
.lines = lines,
|
.lines = lines,
|
||||||
.mgrv = mgrv,
|
.mgrv = mgrv,
|
||||||
.mgrv_data = mgrv_data
|
.mgrv_data = mgrv_data,
|
||||||
|
.top_offset = 0
|
||||||
};
|
};
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
if ( next_pos ) {
|
if ( next_pos ) {
|
||||||
|
@ -986,6 +999,9 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
||||||
entrybox_width, state.line_height,
|
entrybox_width, state.line_height,
|
||||||
NORMAL,
|
NORMAL,
|
||||||
*input );
|
*input );
|
||||||
|
|
||||||
|
state.top_offset = config.padding + state.line_height;
|
||||||
|
|
||||||
// Move indicator to end.
|
// Move indicator to end.
|
||||||
textbox_move ( state.case_indicator,
|
textbox_move ( state.case_indicator,
|
||||||
config.padding + textbox_get_width ( state.prompt_tb ) + entrybox_width,
|
config.padding + textbox_get_width ( state.prompt_tb ) + entrybox_width,
|
||||||
|
@ -998,11 +1014,25 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
||||||
textbox_show ( state.case_indicator );
|
textbox_show ( state.case_indicator );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.message_tb = NULL;
|
||||||
|
if ( message ) {
|
||||||
|
state.top_offset += config.menu_bw;
|
||||||
|
state.message_tb = textbox_create ( main_window, &vinfo, map, TB_AUTOHEIGHT | TB_MARKUP,
|
||||||
|
( config.padding ),
|
||||||
|
state.top_offset,
|
||||||
|
entrybox_width, -1,
|
||||||
|
NORMAL,
|
||||||
|
message );
|
||||||
|
textbox_show ( state.message_tb );
|
||||||
|
state.top_offset += textbox_get_height ( state.message_tb );
|
||||||
|
state.top_offset += config.menu_bw;
|
||||||
|
}
|
||||||
|
|
||||||
int element_height = state.line_height * config.element_height;
|
int element_height = state.line_height * config.element_height;
|
||||||
// filtered list display
|
// filtered list display
|
||||||
state.boxes = g_malloc0_n ( state.max_elements, sizeof ( textbox* ) );
|
state.boxes = g_malloc0_n ( state.max_elements, sizeof ( textbox* ) );
|
||||||
|
|
||||||
int y_offset = config.padding + state.line_height;
|
int y_offset = state.top_offset;
|
||||||
int x_offset = config.padding;
|
int x_offset = config.padding;
|
||||||
|
|
||||||
for ( i = 0; i < state.max_elements; i++ ) {
|
for ( i = 0; i < state.max_elements; i++ ) {
|
||||||
|
@ -1022,7 +1052,7 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
||||||
"↓" );
|
"↓" );
|
||||||
textbox_move ( state.arrowbox_top,
|
textbox_move ( state.arrowbox_top,
|
||||||
state.w - config.padding - state.arrowbox_top->w,
|
state.w - config.padding - state.arrowbox_top->w,
|
||||||
config.padding + state.line_height + LINE_MARGIN );
|
state.top_offset + LINE_MARGIN );
|
||||||
// TODO calculate from top.
|
// TODO calculate from top.
|
||||||
textbox_move ( state.arrowbox_bottom,
|
textbox_move ( state.arrowbox_bottom,
|
||||||
state.w - config.padding - state.arrowbox_bottom->w,
|
state.w - config.padding - state.arrowbox_bottom->w,
|
||||||
|
@ -1036,7 +1066,7 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
||||||
|
|
||||||
// resize window vertically to suit
|
// resize window vertically to suit
|
||||||
// Subtract the margin of the last row.
|
// Subtract the margin of the last row.
|
||||||
state.h = state.line_height + element_height * state.max_rows + ( config.padding ) * 2 + LINE_MARGIN;
|
state.h = state.top_offset + element_height * state.max_rows + ( config.padding ) + LINE_MARGIN;
|
||||||
|
|
||||||
// Add entry
|
// Add entry
|
||||||
if ( config.sidebar_mode == TRUE ) {
|
if ( config.sidebar_mode == TRUE ) {
|
||||||
|
@ -1936,7 +1966,7 @@ SwitcherMode switcher_run ( char **input, Switcher *sw )
|
||||||
&selected_line,
|
&selected_line,
|
||||||
config.levenshtein_sort,
|
config.levenshtein_sort,
|
||||||
sw->mgrv,
|
sw->mgrv,
|
||||||
sw, NULL );
|
sw, NULL, NULL );
|
||||||
|
|
||||||
SwitcherMode retv = sw->result ( mretv, input, selected_line, sw );
|
SwitcherMode retv = sw->result ( mretv, input, selected_line, sw );
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,9 @@ textbox* textbox_create ( Window parent,
|
||||||
|
|
||||||
tb->layout = pango_layout_new ( p_context );
|
tb->layout = pango_layout_new ( p_context );
|
||||||
|
|
||||||
|
tb->markup = FALSE;
|
||||||
|
tb->changed = FALSE;
|
||||||
|
|
||||||
unsigned int cp;
|
unsigned int cp;
|
||||||
switch ( tbft )
|
switch ( tbft )
|
||||||
{
|
{
|
||||||
|
@ -115,7 +118,12 @@ textbox* textbox_create ( Window parent,
|
||||||
pango_font_description_free ( pfd );
|
pango_font_description_free ( pfd );
|
||||||
textbox_font ( tb, tbft );
|
textbox_font ( tb, tbft );
|
||||||
|
|
||||||
textbox_text ( tb, text ? text : "" );
|
if ( ( flags & TB_MARKUP ) == TB_MARKUP ) {
|
||||||
|
textbox_text_markup ( tb, text ? text : "" );
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
textbox_text ( tb, text ? text : "" );
|
||||||
|
}
|
||||||
textbox_cursor_end ( tb );
|
textbox_cursor_end ( tb );
|
||||||
|
|
||||||
// auto height/width modes get handled here
|
// auto height/width modes get handled here
|
||||||
|
@ -180,6 +188,32 @@ void textbox_text ( textbox *tb, const char *text )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tb->cursor = MAX ( 0, MIN ( ( int ) strlen ( text ), tb->cursor ) );
|
||||||
|
}
|
||||||
|
// set the default text to display
|
||||||
|
void textbox_text_markup ( textbox *tb, const char *text )
|
||||||
|
{
|
||||||
|
g_free ( tb->text );
|
||||||
|
const gchar *last_pointer = NULL;
|
||||||
|
if ( g_utf8_validate ( text, -1, &last_pointer ) ) {
|
||||||
|
tb->text = g_strdup ( text );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( last_pointer != NULL ) {
|
||||||
|
// Copy string up to invalid character.
|
||||||
|
tb->text = g_strndup ( text, ( last_pointer - text ) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tb->text = g_strdup ( "Invalid UTF-8 string." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tb->markup = TRUE;
|
||||||
|
pango_layout_set_markup ( tb->layout, tb->text, strlen ( tb->text ) );
|
||||||
|
if ( tb->flags & TB_AUTOWIDTH ) {
|
||||||
|
textbox_moveresize ( tb, tb->x, tb->y, tb->w, tb->h );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
tb->cursor = MAX ( 0, MIN ( ( int ) strlen ( text ), tb->cursor ) );
|
tb->cursor = MAX ( 0, MIN ( ( int ) strlen ( text ), tb->cursor ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +308,14 @@ void textbox_draw ( textbox *tb )
|
||||||
int cursor_x = 0;
|
int cursor_x = 0;
|
||||||
int cursor_width = MAX ( 2, font_height / 10 );
|
int cursor_width = MAX ( 2, font_height / 10 );
|
||||||
|
|
||||||
pango_layout_set_text ( tb->layout, text, text_len );
|
if ( tb->changed ) {
|
||||||
|
if ( tb->markup ) {
|
||||||
|
pango_layout_set_markup ( tb->layout, text, text_len );
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
pango_layout_set_text ( tb->layout, text, text_len );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( tb->flags & TB_EDITABLE ) {
|
if ( tb->flags & TB_EDITABLE ) {
|
||||||
PangoRectangle pos;
|
PangoRectangle pos;
|
||||||
|
@ -443,6 +484,9 @@ void textbox_insert ( textbox *tb, int pos, char *str )
|
||||||
memmove ( at + slen, at, len - pos + 1 );
|
memmove ( at + slen, at, len - pos + 1 );
|
||||||
// insert new str
|
// insert new str
|
||||||
memmove ( at, str, slen );
|
memmove ( at, str, slen );
|
||||||
|
|
||||||
|
// Set modified, lay out need te be redrawn
|
||||||
|
tb->changed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove text
|
// remove text
|
||||||
|
@ -460,6 +504,8 @@ void textbox_delete ( textbox *tb, int pos, int dlen )
|
||||||
else if ( tb->cursor >= ( pos + dlen ) ) {
|
else if ( tb->cursor >= ( pos + dlen ) ) {
|
||||||
tb->cursor -= dlen;
|
tb->cursor -= dlen;
|
||||||
}
|
}
|
||||||
|
// Set modified, lay out need te be redrawn
|
||||||
|
tb->changed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete on character
|
// delete on character
|
||||||
|
|
Loading…
Reference in a new issue