Index: gdm-2.24.0/gui/simple-greeter/gdm-option-widget.c
===================================================================
--- gdm-2.24.0.orig/gui/simple-greeter/gdm-option-widget.c
+++ gdm-2.24.0/gui/simple-greeter/gdm-option-widget.c
@@ -34,6 +34,7 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
+#include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
 
 #include "gdm-option-widget.h"
@@ -70,6 +71,9 @@ struct GdmOptionWidgetPrivate
         gint                     number_of_bottom_rows;
 
         guint                    check_idle_id;
+
+        GtkWindow               *mnemonic_window;
+        guint                    mnemonic_keyval;
 };
 
 enum {
@@ -302,6 +306,131 @@ gdm_option_widget_set_default_item (GdmO
         }
 }
 
+static guint
+parse_label_mnemonic (const gchar *text)
+{
+        guint    accel_key       = GDK_VoidSymbol;
+        gboolean have_underscore = FALSE;
+
+        if (!text)
+                goto done;
+
+        for ( ; *text; text = g_utf8_next_char (text)) {
+                gunichar c = g_utf8_get_char (text);
+
+                /* Check for invalid UTF-8 */
+                if (c == (gunichar) -1)
+                        break;
+
+                if (have_underscore) {
+                        if (c != '_') {
+                                /* Found the mnemonic */
+                                accel_key = gdk_keyval_to_lower (gdk_unicode_to_keyval (c));
+                                break;
+                        }
+
+                        have_underscore = FALSE;
+                } else if (c == '_') {
+                        have_underscore = TRUE;
+                }
+        }
+
+ done:
+        return accel_key;
+}
+
+static gchar *
+label_mnemonic_to_markup_underline (const gchar *text)
+{
+        gchar    *new_text        = NULL;
+        gchar    *dest;
+        gboolean  have_underscore = FALSE;
+
+        if (!text)
+                goto done;
+
+        /* Theoretically, every 2 input letters could become 8 output letters:
+         *
+         * _L -> <u>L</u>
+         *
+         * We therefore allocate 8/2 = 4 out bytes per in byte, plus the
+         * terminating '\0'. */
+
+        new_text = g_malloc (4 * strlen (text) + 1);
+        dest = new_text;
+
+        for ( ; *text; text = g_utf8_next_char (text)) {
+                gunichar c = g_utf8_get_char (text);
+
+                /* Check for invalid UTF-8 */
+                if (c == (gunichar) -1)
+                        break;
+
+                if (have_underscore) {
+                        if (c == '_') {
+                                dest += g_unichar_to_utf8 (c, dest);
+                        } else {
+                                strcpy (dest, "<u>");
+                                dest += 3;
+                                dest += g_unichar_to_utf8 (c, dest);
+                                strcpy (dest, "</u>");
+                                dest += 4;
+                        }
+
+                        have_underscore = FALSE;
+                } else if (c == '_') {
+                        have_underscore = TRUE;
+                } else {
+                        dest += g_unichar_to_utf8 (c, dest);
+                }
+        }
+
+        *dest = '\0';
+        new_text = g_realloc (new_text, strlen (new_text) + 1);
+
+ done:
+        return new_text;
+}
+
+static void
+update_mnemonic (GtkWidget *widget)
+{
+        GdmOptionWidget        *option_widget;
+        GdmOptionWidgetPrivate *priv;
+        GtkWidget              *toplevel;
+
+        option_widget = GDM_OPTION_WIDGET (widget);
+        priv = option_widget->priv;
+
+        if (priv->mnemonic_keyval != GDK_VoidSymbol) {
+                if (priv->mnemonic_window) {
+                        gtk_window_remove_mnemonic (priv->mnemonic_window,
+                                                    priv->mnemonic_keyval,
+                                                    widget);
+                        priv->mnemonic_window = NULL;
+                }
+	}
+
+        if (priv->mnemonic_keyval == GDK_VoidSymbol)
+                return;
+
+        toplevel = gtk_widget_get_toplevel (widget);
+        if (GTK_WIDGET_TOPLEVEL (toplevel))
+        {
+                gtk_window_add_mnemonic (GTK_WINDOW (toplevel),
+                                         priv->mnemonic_keyval,
+                                         widget);
+                priv->mnemonic_window = GTK_WINDOW (toplevel);
+	}
+}
+
+static void
+gdm_option_widget_hierarchy_changed (GtkWidget *widget,
+                                     GtkWidget *old_toplevel)
+{
+        update_mnemonic (widget);
+}
+
 static const char *
 gdm_option_widget_get_label_text (GdmOptionWidget *widget)
 {
@@ -314,10 +443,17 @@ gdm_option_widget_set_label_text (GdmOpt
 {
         if (widget->priv->label_text == NULL ||
             strcmp (widget->priv->label_text, text) != 0) {
+                gchar *markup_text;
+
                 g_free (widget->priv->label_text);
                 widget->priv->label_text = g_strdup (text);
-                gtk_label_set_markup_with_mnemonic (GTK_LABEL (widget->priv->label),
-                                      text);
+                widget->priv->mnemonic_keyval = parse_label_mnemonic (text);
+                update_mnemonic (GTK_WIDGET (widget));
+
+                markup_text = label_mnemonic_to_markup_underline (text);
+                gtk_label_set_markup (GTK_LABEL (widget->priv->label), markup_text);
+                g_free (markup_text);
+
                 g_object_notify (G_OBJECT (widget), "label-text");
         }
 }
@@ -474,6 +610,7 @@ gdm_option_widget_class_init (GdmOptionW
         object_class->constructor = gdm_option_widget_constructor;
         object_class->dispose = gdm_option_widget_dispose;
         object_class->finalize = gdm_option_widget_finalize;
+        widget_class->hierarchy_changed = gdm_option_widget_hierarchy_changed;
         widget_class->mnemonic_activate = gdm_option_widget_mnemonic_activate;
 
         gtk_rc_parse_string (GDM_OPTION_WIDGET_RC_STRING);
@@ -864,6 +1001,8 @@ gdm_option_widget_init (GdmOptionWidget
 
         widget->priv = GDM_OPTION_WIDGET_GET_PRIVATE (widget);
 
+        widget->priv->mnemonic_keyval = GDK_VoidSymbol;
+
         gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 0, 0, 0);
         gtk_alignment_set (GTK_ALIGNMENT (widget), 0.5, 0.5, 0, 0);
 
@@ -900,8 +1039,6 @@ gdm_option_widget_init (GdmOptionWidget
         gtk_widget_set_no_show_all (widget->priv->items_combo_box, TRUE);
         gtk_container_add (GTK_CONTAINER (box),
                            widget->priv->items_combo_box);
-        gtk_label_set_mnemonic_widget (GTK_LABEL (widget->priv->label),
-                                       GTK_WIDGET (widget));
 
         g_assert (NUMBER_OF_OPTION_COLUMNS == 4);
         widget->priv->list_store = gtk_list_store_new (NUMBER_OF_OPTION_COLUMNS,
