diff options
author | Damien Miller <djm@mindrot.org> | 2020-09-18 06:50:38 +0200 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2020-09-18 06:50:38 +0200 |
commit | 9d3d36bdb10b66abd1af42e8655502487b6ba1fa (patch) | |
tree | 9b933cb3df811b64bdf06863ff37c02e1e1f6ca3 /contrib | |
parent | upstream: Remove unused buf, last user was removed when switching (diff) | |
download | openssh-9d3d36bdb10b66abd1af42e8655502487b6ba1fa.tar.xz openssh-9d3d36bdb10b66abd1af42e8655502487b6ba1fa.zip |
focus improvement for gnome-ssh-askpass[23]
When serving a SSH_ASKPASS_PROMPT=none information dialog, ensure
then <enter> doesn't immediately close the dialog. Instead, require an
explicit <tab> to reach the close button, or <esc>.
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/gnome-ssh-askpass2.c | 42 |
1 files 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 <X11/Xlib.h> #include <gtk/gtk.h> #include <gdk/gdkx.h> +#include <gdk/gdkkeysyms.h> 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 <enter> close dialog */ - g_signal_connect(G_OBJECT(entry), "activate", - G_CALLBACK(ok_dialog), dialog); + if (prompt_type == PROMPT_ENTRY) { + gtk_widget_show(entry); + /* Make <enter> 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 */ |