Fix clickexternplayer(), no need to test the target again
[surf.git] / surf.c
diff --git a/surf.c b/surf.c
index 5043d33..a5cfdd0 100644 (file)
--- a/surf.c
+++ b/surf.c
@@ -70,7 +70,7 @@ typedef struct Client {
        GTlsCertificateFlags tlsflags;
        Window xid;
        int progress, fullscreen;
-       const char *title, *targeturi;
+       const char *title, *overtitle, *targeturi;
        const char *needle;
        struct Client *next;
 } Client;
@@ -105,7 +105,6 @@ static void sigchld(int unused);
 static char *buildfile(const char *path);
 static char *buildpath(const char *path);
 static Client *newclient(Client *c);
-static void addaccelgroup(Client *c);
 static void loaduri(Client *c, const Arg *a);
 static const char *geturi(Client *c);
 static void setatom(Client *c, int a, const char *v);
@@ -131,8 +130,6 @@ static WebKitWebView *newview(Client *c, WebKitWebView *rv);
 static GtkWidget *createview(WebKitWebView *v, WebKitNavigationAction *a,
                              Client *c);
 static gboolean buttonreleased(GtkWidget *w, GdkEvent *e, Client *c);
-static gboolean keypress(GtkAccelGroup *group, GObject *obj, guint key,
-                         GdkModifierType mods, Client *c);
 static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event,
                                 gpointer d);
 static gboolean winevent(GtkWidget *w, GdkEvent *e, Client *c);
@@ -333,33 +330,16 @@ newclient(Client *rc)
        if (!(c = calloc(1, sizeof(Client))))
                die("Cannot malloc!\n");
 
-       c->title = NULL;
-       c->progress = 100;
-
        c->next = clients;
        clients = c;
 
-       c->view = newview(c, rc ? rc->view : NULL);
+       c->progress = 100;
        c->tlsflags = G_TLS_CERTIFICATE_VALIDATE_ALL + 1;
+       c->view = newview(c, rc ? rc->view : NULL);
 
        return c;
 }
 
-void
-addaccelgroup(Client *c)
-{
-       int i;
-       GtkAccelGroup *group = gtk_accel_group_new();
-       GClosure *closure;
-
-       for (i = 0; i < LENGTH(keys); i++) {
-               closure = g_cclosure_new(G_CALLBACK(keypress), c, NULL);
-               gtk_accel_group_connect(group, keys[i].keyval, keys[i].mod, 0,
-                                       closure);
-       }
-       gtk_window_add_accel_group(GTK_WINDOW(c->win), group);
-}
-
 void
 loaduri(Client *c, const Arg *a)
 {
@@ -435,26 +415,24 @@ void
 updatetitle(Client *c)
 {
        char *title;
+       const char *name = c->overtitle ? c->overtitle :
+                          c->title ? c->title : "";
 
        if (showindicators) {
                gettogglestats(c);
                getpagestats(c);
 
-               if (c->progress != 100) {
+               if (c->progress != 100)
                        title = g_strdup_printf("[%i%%] %s:%s | %s",
-                               c->progress, togglestats, pagestats,
-                               c->targeturi ? c->targeturi : c->title);
-               } else {
+                               c->progress, togglestats, pagestats, name);
+               else
                        title = g_strdup_printf("%s:%s | %s",
-                               togglestats, pagestats,
-                               c->targeturi ? c->targeturi : c->title);
-               }
+                               togglestats, pagestats, name);
 
                gtk_window_set_title(GTK_WINDOW(c->win), title);
                g_free(title);
        } else {
-               gtk_window_set_title(GTK_WINDOW(c->win), c->title ?
-                                    c->title : "");
+               gtk_window_set_title(GTK_WINDOW(c->win), name);
        }
 }
 
@@ -489,12 +467,11 @@ cookiepolicy_get(void)
                return WEBKIT_COOKIE_POLICY_ACCEPT_NEVER;
        case '@':
                return WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY;
+       default: /* fallthrough */
        case 'A':
-       default:
-               break;
+               return WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS;
        }
 
-       return WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS;
 }
 
 char
@@ -505,12 +482,11 @@ cookiepolicy_set(const WebKitCookieAcceptPolicy p)
                return 'a';
        case WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY:
                return '@';
+       default: /* fallthrough */
        case WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS:
-       default:
-               break;
+               return 'A';
        }
 
-       return 'A';
 }
 
 const char *
@@ -649,9 +625,9 @@ spawn(Client *c, const Arg *a)
                        close(ConnectionNumber(dpy));
                setsid();
                execvp(((char **)a->v)[0], (char **)a->v);
