From 9d3d36bdb10b66abd1af42e8655502487b6ba1fa Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 18 Sep 2020 14:50:38 +1000 Subject: [PATCH] focus improvement for gnome-ssh-askpass[23] When serving a SSH_ASKPASS_PROMPT=none information dialog, ensure then doesn't immediately close the dialog. Instead, require an explicit to reach the close button, or . --- contrib/gnome-ssh-askpass2.c | 42 +++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/contrib/gnome-ssh-askpass2.c b/contrib/gnome-ssh-askpass2.c index bc83a2d67..7656a776b 100644 --- a/contrib/gnome-ssh-askpass2.c +++ b/contrib/gnome-ssh-askpass2.c @@ -59,6 +59,7 @@ #include #include #include +#include static void report_failed_grab (GtkWidget *parent_window, const char *what) @@ -85,6 +86,25 @@ ok_dialog(GtkWidget *entry, gpointer dialog) gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); } +static gboolean +check_none(GtkWidget *widget, GdkEventKey *event, gpointer dialog) +{ + switch (event->keyval) { + case GDK_KEY_Escape: + /* esc -> close dialog */ + gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE); + return TRUE; + case GDK_KEY_Tab: + /* tab -> focus close button */ + gtk_widget_grab_focus(gtk_dialog_get_widget_for_response( + dialog, GTK_RESPONSE_CLOSE)); + return TRUE; + default: + /* eat all other key events */ + return TRUE; + } +} + static int passphrase_dialog(char *message, int prompt_type) { @@ -127,17 +147,29 @@ passphrase_dialog(char *message, int prompt_type) gtk_dialog_set_default_response(GTK_DIALOG(dialog), default_response); gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); - if (prompt_type == PROMPT_ENTRY) { + if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) { entry = gtk_entry_new(); gtk_box_pack_start( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry, FALSE, FALSE, 0); gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); gtk_widget_grab_focus(entry); - gtk_widget_show(entry); - /* Make close dialog */ - g_signal_connect(G_OBJECT(entry), "activate", - G_CALLBACK(ok_dialog), dialog); + if (prompt_type == PROMPT_ENTRY) { + gtk_widget_show(entry); + /* Make close dialog */ + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(ok_dialog), dialog); + } else { + /* + * Ensure the 'close' button is not focused by default + * but is still reachable via tab. This is a bit of a + * hack - it uses a hidden entry that responds to a + * couple of keypress events (escape and tab only). + */ + gtk_widget_realize(entry); + g_signal_connect(G_OBJECT(entry), "key_press_event", + G_CALLBACK(check_none), dialog); + } } /* Grab focus */