summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk/gtkentry.c122
-rw-r--r--gtk/icons/16x16/status/password-invisible.pngbin0 -> 284 bytes
-rw-r--r--gtk/icons/16x16/status/password-visible.pngbin0 -> 312 bytes
-rw-r--r--tests/testentryicons.c8
4 files changed, 117 insertions, 13 deletions
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index fe37a562c0..ab58b6fb87 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -243,6 +243,8 @@ struct _GtkEntryPrivate
guint cache_includes_preedit : 1;
guint caps_lock_warning : 1;
guint caps_lock_warning_shown : 1;
+ guint password_indicator : 1;
+ guint password_indicator_connected : 1;
guint change_count : 8;
guint cursor_visible : 1;
guint editing_canceled : 1; /* Only used by GtkCellRendererText */
@@ -333,6 +335,7 @@ enum {
PROP_TEXT_LENGTH,
PROP_INVISIBLE_CHAR_SET,
PROP_CAPS_LOCK_WARNING,
+ PROP_PASSWORD_INDICATOR,
PROP_PROGRESS_FRACTION,
PROP_PROGRESS_PULSE_STEP,
PROP_PIXBUF_PRIMARY,
@@ -649,6 +652,7 @@ static void get_frame_size (GtkEntry *entry,
static void gtk_entry_move_adjustments (GtkEntry *entry);
static void gtk_entry_update_cached_style_values(GtkEntry *entry);
static gboolean get_middle_click_paste (GtkEntry *entry);
+static void update_password_indicator (GtkEntry *entry);
/* GtkTextHandle handlers */
static void gtk_entry_handle_drag_started (GtkTextHandle *handle,
@@ -1031,7 +1035,7 @@ gtk_entry_class_init (GtkEntryClass *class)
/**
* GtkEntry:caps-lock-warning:
*
- * Whether password entries will show a warning when Caps Lock is on.
+ * Whether the entry will show a warning when Caps Lock is on in password mode.
*
* Note that the warning is shown using a secondary icon, and thus
* does not work if you are using the secondary icon position for some
@@ -1042,11 +1046,29 @@ gtk_entry_class_init (GtkEntryClass *class)
entry_props[PROP_CAPS_LOCK_WARNING] =
g_param_spec_boolean ("caps-lock-warning",
P_("Caps Lock warning"),
- P_("Whether password entries will show a warning when Caps Lock is on"),
+ P_("Whether the entry shows a warning when Caps Lock is on in password mode"),
TRUE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
/**
+ * GtkEntry:password-indicator:
+ *
+ * Whether the entry shows an icon to toggle password mode on and off.
+ *
+ * Note that the icon is shown using a secondary icon, and thus
+ * does not work if you are using the secondary icon position for some
+ * other purpose.
+ *
+ * Since: 3.20
+ */
+ entry_props[PROP_PASSWORD_INDICATOR] =
+ g_param_spec_boolean ("password-indicator",
+ P_("Password indicator"),
+ P_("Whether the entry shows an icon to toggle password mode"),
+ FALSE,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
+ /**
* GtkEntry:progress-fraction:
*
* The current fraction of the task that's been completed.
@@ -2226,6 +2248,15 @@ gtk_entry_set_property (GObject *object,
}
break;
+ case PROP_PASSWORD_INDICATOR:
+ if (priv->password_indicator != g_value_get_boolean (value))
+ {
+ priv->password_indicator = g_value_get_boolean (value);
+ update_password_indicator (entry);
+ g_object_notify_by_pspec (object, pspec);
+ }
+ break;
+
case PROP_PROGRESS_FRACTION:
gtk_entry_set_progress_fraction (entry, g_value_get_double (value));
break;
@@ -2489,6 +2520,10 @@ gtk_entry_get_property (GObject *object,
g_value_set_boolean (value, priv->caps_lock_warning);
break;
+ case PROP_PASSWORD_INDICATOR:
+ g_value_set_boolean (value, priv->password_indicator);
+ break;
+
case PROP_PROGRESS_FRACTION:
g_value_set_double (value, priv->progress_fraction);
break;
@@ -2711,6 +2746,8 @@ gtk_entry_init (GtkEntry *entry)
priv->xalign = 0.0;
priv->caps_lock_warning = TRUE;
priv->caps_lock_warning_shown = FALSE;
+ priv->password_indicator = FALSE;
+ priv->password_indicator_connected = FALSE;
priv->progress_fraction = 0.0;
priv->progress_pulse_fraction = 0.1;
@@ -3144,7 +3181,7 @@ realize_icon_info (GtkWidget *widget,
GDK_BUTTON3_MOTION_MASK |
GDK_POINTER_MOTION_MASK |
GDK_ENTER_NOTIFY_MASK |
- GDK_LEAVE_NOTIFY_MASK);
+ GDK_LEAVE_NOTIFY_MASK);
attributes_mask = GDK_WA_X | GDK_WA_Y;
icon_info->window = gdk_window_new (gtk_widget_get_window (widget),
@@ -3402,6 +3439,7 @@ gtk_entry_realize (GtkWidget *widget)
gtk_entry_adjust_scroll (entry);
gtk_entry_update_primary_selection (entry);
+ update_password_indicator (entry);
/* If the icon positions are already setup, create their windows.
* Otherwise if they don't exist yet, then construct_icon_info()
@@ -7814,6 +7852,7 @@ gtk_entry_set_visibility (GtkEntry *entry,
{
priv->visible = visible;
+ update_password_indicator (entry);
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_VISIBILITY]);
gtk_entry_recompute (entry);
}
@@ -10971,7 +11010,77 @@ gtk_entry_get_placeholder_text (GtkEntry *entry)
return priv->placeholder_text;
}
-/* Caps Lock warning for password entries */
+/* Caps Lock warning and password indicator */
+
+static void
+password_indicator_show (GtkEntry *entry,
+ GtkEntryIconPosition pos,
+ GdkEvent *event,
+ gpointer data)
+{
+ GtkEntryPrivate *priv = entry->priv;
+
+ if (pos == GTK_ENTRY_ICON_SECONDARY && priv->password_indicator)
+ gtk_entry_set_visibility (entry, TRUE);
+}
+
+static void
+password_indicator_hide (GtkEntry *entry,
+ GtkEntryIconPosition pos,
+ GdkEvent *event,
+ gpointer data)
+{
+ GtkEntryPrivate *priv = entry->priv;
+
+ if (pos == GTK_ENTRY_ICON_SECONDARY && priv->password_indicator)
+ gtk_entry_set_visibility (entry, FALSE);
+}
+
+static void
+update_password_indicator (GtkEntry *entry)
+{
+ GtkEntryPrivate *priv = entry->priv;
+
+ if (priv->caps_lock_warning_shown)
+ return;
+
+ if (priv->password_indicator)
+ {
+ if (!priv->password_indicator_connected)
+ {
+ g_signal_connect (entry, "icon-press", G_CALLBACK (password_indicator_show), NULL);
+ g_signal_connect (entry, "icon-release", G_CALLBACK (password_indicator_hide), NULL);
+ priv->password_indicator_connected = TRUE;
+ }
+
+ gtk_entry_set_icon_activatable (entry, GTK_ENTRY_ICON_SECONDARY, TRUE);
+
+ if (gtk_entry_get_display_mode (entry) != DISPLAY_NORMAL)
+ {
+ gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, "password-invisible");
+ gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY, _("Show text"));
+ }
+ else
+ {
+ gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, "password-visible");
+ gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY, _("Hide text"));
+ }
+
+ }
+ else
+ {
+ if (priv->password_indicator_connected)
+ {
+ g_signal_handlers_disconnect_by_func (entry, password_indicator_show, NULL);
+ g_signal_handlers_disconnect_by_func (entry, password_indicator_hide, NULL);
+ priv->password_indicator_connected = FALSE;
+ }
+
+ gtk_entry_set_icon_activatable (entry, GTK_ENTRY_ICON_SECONDARY, FALSE);
+ gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
+ gtk_entry_set_icon_tooltip_text (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
+ }
+}
static void
show_capslock_feedback (GtkEntry *entry,
@@ -10979,7 +11088,8 @@ show_capslock_feedback (GtkEntry *entry,
{
GtkEntryPrivate *priv = entry->priv;
- if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_SECONDARY) == GTK_IMAGE_EMPTY)
+ if (gtk_entry_get_icon_storage_type (entry, GTK_ENTRY_ICON_SECONDARY) == GTK_IMAGE_EMPTY ||
+ priv->password_indicator)
{
gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, "dialog-warning-symbolic");
gtk_entry_set_icon_activatable (entry, GTK_ENTRY_ICON_SECONDARY, FALSE);
@@ -10999,8 +11109,8 @@ remove_capslock_feedback (GtkEntry *entry)
if (priv->caps_lock_warning_shown)
{
- gtk_entry_set_icon_from_icon_name (entry, GTK_ENTRY_ICON_SECONDARY, NULL);
priv->caps_lock_warning_shown = FALSE;
+ update_password_indicator (entry);
}
}
diff --git a/gtk/icons/16x16/status/password-invisible.png b/gtk/icons/16x16/status/password-invisible.png
new file mode 100644
index 0000000000..54eeba9503
--- /dev/null
+++ b/gtk/icons/16x16/status/password-invisible.png
Binary files differ
diff --git a/gtk/icons/16x16/status/password-visible.png b/gtk/icons/16x16/status/password-visible.png
new file mode 100644
index 0000000000..fee7fbd7aa
--- /dev/null
+++ b/gtk/icons/16x16/status/password-visible.png
Binary files differ
diff --git a/tests/testentryicons.c b/tests/testentryicons.c
index d9921edc9a..cc80b3c294 100644
--- a/tests/testentryicons.c
+++ b/tests/testentryicons.c
@@ -214,13 +214,7 @@ main (int argc, char **argv)
gtk_grid_attach (GTK_GRID (grid), entry, 1, 3, 1, 1);
gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
- gtk_entry_set_icon_from_icon_name (GTK_ENTRY (entry),
- GTK_ENTRY_ICON_PRIMARY,
- "dialog-password-symbolic");
-
- gtk_entry_set_icon_activatable (GTK_ENTRY (entry),
- GTK_ENTRY_ICON_PRIMARY,
- FALSE);
+ g_object_set (entry, "password-indicator", TRUE, NULL);
/* Name - Does not set any icons. */
label = gtk_label_new ("Name:");