-               fprintf(stderr, "surf: execvp %s", ((char **)a->v)[0]);
+               fprintf(stderr, "%s: execvp %s", argv0, ((char **)a->v)[0]);
                perror(" failed");
-               exit(0);
+               exit(1);
        }
 }
 
@@ -750,6 +726,13 @@ newview(Client *c, WebKitWebView *rv)
                webkit_cookie_manager_set_accept_policy(
                    webkit_web_context_get_cookie_manager(context),
                    cookiepolicy_get());
+               /* languages */
+               webkit_web_context_set_preferred_languages(context,
+                                                          preferedlanguages);
+               webkit_web_context_set_spell_checking_languages(context,
+                   spellinglanguages);
+               webkit_web_context_set_spell_checking_enabled(context,
+                   enablespellchecking);
 
                g_signal_connect(G_OBJECT(context), "download-started",
                                 G_CALLBACK(downloadstarted), c);
@@ -761,26 +744,26 @@ newview(Client *c, WebKitWebView *rv)
                    NULL);
        }
 
+       g_signal_connect(G_OBJECT(v), "notify::estimated-load-progress",
+                        G_CALLBACK(progresschanged), c);
        g_signal_connect(G_OBJECT(v), "notify::title",
                         G_CALLBACK(titlechanged), c);
-       g_signal_connect(G_OBJECT(v), "mouse-target-changed",
-                        G_CALLBACK(mousetargetchanged), c);
-       g_signal_connect(G_OBJECT(v), "permission-request",
-                        G_CALLBACK(permissionrequested), c);
+       g_signal_connect(G_OBJECT(v), "button-release-event",
+                        G_CALLBACK(buttonreleased), c);
+       g_signal_connect(G_OBJECT(v), "close",
+                       G_CALLBACK(closeview), c);
        g_signal_connect(G_OBJECT(v), "create",
                         G_CALLBACK(createview), c);
-       g_signal_connect(G_OBJECT(v), "ready-to-show",
-                        G_CALLBACK(showview), c);
        g_signal_connect(G_OBJECT(v), "decide-policy",
                         G_CALLBACK(decidepolicy), c);
        g_signal_connect(G_OBJECT(v), "load-changed",
                         G_CALLBACK(loadchanged), c);
-       g_signal_connect(G_OBJECT(v), "notify::estimated-load-progress",
-                        G_CALLBACK(progresschanged), c);
-       g_signal_connect(G_OBJECT(v), "button-release-event",
-                        G_CALLBACK(buttonreleased), c);
-       g_signal_connect(G_OBJECT(v), "close",
-                       G_CALLBACK(closeview), c);
+       g_signal_connect(G_OBJECT(v), "mouse-target-changed",
+                        G_CALLBACK(mousetargetchanged), c);
+       g_signal_connect(G_OBJECT(v), "permission-request",
+                        G_CALLBACK(permissionrequested), c);
+       g_signal_connect(G_OBJECT(v), "ready-to-show",
+                        G_CALLBACK(showview), c);
 
        return v;
 }
@@ -834,28 +817,6 @@ buttonreleased(GtkWidget *w, GdkEvent *e, Client *c)
        return FALSE;
 }
 
-gboolean
-keypress(GtkAccelGroup *group, GObject *obj, guint key, GdkModifierType mods,
-         Client *c)
-{
-       guint i;
-       gboolean processed = FALSE;
-
-       mods = CLEANMASK(mods);
-       key = gdk_keyval_to_lower(key);
-       updatewinid(c);
-       for (i = 0; i < LENGTH(keys); i++) {
-               if (key == keys[i].keyval
-                   && mods == keys[i].mod
-                   && keys[i].func) {
-                       keys[i].func(c, &(keys[i].arg));
-                       processed = TRUE;
-               }
-       }
-
-       return processed;
-}
-
 GdkFilterReturn
 processx(GdkXEvent *e, GdkEvent *event, gpointer d)
 {
@@ -884,23 +845,41 @@ processx(GdkXEvent *e, GdkEvent *event, gpointer d)
 gboolean
 winevent(GtkWidget *w, GdkEvent *e, Client *c)
 {
+       int i;
+
        switch (e->type) {
+       case GDK_ENTER_NOTIFY:
+               c->overtitle = c->targeturi;
+               updatetitle(c);
+               break;
+       case GDK_KEY_PRESS:
+               if (!kioskmode) {
+                       for (i = 0; i < LENGTH(keys); ++i) {
+                               if (gdk_keyval_to_lower(e->key.keyval) ==
+                                   keys[i].keyval &&
+                                   CLEANMASK(e->key.state) == keys[i].mod &&
+                                   keys[i].func) {
+                                       updatewinid(c);
+                                       keys[i].func(c, &(keys[i].arg));
+                                       return TRUE;
+                               }
+                       }
+               }
        case GDK_LEAVE_NOTIFY:
-               c->targeturi = NULL;
+               c->overtitle = NULL;
                updatetitle(c);
                break;
-       case GDK_WINDOW_STATE: /* fallthrough */
+       case GDK_WINDOW_STATE:
                if (e->window_state.changed_mask ==
-                   GDK_WINDOW_STATE_FULLSCREEN) {
+                   GDK_WINDOW_STATE_FULLSCREEN)
                        c->fullscreen = e->window_state.new_window_state &
                                        GDK_WINDOW_STATE_FULLSCREEN;
-                       break;
-               }
+               break;
        default:
-               return FALSE;
+               break;
        }
 
-       return TRUE;
+       return FALSE;
 }
 
 void
