about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorMarco Peereboom <marco@conformal.com>2011-11-08 17:58:25 -0600
committerMarco Peereboom <marco@conformal.com>2011-11-08 17:58:25 -0600
commit859265f95edf9f232c1b7085967578318bd0e380 (patch)
tree41832fb585ad145a4b0ecf305996e429f70b2bb8
parent1a1aed6e998b0074532938c07af9e796bfcbdc5d (diff)
downloadxombrero-859265f95edf9f232c1b7085967578318bd0e380.tar.gz
first attemp at doing a true keyboard mode
-rw-r--r--xxxterm.c197
-rw-r--r--xxxterm.h5
2 files changed, 184 insertions, 18 deletions
diff --git a/xxxterm.c b/xxxterm.c
index 4fdbd5a..278aecb 100644
--- a/xxxterm.c
+++ b/xxxterm.c
@@ -201,9 +201,6 @@ TAILQ_HEAD(command_list, command_entry);
 
 #define XT_HINT_NEWTAB		(1<<0)
 
-#define XT_MODE_INSERT		(0)
-#define XT_MODE_COMMAND		(1)
-
 #define XT_BUFCMD_SZ		(8)
 
 #define XT_EJS_SHOW		(1<<0)
@@ -945,7 +942,7 @@ disable_hints(struct tab *t)
 	DNPRINTF(XT_D_JS, "%s: tab %d\n", __func__, t->tab_id);
 
 	run_script(t, "hints.clearHints();");
-	t->hints_on = 0;
+	t->mode = XT_MODE_COMMAND;
 	t->new_tab = 0;
 }
 
@@ -959,7 +956,7 @@ enable_hints(struct tab *t)
 		run_script(t, "hints.createHints('', 'F');");
 	else
 		run_script(t, "hints.createHints('', 'f');");
-	t->hints_on = 1;
+	t->mode = XT_MODE_HINT;
 }
 
 #define XT_JS_DONE		("done;")
@@ -976,8 +973,8 @@ run_script(struct tab *t, char *s)
 	JSValueRef		val, exception;
 	char			*es;
 
-	DNPRINTF(XT_D_JS, "run_script: tab %d %s\n",
-	    t->tab_id, s == (char *)JS_HINTING ? "JS_HINTING" : s);
+	//DNPRINTF(XT_D_JS, "run_script: tab %d %s\n",
+	//    t->tab_id, s == (char *)JS_HINTING ? "JS_HINTING" : s);
 
 	/* a bit silly but it prevents some heartburn */
 	if (t->script_init == 0) {
@@ -1026,7 +1023,7 @@ hint(struct tab *t, struct karg *args)
 
 	DNPRINTF(XT_D_JS, "hint: tab %d args %d\n", t->tab_id, args->i);
 
-	if (t->hints_on == 0) {
+	if (t->mode == XT_MODE_HINT) {
 		if (args->i == XT_HINT_NEWTAB)
 			t->new_tab = 1;
 		enable_hints(t);
@@ -2501,11 +2498,15 @@ int cmd_prefix = 0;
 int
 command_mode(struct tab *t, struct karg *args)
 {
+	/* this is busted! need to check if the script worked */
 	run_script(t, JS_HINTING);
-	if (args->i == XT_MODE_COMMAND)
+	if (args->i == XT_MODE_COMMAND) {
 		run_script(t, "hints.clearFocus();");
-	else
+		t->mode = XT_MODE_COMMAND;
+	} else {
 		run_script(t, "hints.focusInput();");
+		t->mode = XT_MODE_INSERT;
+	}
 
 	return (XT_CB_HANDLED);
 }
@@ -3121,10 +3122,22 @@ gboolean
 wv_button_cb(GtkWidget *btn, GdkEventButton *e, struct tab *t)
 {
 	struct karg		a;
+	WebKitHitTestResult	*hit_test_result;
+	guint			context;
+
+	hit_test_result = webkit_web_view_get_hit_test_result(t->wv, e);
+	g_object_get(hit_test_result, "context", &context, NULL);
+
+	fprintf(stderr, "%s: %d %d %d\n", __func__, e->button, context, WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE);
 
 	hide_oops(t);
 	hide_buffers(t);
 
+	if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE)
+		t->mode = XT_MODE_INSERT;
+	else
+		t->mode = XT_MODE_COMMAND;
+
 	if (e->type == GDK_BUTTON_PRESS && e->button == 1)
 		btn_down = 1;
 	else if (e->type == GDK_BUTTON_PRESS && e->button == 8 /* btn 4 */) {
@@ -3782,6 +3795,7 @@ notify_load_status_cb(WebKitWebView* wview, GParamSpec* pspec, struct tab *t)
 		}
 
 		show_ca_status(t, uri);
+		run_script(t, JS_HINTING);
 		break;
 
 	case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT:
@@ -4008,18 +4022,26 @@ done:
 		g_free(domain);
 }
 
+gboolean
+webview_console_cb(WebKitWebView *webview, char *message, int line, char *source, gpointer user_data)
+{
+	//fprintf(stderr, "%s: message %s\n", __func__, message);
+	return (FALSE);
+}
+
 void
 webview_load_finished_cb(WebKitWebView *wv, WebKitWebFrame *wf, struct tab *t)
 {
 	/* autorun some js if enabled */
 	js_autorun(t);
 
-	run_script(t, JS_HINTING);
+	fprintf(stderr, "%s: message\n", __func__);
 	if (autofocus_onload &&
 	    t->tab_id == gtk_notebook_get_current_page(notebook))
 		run_script(t, "hints.focusInput();");
 	else
 		run_script(t, "hints.clearFocus();");
+	//run_script(t, JS_INPUT_FOCUS);
 }
 
 void
@@ -4059,7 +4081,7 @@ webview_npd_cb(WebKitWebView *wv, WebKitWebFrame *wf,
 	if (parse_xtp_url(t, uri))
 		    return (TRUE);
 
-	if ((t->hints_on && t->new_tab) || t->ctrl_click) {
+	if ((t->mode == XT_MODE_HINT && t->new_tab) || t->ctrl_click) {
 		t->ctrl_click = 0;
 		create_new_tab(uri, NULL, ctrl_click_focus, -1);
 		webkit_web_policy_decision_ignore(pd);
@@ -4794,11 +4816,16 @@ handle_keypress(struct tab *t, GdkEventKey *e, int entry)
 
 	return (XT_CB_PASSTHROUGH);
 }
-
+#if 0
 int
 wv_keypress_after_cb(GtkWidget *w, GdkEventKey *e, struct tab *t)
 {
 	char			s[2];
+	WebKitDOMDocument	*doc;
+	WebKitDOMElement	*active;
+
+	doc = webkit_web_view_get_dom_document(t->wv);
+	active = webkit_dom_html_document_get_active_element((WebKitDOMHTMLDocument*)doc);
 
 	/* don't use w directly; use t->whatever instead */
 
@@ -4822,12 +4849,71 @@ wv_keypress_after_cb(GtkWidget *w, GdkEventKey *e, struct tab *t)
 
 	return (handle_keypress(t, e, 0));
 }
+#endif
+int
+dom_unwind(struct tab *t, WebKitDOMElement **active)
+{
+	WebKitDOMDocument	*doc;
+	WebKitDOMElement	*a;
+
+	WebKitDOMHTMLFrameElement *frame;
+	WebKitDOMHTMLIFrameElement *iframe;
+
+	/* proof positive that OO is stupid */
+
+	doc = webkit_web_view_get_dom_document(t->wv);
+
+	/* unwind frames and iframes */
+	for (;;) {
+		a = webkit_dom_html_document_get_active_element(
+		    (WebKitDOMHTMLDocument*)doc);
+		frame = (WebKitDOMHTMLFrameElement *)a;
+		if (WEBKIT_DOM_IS_HTML_FRAME_ELEMENT(frame)) {
+			doc = webkit_dom_html_frame_element_get_content_document(
+			    frame);
+			continue;
+		}
+
+		iframe = (WebKitDOMHTMLIFrameElement *)a;
+		if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT(iframe)) {
+			doc = webkit_dom_html_iframe_element_get_content_document(
+			    iframe);
+			continue;
+		}
+
+		break;
+	}
+
+	if (a == NULL)
+		return (0);
+
+	if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT((WebKitDOMNode *)a) ||
+	    WEBKIT_DOM_IS_HTML_TEXT_AREA_ELEMENT((WebKitDOMNode *)a)) {
+		*active = a;
+		return (1);
+	}
+
+	return (0);
+}
 
 int
 wv_keypress_cb(GtkEntry *w, GdkEventKey *e, struct tab *t)
 {
+	char			s[2];
+	WebKitDOMElement	*active = NULL;
+
+	/* don't use w directly; use t->whatever instead */
+
+	if (t == NULL) {
+		show_oops(NULL, "wv_keypress_after_cb");
+		return (XT_CB_PASSTHROUGH);
+	}
+
 	hide_oops(t);
 
+	DNPRINTF(XT_D_KEY, "wv_keypress_after_cb: mode %d keyval 0x%x mask "
+	    "0x%x tab %d\n", t->mode, e->keyval, e->state, t->tab_id);
+
 	/* Hide buffers, if they are visible, with escape. */
 	if (gtk_widget_get_visible(GTK_WIDGET(t->buffers)) &&
 	    CLEAN(e->state) == 0 && e->keyval == GDK_Escape) {
@@ -4836,6 +4922,81 @@ wv_keypress_cb(GtkEntry *w, GdkEventKey *e, struct tab *t)
 		return (XT_CB_HANDLED);
 	}
 
+	if (t->mode == XT_MODE_HINT)
+		return (XT_CB_HANDLED);
+
+	if ((CLEAN(e->state) == 0 && e->keyval == GDK_Tab) ||
+	    (CLEAN(e->state) == SHFT && e->keyval == GDK_Tab)) {
+		fprintf(stderr, "something focussy is about to happen\n");
+		return (XT_CB_PASSTHROUGH);
+	}
+
+	if (dom_unwind(t, &active))
+		t->mode = XT_MODE_INSERT;
+	else
+		t->mode = XT_MODE_COMMAND;
+	fprintf(stderr, "MODE: %d\n", t->mode);
+#if 0
+	WebKitDOMDocument	*doc;
+	WebKitDOMElement	*active;
+	WebKitDOMNode		*a;
+	WebKitDOMHTMLFrameElement *f;
+	WebKitDOMHTMLTextAreaElement *tt;
+
+	doc = webkit_web_view_get_dom_document(t->wv);
+	active = webkit_dom_html_document_get_active_element((WebKitDOMHTMLDocument*)doc);
+	a = (WebKitDOMNode *)active;
+	f = (WebKitDOMHTMLFrameElement *)active;
+
+	fprintf(stderr, "active %p '%s' '%s' input '%d' frame '%d'\n",
+	    active,
+	    webkit_dom_element_get_attribute(active, "node_name"),
+	    webkit_dom_element_get_attribute(active, "name"),
+	    WEBKIT_DOM_IS_HTML_INPUT_ELEMENT(a),
+	    WEBKIT_DOM_IS_HTML_FRAME_ELEMENT(f)
+	    );
+	while (WEBKIT_DOM_IS_HTML_FRAME_ELEMENT(f)) {
+		fprintf(stderr, "=====================\n");
+		doc = webkit_dom_html_frame_element_get_content_document(f);
+		active = webkit_dom_html_document_get_active_element((WebKitDOMHTMLDocument*)doc);
+		a = (WebKitDOMNode *)active;
+		f = (WebKitDOMHTMLFrameElement *)active;
+		tt = (WebKitDOMHTMLTextAreaElement *)active;
+		fprintf(stderr, "active %p '%s' '%s' input '%d' frame '%d' text '%d'\n",
+		    active,
+		    webkit_dom_element_get_attribute(active, "node_name"),
+		    webkit_dom_element_get_attribute(active, "name"),
+		    WEBKIT_DOM_IS_HTML_INPUT_ELEMENT(a),
+		    WEBKIT_DOM_IS_HTML_FRAME_ELEMENT(f),
+		    WEBKIT_DOM_IS_HTML_TEXT_AREA_ELEMENT(tt)
+		    );
+	}
+
+	if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT(a))
+		t->mode = XT_MODE_INSERT;
+	else
+		t->mode = XT_MODE_COMMAND;
+	run_script(t, JS_INPUT_FOCUS);
+#endif
+
+	if (t->mode == XT_MODE_HINT) {
+		/* XXX make sure cmd entry is enabled */
+		return (XT_CB_HANDLED);
+	} else if (t->mode == XT_MODE_COMMAND) {
+		/* prefix input*/
+		snprintf(s, sizeof s, "%c", e->keyval);
+		if (CLEAN(e->state) == 0 && isdigit(s[0]))
+			cmd_prefix = 10 * cmd_prefix + atoi(s);
+		return (handle_keypress(t, e, 0));
+	}
+
+	if (CLEAN(e->state) == 0 && e->keyval == GDK_Escape) {
+		t->mode = XT_MODE_COMMAND;
+		if (active)
+			webkit_dom_element_blur(active);
+		return (XT_CB_HANDLED);
+	}
+
 	return (XT_CB_PASSTHROUGH);
 }
 
@@ -6399,7 +6560,8 @@ create_new_tab(char *title, struct undo *u, int focus, int position)
 
 	g_object_connect(G_OBJECT(t->wv),
 	    "signal::key-press-event", G_CALLBACK(wv_keypress_cb), t,
-	    "signal-after::key-press-event", G_CALLBACK(wv_keypress_after_cb), t,
+	    //"signal::key-press-event", G_CALLBACK(wv_keypress_cb), t,
+	    //"signal-after::key-press-event", G_CALLBACK(wv_keypress_after_cb), t,
 	    "signal::hovering-over-link", G_CALLBACK(webview_hover_cb), t,
 	    "signal::download-requested", G_CALLBACK(webview_download_cb), t,
 	    "signal::mime-type-policy-decision-requested", G_CALLBACK(webview_mimetype_cb), t,
@@ -6414,6 +6576,7 @@ create_new_tab(char *title, struct undo *u, int focus, int position)
 	    "signal::button_press_event", G_CALLBACK(wv_button_cb), t,
 	    "signal::button_release_event", G_CALLBACK(wv_release_button_cb), t,
 	    "signal::populate-popup", G_CALLBACK(wv_popup_cb), t,
+	    //"signal::console-message", G_CALLBACK(webview_console_cb), t,
 	    (char *)NULL);
 	g_signal_connect(t->wv,
 	    "notify::load-status", G_CALLBACK(notify_load_status_cb), t);
@@ -6421,9 +6584,9 @@ create_new_tab(char *title, struct undo *u, int focus, int position)
 	    "notify::title", G_CALLBACK(notify_title_cb), t);
 
 	/* hijack the unused keys as if we were the browser */
-	g_object_connect(G_OBJECT(t->toolbar),
-	    "signal-after::key-press-event", G_CALLBACK(wv_keypress_after_cb), t,
-	    (char *)NULL);
+	//g_object_connect(G_OBJECT(t->toolbar),
+	//    "signal-after::key-press-event", G_CALLBACK(wv_keypress_after_cb), t,
+	//    (char *)NULL);
 
 	g_signal_connect(G_OBJECT(bb), "button_press_event",
 	    G_CALLBACK(tab_close_cb), t);
diff --git a/xxxterm.h b/xxxterm.h
index 8d5f1bd..b9e86e0 100644
--- a/xxxterm.h
+++ b/xxxterm.h
@@ -194,6 +194,10 @@ struct tab {
 	GtkAdjustment		*adjust_v;
 
 	/* flags */
+	int			mode;
+#define XT_MODE_COMMAND		(0)
+#define XT_MODE_INSERT		(1)
+#define XT_MODE_HINT		(2)
 	int			focus_wv;
 	int			ctrl_click;
 	gchar			*status;
@@ -206,7 +210,6 @@ struct tab {
 #endif
 	/* hints */
 	int			script_init;
-	int			hints_on;
 	int			new_tab;
 
 	/* custom stylesheet */