summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2020-09-18 14:50:38 +1000
committerDamien Miller <djm@mindrot.org>2020-09-18 14:50:38 +1000
commit9d3d36bdb10b66abd1af42e8655502487b6ba1fa (patch)
tree9b933cb3df811b64bdf06863ff37c02e1e1f6ca3
parentd6f507f37e6c75a899db0ef8224e72797c5563b6 (diff)
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>.
-rw-r--r--contrib/gnome-ssh-askpass2.c42
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 @@
59#include <X11/Xlib.h> 59#include <X11/Xlib.h>
60#include <gtk/gtk.h> 60#include <gtk/gtk.h>
61#include <gdk/gdkx.h> 61#include <gdk/gdkx.h>
62#include <gdk/gdkkeysyms.h>
62 63
63static void 64static void
64report_failed_grab (GtkWidget *parent_window, const char *what) 65report_failed_grab (GtkWidget *parent_window, const char *what)
@@ -85,6 +86,25 @@ ok_dialog(GtkWidget *entry, gpointer dialog)
85 gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); 86 gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
86} 87}
87 88
89static gboolean
90check_none(GtkWidget *widget, GdkEventKey *event, gpointer dialog)
91{
92 switch (event->keyval) {
93 case GDK_KEY_Escape:
94 /* esc -> close dialog */
95 gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
96 return TRUE;
97 case GDK_KEY_Tab:
98 /* tab -> focus close button */
99 gtk_widget_grab_focus(gtk_dialog_get_widget_for_response(
100 dialog, GTK_RESPONSE_CLOSE));
101 return TRUE;
102 default:
103 /* eat all other key events */
104 return TRUE;
105 }
106}
107
88static int 108static int
89passphrase_dialog(char *message, int prompt_type) 109passphrase_dialog(char *message, int prompt_type)
90{ 110{
@@ -127,17 +147,29 @@ passphrase_dialog(char *message, int prompt_type)
127 gtk_dialog_set_default_response(GTK_DIALOG(dialog), default_response); 147 gtk_dialog_set_default_response(GTK_DIALOG(dialog), default_response);
128 gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); 148 gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
129 149
130 if (prompt_type == PROMPT_ENTRY) { 150 if (prompt_type == PROMPT_ENTRY || prompt_type == PROMPT_NONE) {
131 entry = gtk_entry_new(); 151 entry = gtk_entry_new();
132 gtk_box_pack_start( 152 gtk_box_pack_start(
133 GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), 153 GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
134 entry, FALSE, FALSE, 0); 154 entry, FALSE, FALSE, 0);
135 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); 155 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
136 gtk_widget_grab_focus(entry); 156 gtk_widget_grab_focus(entry);
137 gtk_widget_show(entry); 157 if (prompt_type == PROMPT_ENTRY) {
138 /* Make <enter> close dialog */ 158 gtk_widget_show(entry);
139 g_signal_connect(G_OBJECT(entry), "activate", 159 /* Make <enter> close dialog */
140 G_CALLBACK(ok_dialog), dialog); 160 g_signal_connect(G_OBJECT(entry), "activate",
161 G_CALLBACK(ok_dialog), dialog);
162 } else {
163 /*
164 * Ensure the 'close' button is not focused by default
165 * but is still reachable via tab. This is a bit of a
166 * hack - it uses a hidden entry that responds to a
167 * couple of keypress events (escape and tab only).
168 */
169 gtk_widget_realize(entry);
170 g_signal_connect(G_OBJECT(entry), "key_press_event",
171 G_CALLBACK(check_none), dialog);
172 }
141 } 173 }
142 174
143 /* Grab focus */ 175 /* Grab focus */