1
0
Fork 0
mirror of https://github.com/davatorium/rofi.git synced 2024-11-18 13:54:36 -05:00

Make error dialog work correctly by creating lokal main loop (aka GtkDialog)

This commit is contained in:
Dave Davenport 2016-01-22 18:18:26 +01:00
parent 9a363b3ecb
commit 384a918d28
2 changed files with 102 additions and 101 deletions

View file

@ -103,11 +103,13 @@ cairo_t *draw = NULL;
XIM xim;
XIC xic;
GThreadPool *tpool = NULL;
GMainLoop *main_loop;
GThreadPool *tpool = NULL;
GMainLoop *main_loop = NULL;
GSource *main_loop_source = NULL;
gboolean quiet = FALSE;
MenuState *current_active_menu = NULL;
static void process_result ( MenuState *state );
static char * get_matching_state ( void )
{
if ( config.case_sensitive ) {
@ -210,8 +212,16 @@ typedef struct MenuState
workarea mon;
// Handlers.
void ( *x11_event_loop )( struct MenuState *state, XEvent *ev );
void ( *finalize )( struct MenuState *state );
}MenuState;
static void menu_state_finalize ( MenuState *state )
{
if ( state && state->finalize ) {
state->finalize ( state );
}
}
void menu_state_queue_redraw ( void )
{
if ( current_active_menu ) {
@ -1482,6 +1492,7 @@ MenuState *menu ( Mode *sw,
state->cur_page = -1;
state->border = config.padding + config.menu_bw;
state->x11_event_loop = menu_mainloop_iter;
state->finalize = process_result;
// Request the lines to show.
state->num_lines = mode_get_num_entries ( sw );
@ -1670,12 +1681,38 @@ MenuState *menu ( Mode *sw,
return state;
}
static void error_dialog_event_loop ( MenuState *state, XEvent *ev )
{
// Wait for event.
if ( sndisplay != NULL ) {
sn_display_process_event ( sndisplay, 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;
}
if ( state->update ) {
menu_update ( state );
}
}
void error_dialog ( const char *msg, int markup )
{
MenuState *state = menu_state_create ();
state->retv = MENU_CANCEL;
state->update = TRUE;
state->border = config.padding + config.menu_bw;
state->retv = MENU_CANCEL;
state->update = TRUE;
state->border = config.padding + config.menu_bw;
state->x11_event_loop = error_dialog_event_loop;
state->finalize = NULL;
// Try to grab the keyboard as early as possible.
// We grab this using the rootwindow (as dmenu does it).
@ -1718,33 +1755,11 @@ void error_dialog ( const char *msg, int markup )
if ( sncontext != NULL ) {
sn_launchee_context_complete ( sncontext );
}
current_active_menu = state;
while ( !state->quit ) {
// Update if requested.
if ( state->update ) {
menu_update ( state );
}
// Wait for event.
XEvent ev;
XNextEvent ( display, &ev );
if ( sndisplay != NULL ) {
sn_display_process_event ( sndisplay, &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;
}
g_main_context_iteration ( NULL, TRUE );
}
release_keyboard ( display );
current_active_menu = NULL;
menu_state_free ( state );
}
@ -1840,9 +1855,8 @@ static void run_switcher ( ModeMode mode )
current_active_menu = state;
g_free ( prompt );
}
static void process_result ()
static void process_result ( MenuState *state )
{
MenuState * state = current_active_menu;
unsigned int selected_line = menu_state_get_selected_line ( state );;
MenuReturn mretv = menu_state_get_return_value ( state );
char *input = g_strdup ( menu_state_get_user_input ( state ) );
@ -1903,6 +1917,7 @@ int show_error_message ( const char *msg, int markup )
}
error_dialog ( msg, markup );
teardown ( pfd );
g_main_loop_quit ( main_loop );
return EXIT_SUCCESS;
}
@ -1961,6 +1976,23 @@ static void help ( G_GNUC_UNUSED int argc, char **argv )
printf ( "Bugreports: "PACKAGE_BUGREPORT "\n" );
}
static void release_global_keybindings ()
{
for ( unsigned int i = 0; i < num_modi; i++ ) {
mode_ungrab_key ( modi[i].sw, display );
}
}
static int grab_global_keybindings ()
{
int key_bound = FALSE;
for ( unsigned int i = 0; i < num_modi; i++ ) {
if ( mode_grab_key ( modi[i].sw, display ) ) {
key_bound = TRUE;
}
}
return key_bound;
}
/**
* Function bound by 'atexit'.
* Cleanup globally allocated memory.
@ -1971,6 +2003,17 @@ static void cleanup ()
g_thread_pool_free ( tpool, TRUE, FALSE );
tpool = NULL;
}
if ( main_loop != NULL ) {
g_source_destroy ( main_loop_source );
g_main_loop_unref ( main_loop );
main_loop = NULL;
}
if ( daemon_mode ) {
release_global_keybindings ();
if ( !quiet ) {
fprintf ( stdout, "Quit from daemon mode.\n" );
}
}
// Cleanup
if ( display != NULL ) {
g_assert ( main_window == None );
@ -2107,22 +2150,6 @@ static inline void load_configuration_dynamic ( Display *display )
config_parse_cmd_options_dynamic ( );
}
static void release_global_keybindings ()
{
for ( unsigned int i = 0; i < num_modi; i++ ) {
mode_ungrab_key ( modi[i].sw, display );
}
}
static int grab_global_keybindings ()
{
int key_bound = FALSE;
for ( unsigned int i = 0; i < num_modi; i++ ) {
if ( mode_grab_key ( modi[i].sw, display ) ) {
key_bound = TRUE;
}
}
return key_bound;
}
static void print_global_keybindings ()
{
fprintf ( stdout, "listening to the following keys:\n" );
@ -2171,7 +2198,7 @@ static gboolean main_loop_x11_event_handler ( G_GNUC_UNUSED gpointer data )
}
if ( menu_state_get_completed ( current_active_menu ) ) {
// This menu is done.
process_result ();
menu_state_finalize ( current_active_menu );
}
return G_SOURCE_CONTINUE;
}
@ -2243,10 +2270,10 @@ static void error_trap_pop ( G_GNUC_UNUSED SnDisplay *display, Display *xdispl
XSync ( xdisplay, False ); /* get all errors out of the queue */
--error_trap_depth;
}
static gboolean delayed_start ( gpointer data )
static gboolean delayed_start ( G_GNUC_UNUSED gpointer data )
{
// Force some X Events to be handled.. seems the only way to get a reliable startup.
menu_state_queue_redraw();
menu_state_queue_redraw ();
main_loop_x11_event_handler ( NULL );
// menu_state_queue_redraw();
return FALSE;
@ -2257,7 +2284,7 @@ int main ( int argc, char *argv[] )
cmd_set_arguments ( argc, argv );
// Quiet flag
int quiet = ( find_arg ( "-quiet" ) >= 0 );
quiet = ( find_arg ( "-quiet" ) >= 0 );
// Version
if ( find_arg ( "-v" ) >= 0 || find_arg ( "-version" ) >= 0 ) {
fprintf ( stdout, "Version: "VERSION "\n" );
@ -2329,6 +2356,10 @@ int main ( int argc, char *argv[] )
return EXIT_FAILURE;
}
TICK_N ( "Open Display" );
main_loop = g_main_loop_new ( NULL, FALSE );
TICK_N ( "Setup mainloop" );
// startup not.
sndisplay = sn_display_new ( display, error_trap_push, error_trap_pop );
@ -2380,6 +2411,8 @@ int main ( int argc, char *argv[] )
config_parse_xresources_theme_dump ();
exit ( EXIT_SUCCESS );
}
main_loop_source = x11_event_source_new ( display );
x11_event_source_set_callback ( main_loop_source, main_loop_x11_event_handler );
// Parse the keybindings.
parse_keys_abe ();
TICK_N ( "Parse ABE" );
@ -2428,35 +2461,25 @@ int main ( int argc, char *argv[] )
return EXIT_SUCCESS;
}
// Setup signal handling sources.
// SIGHup signal.
g_unix_signal_add ( SIGHUP, main_loop_signal_handler_hup, NULL );
// SIGTERM
g_unix_signal_add ( SIGINT, main_loop_signal_handler_int, NULL );
// SIGUSR1
g_unix_signal_add ( SIGUSR1, main_loop_signal_handler_usr1, NULL );
// flags to run immediately and exit
char *sname = NULL;
if ( find_arg_str ( "-show", &sname ) == TRUE ) {
int index = switcher_get ( sname );
if ( index >= 0 ) {
main_loop = g_main_loop_new ( NULL, FALSE );
GSource *source = x11_event_source_new ( display );
x11_event_source_set_callback ( source, main_loop_x11_event_handler );
// Setup signal handling sources.
// SIGHup signal.
g_unix_signal_add ( SIGHUP, main_loop_signal_handler_hup, NULL );
// SIGTERM
g_unix_signal_add ( SIGINT, main_loop_signal_handler_int, NULL );
// SIGUSR1
g_unix_signal_add ( SIGUSR1, main_loop_signal_handler_usr1, NULL );
// TODO delay this till mainloop is running or we might miss X events.
run_switcher ( index );
g_idle_add ( delayed_start, GINT_TO_POINTER ( index ) );
// Start mainloop.
g_main_loop_run ( main_loop );
// Cleanup
g_source_unref ( (GSource *) source );
g_main_loop_unref ( main_loop );
}
else {
fprintf ( stderr, "The %s switcher has not been enabled\n", sname );
return EXIT_FAILURE;
}
}
else{
@ -2469,6 +2492,7 @@ int main ( int argc, char *argv[] )
const char *name = mode_get_name ( modi[i].sw );
fprintf ( stderr, "\t* "color_bold "%s"color_reset ": -key-%s <key>\n", name, name );
}
// Cleanup
return EXIT_FAILURE;
}
if ( !quiet ) {
@ -2482,36 +2506,12 @@ int main ( int argc, char *argv[] )
sn_launchee_context_complete ( sncontext );
}
daemon_mode = TRUE;
// Application Main loop.
// This listens in the background for any events on the Xserver
// catching global key presses.
// It also listens from messages from the signal process.
XSelectInput ( display, DefaultRootWindow ( display ), KeyPressMask );
XFlush ( display );
main_loop = g_main_loop_new ( NULL, FALSE );
GSource *source = x11_event_source_new ( display );
x11_event_source_set_callback ( source, main_loop_x11_event_handler );
// Setup signal handling sources.
// SIGHup signal.
g_unix_signal_add ( SIGHUP, main_loop_signal_handler_hup, NULL );
// SIGTERM
g_unix_signal_add ( SIGINT, main_loop_signal_handler_int, NULL );
// SIGUSR1
g_unix_signal_add ( SIGUSR1, main_loop_signal_handler_usr1, NULL );
// Start mainloop.
g_main_loop_run ( main_loop );
// Cleanup
g_source_unref ( (GSource *) source );
g_main_loop_unref ( main_loop );
release_global_keybindings ();
if ( !quiet ) {
fprintf ( stdout, "Quit from daemon mode.\n" );
}
}
// Start mainloop.
g_main_loop_run ( main_loop );
return EXIT_SUCCESS;
}

View file

@ -61,11 +61,12 @@ RowColor colors[num_states];
PangoContext *p_context = NULL;
static gboolean textbox_blink ( textbox *tb )
{
if ( tb->blink < 2) {
if ( tb->blink < 2 ) {
tb->blink = !tb->blink;
tb->update = TRUE;
menu_state_queue_redraw ( );
} else {
}
else {
tb->blink--;
}
return TRUE;
@ -100,7 +101,7 @@ textbox* textbox_create ( TextboxFlags flags, short x, short y, short w, short h
textbox_moveresize ( tb, tb->widget.x, tb->widget.y, tb->widget.w, tb->widget.h );
tb->blink_timeout = 0;
tb->blink = 1;
tb->blink = 1;
if ( ( flags & TB_EDITABLE ) == TB_EDITABLE ) {
tb->blink_timeout = g_timeout_add ( 1200, textbox_blink, tb );
}