+gboolean
+permissionrequested(WebKitWebView *v, WebKitPermissionRequest *r, Client *c)
+{
+ if (WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST(r)) {
+ if (curconfig[Geolocation].val.b)
+ webkit_permission_request_allow(r);
+ else
+ webkit_permission_request_deny(r);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean
+decidepolicy(WebKitWebView *v, WebKitPolicyDecision *d,
+ WebKitPolicyDecisionType dt, Client *c)
+{
+ switch (dt) {
+ case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION:
+ decidenavigation(d, c);
+ break;
+ case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION:
+ decidenewwindow(d, c);
+ break;
+ case WEBKIT_POLICY_DECISION_TYPE_RESPONSE:
+ decideresource(d, c);
+ break;
+ default:
+ webkit_policy_decision_ignore(d);
+ break;
+ }
+ return TRUE;
+}
+
+void
+decidenavigation(WebKitPolicyDecision *d, Client *c)
+{
+ WebKitNavigationAction *a =
+ webkit_navigation_policy_decision_get_navigation_action(
+ WEBKIT_NAVIGATION_POLICY_DECISION(d));
+
+ switch (webkit_navigation_action_get_navigation_type(a)) {
+ case WEBKIT_NAVIGATION_TYPE_LINK_CLICKED: /* fallthrough */
+ case WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED: /* fallthrough */
+ case WEBKIT_NAVIGATION_TYPE_BACK_FORWARD: /* fallthrough */
+ case WEBKIT_NAVIGATION_TYPE_RELOAD: /* fallthrough */
+ case WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED: /* fallthrough */
+ case WEBKIT_NAVIGATION_TYPE_OTHER: /* fallthrough */
+ default:
+ /* Do not navigate to links with a "_blank" target (popup) */
+ if (webkit_navigation_policy_decision_get_frame_name(
+ WEBKIT_NAVIGATION_POLICY_DECISION(d))) {
+ webkit_policy_decision_ignore(d);
+ } else {
+ /* Filter out navigation to different domain ? */
+ /* get action→urirequest, copy and load in new window+view
+ * on Ctrl+Click ? */
+ webkit_policy_decision_use(d);
+ }
+ break;
+ }
+}
+
+void
+decidenewwindow(WebKitPolicyDecision *d, Client *c)
+{
+ Arg arg;
+ WebKitNavigationAction *a =
+ webkit_navigation_policy_decision_get_navigation_action(
+ WEBKIT_NAVIGATION_POLICY_DECISION(d));
+
+
+ switch (webkit_navigation_action_get_navigation_type(a)) {
+ case WEBKIT_NAVIGATION_TYPE_LINK_CLICKED: /* fallthrough */
+ case WEBKIT_NAVIGATION_TYPE_FORM_SUBMITTED: /* fallthrough */
+ case WEBKIT_NAVIGATION_TYPE_BACK_FORWARD: /* fallthrough */
+ case WEBKIT_NAVIGATION_TYPE_RELOAD: /* fallthrough */
+ case WEBKIT_NAVIGATION_TYPE_FORM_RESUBMITTED:
+ /* Filter domains here */
+/* If the value of “mouse-button” is not 0, then the navigation was triggered by a mouse event.
+ * test for link clicked but no button ? */
+ arg.v = webkit_uri_request_get_uri(
+ webkit_navigation_action_get_request(a));
+ newwindow(c, &arg, 0);
+ break;
+ case WEBKIT_NAVIGATION_TYPE_OTHER: /* fallthrough */
+ default:
+ break;
+ }
+
+ webkit_policy_decision_ignore(d);
+}
+
+void
+decideresource(WebKitPolicyDecision *d, Client *c)
+{
+ int i, isascii = 1;
+ WebKitResponsePolicyDecision *r = WEBKIT_RESPONSE_POLICY_DECISION(d);
+ WebKitURIResponse *res =
+ webkit_response_policy_decision_get_response(r);
+ const gchar *uri = webkit_uri_response_get_uri(res);
+
+ if (g_str_has_suffix(uri, "/favicon.ico")) {
+ webkit_policy_decision_ignore(d);
+ return;
+ }
+
+ if (!g_str_has_prefix(uri, "http://")
+ && !g_str_has_prefix(uri, "https://")
+ && !g_str_has_prefix(uri, "about:")
+ && !g_str_has_prefix(uri, "file://")
+ && !g_str_has_prefix(uri, "data:")
+ && !g_str_has_prefix(uri, "blob:")
+ && strlen(uri) > 0) {
+ for (i = 0; i < strlen(uri); i++) {
+ if (!g_ascii_isprint(uri[i])) {
+ isascii = 0;
+ break;
+ }
+ }
+ if (isascii) {
+ handleplumb(c, uri);
+ webkit_policy_decision_ignore(d);
+ return;
+ }
+ }
+
+ if (webkit_response_policy_decision_is_mime_type_supported(r)) {
+ webkit_policy_decision_use(d);
+ } else {
+ webkit_policy_decision_ignore(d);
+ download(c, res);
+ }
+}
+
+void
+insecurecontent(WebKitWebView *v, WebKitInsecureContentEvent e, Client *c)
+{
+ c->insecure = 1;
+}
+
+void
+downloadstarted(WebKitWebContext *wc, WebKitDownload *d, Client *c)
+{
+ g_signal_connect(G_OBJECT(d), "notify::response",
+ G_CALLBACK(responsereceived), c);
+}
+
+void
+responsereceived(WebKitDownload *d, GParamSpec *ps, Client *c)
+{
+ download(c, webkit_download_get_response(d));
+ webkit_download_cancel(d);
+}
+
+void
+download(Client *c, WebKitURIResponse *r)
+{
+ Arg a = (Arg)DOWNLOAD(webkit_uri_response_get_uri(r), geturi(c));
+ spawn(c, &a);
+}
+
+void
+closeview(WebKitWebView *v, Client *c)
+{
+ gtk_widget_destroy(c->win);
+}
+
+void
+destroywin(GtkWidget* w, Client *c)
+{
+ destroyclient(c);
+ if (!clients)
+ gtk_main_quit();
+}
+
+void
+pasteuri(GtkClipboard *clipboard, const char *text, gpointer d)
+{
+ Arg a = {.v = text };
+ if (text)
+ loaduri((Client *) d, &a);
+}
+
+void
+reload(Client *c, const Arg *a)
+{
+ if (a->b)
+ webkit_web_view_reload_bypass_cache(c->view);
+ else
+ webkit_web_view_reload(c->view);
+}
+
+void
+print(Client *c, const Arg *a)
+{
+ webkit_print_operation_run_dialog(webkit_print_operation_new(c->view),
+ GTK_WINDOW(c->win));
+}
+
+void
+showcert(Client *c, const Arg *a)
+{
+ GTlsCertificate *cert = c->failedcert ? c->failedcert : c->cert;
+ GcrCertificate *gcrt;
+ GByteArray *crt;
+ GtkWidget *win;
+ GcrCertificateWidget *wcert;
+
+ if (!cert)
+ return;
+
+ g_object_get(cert, "certificate", &crt, NULL);
+ gcrt = gcr_simple_certificate_new(crt->data, crt->len);
+ g_byte_array_unref(crt);
+
+ win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ wcert = gcr_certificate_widget_new(gcrt);
+ g_object_unref(gcrt);
+
+ gtk_container_add(GTK_CONTAINER(win), GTK_WIDGET(wcert));
+ gtk_widget_show_all(win);
+}
+
+void
+clipboard(Client *c, const Arg *a)
+{
+ if (a->b) { /* load clipboard uri */
+ gtk_clipboard_request_text(gtk_clipboard_get(
+ GDK_SELECTION_PRIMARY),
+ pasteuri, c);
+ } else { /* copy uri */
+ gtk_clipboard_set_text(gtk_clipboard_get(
+ GDK_SELECTION_PRIMARY), c->targeturi
+ ? c->targeturi : geturi(c), -1);
+ }
+}
+
+void
+zoom(Client *c, const Arg *a)
+{
+ if (a->i > 0)
+ webkit_web_view_set_zoom_level(c->view,
+ curconfig[ZoomLevel].val.f + 0.1);
+ else if (a->i < 0)
+ webkit_web_view_set_zoom_level(c->view,
+ curconfig[ZoomLevel].val.f - 0.1);
+ else
+ webkit_web_view_set_zoom_level(c->view, 1.0);
+
+ curconfig[ZoomLevel].val.f = webkit_web_view_get_zoom_level(c->view);
+}
+
+void
+scroll(Client *c, const Arg *a)
+{
+ GdkEvent *ev = gdk_event_new(GDK_KEY_PRESS);
+
+ gdk_event_set_device(ev, gdkkb);
+ ev->key.window = gtk_widget_get_window(GTK_WIDGET(c->win));
+ ev->key.state = GDK_CONTROL_MASK;
+ ev->key.time = GDK_CURRENT_TIME;
+
+ switch (a->i) {
+ case 'd':
+ ev->key.keyval = GDK_KEY_Down;
+ break;
+ case 'D':
+ ev->key.keyval = GDK_KEY_Page_Down;
+ break;
+ case 'l':
+ ev->key.keyval = GDK_KEY_Left;
+ break;
+ case 'r':
+ ev->key.keyval = GDK_KEY_Right;
+ break;
+ case 'U':
+ ev->key.keyval = GDK_KEY_Page_Up;
+ break;
+ case 'u':
+ ev->key.keyval = GDK_KEY_Up;
+ break;
+ }
+
+ gdk_event_put(ev);
+}
+