diff options
author | Stefan Bolte <sbolte@lavabit.com> | 2013-04-19 10:50:01 +0200 |
---|---|---|
committer | Stefan Bolte <sbolte@lavabit.com> | 2013-04-19 10:50:01 +0200 |
commit | afdd84e02ede328e580a93e76775a8dd793e80f4 (patch) | |
tree | a064a88c1e37ac35125720376e301b2b00a90468 | |
parent | dad58080902eba922008a124ada13d7669c773d9 (diff) | |
download | dwb-afdd84e02ede328e580a93e76775a8dd793e80f4.zip |
Basic visual mode
-rw-r--r-- | src/callback.c | 5 | ||||
-rw-r--r-- | src/config.h | 7 | ||||
-rw-r--r-- | src/dwb.c | 19 | ||||
-rw-r--r-- | src/dwb.h | 43 | ||||
-rw-r--r-- | src/view.c | 2 | ||||
-rw-r--r-- | src/visual.c | 114 | ||||
-rw-r--r-- | src/visual.h | 26 |
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 }, }, @@ -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; @@ -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) ) @@ -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 |