hi.  since in surf i page forward using Space, i like paging backwards
with BackSpace (as Space and BackSpace seem naturally mutual-inverses).
but, setting that in config.def.h's "static Key keys[]" seems to result
in the loss of a usable backspace (for editing) in textboxes.

this patch introduces "syek", a parallel to "keys", for signal handlers
to receive signals *after* all "normal" signal handlers have been called
(this is a feature of gtk's glib).

(as far as i can tell...) when a textbox is open, it gets a
key-press-event in the "non-after" pass, and so the "after" signal
handler is never called (so, the textbox will delete one character
backwards), whereas if there is no handler handling, e.g., BackSpace in
the non-after pass, the after pass will call the signal handler in syek.

the patch doesn't actually BackSpace to scroll up one page, since i
don't know if everyone would want that behavior.  but, adding this, in
config.h, to the syek structure, should allow that:
----
    { 0,                     GDK_KEY_BackSpace,scrollv,  { .i = -90 } },
----

(this patch only handles GDK_KEY_PRESS events in the after pass, as i'm
not sure which other events might be useful there.)

i hope the patch works well, and if there are problems with the format
or functionality, please let me know.

cheers, Greg
----
From 1c1d63b6f8c02e98c04ed0d6a32548f2568bcf57 Mon Sep 17 00:00:00 2001
From: Greg Minshall <[email protected]>
Date: Wed, 27 Nov 2019 11:25:23 +0530
Subject: [PATCH] allow KeyPress to use g_signal_connect_after()

if BackSpace, e.g., is used to page back, but uses g_signal_connect(),
then in a text entry field, BackSpace doesn't go back a character.
this seems to get around that problem.
---
 config.def.h |  8 ++++++++
 surf.c       | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/config.def.h b/config.def.h
index d9c93f3..6c4c941 100644
--- a/config.def.h
+++ b/config.def.h
@@ -196,6 +196,14 @@ static Key keys[] = {
     { MODKEY               , GDK_KEY_Return, spawn,      SETURI("_SURF_GO") },
 };
 
+/* 
+ * Keys that should only be handled if no other widget (a text entry
+ * one, say) wants them
+ */
+static Key syek[] = {
+       /* modifier              keyval          function    arg */
+};
+
 /* button definitions */
 /* target can be OnDoc, OnLink, OnImg, OnMedia, OnEdit, OnBar, OnSel, OnAny */
 static Button buttons[] = {
diff --git a/surf.c b/surf.c
index a7c37fd..90aa9a7 100644
--- a/surf.c
+++ b/surf.c
@@ -187,6 +187,7 @@ static gboolean buttonreleased(GtkWidget *w, GdkEvent *e, 
Client *c);
 static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event,
                                 gpointer d);
 static gboolean winevent(GtkWidget *w, GdkEvent *e, Client *c);
+static gboolean wineventafter(GtkWidget *w, GdkEvent *e, Client *c);
 static gboolean readpipe(GIOChannel *s, GIOCondition ioc, gpointer unused);
 static void showview(WebKitWebView *v, Client *c);
 static GtkWidget *createwindow(Client *c);
@@ -1401,6 +1402,35 @@ winevent(GtkWidget *w, GdkEvent *e, Client *c)
        return FALSE;
 }
 
+/* doing events *after* allows us to distinguish from events handled
+ * by "lower" widgets */
+gboolean
+wineventafter(GtkWidget *w, GdkEvent *e, Client *c)
+{
+       int i;
+
+       switch (e->type) {
+       case GDK_KEY_PRESS:
+               if (!curconfig[KioskMode].val.i) {
+                       for (i = 0; i < LENGTH(syek); ++i) {
+                               if (gdk_keyval_to_lower(e->key.keyval) ==
+                                   syek[i].keyval &&
+                                   CLEANMASK(e->key.state) == syek[i].mod &&
+                                   syek[i].func) {
+                                       updatewinid(c);
+                                       syek[i].func(c, &(syek[i].arg));
+                                       return TRUE;
+                               }
+                       }
+               }
+       default:
+               break;
+       }
+
+       return FALSE;
+}
+
+
 void
 showview(WebKitWebView *v, Client *c)
 {
@@ -1473,6 +1503,8 @@ createwindow(Client *c)
                         G_CALLBACK(winevent), c);
        g_signal_connect(G_OBJECT(w), "key-press-event",
                         G_CALLBACK(winevent), c);
+       g_signal_connect_after(G_OBJECT(w), "key-press-event",
+                        G_CALLBACK(wineventafter), c);
        g_signal_connect(G_OBJECT(w), "leave-notify-event",
                         G_CALLBACK(winevent), c);
        g_signal_connect(G_OBJECT(w), "window-state-event",
-- 
2.24.0

Reply via email to