--- sylpheed/src/passphrase.c.alt-passphrase-grab 2006-01-27 11:34:26 +0300 +++ sylpheed/src/passphrase.c 2006-05-28 15:38:21 +0400 @@ -63,8 +63,12 @@ static gboolean grab_all = FALSE; static gboolean pass_ack; static gchar *last_pass = NULL; +static gboolean passphrase_grab_input(GtkWidget *window); +static void passphrase_ungrab_input(void); static void passphrase_ok_cb(GtkWidget *widget, gpointer data); static void passphrase_cancel_cb(GtkWidget *widget, gpointer data); +static void passphrase_map_event(GtkWidget *widget, GdkEvent *event, + gpointer data); static gint passphrase_deleted(GtkWidget *widget, GdkEventAny *event, gpointer data); static gboolean passphrase_key_pressed(GtkWidget *widget, GdkEventKey *event, @@ -85,6 +89,7 @@ static gchar* passphrase_mbox(const gchar *uid_hint, const gchar *pass_hint, gint prev_bad) { gchar *the_passphrase = NULL; + gboolean did_grab = FALSE; GtkWidget *vbox; GtkWidget *confirm_box; GtkWidget *window; @@ -98,6 +103,8 @@ passphrase_mbox(const gchar *uid_hint, c gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_modal(GTK_WINDOW(window), TRUE); gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE); + g_signal_connect(G_OBJECT(window), "map_event", + G_CALLBACK(passphrase_map_event), &did_grab); g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(passphrase_deleted), NULL); g_signal_connect(G_OBJECT(window), "key_press_event", @@ -139,46 +146,16 @@ passphrase_mbox(const gchar *uid_hint, c gtk_widget_show_all(window); - if (grab_all) { - /* make sure that window is viewable - * FIXME: this is still not enough */ - gtk_widget_show_now(window); - gdk_flush(); -#ifdef GDK_WINDOWING_X11 - gdk_x11_display_grab(gdk_display_get_default()); -#endif /* GDK_WINDOWING_X11 */ - if (gdk_pointer_grab(window->window, TRUE, 0, - window->window, NULL, GDK_CURRENT_TIME)) { -#ifdef GDK_WINDOWING_X11 - gdk_x11_display_ungrab(gdk_display_get_default()); -#endif /* GDK_WINDOWING_X11 */ - g_warning("OOPS: Could not grab mouse\n"); - gtk_widget_destroy(window); - return NULL; - } - if (gdk_keyboard_grab(window->window, FALSE, GDK_CURRENT_TIME)) { - gdk_display_pointer_ungrab(gdk_display_get_default(), - GDK_CURRENT_TIME); -#ifdef GDK_WINDOWING_X11 - gdk_x11_display_ungrab(gdk_display_get_default()); -#endif /* GDK_WINDOWING_X11 */ - g_warning("OOPS: Could not grab keyboard\n"); - gtk_widget_destroy(window); - return NULL; - } - } + /* + * Grabbing input here does not work, because the X window is not yet + * visible. It will be done in the "map_event" signal handler for the + * window. + */ gtk_main(); - if (grab_all) { - gdk_display_keyboard_ungrab(gdk_display_get_default(), - GDK_CURRENT_TIME); - gdk_display_pointer_ungrab(gdk_display_get_default(), GDK_CURRENT_TIME); -#ifdef GDK_WINDOWING_X11 - gdk_x11_display_ungrab(gdk_display_get_default()); -#endif /* GDK_WINDOWING_X11 */ - gdk_flush(); - } + if (did_grab) + passphrase_ungrab_input(); manage_window_focus_out(window, NULL, NULL); @@ -194,6 +171,44 @@ passphrase_mbox(const gchar *uid_hint, c return the_passphrase; } +static gboolean +passphrase_grab_input(GtkWidget *window) +{ +#ifdef GDK_WINDOWING_X11 + gdk_x11_display_grab(gdk_display_get_default()); +#endif /* GDK_WINDOWING_X11 */ + if (gdk_pointer_grab(window->window, TRUE, 0, + window->window, NULL, GDK_CURRENT_TIME)) { +#ifdef GDK_WINDOWING_X11 + gdk_x11_display_ungrab(gdk_display_get_default()); +#endif /* GDK_WINDOWING_X11 */ + g_warning("OOPS: Could not grab mouse\n"); + return FALSE; + } + if (gdk_keyboard_grab(window->window, FALSE, GDK_CURRENT_TIME)) { + gdk_display_pointer_ungrab(gdk_display_get_default(), + GDK_CURRENT_TIME); +#ifdef GDK_WINDOWING_X11 + gdk_x11_display_ungrab(gdk_display_get_default()); +#endif /* GDK_WINDOWING_X11 */ + g_warning("OOPS: Could not grab keyboard\n"); + return FALSE; + } + return TRUE; +} + +static void +passphrase_ungrab_input(void) +{ + gdk_display_keyboard_ungrab(gdk_display_get_default(), + GDK_CURRENT_TIME); + gdk_display_pointer_ungrab(gdk_display_get_default(), GDK_CURRENT_TIME); +#ifdef GDK_WINDOWING_X11 + gdk_x11_display_ungrab(gdk_display_get_default()); +#endif /* GDK_WINDOWING_X11 */ + gdk_flush(); +} + static void passphrase_ok_cb(GtkWidget *widget, gpointer data) @@ -210,6 +225,19 @@ passphrase_cancel_cb(GtkWidget *widget, } +static void +passphrase_map_event(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + gboolean *did_grab = data; + + if (grab_all) { + if (passphrase_grab_input(widget)) + *did_grab = TRUE; + else + passphrase_cancel_cb(NULL, NULL); + } +} + static gint passphrase_deleted(GtkWidget *widget, GdkEventAny *event, gpointer data) {