Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:zhy20120210:home:zhy20120210:SLES-11-SP1-x86-64
gdm
gdm-option-mnemonics-sans-labels.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gdm-option-mnemonics-sans-labels.patch of Package gdm
diff --git a/gui/simple-greeter/gdm-option-widget.c b/gui/simple-greeter/gdm-option-widget.c index d49a375..352d288 100644 --- a/gui/simple-greeter/gdm-option-widget.c +++ b/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 (GdmOptionWidget *widget, } } +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 (GdmOptionWidget *widget, { 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 (GdmOptionWidgetClass *klass) 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) 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 *widget) 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,
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor