From 0be14edf9004719890bd4b253c5cc9dd7a2f0e47 Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Sun, 21 May 2017 01:55:03 +0200 Subject: [PATCH] Don't handle hint in new window by javascript. There are a lot of restrictions that introduces some hacks to allow to open hints into new window. The hinting script does now only fire the hints in case of ;o and ;t hinting and the decision where to open the navigation decision is met in the c layer. --- src/hints.c | 7 +++++++ src/main.c | 10 ++++++++-- src/main.h | 1 + src/scripts/hints.js | 24 ++++++------------------ 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/hints.c b/src/hints.c index 763e868..6046706 100644 --- a/src/hints.c +++ b/src/hints.c @@ -277,6 +277,13 @@ static gboolean call_hints_function(Client *c, const char *func, const char* arg if (!hints.gmode && c->mode->id == 'c') { vb_enter(c, 'n'); } + /* If open in new window hinting is use, set a flag on the mode after + * changing to normal mode. This is used in on_webview_decide_policy + * to enforce opening into new instance for the next navigation + * action. */ + if (hints.mode == 't') { + c->mode->flags |= FLAG_NEW_WIN; + } } else if (!strncmp(value, "INSERT:", 7)) { fire_timeout(c, false); vb_enter(c, 'i'); diff --git a/src/main.c b/src/main.c index b0e34f1..e03aaaa 100644 --- a/src/main.c +++ b/src/main.c @@ -1141,8 +1141,14 @@ static gboolean on_webview_decide_policy(WebKitWebView *webview, webkit_policy_decision_ignore(dec); return TRUE; } - if (webkit_navigation_action_get_navigation_type(a) == WEBKIT_NAVIGATION_TYPE_LINK_CLICKED - && (button == 2 || (button == 1 && mod & GDK_CONTROL_MASK))) { + /* Spawn new instance if the new win flag is set on the mode, or + * the navigation was triggered by CTRL-LeftMouse or MiddleMouse. */ + if ((c->mode->flags & FLAG_NEW_WIN) + || (webkit_navigation_action_get_navigation_type(a) == WEBKIT_NAVIGATION_TYPE_LINK_CLICKED + && (button == 2 || (button == 1 && mod & GDK_CONTROL_MASK)))) { + + /* Remove the FLAG_NEW_WIN after the first use. */ + c->mode->flags &= ~FLAG_NEW_WIN; webkit_policy_decision_ignore(dec); spawn_new_instance(webkit_uri_request_get_uri(req), TRUE); diff --git a/src/main.h b/src/main.h index 3b7a31e..d2ac9f1 100644 --- a/src/main.h +++ b/src/main.h @@ -198,6 +198,7 @@ struct Mode { #define FLAG_HINTING 0x0002 /* marks active hinting submode */ #define FLAG_COMPLETION 0x0004 /* marks active completion submode */ #define FLAG_PASSTHROUGH 0x0008 /* don't handle any other keybind than */ +#define FLAG_NEW_WIN 0x0010 /* enforce opening of pages into new window */ unsigned int flags; }; diff --git a/src/scripts/hints.js b/src/scripts/hints.js index f482bd7..724490e 100644 --- a/src/scripts/hints.js +++ b/src/scripts/hints.js @@ -383,25 +383,14 @@ var hints = Object.freeze((function(){ } /* internal used methods */ - function open(e, newWin) { - /* We call open() and click() in async mode to avoid return as fast as possible. */ - /* If we don't return immediately, the EvalJS dbus call will probably timeout and cause */ - /* errors. */ + function open(e) { var href; if ((href = e.getAttribute('href')) && href != '#') { - if (newWin) { - /* Since the "noopener" vulnerability thing, it's not possible to set an anchor's */ - /* target to _blank. Therefore, we can't simulate ctrl-click through _blank like we */ - /* used to. Therefore, we limit ourselves to "window.open()" in cases we're firing a */ - /* simple link. In other cases, we fire the even normally. */ - window.setTimeout(function() { - window.open(href, '_blank'); - }, 0 - ); - } else { - window.location.href = href; - } + window.location.href = href; } else { + /* We call click() in async mode to return as fast as possible. If + * we don't return immediately, the EvalJS dbus call will probably + * timeout and cause errors. */ window.setTimeout(function() {e.click();}, 0); } } @@ -465,8 +454,7 @@ var hints = Object.freeze((function(){ }, /* holds the actions to perform on hint fire */ actionmap = { - o: function(e) {open(e, false); return "DONE:";}, - t: function(e) {open(e, true); return "DONE:";}, + ot: function(e) {open(e); return "DONE:";}, eiIOpPsTxy: function(e) {return "DATA:" + getSrc(e);}, Y: function(e) {return "DATA:" + (e.textContent || "");} }; -- 2.20.1