Re: [dev] Binding mouse events in surf

From: Jonathan Slark <jonathan.slark_AT_talktalk.net>
Date: Thu, 03 Dec 2009 03:52:05 +0000

Josh Rickmar wrote:
> Is there any way to currently bind mouse buttons to functions in surf's
> config.h? I'm trying to figure out a way to make the forward/backward
> buttons on my mouse (buttons 8 and 9) call the navigate function. Are
> there any GDK_* values for the mouse which will work?
>
> If something like this isn't currently possible, is there an external
> application to bind these buttons to the back/forward keyboard shortcuts
> when a surf window has focus?

That is kinda weird, I was looking into this myself today!

First I tried to write a small piece of JavaScript to do it but it
didn't seem to support anything more than three buttons. I gave up and
was browsing the archive of this mailing list when I came across Michael
Roth's patch to do this for 0.2, it also supported mouse chords.

I downloaded the patch but it failed against the 0.3 source. I remade
the patch but I it didn't work too well. When I pressed the buttons it
would go back or forward on both the press and the release, ie it would
go back or forward twice instead of just the once. Also GTK was
spitting out a critical error about the rewritten context menu in the patch.

I've removed the rewritten context menu so it just uses the normal surf
code. I've further simplified the patch by removing mouse chording
support, in doing this I also solved the press/release bug.

In short, the patch is very simple and does the job. The patch updates
config.def.h so refer to this for how to bind the mouse buttons.

Jon.

diff -rupN src.orig/surf-0.3/config.def.h src/surf-0.3/config.def.h
--- src.orig/surf-0.3/config.def.h 2009-10-30 12:41:02.000000000 +0000
+++ src/surf-0.3/config.def.h 2009-12-03 03:12:40.533573651 +0000
@@ -35,6 +35,12 @@ static Key keys[] = {
     { MODKEY|GDK_SHIFT_MASK,GDK_n, find, { .b = FALSE } },
 };
 
+static Button buttons[] = {
+ /* modifier button function arg */
+ { 0, 8, navigate, { .i = -1 } },
+ { 0, 9, navigate, { .i = +1 } },
+};
+
 static Item items[] = {
     { "Back", navigate, { .i = -1 } },
     { "Forward", navigate, { .i = +1 } },
diff -rupN src.orig/surf-0.3/surf.c src/surf-0.3/surf.c
--- src.orig/surf-0.3/surf.c 2009-10-30 12:41:02.000000000 +0000
+++ src/surf-0.3/surf.c 2009-12-03 03:07:54.654550576 +0000
@@ -54,6 +54,13 @@ typedef struct {
         const Arg arg;
 } Key;
 
+typedef struct {
+ guint mod;
+ guint button;
+ void (*func)(Client *c, const Arg *arg);
+ const Arg arg;
+} Button;
+
 static Display *dpy;
 static Atom uriprop, findprop;
 static SoupCookieJar *cookies;
@@ -87,6 +94,7 @@ static char *geturi(Client *c);
 static gboolean initdownload(WebKitWebView *v, WebKitDownload *o, Client *c);
 static void itemclick(GtkMenuItem *mi, Client *c);
 static gboolean keypress(GtkWidget *w, GdkEventKey *ev, Client *c);
+static gboolean buttonevent(WebKitWebView *v, GdkEventButton *ev, Client *c);
 static void linkhover(WebKitWebView *v, const char* t, const char* l, Client *c);
 static void loadcommit(WebKitWebView *v, WebKitWebFrame *f, Client *c);
 static void loadstart(WebKitWebView *v, WebKitWebFrame *f, Client *c);
@@ -408,6 +416,25 @@ keypress(GtkWidget* w, GdkEventKey *ev,
         return processed;
 }
 
+gboolean
+buttonevent(WebKitWebView *v, GdkEventButton *ev, Client *c) {
+ guint i;
+ gboolean processed = FALSE;
+
+ updatewinid(c);
+ if(ev->type == GDK_BUTTON_PRESS) {
+ for(i = 0; i < LENGTH(buttons); i++) {
+ if(ev->button == buttons[i].button
+ && CLEANMASK(ev->state) == buttons[i].mod
+ && buttons[i].func) {
+ buttons[i].func(c, &(buttons[i].arg));
+ processed = TRUE;
+ }
+ }
+ }
+return processed;
+}
+
 void
 linkhover(WebKitWebView *v, const char* t, const char* l, Client *c) {
         if(l)
@@ -505,6 +532,7 @@ newclient(void) {
         g_signal_connect(G_OBJECT(c->view), "download-requested", G_CALLBACK(initdownload), c);
         g_signal_connect(G_OBJECT(c->view), "window-object-cleared", G_CALLBACK(windowobjectcleared), c);
         g_signal_connect(G_OBJECT(c->view), "populate-popup", G_CALLBACK(context), c);
+ g_signal_connect(G_OBJECT(c->view), "button-press-event", G_CALLBACK(buttonevent), c);
 
         /* Indicator */
         c->indicator = gtk_drawing_area_new();
Received on Thu Dec 03 2009 - 03:52:05 UTC

This archive was generated by hypermail 2.2.0 : Thu Dec 03 2009 - 04:12:04 UTC