summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Bolte <sbolte@lavabit.com>2013-04-19 10:50:01 +0200
committerStefan Bolte <sbolte@lavabit.com>2013-04-19 10:50:01 +0200
commitafdd84e02ede328e580a93e76775a8dd793e80f4 (patch)
treea064a88c1e37ac35125720376e301b2b00a90468
parentdad58080902eba922008a124ada13d7669c773d9 (diff)
downloaddwb-afdd84e02ede328e580a93e76775a8dd793e80f4.zip
Basic visual mode
-rw-r--r--src/callback.c5
-rw-r--r--src/config.h7
-rw-r--r--src/dwb.c19
-rw-r--r--src/dwb.h43
-rw-r--r--src/view.c2
-rw-r--r--src/visual.c114
-rw-r--r--src/visual.h26
7 files changed, 192 insertions, 24 deletions
diff --git a/src/callback.c b/src/callback.c
index 40f54b29..05916830 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -23,6 +23,7 @@
#include "entry.h"
#include "scripts.h"
#include "util.h"
+#include "visual.h"
/* dwb_entry_keyrelease_cb {{{*/
@@ -183,7 +184,9 @@ callback_key_press(GtkWidget *w, GdkEventKey *e)
SCRIPTS_EMIT_RETURN(signal, json, true);
}
- if (e->keyval == GDK_KEY_Escape)
+ if (mode == CARET_MODE)
+ return visual_caret(e);
+ else if (e->keyval == GDK_KEY_Escape)
{
if (dwb.state.mode & COMPLETION_MODE)
completion_clean_completion(true);
diff --git a/src/config.h b/src/config.h
index a899a66f..f017ea5f 100644
--- a/src/config.h
+++ b/src/config.h
@@ -60,6 +60,7 @@ static KeyValue KEYS[] = {
{ "win_hist_back", { "wh", 0, 0 }, },
{ "win_hist_forward", { "wl", 0, 0 }, },
{ "insert_mode", { "i", 0, 0 }, },
+ { "visual_mode", { "v", 0, 0 }, },
{ "normal_mode", { "n", GDK_CONTROL_MASK, 0 }, },
{ "open", { "o", 0, 0 }, },
{ "open_url", { "go", 0, 0 }, },
@@ -147,7 +148,7 @@ static KeyValue KEYS[] = {
{ "toggle_plugins_host", { "ph", 0, 0 }, },
{ "toggle_plugins_uri_tmp", { "ptu", 0, 0 }, },
{ "toggle_plugins_host_tmp", { "pth", 0, 0 }, },
- { "new_tab", { "V", 0, 0 }, },
+ { "new_tab", { "T", GDK_CONTROL_MASK, 0 }, },
{ "new_win", { "W", 0, 0 }, },
{ "save", { "sf", 0, 0 }, },
{ "undo", { "u", 0, 0 }, },
@@ -470,6 +471,10 @@ static FunctionMap FMAP [] = {
(Func)commands_change_mode, NULL, POST_SM,
{ .n = INSERT_MODE, .b = false }, EP_NONE, { "i", "insert", NULL }, },
+ { { "visual_mode", "Visual Mode", }, CP_COMMANDLINE | CP_HAS_MODE,
+ (Func)commands_change_mode, NULL, POST_SM,
+ { .n = CARET_MODE, .b = false }, EP_NONE, { "visual" }, },
+
{ { "normal_mode", "Normal Mode", }, CP_OVERRIDE_INSERT | CP_OVERRIDE_ENTRY | CP_OVERRIDE_ALL,
(Func)commands_change_mode, NULL, POST_SM,
{ .n = NORMAL_MODE, .b = true }, EP_NONE, { NULL }, },
diff --git a/src/dwb.c b/src/dwb.c
index 3702aed1..1259672a 100644
--- a/src/dwb.c
+++ b/src/dwb.c
@@ -3149,6 +3149,22 @@ dwb_normal_mode(gboolean clean)
return STATUS_OK;
}/*}}}*/
+static DwbStatus
+dwb_caret_mode()
+{
+ dwb.state.mode = CARET_MODE;
+ dwb_set_normal_message(dwb.state.fview, false, "-- CARET --");
+ WebKitWebSettings *settings = webkit_web_view_get_settings(WEBVIEW(dwb.state.fview));
+ g_object_set(settings, "enable-caret-browsing", TRUE, NULL);
+ GdkEvent *event = gdk_event_new(GDK_BUTTON_PRESS);
+ event->button.button = 1;
+ event->button.x = 1;
+ event->button.y = 1;
+ event->button.window = g_object_ref(gtk_widget_get_window(VIEW(dwb.state.fview)->web));
+ gtk_main_do_event(event);
+ gdk_event_free(event);
+ return STATUS_OK;
+}
/* dwb_change_mode (Mode mode, ...) return DwbStatus {{{*/
DwbStatus
dwb_change_mode(Mode mode, ...)
@@ -3196,7 +3212,8 @@ dwb_change_mode(Mode mode, ...)
break;
case INSERT_MODE: ret = dwb_insert_mode(); break;
case COMMAND_MODE: ret = dwb_command_mode(); break;
- case HINT_MODE: dwb.state.mode = HINT_MODE; break;
+ case HINT_MODE: dwb.state.mode = mode; break;
+ case CARET_MODE: ret = dwb_caret_mode(); break;
default: PRINT_DEBUG("Unknown mode: %d", mode); break;
}
return ret;
diff --git a/src/dwb.h b/src/dwb.h
index ae2a48ca..b43c7dd5 100644
--- a/src/dwb.h
+++ b/src/dwb.h
@@ -339,27 +339,28 @@ typedef enum {
} BarVisibility;
typedef enum {
- NORMAL_MODE = 1<<0,
- INSERT_MODE = 1<<1,
- COMMAND_MODE = 1<<2,
- HINT_MODE = 1<<3,
- QUICK_MARK_SAVE = 1<<4,
- QUICK_MARK_OPEN = 1<<5,
- FIND_MODE = 1<<6,
- COMPLETION_MODE = 1<<7,
- AUTO_COMPLETE = 1<<8,
- SEARCH_FIELD_MODE = 1<<10,
- SETTINGS_MODE = 1<<12,
- KEY_MODE = 1<<13,
- DOWNLOAD_GET_PATH = 1<<14,
- SAVE_SESSION = 1<<15,
- COMPLETE_PATH = 1<<16,
- COMPLETE_BUFFER = 1<<17,
- COMPLETE_QUICKMARKS = 1<<18,
- COMPLETE_COMMAND_MODE = 1<<19,
- CONFIRM = 1<<21,
- SETTINGS_MODE_LOCAL = 1<<22,
- COMPLETE_SCRIPTS = 1<<23,
+ NORMAL_MODE = 0x000001,
+ INSERT_MODE = 0x000002,
+ COMMAND_MODE = 0x000004,
+ HINT_MODE = 0x000008,
+ QUICK_MARK_SAVE = 0x000010,
+ QUICK_MARK_OPEN = 0x000020,
+ COMPLETE_SCRIPTS = 0x000040,
+ COMPLETION_MODE = 0x000080,
+ AUTO_COMPLETE = 0x000100,
+ SEARCH_FIELD_MODE = 0x000200,
+ SETTINGS_MODE = 0x000400,
+ KEY_MODE = 0x000800,
+ DOWNLOAD_GET_PATH = 0x001000,
+ SAVE_SESSION = 0x002000,
+ COMPLETE_PATH = 0x004000,
+ COMPLETE_BUFFER = 0x008000,
+ COMPLETE_QUICKMARKS = 0x010000,
+ COMPLETE_COMMAND_MODE = 0x020000,
+ CONFIRM = 0x040000,
+ SETTINGS_MODE_LOCAL = 0x080000,
+ FIND_MODE = 0x100000,
+ CARET_MODE = 0x200000,
} Mode;
#define BASIC_MODES(mode) ( MAX( ( (mode) & (NORMAL_MODE | INSERT_MODE | COMMAND_MODE | HINT_MODE) ), NORMAL_MODE) )
diff --git a/src/view.c b/src/view.c
index a50de74d..681696ec 100644
--- a/src/view.c
+++ b/src/view.c
@@ -1387,6 +1387,8 @@ static gboolean
view_key_ignore_cb(WebKitWebView *wv, GdkEventKey *e, GList *gl)
{
// passthrough none
+ if (dwb.state.mode == CARET_MODE)
+ return false;
if (dwb.misc.passthrough == PASSTHROUGH_NONE)
return !(dwb.state.mode & INSERT_MODE);
// passthrough all
diff --git a/src/visual.c b/src/visual.c
new file mode 100644
index 00000000..ef9c15a1
--- /dev/null
+++ b/src/visual.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2013 Stefan Bolte <portix@gmx.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "dwb.h"
+#include "js.h"
+
+static void
+dispatch_event(guint keyval[3], guint state[3])
+{
+ GdkEvent *event = gdk_event_new(GDK_KEY_PRESS);
+ event->key.window = g_object_ref(gtk_widget_get_window(VIEW(dwb.state.fview)->web));
+ for (int i=0; i<3 && keyval[i] != 0; i++)
+ {
+ event->key.keyval = keyval[i];
+ event->key.state = state[i];
+ GdkKeymapKey *key;
+ gint n;
+ if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), keyval[i], &key, &n))
+ {
+ event->key.hardware_keycode = key[0].keycode;
+ g_free(key);
+ }
+ gtk_main_do_event(event);
+ }
+ gdk_event_free(event);
+}
+
+gboolean
+visual_caret(GdkEventKey *e)
+{
+ static gint visual = false;
+
+ guint defaultMask = visual ? GDK_SHIFT_MASK : 0;
+
+ guint keyval[3] = { 0, 0, 0 };
+ guint state[3] = { defaultMask, defaultMask, defaultMask };
+
+ switch (e->keyval)
+ {
+ case GDK_KEY_j:
+ keyval[0] = GDK_KEY_Down;
+ break;
+ case GDK_KEY_k:
+ keyval[0] = GDK_KEY_Up;
+ break;
+ case GDK_KEY_h:
+ keyval[0] = GDK_KEY_Left;
+ break;
+ case GDK_KEY_l:
+ keyval[0] = GDK_KEY_Right;
+ break;
+ case GDK_KEY_w:
+ keyval[0] = keyval[1] = GDK_KEY_Right;
+ keyval[2] = GDK_KEY_Left;
+ state[0] = state[1] = state[2] = GDK_CONTROL_MASK | defaultMask;
+ break;
+ case GDK_KEY_b:
+ keyval[0] = GDK_KEY_Left;
+ state[0] = GDK_CONTROL_MASK | defaultMask;
+ break;
+ case GDK_KEY_e:
+ keyval[0] = GDK_KEY_Right;
+ state[0] = GDK_CONTROL_MASK | defaultMask;
+ break;
+ case GDK_KEY_0:
+ keyval[0] = GDK_KEY_Home;
+ break;
+ case GDK_KEY_dollar:
+ keyval[0] = GDK_KEY_End;
+ break;
+ case GDK_KEY_v:
+ visual = true;
+ dwb_set_normal_message(dwb.state.fview, false, "-- VISUAL --");
+ break;
+ case GDK_KEY_y:
+ webkit_web_view_copy_clipboard(CURRENT_WEBVIEW());
+ dwb_set_normal_message(dwb.state.fview, true, "Yanked to clipboard");
+ dwb_change_mode(NORMAL_MODE, false);
+ visual = false;
+ return true;
+ case GDK_KEY_Escape:
+ if (visual)
+ {
+ dwb_set_normal_message(dwb.state.fview, false, "-- CARET --");
+ visual = false;
+ }
+ else
+ {
+ WebKitWebSettings *settings = webkit_web_view_get_settings(CURRENT_WEBVIEW());
+ g_object_set(settings, "enable-caret-browsing", FALSE, NULL);
+ dwb_change_mode(NORMAL_MODE, true);
+ }
+ break;
+ default :return false;
+ }
+ dispatch_event(keyval, state);
+ js_call_as_function(MAIN_FRAME(), CURRENT_VIEW()->js_base, "caretUpdateCursor", NULL, kJSTypeUndefined, NULL);
+ return true;
+}
diff --git a/src/visual.h b/src/visual.h
new file mode 100644
index 00000000..2fa92721
--- /dev/null
+++ b/src/visual.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2013 Stefan Bolte <portix@gmx.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __INCLUDE_VISUAL_H
+#define __INCLUDE_VISUAL_H
+
+#include "dwb.h"
+
+gboolean visual_caret(GdkEventKey *e);
+
+#endif