[geany/geany] 100e0e: infobars: Intercept some keys when the info bar is shown to allow interacting with it using the keyboard only.

Thomas Martitz git-noreply at xxxxx
Sat May 24 13:05:33 UTC 2014


Branch:      refs/heads/master
Author:      Thomas Martitz <kugel at rockbox.org>
Committer:   Thomas Martitz <kugel at rockbox.org>
Date:        Sat, 24 May 2014 13:05:33 UTC
Commit:      100e0e1bf17e496dbe728a3637d199157d93b10e
             https://github.com/geany/geany/commit/100e0e1bf17e496dbe728a3637d199157d93b10e

Log Message:
-----------
infobars: Intercept some keys when the info bar is shown to allow interacting with it using the keyboard only.

When the info bar is shown tab/shift+tab and escape are intercepted.
* tab/shift+tab change the focus to the info bar buttons which can then be
  cycled through with more tab presses
* escape closes the info bar (same as clicking cancel)

Both keys aren't needed for the document because it's read-only. Other keys,
such arrow/page up/down, remain to the document for navigating.


Modified Paths:
--------------
    src/document.c

Modified: src/document.c
43 lines changed, 43 insertions(+), 0 deletions(-)
===================================================================
@@ -75,6 +75,8 @@
 /*#define USE_GIO_FILEMON 1*/
 #include <gio/gio.h>
 
+#include <gdk/gdkkeysyms.h>
+
 GeanyFilePrefs file_prefs;
 
 
@@ -3152,6 +3154,45 @@ static void on_monitor_reload_file_response(GtkWidget *bar, gint response_id, Ge
 	doc->priv->info_bars[MSG_TYPE_RELOAD] = NULL;
 }
 
+static gboolean on_sci_key(GtkWidget *w, GdkEventKey *event, gpointer data)
+{
+	GtkInfoBar *bar = GTK_INFO_BAR(data);
+
+	g_return_val_if_fail(event->type == GDK_KEY_PRESS, FALSE);
+
+	switch (event->keyval)
+	{
+		case GDK_KEY_Tab:
+		case GDK_KEY_ISO_Left_Tab:
+		{
+			GtkWidget *w = gtk_info_bar_get_action_area(bar);
+			GtkDirectionType dir = event->keyval == GDK_KEY_Tab ? GTK_DIR_TAB_FORWARD : GTK_DIR_TAB_BACKWARD;
+			gtk_widget_child_focus(w, dir);
+			return TRUE;
+		}
+		case GDK_KEY_Escape:
+		{
+			gtk_info_bar_response(bar, GTK_RESPONSE_CANCEL);
+			return TRUE;
+		}
+		default:
+			return FALSE;
+	}
+}
+
+/* g_signal_handlers_disconnect_by_data is a macro that cannot be used as GCallback */
+static gint nonmacro_g_signal_handlers_disconnect_by_data(gpointer instance, gpointer data)
+{
+	return g_signal_handlers_disconnect_by_data(instance, data);
+}
+
+static void enable_key_intercept(GeanyDocument *doc, GtkWidget *bar)
+{
+	g_signal_connect(doc->editor->sci, "key-press-event",   G_CALLBACK(on_sci_key), bar);
+	/* make the signal disconnect automatically */
+	g_signal_connect_swapped(bar, "unrealize",
+			G_CALLBACK(nonmacro_g_signal_handlers_disconnect_by_data), doc->editor->sci);
+}
 
 static void monitor_reload_file(GeanyDocument *doc)
 {
@@ -3172,6 +3213,7 @@ static void monitor_reload_file(GeanyDocument *doc)
 
 		protect_document(doc);
 		doc->priv->info_bars[MSG_TYPE_RELOAD] = bar;
+		enable_key_intercept(doc, bar);
 	}
 	g_free(base_name);
 }
@@ -3221,6 +3263,7 @@ static void monitor_resave_missing_file(GeanyDocument *doc)
 
 		protect_document(doc);
 		doc->priv->info_bars[MSG_TYPE_RESAVE] = bar;
+		enable_key_intercept(doc, bar);
 	}
 }
 



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list