aboutsummaryrefslogtreecommitdiff
path: root/sgm-flexible-mnemonics.c
diff options
context:
space:
mode:
Diffstat (limited to 'sgm-flexible-mnemonics.c')
-rw-r--r--sgm-flexible-mnemonics.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/sgm-flexible-mnemonics.c b/sgm-flexible-mnemonics.c
new file mode 100644
index 0000000..8249c95
--- /dev/null
+++ b/sgm-flexible-mnemonics.c
@@ -0,0 +1,121 @@
+/*
+ * SGM -- The STLWRT-ian GTK Modules
+ * Copyright (C) 2021 Gordon N. Squash.
+ *
+ * This module is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This module is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this module; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * This module, "sgm-flexible-mnemonics", adds the code back to GTK to
+ * configure the display of mnemonics -- mnemonics being the underlined
+ * letters in menu items and buttons which, when the corresponding letter
+ * key is pressed, activates the menu item or button in question.
+ * Historically, GTK has allowed the user to alter whether mnemonics are
+ * displayed at all and whether mnemonics are displayed all the time, or
+ * only when the user presses a modifier key, seemingly about to activate
+ * one of the widgets with a mnemonic. Since GTK+ 3.9.8 (development
+ * version of GTK+ 3.10), however, the behavior of mnemonics has been
+ * hard-coded in GTK, and people who don't like the new default GTK
+ * behavior are left frustrated that they, for example, can't see menu
+ * mnemonics all the time. This module adds the configurability back
+ * to GTK.
+ *
+ * This module uses a slightly round-about hack to always display mnemonics.
+ * This module hooks into the "size_allocate" function of each and every
+ * GtkLabel, and ensures the label's toplevel window has the
+ * "mnemonics-visible" property set to TRUE. It would be nice to simply
+ * hook into a GtkWindow's "mnemonics-visible" property and reset the
+ * property to TRUE if it is ever set to FALSE by GTK. However, this
+ * doesn't work so well in practice, since in reality mnemonics are
+ * displayed globally and then hidden on a per-label basis. Hence we need
+ * to ensure that no label has mnemonics turned off, if "gtk-auto-mnemonics"
+ * is set to FALSE.
+ */
+
+
+#include <gtk/gtk.h>
+#include <glib.h>
+
+
+static void (*original_gtk_label_size_allocate) (GtkWidget *widget,
+ GtkAllocation *allocation);
+
+static void sgm_gtk_label_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+
+
+/* Function definitions */
+G_MODULE_EXPORT const char *
+g_module_check_init (GModule *module)
+{
+ /*
+ * Exit immediately on GTK+ versions prior to 3.9.8. This is because
+ * configurable mnemonics support was removed in 3.9.8, and this
+ * module is unnecessary on earlier versions of GTK+.
+ */
+ if (gtk_check_version (3,9,8) != NULL)
+ {
+ return "Your version of GTK+ is old enough that this module is redundant.\n"
+ "This module will therefore not load.";
+ }
+
+ /*
+ * Otherwise, this module is useful for the current version of GTK+, so
+ * proceed with loading it.
+ */
+ else
+ {
+ g_module_make_resident (module);
+ return NULL;
+ }
+}
+
+G_MODULE_EXPORT int
+gtk_module_init (gint * argc, char *** argv)
+{
+ GtkWidgetClass *gtk_label_class;
+
+ (void) argc;
+ (void) argv;
+
+ gtk_label_class = g_type_class_ref (GTK_TYPE_LABEL);
+ original_gtk_label_size_allocate = gtk_label_class->size_allocate;
+ gtk_label_class->size_allocate = sgm_gtk_label_size_allocate;
+ g_type_class_unref (gtk_label_class);
+
+ return 0;
+}
+
+
+static void
+sgm_gtk_label_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkWidget *toplevel_window;
+ GtkSettings *settings;
+ gboolean auto_mnemonics;
+ gboolean mnemonics_visible;
+
+ original_gtk_label_size_allocate (widget, allocation);
+
+ toplevel_window = gtk_widget_get_toplevel (widget);
+ settings = gtk_widget_get_settings (toplevel_window);
+ g_object_get (settings, "gtk-auto-mnemonics", &auto_mnemonics, NULL);
+ g_object_get (toplevel_window, "mnemonics-visible", &mnemonics_visible, NULL);
+
+ if (!mnemonics_visible && !auto_mnemonics)
+ g_object_set (toplevel_window, "mnemonics-visible", TRUE, NULL);
+}
bgstack15