X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=surf.c;h=214b9c7b6384ec33b88cde612260957c43e4c1a8;hb=fe3bd631d4e163e15ab685c22ad70c67f8b94f83;hp=682c1e299c38043f9381b31841dd98c83a5d5725;hpb=0415175e10880585c765613af0bd43e02de87116;p=surf.git diff --git a/surf.c b/surf.c index 682c1e2..214b9c7 100644 --- a/surf.c +++ b/surf.c @@ -42,22 +42,16 @@ union Arg { }; typedef struct Client { - GtkWidget *win, *scroll, *vbox, *indicator; + GtkWidget *win, *scroll, *vbox, *pane; WebKitWebView *view; WebKitWebInspector *inspector; char *title, *linkhover; const char *uri, *needle; gint progress; struct Client *next; - gboolean zoomed, fullscreen, isinspector, sslfailed; + gboolean zoomed, fullscreen, isinspecting, sslfailed; } Client; -typedef struct { - char *label; - void (*func)(Client *c, const Arg *arg); - const Arg arg; -} Item; - typedef struct { guint mod; guint keyval; @@ -83,7 +77,8 @@ static GdkNativeWindow embed = 0; static gboolean showxid = FALSE; static char winid[64]; static gboolean usingproxy = 0; -static char togglestat[5]; +static char togglestat[6]; +static char pagestat[3]; static void beforerequest(WebKitWebView *w, WebKitWebFrame *f, WebKitWebResource *r, WebKitNetworkRequest *req, @@ -113,13 +108,12 @@ static gboolean decidewindow(WebKitWebView *v, WebKitWebFrame *f, static void destroyclient(Client *c); static void destroywin(GtkWidget* w, Client *c); static void die(const char *errstr, ...); -static void drawindicator(Client *c); static void eval(Client *c, const Arg *arg); -static gboolean exposeindicator(GtkWidget *w, GdkEventExpose *e, Client *c); static void find(Client *c, const Arg *arg); static void fullscreen(Client *c, const Arg *arg); static const char *getatom(Client *c, int a); static void gettogglestat(Client *c); +static void getpagestat(Client *c); static char *geturi(Client *c); static gboolean initdownload(WebKitWebView *v, WebKitDownload *o, Client *c); @@ -159,6 +153,8 @@ static void stop(Client *c, const Arg *arg); static void titlechange(WebKitWebView *v, WebKitWebFrame *frame, const char *title, Client *c); static void toggle(Client *c, const Arg *arg); +static void togglescrollbars(Client *c, const Arg *arg); +static void togglestyle(Client *c, const Arg *arg); static void update(Client *c); static void updatewinid(Client *c); static void usage(void); @@ -174,6 +170,7 @@ beforerequest(WebKitWebView *w, WebKitWebFrame *f, WebKitWebResource *r, WebKitNetworkRequest *req, WebKitNetworkResponse *resp, gpointer d) { const gchar *uri = webkit_network_request_get_uri(req); + if(g_str_has_suffix(uri, "/favicon.ico")) webkit_network_request_set_uri(req, "about:blank"); } @@ -296,7 +293,8 @@ evalscript(JSContextRef js, char *script, char* scriptname) { jsscript = JSStringCreateWithUTF8CString(script); jsscriptname = JSStringCreateWithUTF8CString(scriptname); - JSEvaluateScript(js, jsscript, JSContextGetGlobalObject(js), jsscriptname, 0, &exception); + JSEvaluateScript(js, jsscript, JSContextGetGlobalObject(js), + jsscriptname, 0, &exception); JSStringRelease(jsscript); JSStringRelease(jsscriptname); } @@ -307,7 +305,8 @@ runscript(WebKitWebFrame *frame) { GError *error; if(g_file_get_contents(scriptfile, &script, NULL, &error)) { - evalscript(webkit_web_frame_get_global_context(frame), script, scriptfile); + evalscript(webkit_web_frame_get_global_context(frame), + script, scriptfile); } } @@ -315,10 +314,15 @@ static void clipboard(Client *c, const Arg *arg) { gboolean paste = *(gboolean *)arg; - if(paste) - gtk_clipboard_request_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), pasteuri, c); - else - gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), c->linkhover ? c->linkhover : geturi(c), -1); + if(paste) { + gtk_clipboard_request_text( + gtk_clipboard_get(GDK_SELECTION_PRIMARY), + pasteuri, c); + } else { + gtk_clipboard_set_text( + gtk_clipboard_get(GDK_SELECTION_PRIMARY), + c->linkhover ? c->linkhover : geturi(c), -1); + } } static char * @@ -370,7 +374,6 @@ destroyclient(Client *c) { Client *p; webkit_web_view_stop_loading(c->view); - gtk_widget_destroy(c->indicator); gtk_widget_destroy(GTK_WIDGET(c->view)); gtk_widget_destroy(c->scroll); gtk_widget_destroy(c->vbox); @@ -402,51 +405,6 @@ die(const char *errstr, ...) { exit(EXIT_FAILURE); } -static void -drawindicator(Client *c) { - gint width; - const char *uri; - char *colorname; - GtkWidget *w; - GdkGC *gc; - GdkColor fg; - - uri = geturi(c); - w = c->indicator; - width = c->progress * w->allocation.width / 100; - gc = gdk_gc_new(w->window); - if(strstr(uri, "https://") == uri) { - if(usingproxy) { - colorname = c->sslfailed? progress_proxy_untrust : - progress_proxy_trust; - } else { - colorname = c->sslfailed? progress_untrust : - progress_trust; - } - } else { - if(usingproxy) { - colorname = progress_proxy; - } else { - colorname = progress; - } - } - - gdk_color_parse(colorname, &fg); - gdk_gc_set_rgb_fg_color(gc, &fg); - gdk_draw_rectangle(w->window, - w->style->bg_gc[GTK_WIDGET_STATE(w)], - TRUE, 0, 0, w->allocation.width, w->allocation.height); - gdk_draw_rectangle(w->window, gc, TRUE, 0, 0, width, - w->allocation.height); - g_object_unref(gc); -} - -static gboolean -exposeindicator(GtkWidget *w, GdkEventExpose *e, Client *c) { - drawindicator(c); - return TRUE; -} - static void find(Client *c, const Arg *arg) { const char *s; @@ -477,11 +435,13 @@ getatom(Client *c, int a) { XGetWindowProperty(dpy, GDK_WINDOW_XID(GTK_WIDGET(c->win)->window), atoms[a], 0L, BUFSIZ, False, XA_STRING, &adummy, &idummy, &ldummy, &ldummy, &p); - if(p) + if(p) { strncpy(buf, (char *)p, LENGTH(buf)-1); - else + } else { buf[0] = '\0'; + } XFree(p); + return buf; } @@ -506,28 +466,45 @@ initdownload(WebKitWebView *view, WebKitDownload *o, Client *c) { static void inspector(Client *c, const Arg *arg) { - if(c->isinspector) - return; - webkit_web_inspector_show(c->inspector); + if(c->isinspecting) { + webkit_web_inspector_close(c->inspector); + } else { + webkit_web_inspector_show(c->inspector); + } } static WebKitWebView * inspector_new(WebKitWebInspector *i, WebKitWebView *v, Client *c) { - Client *n = newclient(); - n->isinspector = true; - - return n->view; + return WEBKIT_WEB_VIEW(webkit_web_view_new()); } static gboolean inspector_show(WebKitWebInspector *i, Client *c) { - gtk_widget_show(GTK_WIDGET(webkit_web_inspector_get_web_view(i))); + WebKitWebView *w; + + if(c->isinspecting) + return false; + + w = webkit_web_inspector_get_web_view(i); + gtk_paned_pack2(GTK_PANED(c->pane), GTK_WIDGET(w), TRUE, TRUE); + gtk_widget_show(GTK_WIDGET(w)); + c->isinspecting = true; + return true; } static gboolean inspector_close(WebKitWebInspector *i, Client *c) { - gtk_widget_hide(GTK_WIDGET(webkit_web_inspector_get_web_view(i))); + GtkWidget *w; + + if(!c->isinspecting) + return false; + + w = GTK_WIDGET(webkit_web_inspector_get_web_view(i)); + gtk_widget_hide(w); + gtk_widget_destroy(w); + c->isinspecting = false; + return true; } @@ -671,16 +648,16 @@ newclient(void) { "key-press-event", G_CALLBACK(keypress), c); + /* Pane */ + c->pane = gtk_vpaned_new(); + /* VBox */ c->vbox = gtk_vbox_new(FALSE, 0); - - /* Scrolled Window */ - c->scroll = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(c->scroll), - GTK_POLICY_NEVER, GTK_POLICY_NEVER); + gtk_paned_pack1(GTK_PANED(c->pane), c->vbox, TRUE, TRUE); /* Webview */ c->view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_signal_connect(G_OBJECT(c->view), "title-changed", G_CALLBACK(titlechange), c); @@ -718,24 +695,31 @@ newclient(void) { "resource-request-starting", G_CALLBACK(beforerequest), c); - /* Indicator */ - c->indicator = gtk_drawing_area_new(); - gtk_widget_set_size_request(c->indicator, 0, indicator_thickness); - g_signal_connect (G_OBJECT (c->indicator), "expose_event", - G_CALLBACK (exposeindicator), c); + /* Scrolled Window */ + c->scroll = gtk_scrolled_window_new(NULL, NULL); + + frame = webkit_web_view_get_main_frame(WEBKIT_WEB_VIEW(c->view)); + g_signal_connect(G_OBJECT(frame), "scrollbars-policy-changed", + G_CALLBACK(gtk_true), NULL); + + if(!enablescrollbars) { + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(c->scroll), + GTK_POLICY_NEVER, GTK_POLICY_NEVER); + } else { + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(c->scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + } /* Arranging */ gtk_container_add(GTK_CONTAINER(c->scroll), GTK_WIDGET(c->view)); - gtk_container_add(GTK_CONTAINER(c->win), c->vbox); + gtk_container_add(GTK_CONTAINER(c->win), c->pane); gtk_container_add(GTK_CONTAINER(c->vbox), c->scroll); - gtk_container_add(GTK_CONTAINER(c->vbox), c->indicator); /* Setup */ - gtk_box_set_child_packing(GTK_BOX(c->vbox), c->indicator, FALSE, - FALSE, 0, GTK_PACK_START); gtk_box_set_child_packing(GTK_BOX(c->vbox), c->scroll, TRUE, TRUE, 0, GTK_PACK_START); gtk_widget_grab_focus(GTK_WIDGET(c->view)); + gtk_widget_show(c->pane); gtk_widget_show(c->vbox); gtk_widget_show(c->scroll); gtk_widget_show(GTK_WIDGET(c->view)); @@ -746,8 +730,8 @@ newclient(void) { gdk_window_add_filter(GTK_WIDGET(c->win)->window, processx, c); webkit_web_view_set_full_content_zoom(c->view, TRUE); - frame = webkit_web_view_get_main_frame(c->view); runscript(frame); + settings = webkit_web_view_get_settings(c->view); if(!(ua = getenv("SURF_USERAGENT"))) ua = useragent; @@ -776,7 +760,7 @@ newclient(void) { G_CALLBACK(inspector_close), c); g_signal_connect(G_OBJECT(c->inspector), "finished", G_CALLBACK(inspector_finished), c); - c->isinspector = false; + c->isinspecting = false; } g_free(uri); @@ -789,6 +773,7 @@ newclient(void) { c->title = NULL; c->next = clients; clients = c; + if(showxid) { gdk_display_sync(gtk_widget_get_display(c->win)); printf("%u\n", @@ -798,28 +783,31 @@ newclient(void) { die("Error closing stdout"); } } + return c; } static void newwindow(Client *c, const Arg *arg, gboolean noembed) { guint i = 0; - const char *cmd[10], *uri; + const char *cmd[11], *uri; const Arg a = { .v = (void *)cmd }; char tmp[64]; cmd[i++] = argv0; + if(!enablescrollbars) + cmd[i++] = "-b"; if(embed && !noembed) { cmd[i++] = "-e"; snprintf(tmp, LENGTH(tmp), "%u\n", (int)embed); cmd[i++] = tmp; } - if(!enablescripts) - cmd[i++] = "-s"; - if(!enableplugins) - cmd[i++] = "-p"; if(!loadimages) cmd[i++] = "-i"; + if(!enableplugins) + cmd[i++] = "-p"; + if(!enablescripts) + cmd[i++] = "-s"; if(showxid) cmd[i++] = "-x"; cmd[i++] = "--"; @@ -914,10 +902,11 @@ progresschange(WebKitWebView *view, GParamSpec *pspec, Client *c) { static void reload(Client *c, const Arg *arg) { gboolean nocache = *(gboolean *)arg; - if(nocache) + if(nocache) { webkit_web_view_reload_bypass_cache(c->view); - else + } else { webkit_web_view_reload(c->view); + } } static void @@ -973,8 +962,6 @@ setup(void) { /* clean up any zombies immediately */ sigchld(0); gtk_init(NULL, NULL); - if (!g_thread_supported()) - g_thread_init(NULL); dpy = GDK_DISPLAY(); @@ -1074,9 +1061,61 @@ toggle(Client *c, const Arg *arg) { reload(c,&a); } +static void +twitch(Client *c, const Arg *arg) { + GtkAdjustment *a; + gdouble v; + + a = gtk_scrolled_window_get_vadjustment( + GTK_SCROLLED_WINDOW(c->scroll)); + + v = gtk_adjustment_get_value(a); + + v += arg->i; + + v = MAX(v, 0.0); + v = MIN(v, gtk_adjustment_get_upper(a) - + gtk_adjustment_get_page_size(a)); + gtk_adjustment_set_value(a, v); +} + +static void +togglescrollbars(Client *c, const Arg *arg) { + GtkPolicyType vspolicy; + Arg a; + + gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(c->scroll), NULL, &vspolicy); + + if(vspolicy == GTK_POLICY_AUTOMATIC) { + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(c->scroll), + GTK_POLICY_NEVER, GTK_POLICY_NEVER); + } else { + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(c->scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + a.i = +1; + twitch(c, &a); + a.i = -1; + twitch(c, &a); + } +} + +static void +togglestyle(Client *c, const Arg *arg) { + WebKitWebSettings *settings; + char *uri; + + settings = webkit_web_view_get_settings(c->view); + g_object_get(G_OBJECT(settings), "user-stylesheet-uri", &uri, NULL); + uri = uri[0] ? g_strdup("") : g_strconcat("file://", stylefile, NULL); + g_object_set(G_OBJECT(settings), "user-stylesheet-uri", uri, NULL); + + update(c); +} + static void gettogglestat(Client *c){ gboolean value; + char *uri; WebKitWebSettings *settings = webkit_web_view_get_settings(c->view); g_object_get(G_OBJECT(settings), "enable-caret-browsing", @@ -1092,26 +1131,41 @@ gettogglestat(Client *c){ g_object_get(G_OBJECT(settings), "enable-plugins", &value, NULL); togglestat[3] = value? 'V': 'v'; - togglestat[4] = '\0'; + g_object_get(G_OBJECT(settings), "user-stylesheet-uri", &uri, NULL); + togglestat[4] = uri[0] ? 'M': 'm'; + + togglestat[5] = '\0'; } +static void +getpagestat(Client *c) { + const char *uri = geturi(c); + + if(strstr(uri, "https://") == uri) { + pagestat[0] = c->sslfailed ? 'U' : 'T'; + } else { + pagestat[0] = '-'; + } + + pagestat[1] = usingproxy ? 'P' : '-'; + pagestat[2] = '\0'; + +} static void update(Client *c) { char *t; gettogglestat(c); + getpagestat(c); if(c->linkhover) { - t = g_strdup_printf("%s| %s", togglestat, c->linkhover); + t = g_strdup_printf("%s:%s | %s", togglestat, pagestat, c->linkhover); } else if(c->progress != 100) { - drawindicator(c); - gtk_widget_show(c->indicator); - t = g_strdup_printf("[%i%%] %s| %s", c->progress, togglestat, - c->title); + t = g_strdup_printf("[%i%%] %s:%s | %s", c->progress, togglestat, + pagestat, c->title); } else { - gtk_widget_hide_all(c->indicator); - t = g_strdup_printf("%s| %s", togglestat, c->title); + t = g_strdup_printf("%s:%s | %s", togglestat, pagestat, c->title); } gtk_window_set_title(GTK_WINDOW(c->win), t); @@ -1126,7 +1180,7 @@ updatewinid(Client *c) { static void usage(void) { - die("usage: %s [-inpsvx] [-c cookiefile] [-e xid] [-r scriptfile]" + die("usage: %s [-binpsvx] [-c cookiefile] [-e xid] [-r scriptfile]" " [-t stylefile] [-u useragent] [uri]\n", basename(argv0)); } @@ -1160,6 +1214,9 @@ main(int argc, char *argv[]) { /* command line args */ ARGBEGIN { + case 'b': + enablescrollbars = 0; + break; case 'c': cookiefile = EARGF(usage()); break;