Most of this code is certainly not by me, but I couldn't find such patch, and I tought it could be useful to have around.
Surf starts in 'normal' mode, where all your keybindings have effect with and without pressing the modkey, e.g. both 'j' and '^j' scroll down a line. Pressing 'i' in 'normal mode' brings you to 'insert mode', where your keybindings take effect only when modkey is pressed. Without modkey, keypress come through and are being processed by the engine (by the website), so you can write to text elements or control an web application. 'Esc' brings you again to 'normal mode'. --s_
diff -r 51a6d05c2c84 config.def.h --- a/config.def.h Mon Mar 26 09:33:42 2012 +0200 +++ b/config.def.h Thu May 31 19:39:00 2012 +0200 @@ -42,4 +42,5 @@ { MODKEY, GDK_f, spawn, SETPROP("_SURF_FIND", "_SURF_FIND") }, { MODKEY, GDK_n, find, { .b = TRUE } }, { MODKEY|GDK_SHIFT_MASK,GDK_n, find, { .b = FALSE } }, + { 0, GDK_i, insert, { 0 } }, }; diff -r 51a6d05c2c84 surf.c --- a/surf.c Mon Mar 26 09:33:42 2012 +0200 +++ b/surf.c Thu May 31 19:39:00 2012 +0200 @@ -63,7 +63,9 @@ static char winid[64]; static char *progname; static gboolean loadimage = 1, plugin = 1, script = 1; +static gboolean insert_mode = FALSE; +static void insert(Client *c, const Arg *arg); static char *buildpath(const char *path); static void cleanup(void); static void clipboard(Client *c, const Arg *arg); @@ -353,21 +355,49 @@ return FALSE; } +void +insert(Client *c, const Arg *arg) { + insert_mode = TRUE; + update(clients); +} + gboolean keypress(GtkWidget* w, GdkEventKey *ev, Client *c) { guint i; gboolean processed = FALSE; + guint state; updatewinid(c); + + /* turn off insert mode */ + if (insert_mode && (ev->keyval == GDK_Escape)) { + insert_mode = FALSE; + update(c); + return TRUE; + } + + if (insert_mode && ( ((ev->state & MODKEY) != MODKEY) || !MODKEY ) ) { + return FALSE; + } + + if (ev->keyval == GDK_Escape) { + webkit_web_view_set_highlight_text_matches(c->view, FALSE); + return TRUE; + } + for(i = 0; i < LENGTH(keys); i++) { - if(gdk_keyval_to_lower(ev->keyval) == keys[i].keyval - && (ev->state & keys[i].mod) == keys[i].mod - && keys[i].func) { - keys[i].func(c, &(keys[i].arg)); - processed = TRUE; - } + if(!insert_mode && (MODKEY & keys[i].mod) ) + state = ev->state | MODKEY; + else + state = ev->state; + + if(gdk_keyval_to_lower(ev->keyval) == keys[i].keyval && keys[i].func) + if(state == keys[i].mod){ + keys[i].func(c, &(keys[i].arg)); + processed = TRUE; + } } - return processed; + return processed; } void