[gnome-shell] st-entry: Display a capslock warning in password entries



commit a26a77f9db823a0075ab008cfb96678bd9a7ac16
Author: Florian MÃllner <fmuellner gnome org>
Date:   Mon Oct 17 22:01:58 2011 +0200

    st-entry: Display a capslock warning in password entries
    
    Implement the GtkEntry behavior of showing a warning icon when
    capslock is turned on while entering hidden text.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=660806

 src/st/st-entry.c |   82 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 79 insertions(+), 3 deletions(-)
---
diff --git a/src/st/st-entry.c b/src/st/st-entry.c
index 2d1a2f8..72a32e5 100644
--- a/src/st/st-entry.c
+++ b/src/st/st-entry.c
@@ -59,6 +59,7 @@
 #include "st-entry.h"
 
 #include "st-im-text.h"
+#include "st-icon.h"
 #include "st-widget.h"
 #include "st-texture-cache.h"
 #include "st-marshal.h"
@@ -102,6 +103,7 @@ struct _StEntryPrivate
   gfloat        spacing;
 
   gboolean      hint_visible;
+  gboolean      capslock_warning_shown;
 };
 
 static guint entry_signals[LAST_SIGNAL] = { 0, };
@@ -161,9 +163,52 @@ st_entry_get_property (GObject    *gobject,
 }
 
 static void
+show_capslock_feedback (StEntry *entry)
+{
+  if (entry->priv->secondary_icon == NULL)
+    {
+      ClutterActor *icon = g_object_new (ST_TYPE_ICON,
+                                         "style-class", "capslock-warning",
+                                         "icon-type", ST_ICON_SYMBOLIC,
+                                         "icon-name", "dialog-warning",
+                                         NULL);
+
+      st_entry_set_secondary_icon (entry, icon);
+      entry->priv->capslock_warning_shown = TRUE;
+    }
+}
+
+static void
+remove_capslock_feedback (StEntry *entry)
+{
+  if (entry->priv->capslock_warning_shown)
+    {
+      st_entry_set_secondary_icon (entry, NULL);
+      entry->priv->capslock_warning_shown = FALSE;
+    }
+}
+
+static void
+keymap_state_changed (GdkKeymap *keymap,
+                      gpointer   user_data)
+{
+  StEntry *entry = ST_ENTRY (user_data);
+
+  if (clutter_text_get_password_char (CLUTTER_TEXT (entry->priv->entry)) != 0)
+    {
+      if (gdk_keymap_get_caps_lock_state (keymap))
+        show_capslock_feedback (entry);
+      else
+        remove_capslock_feedback (entry);
+    }
+}
+
+static void
 st_entry_dispose (GObject *object)
 {
-  StEntryPrivate *priv = ST_ENTRY_PRIV (object);
+  StEntry *entry = ST_ENTRY (object);
+  StEntryPrivate *priv = entry->priv;
+  GdkKeymap *keymap;
 
   if (priv->entry)
     {
@@ -171,6 +216,9 @@ st_entry_dispose (GObject *object)
       priv->entry = NULL;
     }
 
+  keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+  g_signal_handlers_disconnect_by_func (keymap, keymap_state_changed, entry);
+
   G_OBJECT_CLASS (st_entry_parent_class)->dispose (object);
 }
 
@@ -407,7 +455,9 @@ static void
 clutter_text_focus_in_cb (ClutterText  *text,
                           ClutterActor *actor)
 {
-  StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
+  StEntry *entry = ST_ENTRY (actor);
+  StEntryPrivate *priv = entry->priv;
+  GdkKeymap *keymap;
 
   /* remove the hint if visible */
   if (priv->hint && priv->hint_visible)
@@ -416,6 +466,12 @@ clutter_text_focus_in_cb (ClutterText  *text,
 
       clutter_text_set_text (text, "");
     }
+
+  keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+  keymap_state_changed (keymap, entry);
+  g_signal_connect (keymap, "state-changed",
+                    G_CALLBACK (keymap_state_changed), entry);
+
   st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "indeterminate");
   st_widget_add_style_pseudo_class (ST_WIDGET (actor), "focus");
   clutter_text_set_cursor_visible (text, TRUE);
@@ -425,7 +481,9 @@ static void
 clutter_text_focus_out_cb (ClutterText  *text,
                            ClutterActor *actor)
 {
-  StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
+  StEntry *entry = ST_ENTRY (actor);
+  StEntryPrivate *priv = entry->priv;
+  GdkKeymap *keymap;
 
   st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "focus");
 
@@ -438,6 +496,21 @@ clutter_text_focus_out_cb (ClutterText  *text,
       st_widget_add_style_pseudo_class (ST_WIDGET (actor), "indeterminate");
     }
   clutter_text_set_cursor_visible (text, FALSE);
+  remove_capslock_feedback (entry);
+
+  keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
+  g_signal_handlers_disconnect_by_func (keymap, keymap_state_changed, entry);
+}
+
+static void
+clutter_text_password_char_cb (GObject    *object,
+                               GParamSpec *pspec,
+                               gpointer    user_data)
+{
+  StEntry *entry = ST_ENTRY (user_data);
+
+  if (clutter_text_get_password_char (CLUTTER_TEXT (entry->priv->entry)) == 0)
+    remove_capslock_feedback (entry);
 }
 
 static void
@@ -700,6 +773,9 @@ st_entry_init (StEntry *entry)
   g_signal_connect (priv->entry, "key-focus-out",
                     G_CALLBACK (clutter_text_focus_out_cb), entry);
 
+  g_signal_connect (priv->entry, "notify::password-char",
+                    G_CALLBACK (clutter_text_password_char_cb), entry);
+
   priv->spacing = 6.0f;
 
   clutter_actor_set_parent (priv->entry, CLUTTER_ACTOR (entry));



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]