@@ -931,7 +910,6 @@ showview(WebKitWebView *v, Client *c)
                webkit_web_view_set_background_color(c->view, &bgcolor);
 
        if (!kioskmode) {
-               addaccelgroup(c);
                gdk_window_set_events(gwin, GDK_ALL_EVENTS_MASK);
                gdk_window_add_filter(gwin, processx, c);
        }
@@ -971,6 +949,10 @@ createwindow(Client *c)
 
        g_signal_connect(G_OBJECT(w), "destroy",
                         G_CALLBACK(destroywin), c);
+       g_signal_connect(G_OBJECT(w), "enter-notify-event",
+                        G_CALLBACK(winevent), c);
+       g_signal_connect(G_OBJECT(w), "key-press-event",
+                        G_CALLBACK(winevent), c);
        g_signal_connect(G_OBJECT(w), "leave-notify-event",
                         G_CALLBACK(winevent), c);
        g_signal_connect(G_OBJECT(w), "window-state-event",
@@ -1043,6 +1025,8 @@ mousetargetchanged(WebKitWebView *v, WebKitHitTestResult *h, guint modifiers,
                c->targeturi = webkit_hit_test_result_get_media_uri(h);
        else
                c->targeturi = NULL;
+
+       c->overtitle = c->targeturi;
        updatetitle(c);
 }
 
@@ -1149,10 +1133,10 @@ decideresource(WebKitPolicyDecision *d, Client *c)
            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_uri_request_set_uri(
-                   webkit_response_policy_decision_get_request(r),
-                   "about:blank");
+       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://")
@@ -1170,6 +1154,7 @@ decideresource(WebKitPolicyDecision *d, Client *c)
                if (isascii) {
                        handleplumb(c, uri);
                        webkit_policy_decision_ignore(d);
+                       return;
                }
        }
 
@@ -1220,7 +1205,7 @@ void
 pasteuri(GtkClipboard *clipboard, const char *text, gpointer d)
 {
        Arg a = {.v = text };
-       if (!text)
+       if (text)
                loaduri((Client *) d, &a);
 }
 
@@ -1373,7 +1358,12 @@ void
 togglestyle(Client *c, const Arg *a)
 {
        enablestyle = !enablestyle;
-       setstyle(c, enablestyle ? getstyle(geturi(c)) : "");
+
+       if (enablestyle)
+               setstyle(c, getstyle(geturi(c)));
+       else
+               webkit_user_content_manager_remove_all_style_sheets(
+                   webkit_web_view_get_user_content_manager(c->view));
 
        updatetitle(c);
 }
@@ -1435,10 +1425,8 @@ clickexternplayer(Client *c, const Arg *a, WebKitHitTestResult *h)
 {
        Arg arg;
 
-       if (webkit_hit_test_result_get_context(h) & OnMedia) {
-               arg = (Arg)VIDEOPLAY(webkit_hit_test_result_get_media_uri(h));
-               spawn(c, &arg);
-       }
+       arg = (Arg)VIDEOPLAY(webkit_hit_test_result_get_media_uri(h));
+       spawn(c, &arg);
 }
 
 int
@@ -1527,7 +1515,7 @@ main(int argc, char *argv[])
                stylefile = EARGF(usage());
                break;
        case 'u':
-               useragent = EARGF(usage());
+               fulluseragent = EARGF(usage());
                break;
        case 'v':
                die("surf-"VERSION", ©2009-2015 surf engineers, "
@@ -1543,15 +1531,15 @@ main(int argc, char *argv[])
        } ARGEND;
        if (argc > 0)
                arg.v = argv[0];
+       else
+               arg.v = "about:blank";
 
        setup();
        c = newclient(NULL);
        showview(NULL, c);
 
-       if (arg.v)
-               loaduri(clients, &arg);
-       else
-               updatetitle(c);
+       loaduri(c, &arg);
+       updatetitle(c);
 
        gtk_main();
        cleanup();