X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=surf.c;h=1c999dd09097e15847b60926b03c88af843766d1;hb=3c1ed5d56af13f09a81beb00c59464972c36b2f0;hp=899ab0427567246d6d7e0e920a5212f7f716d172;hpb=13b04d8b61b3e0f334b57749cf9b8755135ef4f4;p=surf.git diff --git a/surf.c b/surf.c index 899ab04..1c999dd 100644 --- a/surf.c +++ b/surf.c @@ -20,12 +20,15 @@ #include #include #include +#include +#include #include "arg.h" char *argv0; #define LENGTH(x) (sizeof x / sizeof x[0]) +#define CLEANMASK(mask) (mask & (MODKEY|GDK_SHIFT_MASK)) #define COOKIEJAR_TYPE (cookiejar_get_type ()) #define COOKIEJAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COOKIEJAR_TYPE, CookieJar)) @@ -39,14 +42,14 @@ 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; - gboolean sslfailed; struct Client *next; - gboolean zoomed, fullscreen; + gboolean zoomed, fullscreen, isinspecting, sslfailed; } Client; typedef struct { @@ -79,9 +82,9 @@ static Client *clients = NULL; static GdkNativeWindow embed = 0; static gboolean showxid = FALSE; static char winid[64]; -static gboolean loadimages = 1, enableplugins = 1, enablescripts = 1, - usingproxy = 0; +static gboolean usingproxy = 0; static char togglestat[5]; +static char pagestat[2]; static void beforerequest(WebKitWebView *w, WebKitWebFrame *f, WebKitWebResource *r, WebKitNetworkRequest *req, @@ -91,12 +94,14 @@ static gboolean buttonrelease(WebKitWebView *web, GdkEventButton *e, GList *gl); static void cleanup(void); static void clipboard(Client *c, const Arg *arg); + static void cookiejar_changed(SoupCookieJar *self, SoupCookie *old_cookie, SoupCookie *new_cookie); static void cookiejar_finalize(GObject *self); static SoupCookieJar *cookiejar_new(const char *filename, gboolean read_only); static void cookiejar_set_property(GObject *self, guint prop_id, const GValue *value, GParamSpec *pspec); + static char *copystr(char **str, const char *src); static WebKitWebView *createwindow(WebKitWebView *v, WebKitWebFrame *f, Client *c); @@ -108,14 +113,23 @@ static gboolean decidewindow(WebKitWebView *v, WebKitWebFrame *f, WebKitWebPolicyDecision *p, Client *c); static void destroyclient(Client *c); static void destroywin(GtkWidget* w, Client *c); -static void die(char *str); -static void drawindicator(Client *c); -static gboolean exposeindicator(GtkWidget *w, GdkEventExpose *e, Client *c); +static void die(const char *errstr, ...); +static void eval(Client *c, const Arg *arg); 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); + +static void inspector(Client *c, const Arg *arg); +static WebKitWebView *inspector_new(WebKitWebInspector *i, WebKitWebView *v, + Client *c); +static gboolean inspector_show(WebKitWebInspector *i, Client *c); +static gboolean inspector_close(WebKitWebInspector *i, Client *c); +static void inspector_finished(WebKitWebInspector *i, Client *c); + static gboolean keypress(GtkWidget *w, GdkEventKey *ev, Client *c); static void linkhover(WebKitWebView *v, const char* t, const char* l, Client *c); @@ -141,12 +155,10 @@ static void setup(void); static void sigchld(int unused); static void source(Client *c, const Arg *arg); static void spawn(Client *c, const Arg *arg); -static void eval(Client *c, const Arg *arg); 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 gettogglestat(Client *c); static void update(Client *c); static void updatewinid(Client *c); static void usage(void); @@ -358,7 +370,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); @@ -381,54 +392,13 @@ destroywin(GtkWidget* w, Client *c) { } static void -die(char *str) { - fputs(str, stderr); - exit(EXIT_FAILURE); -} +die(const char *errstr, ...) { + va_list ap; -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; + va_start(ap, errstr); + vfprintf(stderr, errstr, ap); + va_end(ap); + exit(EXIT_FAILURE); } static void @@ -488,6 +458,55 @@ initdownload(WebKitWebView *view, WebKitDownload *o, Client *c) { return FALSE; } +static void +inspector(Client *c, const Arg *arg) { + 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) { + return WEBKIT_WEB_VIEW(webkit_web_view_new()); +} + +static gboolean +inspector_show(WebKitWebInspector *i, Client *c) { + 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) { + 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; +} + +static void +inspector_finished(WebKitWebInspector *i, Client *c) { + g_free(c->inspector); +} + static gboolean keypress(GtkWidget* w, GdkEventKey *ev, Client *c) { guint i; @@ -496,7 +515,7 @@ keypress(GtkWidget* w, GdkEventKey *ev, Client *c) { updatewinid(c); for(i = 0; i < LENGTH(keys); i++) { if(gdk_keyval_to_lower(ev->keyval) == keys[i].keyval - && (ev->state & keys[i].mod) == keys[i].mod + && CLEANMASK(ev->state) == keys[i].mod && keys[i].func) { keys[i].func(c, &(keys[i].arg)); processed = TRUE; @@ -623,8 +642,12 @@ newclient(void) { "key-press-event", G_CALLBACK(keypress), c); + /* Pane */ + c->pane = gtk_vpaned_new(); + /* VBox */ c->vbox = gtk_vbox_new(FALSE, 0); + gtk_paned_pack1(GTK_PANED(c->pane), c->vbox, TRUE, TRUE); /* Scrolled Window */ c->scroll = gtk_scrolled_window_new(NULL, NULL); @@ -670,24 +693,16 @@ 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); - /* 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)); @@ -706,11 +721,30 @@ newclient(void) { g_object_set(G_OBJECT(settings), "user-agent", ua, NULL); uri = g_strconcat("file://", stylefile, NULL); g_object_set(G_OBJECT(settings), "user-stylesheet-uri", uri, NULL); - g_object_set(G_OBJECT(settings), "auto-load-images", loadimages, NULL); - g_object_set(G_OBJECT(settings), "enable-plugins", enableplugins, NULL); - g_object_set(G_OBJECT(settings), "enable-scripts", enablescripts, NULL); + g_object_set(G_OBJECT(settings), "auto-load-images", loadimages, + NULL); + g_object_set(G_OBJECT(settings), "enable-plugins", enableplugins, + NULL); + g_object_set(G_OBJECT(settings), "enable-scripts", enablescripts, + NULL); g_object_set(G_OBJECT(settings), "enable-spatial-navigation", - spatialbrowsing, NULL); + enablespatialbrowsing, NULL); + g_object_set(G_OBJECT(settings), "enable-developer-extras", + enableinspector, NULL); + + if(enableinspector) { + c->inspector = WEBKIT_WEB_INSPECTOR( + webkit_web_view_get_inspector(c->view)); + g_signal_connect(G_OBJECT(c->inspector), "inspect-web-view", + G_CALLBACK(inspector_new), c); + g_signal_connect(G_OBJECT(c->inspector), "show-window", + G_CALLBACK(inspector_show), c); + g_signal_connect(G_OBJECT(c->inspector), "close-window", + G_CALLBACK(inspector_close), c); + g_signal_connect(G_OBJECT(c->inspector), "finished", + G_CALLBACK(inspector_finished), c); + c->isinspecting = false; + } g_free(uri); @@ -722,6 +756,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", @@ -731,6 +766,7 @@ newclient(void) { die("Error closing stdout"); } } + return c; } @@ -906,8 +942,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(); @@ -1028,23 +1062,26 @@ gettogglestat(Client *c){ togglestat[4] = '\0'; } +static void +getpagestat(Client *c) { + pagestat[0] = c->sslfailed ? 'U' : 'T'; + pagestat[1] = usingproxy ? 'P' : '-'; +} 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); @@ -1059,9 +1096,8 @@ updatewinid(Client *c) { static void usage(void) { - fputs("surf - simple browser\n", stderr); - die("usage: surf [-c cookiefile] [-e xid] [-i] [-p] [-r scriptfile]" - " [-s] [-t stylefile] [-u useragent] [-v] [-x] [uri]\n"); + die("usage: %s [-inpsvx] [-c cookiefile] [-e xid] [-r scriptfile]" + " [-t stylefile] [-u useragent] [uri]\n", basename(argv0)); } static void @@ -1103,6 +1139,9 @@ main(int argc, char *argv[]) { case 'i': loadimages = 0; break; + case 'n': + enableinspector = 0; + break; case 'p': enableplugins = 0; break; @@ -1118,11 +1157,12 @@ main(int argc, char *argv[]) { case 'u': useragent = EARGF(usage()); break; + case 'v': + die("surf-"VERSION", ©2009-2012 surf engineers, " + "see LICENSE for details\n"); case 'x': showxid = TRUE; break; - case 'v': - die("surf-"VERSION", ©2009-2012 surf engineers, see LICENSE for details\n"); default: usage(); } ARGEND;