X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=surf.c;h=e0ad8ea89ad9fb92aba45357066d11ddbb3f3c59;hb=12101938d8df3da51871ed5d1da7c6144c2138cb;hp=17f7750cd16dd416205fb1a43078019e22b93b97;hpb=3e972f8e2a170f15e76fae7dc4de656963deb89b;p=surf.git diff --git a/surf.c b/surf.c index 17f7750..e0ad8ea 100644 --- a/surf.c +++ b/surf.c @@ -77,9 +77,10 @@ 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 addaccelgroup(Client *c); static void beforerequest(WebKitWebView *w, WebKitWebFrame *f, WebKitWebResource *r, WebKitNetworkRequest *req, WebKitNetworkResponse *resp, gpointer d); @@ -124,7 +125,9 @@ 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 gboolean keypress(GtkAccelGroup *group, + GObject *obj, guint key, GdkModifierType mods, + Client *c); static void linkhover(WebKitWebView *v, const char* t, const char* l, Client *c); static void loadstatuschange(WebKitWebView *view, GParamSpec *pspec, @@ -153,6 +156,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); @@ -163,11 +168,26 @@ static void zoom(Client *c, const Arg *arg); /* configuration, allows nested code to access above variables */ #include "config.h" +static 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); +} + static void 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"); } @@ -290,7 +310,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); } @@ -301,7 +322,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); } } @@ -309,10 +331,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 * @@ -425,11 +452,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; } @@ -502,14 +531,17 @@ inspector_finished(WebKitWebInspector *i, Client *c) { } static gboolean -keypress(GtkWidget* w, GdkEventKey *ev, Client *c) { +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(gdk_keyval_to_lower(ev->keyval) == keys[i].keyval - && CLEANMASK(ev->state) == keys[i].mod + if(key == keys[i].keyval + && mods == keys[i].mod && keys[i].func) { keys[i].func(c, &(keys[i].arg)); processed = TRUE; @@ -565,12 +597,13 @@ loaduri(Client *c, const Arg *arg) { char *u, *rp; const char *uri = (char *)arg->v; Arg a = { .b = FALSE }; + struct stat st; if(strcmp(uri, "") == 0) return; /* In case it's a file path. */ - if(uri[0] == '/') { + if(stat(uri, &st) == 0) { rp = realpath(uri, NULL); u = g_strdup_printf("file://%s", rp); free(rp); @@ -632,9 +665,9 @@ newclient(void) { g_signal_connect(G_OBJECT(c->win), "destroy", G_CALLBACK(destroywin), c); - g_signal_connect(G_OBJECT(c->win), - "key-press-event", - G_CALLBACK(keypress), c); + + if(!kioskmode) + addaccelgroup(c); /* Pane */ c->pane = gtk_vpaned_new(); @@ -643,13 +676,9 @@ newclient(void) { 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); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(c->scroll), - GTK_POLICY_NEVER, GTK_POLICY_NEVER); - /* Webview */ c->view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_signal_connect(G_OBJECT(c->view), "title-changed", G_CALLBACK(titlechange), c); @@ -687,6 +716,21 @@ newclient(void) { "resource-request-starting", G_CALLBACK(beforerequest), 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->pane); @@ -707,8 +751,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; @@ -725,6 +769,10 @@ newclient(void) { enablespatialbrowsing, NULL); g_object_set(G_OBJECT(settings), "enable-developer-extras", enableinspector, NULL); + g_object_set(G_OBJECT(settings), "enable-default-context-menu", + kioskmode ^ 1, NULL); + g_object_set(G_OBJECT(settings), "default-font-size", + defaultfontsize, NULL); if(enableinspector) { c->inspector = WEBKIT_WEB_INSPECTOR( @@ -767,22 +815,26 @@ newclient(void) { static void newwindow(Client *c, const Arg *arg, gboolean noembed) { guint i = 0; - const char *cmd[10], *uri; + const char *cmd[12], *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(kioskmode) + cmd[i++] = "-k"; + if(!enableplugins) + cmd[i++] = "-p"; + if(!enablescripts) + cmd[i++] = "-s"; if(showxid) cmd[i++] = "-x"; cmd[i++] = "--"; @@ -856,11 +908,12 @@ processx(GdkXEvent *e, GdkEvent *event, gpointer d) { if(ev->atom == atoms[AtomFind]) { arg.b = TRUE; find(c, &arg); + return GDK_FILTER_REMOVE; - } - else if(ev->atom == atoms[AtomGo]) { + } else if(ev->atom == atoms[AtomGo]) { arg.v = getatom(c, AtomGo); loaduri(c, &arg); + return GDK_FILTER_REMOVE; } } @@ -877,10 +930,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 @@ -1035,9 +1089,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", @@ -1053,7 +1159,10 @@ 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 @@ -1099,7 +1208,7 @@ updatewinid(Client *c) { static void usage(void) { - die("usage: %s [-inpsvx] [-c cookiefile] [-e xid] [-r scriptfile]" + die("usage: %s [-biknpsvx] [-c cookiefile] [-e xid] [-r scriptfile]" " [-t stylefile] [-u useragent] [uri]\n", basename(argv0)); } @@ -1133,6 +1242,9 @@ main(int argc, char *argv[]) { /* command line args */ ARGBEGIN { + case 'b': + enablescrollbars = 0; + break; case 'c': cookiefile = EARGF(usage()); break; @@ -1142,6 +1254,9 @@ main(int argc, char *argv[]) { case 'i': loadimages = 0; break; + case 'k': + kioskmode = 1; + break; case 'n': enableinspector = 0; break;