user-accounts: Simplify generated password handling
Move the 'generate password' icon into the entry to make the focus chain more straightforward. Also switch from generating a choice of 6 passwords in a menu, just put put the next choice directly into the entry. To keep the password generation keyboard accessible, add a 'Generate password' context menu item. https://bugzilla.gnome.org/show_bug.cgi?id=633601 https://bugzilla.gnome.org/show_bug.cgi?id=658522
This commit is contained in:
parent
359f029419
commit
a7beb087db
2 changed files with 55 additions and 128 deletions
|
@ -206,30 +206,13 @@
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="visibility">False</property>
|
<property name="visibility">False</property>
|
||||||
|
<property name="secondary-icon-name">system-run-symbolic</property>
|
||||||
|
<property name="secondary-icon-tooltip-text" translatable="yes">Generate a password</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="generate-again-button">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">False</property>
|
|
||||||
<property name="tooltip_text" translatable="yes">Choose a generated password</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImage" id="generate-again-image">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="stock">gtk-execute</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">False</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
|
|
|
@ -50,8 +50,6 @@ struct _UmPasswordDialog {
|
||||||
GtkWidget *strength_indicator_label;
|
GtkWidget *strength_indicator_label;
|
||||||
GtkWidget *normal_hint_entry;
|
GtkWidget *normal_hint_entry;
|
||||||
GtkWidget *normal_hint_label;
|
GtkWidget *normal_hint_label;
|
||||||
GtkWidget *generate_button;
|
|
||||||
GtkWidget *generate_menu;
|
|
||||||
GtkWidget *show_password_button;
|
GtkWidget *show_password_button;
|
||||||
GtkWidget *ok_button;
|
GtkWidget *ok_button;
|
||||||
|
|
||||||
|
@ -62,88 +60,35 @@ struct _UmPasswordDialog {
|
||||||
gboolean old_password_ok;
|
gboolean old_password_ok;
|
||||||
|
|
||||||
PasswdHandler *passwd_handler;
|
PasswdHandler *passwd_handler;
|
||||||
|
|
||||||
|
gchar **generated;
|
||||||
|
gint next_generated;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
generate_clicked (GtkButton *button,
|
generate_one_password (GtkWidget *widget,
|
||||||
UmPasswordDialog *um)
|
UmPasswordDialog *um)
|
||||||
{
|
|
||||||
gtk_menu_popup (GTK_MENU (um->generate_menu),
|
|
||||||
NULL, NULL,
|
|
||||||
(GtkMenuPositionFunc) popup_menu_below_button, um->generate_button,
|
|
||||||
0, gtk_get_current_event_time ());
|
|
||||||
|
|
||||||
gtk_widget_set_has_tooltip (um->generate_button, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
generate_draw (GtkWidget *widget,
|
|
||||||
cairo_t *cr,
|
|
||||||
UmPasswordDialog *um)
|
|
||||||
{
|
|
||||||
if (!gtk_widget_is_sensitive (widget))
|
|
||||||
return;
|
|
||||||
|
|
||||||
down_arrow (gtk_widget_get_style_context (widget),
|
|
||||||
cr,
|
|
||||||
gtk_widget_get_allocated_width (widget) - 12,
|
|
||||||
gtk_widget_get_allocated_height (widget) - 12,
|
|
||||||
12, 12);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
activate_password_item (GtkMenuItem *item,
|
|
||||||
UmPasswordDialog *um)
|
|
||||||
{
|
|
||||||
const char *password;
|
|
||||||
|
|
||||||
password = gtk_menu_item_get_label (item);
|
|
||||||
|
|
||||||
gtk_entry_set_text (GTK_ENTRY (um->password_entry), password);
|
|
||||||
gtk_entry_set_text (GTK_ENTRY (um->verify_entry), "");
|
|
||||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (um->show_password_button), TRUE);
|
|
||||||
gtk_widget_grab_focus (um->verify_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void generate_passwords (UmPasswordDialog *um);
|
|
||||||
|
|
||||||
static void
|
|
||||||
activate_generate_item (GtkMenuItem *item,
|
|
||||||
UmPasswordDialog *um)
|
|
||||||
{
|
|
||||||
generate_passwords (um);
|
|
||||||
generate_clicked (GTK_BUTTON (um->generate_button), um);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_generate_menu_unmap (GtkWidget *menu,
|
|
||||||
UmPasswordDialog *um)
|
|
||||||
{
|
|
||||||
gtk_widget_set_has_tooltip (um->generate_button, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
generate_passwords (UmPasswordDialog *um)
|
|
||||||
{
|
{
|
||||||
gint min_len, max_len;
|
gint min_len, max_len;
|
||||||
gchar *output, *err, *cmdline;
|
gchar *output, *err, *cmdline, *p;
|
||||||
gint status;
|
gint status;
|
||||||
GError *error;
|
GError *error;
|
||||||
gint i;
|
|
||||||
GtkWidget *item;
|
if (um->generated && um->generated[um->next_generated]) {
|
||||||
|
gtk_entry_set_text (GTK_ENTRY (um->password_entry), um->generated[um->next_generated]);
|
||||||
|
gtk_entry_set_text (GTK_ENTRY (um->verify_entry), "");
|
||||||
|
um->next_generated++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_strfreev (um->generated);
|
||||||
|
um->generated = NULL;
|
||||||
|
um->next_generated = 0;
|
||||||
|
|
||||||
min_len = 6;
|
min_len = 6;
|
||||||
max_len = 12;
|
max_len = 12;
|
||||||
|
|
||||||
if (um->generate_menu) {
|
cmdline = g_strdup_printf ("apg -n 10 -M SNC -m %d -x %d", min_len, max_len);
|
||||||
gtk_widget_destroy (um->generate_menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
um->generate_menu = gtk_menu_new ();
|
|
||||||
g_signal_connect (um->generate_menu, "unmap",
|
|
||||||
G_CALLBACK (on_generate_menu_unmap), um);
|
|
||||||
|
|
||||||
cmdline = g_strdup_printf ("apg -n 6 -M SNC -m %d -x %d", min_len, max_len);
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
output = NULL;
|
output = NULL;
|
||||||
err = NULL;
|
err = NULL;
|
||||||
|
@ -151,19 +96,16 @@ generate_passwords (UmPasswordDialog *um)
|
||||||
g_warning ("Failed to run apg: %s", error->message);
|
g_warning ("Failed to run apg: %s", error->message);
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
} else if (WEXITSTATUS (status) == 0) {
|
} else if (WEXITSTATUS (status) == 0) {
|
||||||
char **lines;
|
p = output;
|
||||||
lines = g_strsplit (output, "\n", 0);
|
if (*p == '\n')
|
||||||
for (i = 0; lines[i]; i++) {
|
p++;
|
||||||
if (lines[i][0] == 0)
|
if (p[strlen(p) - 1] == '\n')
|
||||||
continue;
|
p[strlen(p) - 1] = '\0';
|
||||||
|
um->generated = g_strsplit (p, "\n", -1);
|
||||||
|
|
||||||
item = gtk_menu_item_new_with_label (lines[i]);
|
gtk_entry_set_text (GTK_ENTRY (um->password_entry), um->generated[0]);
|
||||||
g_signal_connect (item, "activate",
|
gtk_entry_set_text (GTK_ENTRY (um->verify_entry), "");
|
||||||
G_CALLBACK (activate_password_item), um);
|
um->next_generated = 1;
|
||||||
gtk_widget_show (item);
|
|
||||||
gtk_menu_shell_append (GTK_MENU_SHELL (um->generate_menu), item);
|
|
||||||
}
|
|
||||||
g_strfreev (lines);
|
|
||||||
} else {
|
} else {
|
||||||
g_warning ("agp returned an error: %s", err);
|
g_warning ("agp returned an error: %s", err);
|
||||||
}
|
}
|
||||||
|
@ -171,16 +113,29 @@ generate_passwords (UmPasswordDialog *um)
|
||||||
g_free (cmdline);
|
g_free (cmdline);
|
||||||
g_free (output);
|
g_free (output);
|
||||||
g_free (err);
|
g_free (err);
|
||||||
|
}
|
||||||
|
|
||||||
item = gtk_separator_menu_item_new ();
|
static void
|
||||||
gtk_widget_show (item);
|
activate_icon (GtkEntry *entry,
|
||||||
gtk_menu_shell_append (GTK_MENU_SHELL (um->generate_menu), item);
|
GtkEntryIconPosition pos,
|
||||||
|
GdkEventButton *event,
|
||||||
|
UmPasswordDialog *um)
|
||||||
|
{
|
||||||
|
generate_one_password (GTK_WIDGET (entry), um);
|
||||||
|
}
|
||||||
|
|
||||||
item = gtk_menu_item_new_with_label (_("More choices..."));
|
static void
|
||||||
|
populate_menu (GtkEntry *entry,
|
||||||
|
GtkMenu *menu,
|
||||||
|
UmPasswordDialog *um)
|
||||||
|
{
|
||||||
|
GtkWidget *item;
|
||||||
|
|
||||||
|
item = gtk_menu_item_new_with_mnemonic (_("_Generate a password"));
|
||||||
g_signal_connect (item, "activate",
|
g_signal_connect (item, "activate",
|
||||||
G_CALLBACK (activate_generate_item), um);
|
G_CALLBACK (generate_one_password), um);
|
||||||
gtk_widget_show (item);
|
gtk_widget_show (item);
|
||||||
gtk_menu_shell_append (GTK_MENU_SHELL (um->generate_menu), item);
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This code is based on the Master Password dialog in Firefox
|
/* This code is based on the Master Password dialog in Firefox
|
||||||
|
@ -411,8 +366,7 @@ action_changed (GtkComboBox *combo,
|
||||||
active = gtk_combo_box_get_active (combo);
|
active = gtk_combo_box_get_active (combo);
|
||||||
if (active == 0) {
|
if (active == 0) {
|
||||||
gtk_widget_set_sensitive (um->password_entry, TRUE);
|
gtk_widget_set_sensitive (um->password_entry, TRUE);
|
||||||
gtk_widget_set_sensitive (um->generate_button, TRUE);
|
gtk_entry_set_icon_sensitive (GTK_ENTRY (um->password_entry), GTK_ENTRY_ICON_SECONDARY, TRUE);
|
||||||
gtk_widget_set_has_tooltip (um->generate_button, TRUE);
|
|
||||||
gtk_widget_set_sensitive (um->verify_entry, TRUE);
|
gtk_widget_set_sensitive (um->verify_entry, TRUE);
|
||||||
gtk_widget_set_sensitive (um->old_password_entry, TRUE);
|
gtk_widget_set_sensitive (um->old_password_entry, TRUE);
|
||||||
gtk_widget_set_sensitive (um->normal_hint_entry, TRUE);
|
gtk_widget_set_sensitive (um->normal_hint_entry, TRUE);
|
||||||
|
@ -424,8 +378,7 @@ action_changed (GtkComboBox *combo,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gtk_widget_set_sensitive (um->password_entry, FALSE);
|
gtk_widget_set_sensitive (um->password_entry, FALSE);
|
||||||
gtk_widget_set_sensitive (um->generate_button, FALSE);
|
gtk_entry_set_icon_sensitive (GTK_ENTRY (um->password_entry), GTK_ENTRY_ICON_SECONDARY, FALSE);
|
||||||
gtk_widget_set_has_tooltip (um->generate_button, FALSE);
|
|
||||||
gtk_widget_set_sensitive (um->verify_entry, FALSE);
|
gtk_widget_set_sensitive (um->verify_entry, FALSE);
|
||||||
gtk_widget_set_sensitive (um->old_password_entry, FALSE);
|
gtk_widget_set_sensitive (um->old_password_entry, FALSE);
|
||||||
gtk_widget_set_sensitive (um->normal_hint_entry, FALSE);
|
gtk_widget_set_sensitive (um->normal_hint_entry, FALSE);
|
||||||
|
@ -670,6 +623,11 @@ um_password_dialog_new (void)
|
||||||
G_CALLBACK (password_entry_changed), um);
|
G_CALLBACK (password_entry_changed), um);
|
||||||
gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
|
gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
|
||||||
|
|
||||||
|
g_signal_connect (widget, "icon-press",
|
||||||
|
G_CALLBACK (activate_icon), um);
|
||||||
|
g_signal_connect (widget, "populate-popup",
|
||||||
|
G_CALLBACK (populate_menu), um);
|
||||||
|
|
||||||
um->password_entry = widget;
|
um->password_entry = widget;
|
||||||
|
|
||||||
widget = (GtkWidget *) gtk_builder_get_object (builder, "old-password-entry");
|
widget = (GtkWidget *) gtk_builder_get_object (builder, "old-password-entry");
|
||||||
|
@ -700,18 +658,6 @@ um_password_dialog_new (void)
|
||||||
widget = (GtkWidget *) gtk_builder_get_object (builder, "strength-indicator-label");
|
widget = (GtkWidget *) gtk_builder_get_object (builder, "strength-indicator-label");
|
||||||
gtk_label_set_width_chars (GTK_LABEL (widget), len);
|
gtk_label_set_width_chars (GTK_LABEL (widget), len);
|
||||||
|
|
||||||
|
|
||||||
widget = (GtkWidget *) gtk_builder_get_object (builder, "generate-again-button");
|
|
||||||
g_signal_connect (widget, "clicked",
|
|
||||||
G_CALLBACK (generate_clicked), um);
|
|
||||||
#if 0
|
|
||||||
g_signal_connect (widget, "state-changed",
|
|
||||||
G_CALLBACK (generate_state_changed), um);
|
|
||||||
#endif
|
|
||||||
um->generate_button = widget;
|
|
||||||
g_signal_connect_after (widget, "draw",
|
|
||||||
G_CALLBACK (generate_draw), um);
|
|
||||||
|
|
||||||
um->normal_hint_entry = (GtkWidget *) gtk_builder_get_object (builder, "normal-hint-entry");
|
um->normal_hint_entry = (GtkWidget *) gtk_builder_get_object (builder, "normal-hint-entry");
|
||||||
|
|
||||||
/* Label size hack.
|
/* Label size hack.
|
||||||
|
@ -728,8 +674,6 @@ um_password_dialog_new (void)
|
||||||
|
|
||||||
g_object_unref (builder);
|
g_object_unref (builder);
|
||||||
|
|
||||||
generate_passwords (um);
|
|
||||||
|
|
||||||
return um;
|
return um;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue