From ead88eca150b84b8fad610e5181dc0f08225751d Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Wed, 20 Jun 2012 16:51:24 -0400 Subject: Save a pointer to the text entry box that is focused when the page is load for each tab. Try to use this first when using the insert_mode command instead of just focusing on the first text box in the html. Don't switch to command mode if the currently-focused input box contains any text in it. This prevents an annoying switch to command after the page has focused a particular element and the user has already begun typing something. --- inputfocus.c | 108 ++++++++++++++++++++++++++++++++++++++--------------------- xombrero.c | 5 +++ xombrero.h | 4 ++- 3 files changed, 78 insertions(+), 39 deletions(-) diff --git a/inputfocus.c b/inputfocus.c index 4fcda11..ccb371c 100644 --- a/inputfocus.c +++ b/inputfocus.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2011 Marco Peereboom + * Copyright (c) 2012 Josh Rickmar * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -72,19 +73,39 @@ done: return (rv); } + +char * +get_element_text(WebKitDOMNode *n) +{ + if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT(n)) + return (g_strdup(webkit_dom_html_input_element_get_value( + (WebKitDOMHTMLInputElement *)n))); + else if (WEBKIT_DOM_IS_HTML_TEXT_AREA_ELEMENT(n)) + return (g_strdup(webkit_dom_html_text_area_element_get_value( + (WebKitDOMHTMLTextAreaElement *)n))); + return (NULL); +} + int focus_input(struct tab *t) { WebKitDOMDocument *doc; WebKitDOMNode *n; WebKitDOMNodeList *fl = NULL, *ifl = NULL; - int i, fl_count, ifl_count, rv = 0; + WebKitDOMElement *a; + int i, fl_count, ifl_count, rv = 0; /* not found */ WebKitDOMHTMLFrameElement *frame; WebKitDOMHTMLIFrameElement *iframe; /* * Here is what we are doing: + * + * If a textbox is already focused, leave it alone. + * + * Try the tab's previous active entry, for example if it was set by + * some javascript when the page loaded. + * * See if we got frames or iframes * * if we do focus on input or textarea in frame or in iframe @@ -95,6 +116,24 @@ focus_input(struct tab *t) doc = webkit_web_view_get_dom_document(t->wv); + /* try current active element */ + a = webkit_dom_html_document_get_active_element( + (WebKitDOMHTMLDocument*)doc); + if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT((WebKitDOMNode *)a) || + WEBKIT_DOM_IS_HTML_TEXT_AREA_ELEMENT((WebKitDOMNode *)a)) { + rv = 1; /* found */ + goto done; + } + + /* try previous active element */ + if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT((WebKitDOMNode *)t->active) || + WEBKIT_DOM_IS_HTML_TEXT_AREA_ELEMENT((WebKitDOMNode *)t->active)) { + webkit_dom_element_focus((WebKitDOMElement*)t->active); + webkit_dom_html_element_click((WebKitDOMHTMLElement*)t->active); + rv = 1; /* found */ + goto done; + } + /* get frames */ fl = webkit_dom_document_get_elements_by_tag_name(doc, "frame"); fl_count = webkit_dom_node_list_get_length(fl); @@ -110,7 +149,7 @@ focus_input(struct tab *t) doc = webkit_dom_html_frame_element_get_content_document(frame); if (focus_input_document(t, doc)) { - rv = 1; + rv = 1; /* focus */ goto done; } } @@ -122,16 +161,15 @@ focus_input(struct tab *t) doc = webkit_dom_html_iframe_element_get_content_document(iframe); if (focus_input_document(t, doc)) { - rv = 1; + rv = 1; /* found */ goto done; } } /* if we made it here nothing got focused so use normal heuristic */ - if (focus_input_document(t, webkit_web_view_get_dom_document(t->wv))) { - rv = 1; - goto done; - } + if (focus_input_document(t, webkit_web_view_get_dom_document(t->wv))) + rv = 1; /* found */ + done: if (fl) g_object_unref(fl); @@ -142,7 +180,7 @@ done: } int -dom_is_input(struct tab *t, WebKitDOMElement **active) +dom_is_input(struct tab *t, char **text) { WebKitDOMDocument *doc; WebKitDOMElement *a; @@ -195,7 +233,8 @@ dom_is_input(struct tab *t, WebKitDOMElement **active) aa = (WebKitDOMHTMLElement*)a; if (WEBKIT_DOM_IS_HTML_ELEMENT(aa) && webkit_dom_html_element_get_is_content_editable(aa)) { - *active = a; + t->active = a; + *text = get_element_text((WebKitDOMNode *)a); return (1); } break; @@ -206,7 +245,8 @@ dom_is_input(struct tab *t, WebKitDOMElement **active) if (WEBKIT_DOM_IS_HTML_INPUT_ELEMENT((WebKitDOMNode *)a) || WEBKIT_DOM_IS_HTML_TEXT_AREA_ELEMENT((WebKitDOMNode *)a)) { - *active = a; + t->active = a; + *text = get_element_text((WebKitDOMNode *)a); return (1); } @@ -216,31 +256,24 @@ dom_is_input(struct tab *t, WebKitDOMElement **active) void * input_check_mode(struct tab *t) { - WebKitDOMElement *active = NULL; + char *text = NULL; - if (dom_is_input(t, &active)) + if (dom_is_input(t, &text)) { t->mode = XT_MODE_INSERT; - - return (active); -} - -void -input_focus_blur(struct tab *t, void *active) -{ - /* active is (WebKitDOMElement*) */ - if (active) - webkit_dom_element_blur(active); + return (t->active); + } else + return (NULL); } int command_mode(struct tab *t, struct karg *args) { - WebKitDOMElement *active = NULL; + char *text = NULL; if (args->i == XT_MODE_COMMAND) { - if (dom_is_input(t, &active)) - if (active) - webkit_dom_element_blur(active); + if (dom_is_input(t, &text)) + if (t->active) + webkit_dom_element_blur(t->active); t->mode = XT_MODE_COMMAND; } else { if (focus_input(t)) @@ -253,7 +286,7 @@ command_mode(struct tab *t, struct karg *args) void input_autofocus(struct tab *t) { - WebKitDOMElement *active = NULL; + char *text = NULL; if (autofocus_onload && t->tab_id == gtk_notebook_get_current_page(notebook)) { @@ -262,10 +295,16 @@ input_autofocus(struct tab *t) else t->mode = XT_MODE_COMMAND; } else { - if (dom_is_input(t, &active)) - if (active) - webkit_dom_element_blur(active); - t->mode = XT_MODE_COMMAND; + if (dom_is_input(t, &text)) { + if (text != NULL && g_strcmp0(text, "")) { + g_free(text); + t->mode = XT_MODE_INSERT; + } else if (t->active) { + webkit_dom_element_blur(t->active); + t->mode = XT_MODE_COMMAND; + } + } else + t->mode = XT_MODE_COMMAND; } } #else /* WEBKIT_CHECK_VERSION */ @@ -290,13 +329,6 @@ input_autofocus(struct tab *t) } } -void -input_focus_blur(struct tab *t, void *active) -{ - run_script(t, "hints.clearFocus();"); - t->mode = XT_MODE_COMMAND; -} - void * input_check_mode(struct tab *t) { diff --git a/xombrero.c b/xombrero.c index b003bfe..6268399 100644 --- a/xombrero.c +++ b/xombrero.c @@ -4085,6 +4085,9 @@ notify_load_status_cb(WebKitWebView* wview, GParamSpec* pspec, struct tab *t) g_free(text); g_free(base); + /* DOM is changing, unreference the previous focused element */ + t->active = NULL; + /* take focus if we are visible */ focus_webview(t); t->focus_wv = 1; @@ -7326,6 +7329,8 @@ create_new_tab(char *title, struct undo *u, int focus, int position) t->user_agent_id = 0; t->http_accept_id = 0; + t->active = NULL; + #if GTK_CHECK_VERSION(2, 20, 0) t->spinner = gtk_spinner_new(); #endif diff --git a/xombrero.h b/xombrero.h index 4dbc2ad..13baebb 100644 --- a/xombrero.h +++ b/xombrero.h @@ -283,6 +283,9 @@ struct tab { WebKitWebInspector *inspector; GtkWidget *inspector_window; GtkWidget *inspector_view; + + /* focused text entry */ + WebKitDOMElement *active; }; TAILQ_HEAD(tab_list, tab); @@ -555,7 +558,6 @@ int toggle_pl(struct tab *, struct karg *); /* input autofocus */ void input_autofocus(struct tab *); -void input_focus_blur(struct tab *, void *); void *input_check_mode(struct tab *); int command_mode(struct tab *, struct karg *); -- cgit 1.4.1-2-gfad0