mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-18 13:54:36 -05:00
Add display text modi.
This commit is contained in:
parent
e44183b406
commit
0795cfda8d
6 changed files with 145 additions and 10 deletions
|
@ -11,7 +11,7 @@ rofi - A window switcher, run dialog and dmenu replacement
|
|||
[ -terminal *terminal* ] [ -location *position* ] [ -hmode ] [ -fixed-num-lines ] [ -padding *padding* ]
|
||||
[ -opacity *opacity%* ] [ -display *display* ] [ -bc *color* ] [ -bw *width* ] [ -dmenu [ -p *prompt* ] ]
|
||||
[ -ssh-set-title *true|false* ] [ -now ] [ -rnow ] [ -snow ] [ -version ] [ -help] [ -dump-xresources ]
|
||||
[ -disable-history ] [ -levenshtein-sort ] [ -show *mode* ] [ -switcher *mode1,mode2* ]
|
||||
[ -disable-history ] [ -levenshtein-sort ] [ -show *mode* ] [ -switcher *mode1,mode2* ] [ -e *message*]
|
||||
|
||||
## DESCRIPTION
|
||||
|
||||
|
@ -256,6 +256,9 @@ The default key combinations are:
|
|||
|
||||
rofi -switchers "window,run,ssh,Workspaces:i3_switch_workspaces.sh" -show Workspaces
|
||||
|
||||
`-e` *message*
|
||||
|
||||
Popup a message dialog (used internally for showing errors) with *message*.
|
||||
|
||||
|
||||
## Keybindings
|
||||
|
|
|
@ -132,4 +132,6 @@ int token_match ( char **tokens, const char *input,
|
|||
__attribute__( ( unused ) ) int index,
|
||||
__attribute__( ( unused ) ) void *data );
|
||||
|
||||
|
||||
void error_dialog ( char *msg );
|
||||
#endif
|
||||
|
|
111
source/rofi.c
111
source/rofi.c
|
@ -1070,12 +1070,14 @@ static void menu_calculate_window_and_element_width ( MenuState *state, workarea
|
|||
state->w -= config.menu_bw * 2;
|
||||
}
|
||||
|
||||
state->element_width = state->w - ( 2 * ( config.padding ) );
|
||||
// Divide by the # columns
|
||||
state->element_width = ( state->element_width - ( state->columns - 1 ) * LINE_MARGIN ) / state->columns;
|
||||
if ( config.hmode == TRUE ) {
|
||||
state->element_width = ( state->w - ( 2 * ( config.padding ) ) - state->max_elements * LINE_MARGIN ) / (
|
||||
state->max_elements + 1 );
|
||||
if(state->columns > 0 ) {
|
||||
state->element_width = state->w - ( 2 * ( config.padding ) );
|
||||
// Divide by the # columns
|
||||
state->element_width = ( state->element_width - ( state->columns - 1 ) * LINE_MARGIN ) / state->columns;
|
||||
if ( config.hmode == TRUE ) {
|
||||
state->element_width = ( state->w - ( 2 * ( config.padding ) ) - state->max_elements * LINE_MARGIN ) / (
|
||||
state->max_elements + 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1410,6 +1412,7 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
|||
.init = TRUE,
|
||||
.quit = FALSE,
|
||||
.filtered_lines = 0,
|
||||
.max_elements = 0,
|
||||
// We want to filter on the first run.
|
||||
.refilter = TRUE,
|
||||
.update = FALSE
|
||||
|
@ -1661,6 +1664,91 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
|||
return state.retv;
|
||||
}
|
||||
|
||||
void error_dialog ( char *msg )
|
||||
{
|
||||
MenuState state = {
|
||||
.selected_line = NULL,
|
||||
.retv = MENU_CANCEL,
|
||||
.prev_key = 0,
|
||||
.last_button_press = 0,
|
||||
.last_offset = 0,
|
||||
.num_lines = 0,
|
||||
.distance = NULL,
|
||||
.init = FALSE,
|
||||
.quit = FALSE,
|
||||
.filtered_lines = 0,
|
||||
.columns = 0,
|
||||
.update =TRUE,
|
||||
};
|
||||
workarea mon;
|
||||
// Get active monitor size.
|
||||
monitor_active ( &mon );
|
||||
// main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker
|
||||
XWindowAttributes attr;
|
||||
if ( main_window == None || XGetWindowAttributes ( display, main_window, &attr ) == 0 ) {
|
||||
main_window = create_window ( display );
|
||||
}
|
||||
|
||||
|
||||
menu_calculate_window_and_element_width ( &state, &mon );
|
||||
state.max_elements = 0;
|
||||
|
||||
state.text = textbox_create ( main_window, TB_AUTOHEIGHT,
|
||||
( config.padding ),
|
||||
( config.padding ),
|
||||
( state.w - ( 2 * ( config.padding ) ) ),
|
||||
1,
|
||||
NORMAL,
|
||||
( msg != NULL ) ? msg : "" );
|
||||
textbox_show ( state.text );
|
||||
int line_height = textbox_get_height ( state.text );
|
||||
|
||||
// resize window vertically to suit
|
||||
// Subtract the margin of the last row.
|
||||
state.h = line_height * ( state.max_rows + 1 ) + ( config.padding ) * 2 + LINE_MARGIN;
|
||||
if ( config.hmode == TRUE ) {
|
||||
state.h = line_height + ( config.padding ) * 2;
|
||||
}
|
||||
|
||||
// Move the window to the correct x,y position.
|
||||
calculate_window_position ( &state, &mon );
|
||||
XMoveResizeWindow ( display, main_window, state.x, state.y, state.w, state.h );
|
||||
|
||||
// Display it.
|
||||
XMapRaised ( display, main_window );
|
||||
|
||||
if ( take_keyboard ( main_window ) ) {
|
||||
|
||||
while(!state.quit) {
|
||||
// Update if requested.
|
||||
if ( state.update ) {
|
||||
textbox_draw ( state.text );
|
||||
state.update = FALSE;
|
||||
}
|
||||
// Wait for event.
|
||||
XEvent ev;
|
||||
XNextEvent ( display, &ev );
|
||||
|
||||
|
||||
// Handle event.
|
||||
if ( ev.type == Expose ) {
|
||||
while ( XCheckTypedEvent ( display, Expose, &ev ) ) {
|
||||
;
|
||||
}
|
||||
state.update = TRUE;
|
||||
}
|
||||
// Key press event.
|
||||
else if ( ev.type == KeyPress ) {
|
||||
while ( XCheckTypedEvent ( display, KeyPress, &ev ) ) {
|
||||
;
|
||||
}
|
||||
state.quit = TRUE;
|
||||
}
|
||||
}
|
||||
release_keyboard ();
|
||||
}
|
||||
|
||||
}
|
||||
SwitcherMode run_switcher_window ( char **input, G_GNUC_UNUSED void *data )
|
||||
{
|
||||
Screen *screen = DefaultScreenOfDisplay ( display );
|
||||
|
@ -2276,6 +2364,17 @@ int main ( int argc, char *argv[] )
|
|||
display_get_i3_path ( display );
|
||||
#endif
|
||||
|
||||
char *msg = NULL;
|
||||
if ( find_arg_str ( argc, argv, "-e", &(msg) ) ) {
|
||||
textbox_setup (
|
||||
config.menu_bg, config.menu_fg,
|
||||
config.menu_hlbg,
|
||||
config.menu_hlfg );
|
||||
error_dialog(msg);
|
||||
textbox_cleanup ();
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
// flags to run immediately and exit
|
||||
char *sname = NULL;
|
||||
|
|
|
@ -60,9 +60,19 @@ static inline void execsh ( const char *cmd, int run_in_term )
|
|||
args[i++] = g_strdup ( cmd );
|
||||
args[i++] = NULL;
|
||||
|
||||
GError *error = NULL;
|
||||
g_spawn_async ( NULL, args, NULL,
|
||||
G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL, NULL, NULL );
|
||||
NULL, NULL, NULL, &error );
|
||||
if( error != NULL )
|
||||
{
|
||||
char *msg = g_strdup_printf("Failed to execute: '%s'\nError: '%s'", cmd,
|
||||
error->message);
|
||||
error_dialog(msg);
|
||||
g_free(msg);
|
||||
// print error.
|
||||
g_error_free(error);
|
||||
}
|
||||
|
||||
// Free the args list.
|
||||
g_strfreev ( args );
|
||||
|
|
|
@ -48,6 +48,7 @@ pid_t execute_generator ( char * cmd )
|
|||
args[3] = NULL;
|
||||
|
||||
int fd = -1;
|
||||
GError *error = NULL;
|
||||
g_spawn_async_with_pipes ( NULL,
|
||||
args,
|
||||
NULL,
|
||||
|
@ -56,7 +57,17 @@ pid_t execute_generator ( char * cmd )
|
|||
NULL,
|
||||
NULL,
|
||||
NULL, &fd, NULL,
|
||||
NULL );
|
||||
&error );
|
||||
|
||||
if( error != NULL )
|
||||
{
|
||||
char *msg = g_strdup_printf("Failed to execute: '%s'\nError: '%s'", cmd,
|
||||
error->message);
|
||||
error_dialog(msg);
|
||||
g_free(msg);
|
||||
// print error.
|
||||
g_error_free(error);
|
||||
}
|
||||
g_strfreev ( args );
|
||||
return fd;
|
||||
}
|
||||
|
|
|
@ -65,10 +65,20 @@ static inline int execshssh ( const char *host )
|
|||
args[i++] = g_strdup ( host );
|
||||
args[i++] = NULL;
|
||||
|
||||
GError *error = NULL;
|
||||
g_spawn_async ( NULL, args, NULL,
|
||||
G_SPAWN_SEARCH_PATH,
|
||||
NULL, NULL, NULL, NULL );
|
||||
NULL, NULL, NULL, &error );
|
||||
|
||||
if( error != NULL )
|
||||
{
|
||||
char *msg = g_strdup_printf("Failed to execute: 'ssh %s'\nError: '%s'", host,
|
||||
error->message);
|
||||
error_dialog(msg);
|
||||
g_free(msg);
|
||||
// print error.
|
||||
g_error_free(error);
|
||||
}
|
||||
// Free the args list.
|
||||
g_strfreev ( args );
|
||||
|
||||
|
|
Loading…
Reference in a new issue