diff --git a/include/rofi.h b/include/rofi.h index 316d4cb5..a43a29eb 100644 --- a/include/rofi.h +++ b/include/rofi.h @@ -26,6 +26,12 @@ extern const char *cache_dir; */ void error_dialog ( const char *msg, int markup ); +typedef enum +{ + MENU_NORMAL = 0, + MENU_PASSWORD = 1 +} MenuFlags; + /** * @param sw the Mode to show. * @param lines An array of strings to display. @@ -37,12 +43,17 @@ void error_dialog ( const char *msg, int markup ); * @param mmc_data data to pass to mmc. * @param selected_line pointer to integer holding the selected line. * @param message Extra message to display. + * @param flags Flags indicating state of the menu. * * Main menu callback. * * @returns The command issued (see MenuReturn) */ -MenuReturn menu ( Mode *sw, char **input, char *prompt, unsigned int *selected_line, unsigned int *next_pos, const char *message ) +MenuReturn menu ( Mode *sw, + char **input, char *prompt, + unsigned int *selected_line, + unsigned int *next_pos, + const char *message, MenuFlags flags ) __attribute__ ( ( nonnull ( 1, 2, 3, 4 ) ) ); /** Reset terminal */ diff --git a/include/textbox.h b/include/textbox.h index 7c744b14..fe59b02a 100644 --- a/include/textbox.h +++ b/include/textbox.h @@ -48,6 +48,7 @@ typedef enum TB_EDITABLE = 1 << 19, TB_MARKUP = 1 << 20, TB_WRAP = 1 << 21, + TB_PASSWORD = 1 << 22, } TextboxFlags; typedef enum diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c index 961b74a8..bee4152f 100644 --- a/source/dialogs/dmenu.c +++ b/source/dialogs/dmenu.c @@ -348,6 +348,7 @@ Mode dmenu_mode = int dmenu_switcher_dialog ( void ) { mode_init ( &dmenu_mode ); + MenuFlags menu_flags = MENU_NORMAL; DmenuModePrivateData *pd = (DmenuModePrivateData *) dmenu_mode.private_data; char *input = NULL; int retv = FALSE; @@ -362,6 +363,9 @@ int dmenu_switcher_dialog ( void ) return TRUE; } } + if ( find_arg ( "-password" ) >= 0 ) { + menu_flags |= MENU_PASSWORD; + } /* copy filter string */ input = g_strdup ( config.filter ); @@ -393,7 +397,7 @@ int dmenu_switcher_dialog ( void ) do { retv = FALSE; unsigned int next_pos = pd->selected_line; - int mretv = menu ( &dmenu_mode, &input, pd->prompt, &( pd->selected_line ), &next_pos, pd->message ); + int mretv = menu ( &dmenu_mode, &input, pd->prompt, &( pd->selected_line ), &next_pos, pd->message, menu_flags ); // Special behavior. // TODO clean this up! if ( only_selected ) { @@ -489,4 +493,5 @@ void print_dmenu_options ( void ) print_help_msg ( "-only-match", "", "Force selection or custom entry", NULL, is_term ); print_help_msg ( "-no-custom", "", "Don't accept custom entry", NULL, is_term ); print_help_msg ( "-select", "[string]", "Select the first row that matches", NULL, is_term ); + print_help_msg ( "-password", "", "Do not show what the user inputs. Show '*' instead.", NULL, is_term ); } diff --git a/source/rofi.c b/source/rofi.c index f505b052..a0ef91a2 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -1208,7 +1208,13 @@ static void menu_setup_fake_transparency ( Display *display, MenuState *state ) } } -MenuReturn menu ( Mode *sw, char **input, char *prompt, unsigned int *selected_line, unsigned int *next_pos, const char *message ) +MenuReturn menu ( Mode *sw, + char **input, + char *prompt, + unsigned int *selected_line, + unsigned int *next_pos, + const char *message, + MenuFlags menu_flags ) { TICK (); int shift = FALSE; @@ -1325,9 +1331,11 @@ MenuReturn menu ( Mode *sw, char **input, char *prompt, unsigned int *selected_l state.prompt_tb = textbox_create ( TB_AUTOWIDTH, ( state.border ), ( state.border ), 0, state.line_height, NORMAL, prompt ); // Entry box - int entrybox_width = state.w - ( 2 * ( state.border ) ) - textbox_get_width ( state.prompt_tb ) - - textbox_get_width ( state.case_indicator ); - state.text = textbox_create ( TB_EDITABLE, + int entrybox_width = state.w - ( 2 * ( state.border ) ) - textbox_get_width ( state.prompt_tb ) + - textbox_get_width ( state.case_indicator ); + TextboxFlags tfl = TB_EDITABLE; + tfl |= ( ( menu_flags & MENU_PASSWORD ) == MENU_PASSWORD ) ? TB_PASSWORD : 0; + state.text = textbox_create ( tfl, ( state.border ) + textbox_get_width ( state.prompt_tb ), ( state.border ), entrybox_width, state.line_height, NORMAL, *input ); @@ -2265,7 +2273,7 @@ ModeMode switcher_run ( char **input, Mode *sw ) { char *prompt = g_strdup_printf ( "%s:", mode_get_name ( sw ) ); unsigned int selected_line = UINT32_MAX; - int mretv = menu ( sw, input, prompt, &selected_line, NULL, NULL ); + int mretv = menu ( sw, input, prompt, &selected_line, NULL, NULL, MENU_NORMAL ); g_free ( prompt ); return mode_result ( sw, mretv, input, selected_line ); } diff --git a/source/textbox.c b/source/textbox.c index 84a51133..4226c39e 100644 --- a/source/textbox.c +++ b/source/textbox.c @@ -143,8 +143,15 @@ void textbox_text ( textbox *tb, const char *text ) tb->text = g_strdup ( "Invalid UTF-8 string." ); } } - - if ( tb->flags & TB_MARKUP || tb->tbft & MARKUP ) { + if ( ( tb->flags & TB_PASSWORD ) == TB_PASSWORD ) { + size_t l = strlen ( tb->text ); + char string [l + 1]; + memset ( string, '*', l ); + string[l] = '\0'; + pango_layout_set_attributes ( tb->layout, NULL ); + pango_layout_set_text ( tb->layout, string, l ); + } + else if ( tb->flags & TB_MARKUP || tb->tbft & MARKUP ) { pango_layout_set_markup ( tb->layout, tb->text, strlen ( tb->text ) ); } else { @@ -240,7 +247,15 @@ static void texbox_update ( textbox *tb ) int cursor_width = MAX ( 2, font_height / 10 ); if ( tb->changed ) { - if ( tb->flags & TB_MARKUP ) { + if ( ( tb->flags & TB_PASSWORD ) == TB_PASSWORD ) { + size_t l = strlen ( tb->text ); + char string [l + 1]; + memset ( string, '*', l ); + string[l] = '\0'; + pango_layout_set_attributes ( tb->layout, NULL ); + pango_layout_set_text ( tb->layout, string, l ); + } + else if ( tb->flags & TB_MARKUP ) { pango_layout_set_markup ( tb->layout, text, text_len ); } else{