tStyle change in functions ordering - surf - customized build of surf, the suck… | |
git clone git://src.adamsgaard.dk/surf | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 432f3c6b53cf47db3141a3e9b8b5aec2152f9aae | |
parent 7e9a85a5cb31a2ddefd06498eff33df724bdc6cf | |
Author: Quentin Rameau <[email protected]> | |
Date: Sat, 21 Nov 2015 19:14:08 +0100 | |
Style change in functions ordering | |
Try to group and order functions in a logical manner. | |
Same thing for config keybindings. | |
Diffstat: | |
M config.def.h | 40 ++++++++++++++++-------------… | |
M surf.c | 1738 +++++++++++++++--------------… | |
2 files changed, 889 insertions(+), 889 deletions(-) | |
--- | |
diff --git a/config.def.h b/config.def.h | |
t@@ -84,18 +84,15 @@ static SiteStyle styles[] = { | |
*/ | |
static Key keys[] = { | |
/* modifier keyval function arg */ | |
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_r, reload, { .b = TRUE } }, | |
- { MODKEY, GDK_KEY_r, reload, { .b = FALSE } }, | |
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_p, print, { 0 } }, | |
+ { MODKEY, GDK_KEY_g, spawn, SETPROP("_SURF_UR… | |
+ { MODKEY, GDK_KEY_f, spawn, SETPROP("_SURF_FI… | |
+ { MODKEY, GDK_KEY_slash, spawn, SETPROP("_SURF_FI… | |
- { MODKEY, GDK_KEY_p, clipboard, { .b = TRUE } }, | |
- { MODKEY, GDK_KEY_y, clipboard, { .b = FALSE } }, | |
+ { 0, GDK_KEY_Escape, stop, { 0 } }, | |
+ { MODKEY, GDK_KEY_c, stop, { 0 } }, | |
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_j, zoom, { .i = -1 } }, | |
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_k, zoom, { .i = +1 } }, | |
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_q, zoom, { .i = 0 } }, | |
- { MODKEY, GDK_KEY_minus, zoom, { .i = -1 } }, | |
- { MODKEY, GDK_KEY_plus, zoom, { .i = +1 } }, | |
+ { MODKEY|GDK_SHIFT_MASK, GDK_KEY_r, reload, { .b = TRUE } }, | |
+ { MODKEY, GDK_KEY_r, reload, { .b = FALSE } }, | |
{ MODKEY, GDK_KEY_l, navigate, { .i = +1 } }, | |
{ MODKEY, GDK_KEY_h, navigate, { .i = -1 } }, | |
t@@ -108,17 +105,25 @@ static Key keys[] = { | |
{ MODKEY, GDK_KEY_i, scroll_h, { .i = +10 } }, | |
{ MODKEY, GDK_KEY_u, scroll_h, { .i = -10 } }, | |
- { 0, GDK_KEY_F11, togglefullscreen, { 0 } }, | |
- { 0, GDK_KEY_Escape, stop, { 0 } }, | |
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_o, toggleinspector, { 0 } }, | |
+ { MODKEY|GDK_SHIFT_MASK, GDK_KEY_j, zoom, { .i = -1 } }, | |
+ { MODKEY|GDK_SHIFT_MASK, GDK_KEY_k, zoom, { .i = +1 } }, | |
+ { MODKEY|GDK_SHIFT_MASK, GDK_KEY_q, zoom, { .i = 0 } }, | |
+ { MODKEY, GDK_KEY_minus, zoom, { .i = -1 } }, | |
+ { MODKEY, GDK_KEY_plus, zoom, { .i = +1 } }, | |
- { MODKEY, GDK_KEY_g, spawn, SETPROP("_SURF_UR… | |
- { MODKEY, GDK_KEY_f, spawn, SETPROP("_SURF_FI… | |
- { MODKEY, GDK_KEY_slash, spawn, SETPROP("_SURF_FI… | |
+ { MODKEY, GDK_KEY_p, clipboard, { .b = TRUE } }, | |
+ { MODKEY, GDK_KEY_y, clipboard, { .b = FALSE } }, | |
{ MODKEY, GDK_KEY_n, find, { .i = +1 } }, | |
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_n, find, { .i = -1 } }, | |
+ { MODKEY|GDK_SHIFT_MASK, GDK_KEY_p, print, { 0 } }, | |
+ | |
+ { MODKEY|GDK_SHIFT_MASK, GDK_KEY_a, togglecookiepolicy, { 0 } }, | |
+ { 0, GDK_KEY_F11, togglefullscreen, { 0 } }, | |
+ { MODKEY|GDK_SHIFT_MASK, GDK_KEY_o, toggleinspector, { 0 } }, | |
+ { MODKEY|GDK_SHIFT_MASK, GDK_KEY_m, togglestyle, { 0 } }, | |
+ | |
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_c, toggle, { .i = CaretBrows… | |
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_f, toggle, { .i = FrameFlatt… | |
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_g, toggle, { .i = Geolocatio… | |
t@@ -126,9 +131,6 @@ static Key keys[] = { | |
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_i, toggle, { .i = LoadImages… | |
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_v, toggle, { .i = Plugins } … | |
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_b, toggle, { .i = ScrollBars… | |
- | |
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_a, togglecookiepolicy, { 0 } }, | |
- { MODKEY|GDK_SHIFT_MASK, GDK_KEY_m, togglestyle, { 0 } }, | |
}; | |
/* button definitions */ | |
diff --git a/surf.c b/surf.c | |
t@@ -29,14 +29,22 @@ | |
#include "arg.h" | |
-char *argv0; | |
- | |
#define LENGTH(x) (sizeof(x) / sizeof(x[0])) | |
#define CLEANMASK(mask) (mask & (MODKEY|GDK_SHIFT_MASK)) | |
enum { AtomFind, AtomGo, AtomUri, AtomLast }; | |
enum { | |
+ CaretBrowsing, | |
+ FrameFlattening, | |
+ Geolocation, | |
+ JavaScript, | |
+ LoadImages, | |
+ Plugins, | |
+ ScrollBars, | |
+}; | |
+ | |
+enum { | |
OnDoc = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT, | |
OnLink = WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK, | |
OnImg = WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE, | |
t@@ -47,42 +55,31 @@ enum { | |
OnAny = OnDoc | OnLink | OnImg | OnMedia | OnEdit | OnBar | OnSel, | |
}; | |
-enum { | |
- CaretBrowsing, | |
- FrameFlattening, | |
- Geolocation, | |
- JavaScript, | |
- LoadImages, | |
- Plugins, | |
- ScrollBars, | |
-}; | |
- | |
-typedef union Arg Arg; | |
-union Arg { | |
+typedef union { | |
gboolean b; | |
gint i; | |
const void *v; | |
-}; | |
+} Arg; | |
typedef struct Client { | |
GtkWidget *win; | |
- Window xid; | |
WebKitWebView *view; | |
WebKitWebInspector *inspector; | |
WebKitFindController *finder; | |
WebKitHitTestResult *mousepos; | |
GTlsCertificateFlags tlsflags; | |
+ Window xid; | |
+ gint progress; | |
+ gboolean fullscreen; | |
const char *title, *targeturi; | |
const char *needle; | |
- gint progress; | |
struct Client *next; | |
- gboolean fullscreen; | |
} Client; | |
typedef struct { | |
guint mod; | |
guint keyval; | |
- void (*func)(Client *c, const Arg *arg); | |
+ void (*func)(Client *c, const Arg *a); | |
const Arg arg; | |
} Key; | |
t@@ -101,114 +98,168 @@ typedef struct { | |
regex_t re; | |
} SiteStyle; | |
-static Display *dpy; | |
-static Atom atoms[AtomLast]; | |
-static Client *clients = NULL; | |
-static Window embed = 0; | |
-static gboolean showxid = FALSE; | |
-static char winid[64]; | |
-static char togglestats[10]; | |
-static char pagestats[2]; | |
-static int cookiepolicy; | |
-static char *stylefile = NULL; | |
-static const char *useragent; | |
- | |
-static void addaccelgroup(Client *c); | |
+/* Surf */ | |
+static void usage(void); | |
+static void die(const char *errstr, ...); | |
+static void setup(void); | |
+static void sigchld(int unused); | |
static char *buildfile(const char *path); | |
static char *buildpath(const char *path); | |
-static gboolean buttonreleased(GtkWidget *w, GdkEventKey *e, Client *c); | |
-static void cleanup(void); | |
-static void clipboard(Client *c, const Arg *a); | |
- | |
+static Client *newclient(Client *c); | |
+static void addaccelgroup(Client *c); | |
+static void loaduri(Client *c, const Arg *a); | |
+static char *geturi(Client *c); | |
+static void setatom(Client *c, int a, const char *v); | |
+static const char *getatom(Client *c, int a); | |
+static void updatetitle(Client *c); | |
+static void gettogglestats(Client *c); | |
+static void getpagestats(Client *c); | |
static WebKitCookieAcceptPolicy cookiepolicy_get(void); | |
static char cookiepolicy_set(const WebKitCookieAcceptPolicy p); | |
+static const gchar *getstyle(const char *uri); | |
+static void setstyle(Client *c, const char *stylefile); | |
+static void runscript(Client *c); | |
+static void evalscript(Client *c, const char *jsstr, ...); | |
+static void updatewinid(Client *c); | |
+static void handleplumb(Client *c, const gchar *uri); | |
+static void newwindow(Client *c, const Arg *arg, gboolean noembed); | |
+static void spawn(Client *c, const Arg *a); | |
+static void destroyclient(Client *c); | |
+static void cleanup(void); | |
+/* GTK/WebKit */ | |
+static WebKitWebView *newview(Client *c, WebKitWebView *rv); | |
static GtkWidget *createview(WebKitWebView *v, WebKitNavigationAction *a, | |
Client *c); | |
+static gboolean buttonreleased(GtkWidget *w, GdkEventKey *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); | |
+static void showview(WebKitWebView *v, Client *c); | |
+static GtkWidget *createwindow(Client *c); | |
+static void loadchanged(WebKitWebView *v, WebKitLoadEvent e, Client *c); | |
+static void progresschanged(WebKitWebView *v, GParamSpec *ps, Client *c); | |
+static void titlechanged(WebKitWebView *view, GParamSpec *ps, Client *c); | |
+static void mousetargetchanged(WebKitWebView *v, WebKitHitTestResult *h, | |
+ guint modifiers, Client *c); | |
+static gboolean permissionrequested(WebKitWebView *v, | |
+ WebKitPermissionRequest *r, Client *c); | |
static gboolean decidepolicy(WebKitWebView *v, WebKitPolicyDecision *d, | |
WebKitPolicyDecisionType dt, Client *c); | |
static void decidenavigation(WebKitPolicyDecision *d, Client *c); | |
static void decidenewwindow(WebKitPolicyDecision *d, Client *c); | |
static void decideresource(WebKitPolicyDecision *d, Client *c); | |
-static void closeview(WebKitWebView *v, Client *c); | |
-static void destroyclient(Client *c); | |
-static void destroywin(GtkWidget* w, Client *c); | |
-static void die(const char *errstr, ...); | |
-static void evalscript(Client *c, const char *jsstr, ...); | |
-static void runscript(Client *c); | |
-static void find(Client *c, const Arg *a); | |
-static void togglefullscreen(Client *c, const Arg *a); | |
-static gboolean permissionrequested(WebKitWebView *v, | |
- WebKitPermissionRequest *r, Client *c); | |
-static const char *getatom(Client *c, int a); | |
-static void gettogglestats(Client *c); | |
-static void getpagestats(Client *c); | |
-static char *geturi(Client *c); | |
-static const gchar *getstyle(const char *uri); | |
-static void setstyle(Client *c, const char *stylefile); | |
- | |
-static void handleplumb(Client *c, const gchar *uri); | |
- | |
static void downloadstarted(WebKitWebContext *wc, WebKitDownload *d, | |
Client *c); | |
static void responsereceived(WebKitDownload *d, GParamSpec *ps, Client *c); | |
static void download(Client *c, WebKitURIResponse *r); | |
+static void closeview(WebKitWebView *v, Client *c); | |
+static void destroywin(GtkWidget* w, Client *c); | |
-static void toggleinspector(Client *c, const Arg *a); | |
- | |
-static gboolean keypress(GtkAccelGroup *group, GObject *obj, guint key, | |
- GdkModifierType mods, Client *c); | |
-static void mousetargetchanged(WebKitWebView *v, WebKitHitTestResult *h, | |
- guint modifiers, Client *c); | |
-static void loadchanged(WebKitWebView *v, WebKitLoadEvent e, Client *c); | |
-static void loaduri(Client *c, const Arg *a); | |
-static void navigate(Client *c, const Arg *a); | |
-static void clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h); | |
-static Client *newclient(Client *c); | |
-static WebKitWebView *newview(Client *c, WebKitWebView *rv); | |
-static void showview(WebKitWebView *v, Client *c); | |
-static void newwindow(Client *c, const Arg *arg, gboolean noembed); | |
-static GtkWidget *createwindow(Client *c); | |
+/* Hotkeys */ | |
static void pasteuri(GtkClipboard *clipboard, const char *text, gpointer d); | |
-static void print(Client *c, const Arg *a); | |
-static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event, | |
- gpointer d); | |
-static gboolean winevent(GtkWidget *w, GdkEvent *e, Client *c); | |
-static void progresschanged(WebKitWebView *v, GParamSpec *ps, Client *c); | |
-static void clicknewwindow(Client *c, const Arg *a, WebKitHitTestResult *h); | |
static void reload(Client *c, const Arg *arg); | |
-static void scroll_h(Client *c, const Arg *a); | |
+static void print(Client *c, const Arg *a); | |
+static void clipboard(Client *c, const Arg *a); | |
+static void zoom(Client *c, const Arg *a); | |
static void scroll_v(Client *c, const Arg *a); | |
-static void setatom(Client *c, int a, const char *v); | |
-static void setup(void); | |
-static void sigchld(int unused); | |
-static void spawn(Client *c, const Arg *arg); | |
+static void scroll_h(Client *c, const Arg *a); | |
+static void navigate(Client *c, const Arg *a); | |
static void stop(Client *c, const Arg *arg); | |
-static void titlechanged(WebKitWebView *view, GParamSpec *ps, Client *c); | |
static void toggle(Client *c, const Arg *a); | |
+static void togglefullscreen(Client *c, const Arg *a); | |
static void togglecookiepolicy(Client *c, const Arg *arg); | |
static void togglestyle(Client *c, const Arg *arg); | |
-static void updatetitle(Client *c); | |
-static void updatewinid(Client *c); | |
-static void usage(void); | |
-static void zoom(Client *c, const Arg *a); | |
+static void toggleinspector(Client *c, const Arg *a); | |
+static void find(Client *c, const Arg *a); | |
+ | |
+/* Buttons */ | |
+static void clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h); | |
+static void clicknewwindow(Client *c, const Arg *a, WebKitHitTestResult *h); | |
+ | |
+static char winid[64]; | |
+static char togglestats[10]; | |
+static char pagestats[2]; | |
+static Atom atoms[AtomLast]; | |
+static Window embed; | |
+static gboolean showxid = FALSE; | |
+static int cookiepolicy; | |
+static Display *dpy; | |
+static Client *clients; | |
+static char *stylefile; | |
+static const char *useragent; | |
+char *argv0; | |
/* configuration, allows nested code to access above variables */ | |
#include "config.h" | |
void | |
-addaccelgroup(Client *c) | |
+usage(void) | |
+{ | |
+ die("usage: %s [-bBdDfFgGiIkKmMnNpPsSvx] [-a cookiepolicies ] " | |
+ "[-c cookiefile] [-e xid] [-r scriptfile] [-t stylefile] " | |
+ "[-u useragent] [-z zoomlevel] [uri]\n", basename(argv0)); | |
+} | |
+ | |
+void | |
+die(const char *errstr, ...) | |
+{ | |
+ va_list ap; | |
+ | |
+ va_start(ap, errstr); | |
+ vfprintf(stderr, errstr, ap); | |
+ va_end(ap); | |
+ exit(EXIT_FAILURE); | |
+} | |
+ | |
+void | |
+setup(void) | |
{ | |
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); | |
+ /* clean up any zombies immediately */ | |
+ sigchld(0); | |
+ gtk_init(NULL, NULL); | |
+ | |
+ dpy = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); | |
+ | |
+ /* atoms */ | |
+ atoms[AtomFind] = XInternAtom(dpy, "_SURF_FIND", False); | |
+ atoms[AtomGo] = XInternAtom(dpy, "_SURF_GO", False); | |
+ atoms[AtomUri] = XInternAtom(dpy, "_SURF_URI", False); | |
+ | |
+ /* dirs and files */ | |
+ cookiefile = buildfile(cookiefile); | |
+ scriptfile = buildfile(scriptfile); | |
+ cachedir = buildpath(cachedir); | |
+ | |
+ if (stylefile == NULL) { | |
+ styledir = buildpath(styledir); | |
+ for (i = 0; i < LENGTH(styles); i++) { | |
+ if (regcomp(&(styles[i].re), styles[i].regex, | |
+ REG_EXTENDED)) { | |
+ fprintf(stderr, | |
+ "Could not compile regex: %s\n", | |
+ styles[i].regex); | |
+ styles[i].regex = NULL; | |
+ } | |
+ styles[i].style = g_strconcat(styledir, "/", | |
+ styles[i].style, NULL); | |
+ } | |
+ g_free(styledir); | |
+ } else { | |
+ stylefile = buildfile(stylefile); | |
} | |
- gtk_window_add_accel_group(GTK_WINDOW(c->win), group); | |
+} | |
+ | |
+void | |
+sigchld(int unused) | |
+{ | |
+ if (signal(SIGCHLD, sigchld) == SIG_ERR) | |
+ die("Can't install SIGCHLD handler"); | |
+ while (0 < waitpid(-1, NULL, WNOHANG)); | |
} | |
char * | |
t@@ -273,37 +324,161 @@ buildpath(const char *path) | |
return fpath; | |
} | |
-gboolean | |
-buttonreleased(GtkWidget *w, GdkEventKey *e, Client *c) | |
+Client * | |
+newclient(Client *rc) | |
{ | |
- WebKitHitTestResultContext element; | |
- GdkEventButton *eb = (GdkEventButton*)e; | |
- int i; | |
+ Client *c; | |
- element = webkit_hit_test_result_get_context(c->mousepos); | |
+ if (!(c = calloc(1, sizeof(Client)))) | |
+ die("Cannot malloc!\n"); | |
- for (i = 0; i < LENGTH(buttons); ++i) { | |
- if (element & buttons[i].target && | |
- eb->button == buttons[i].button && | |
- CLEANMASK(eb->state) == CLEANMASK(buttons[i].mask) && | |
- buttons[i].func) { | |
- buttons[i].func(c, &buttons[i].arg, c->mousepos); | |
- return buttons[i].stopevent; | |
- } | |
- } | |
+ c->title = NULL; | |
+ c->progress = 100; | |
- return FALSE; | |
+ c->next = clients; | |
+ clients = c; | |
+ | |
+ c->view = newview(c, rc ? rc->view : NULL); | |
+ c->tlsflags = G_TLS_CERTIFICATE_VALIDATE_ALL + 1; | |
+ | |
+ return c; | |
} | |
void | |
-cleanup(void) | |
+addaccelgroup(Client *c) | |
{ | |
- while (clients) | |
- destroyclient(clients); | |
- g_free(cookiefile); | |
- g_free(scriptfile); | |
- g_free(stylefile); | |
- g_free(cachedir); | |
+ 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) | |
+{ | |
+ struct stat st; | |
+ char *url, *path; | |
+ const char *uri = (char *)a->v; | |
+ | |
+ if (g_strcmp0(uri, "") == 0) | |
+ return; | |
+ | |
+ if (g_strrstr(uri, "://") || g_str_has_prefix(uri, "about:")) { | |
+ url = g_strdup(uri); | |
+ } else if (!stat(uri, &st) && (path = realpath(uri, NULL))) { | |
+ url = g_strdup_printf("file://%s", path); | |
+ free(path); | |
+ } else { | |
+ url = g_strdup_printf("http://%s", uri); | |
+ } | |
+ | |
+ setatom(c, AtomUri, url); | |
+ | |
+ if (strcmp(url, geturi(c)) == 0) { | |
+ reload(c, a); | |
+ } else { | |
+ webkit_web_view_load_uri(c->view, url); | |
+ c->title = geturi(c); | |
+ updatetitle(c); | |
+ } | |
+ | |
+ g_free(url); | |
+} | |
+ | |
+char * | |
+geturi(Client *c) | |
+{ | |
+ char *uri; | |
+ | |
+ if (!(uri = (char *)webkit_web_view_get_uri(c->view))) | |
+ uri = "about:blank"; | |
+ return uri; | |
+} | |
+ | |
+void | |
+setatom(Client *c, int a, const char *v) | |
+{ | |
+ XSync(dpy, False); | |
+ XChangeProperty(dpy, c->xid, | |
+ atoms[a], XA_STRING, 8, PropModeReplace, | |
+ (unsigned char *)v, strlen(v) + 1); | |
+} | |
+ | |
+const char * | |
+getatom(Client *c, int a) | |
+{ | |
+ static char buf[BUFSIZ]; | |
+ Atom adummy; | |
+ int idummy; | |
+ unsigned long ldummy; | |
+ unsigned char *p = NULL; | |
+ | |
+ XGetWindowProperty(dpy, c->xid, | |
+ atoms[a], 0L, BUFSIZ, False, XA_STRING, | |
+ &adummy, &idummy, &ldummy, &ldummy, &p); | |
+ if (p) | |
+ strncpy(buf, (char *)p, LENGTH(buf)-1); | |
+ else | |
+ buf[0] = '\0'; | |
+ XFree(p); | |
+ | |
+ return buf; | |
+} | |
+ | |
+void | |
+updatetitle(Client *c) | |
+{ | |
+ char *title; | |
+ | |
+ if (showindicators) { | |
+ gettogglestats(c); | |
+ getpagestats(c); | |
+ | |
+ if (c->progress != 100) { | |
+ title = g_strdup_printf("[%i%%] %s:%s | %s", | |
+ c->progress, togglestats, pagestats, | |
+ c->targeturi ? c->targeturi : c->title); | |
+ } else { | |
+ title = g_strdup_printf("%s:%s | %s", | |
+ togglestats, pagestats, | |
+ c->targeturi ? c->targeturi : c->title); | |
+ } | |
+ | |
+ 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 : ""); | |
+ } | |
+} | |
+ | |
+void | |
+gettogglestats(Client *c) | |
+{ | |
+ togglestats[0] = cookiepolicy_set(cookiepolicy_get()); | |
+ togglestats[1] = enablecaretbrowsing ? 'C' : 'c'; | |
+ togglestats[2] = allowgeolocation ? 'G' : 'g'; | |
+ togglestats[3] = enablecache ? 'D' : 'd'; | |
+ togglestats[4] = loadimages ? 'I' : 'i'; | |
+ togglestats[5] = enablescripts ? 'S': 's'; | |
+ togglestats[6] = enableplugins ? 'V' : 'v'; | |
+ togglestats[7] = enablestyle ? 'M' : 'm'; | |
+ togglestats[8] = enableframeflattening ? 'F' : 'f'; | |
+ togglestats[9] = '\0'; | |
+} | |
+ | |
+void | |
+getpagestats(Client *c) | |
+{ | |
+ pagestats[0] = c->tlsflags > G_TLS_CERTIFICATE_VALIDATE_ALL ? '-' : | |
+ c->tlsflags > 0 ? 'U' : 'T'; | |
+ pagestats[1] = '\0'; | |
} | |
WebKitCookieAcceptPolicy | |
t@@ -338,18 +513,41 @@ cookiepolicy_set(const WebKitCookieAcceptPolicy ep) | |
return 'A'; | |
} | |
+const gchar * | |
+getstyle(const char *uri) | |
+{ | |
+ int i; | |
+ | |
+ if (stylefile != NULL) | |
+ return stylefile; | |
+ | |
+ for (i = 0; i < LENGTH(styles); i++) { | |
+ if (styles[i].regex && !regexec(&(styles[i].re), uri, 0, | |
+ NULL, 0)) | |
+ return styles[i].style; | |
+ } | |
+ | |
+ return ""; | |
+} | |
+ | |
void | |
-evalscript(Client *c, const char *jsstr, ...) | |
+setstyle(Client *c, const char *stylefile) | |
{ | |
- va_list ap; | |
- gchar *script; | |
+ gchar *style; | |
- va_start(ap, jsstr); | |
- script = g_strdup_vprintf(jsstr, ap); | |
- va_end(ap); | |
+ if (!g_file_get_contents(stylefile, &style, NULL, NULL)) { | |
+ fprintf(stderr, "Could not read style file: %s\n", stylefile); | |
+ return; | |
+ } | |
- webkit_web_view_run_javascript(c->view, script, NULL, NULL, NULL); | |
- g_free(script); | |
+ webkit_user_content_manager_add_style_sheet( | |
+ webkit_web_view_get_user_content_manager(c->view), | |
+ webkit_user_style_sheet_new(style, | |
+ WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, | |
+ WEBKIT_USER_STYLE_LEVEL_USER, | |
+ NULL, NULL)); | |
+ | |
+ g_free(style); | |
} | |
void | |
t@@ -364,517 +562,129 @@ runscript(Client *c) | |
} | |
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); | |
- } | |
-} | |
- | |
-GtkWidget * | |
-createview(WebKitWebView *v, WebKitNavigationAction *a, Client *c) | |
+evalscript(Client *c, const char *jsstr, ...) | |
{ | |
- Client *n; | |
+ va_list ap; | |
+ gchar *script; | |
- switch (webkit_navigation_action_get_navigation_type(a)) { | |
- case WEBKIT_NAVIGATION_TYPE_OTHER: /* fallthrough */ | |
- /* | |
- * popup windows of type “other” are almost always trigger… | |
- * by user gesture, so inverse the logic here | |
- */ | |
-/* instead of this, compare destination uri to mouse-over uri for validating w… | |
- if (webkit_navigation_action_is_user_gesture(a)) { | |
- return NULL; | |
- break; | |
- } | |
- 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: | |
- n = newclient(c); | |
- break; | |
- default: | |
- return NULL; | |
- break; | |
- } | |
+ va_start(ap, jsstr); | |
+ script = g_strdup_vprintf(jsstr, ap); | |
+ va_end(ap); | |
- return GTK_WIDGET(n->view); | |
+ webkit_web_view_run_javascript(c->view, script, NULL, NULL, NULL); | |
+ g_free(script); | |
} | |
-gboolean | |
-decidepolicy(WebKitWebView *v, WebKitPolicyDecision *d, | |
- WebKitPolicyDecisionType dt, Client *c) | |
+void | |
+updatewinid(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; | |
+ snprintf(winid, LENGTH(winid), "%lu", c->xid); | |
} | |
void | |
-decidenavigation(WebKitPolicyDecision *d, Client *c) | |
+handleplumb(Client *c, const gchar *uri) | |
{ | |
- WebKitNavigationAction *a; | |
+ Arg arg; | |
- 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: | |
- 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 windo… | |
- * on Ctrl+Click ? */ | |
- webkit_policy_decision_use(d); | |
- } | |
- break; | |
- } | |
-} | |
- | |
-void | |
-decidenewwindow(WebKitPolicyDecision *d, Client *c) | |
-{ | |
- WebKitNavigationAction *a; | |
- Arg arg; | |
- | |
- 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 trigge… | |
- * 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) | |
-{ | |
- const gchar *uri; | |
- int i, isascii = 1; | |
- WebKitResponsePolicyDecision *r = WEBKIT_RESPONSE_POLICY_DECISION(d); | |
- WebKitURIResponse *res; | |
- | |
- res = webkit_response_policy_decision_get_response(r); | |
- 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_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); | |
- } | |
- } | |
- | |
- 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 | |
-destroyclient(Client *c) | |
-{ | |
- Client *p; | |
- | |
- webkit_web_view_stop_loading(c->view); | |
- /* Not needed, has already been called | |
- gtk_widget_destroy(c->win); | |
- */ | |
- | |
- for (p = clients; p && p->next != c; p = p->next) | |
- ; | |
- if (p) | |
- p->next = c->next; | |
- else | |
- clients = c->next; | |
- free(c); | |
-} | |
- | |
-void | |
-closeview(WebKitWebView *v, Client *c) | |
-{ | |
- gtk_widget_destroy(c->win); | |
-} | |
- | |
-void | |
-destroywin(GtkWidget* w, Client *c) | |
-{ | |
- destroyclient(c); | |
- if (clients == NULL) | |
- gtk_main_quit(); | |
-} | |
- | |
-void | |
-die(const char *errstr, ...) | |
-{ | |
- va_list ap; | |
- | |
- va_start(ap, errstr); | |
- vfprintf(stderr, errstr, ap); | |
- va_end(ap); | |
- exit(EXIT_FAILURE); | |
-} | |
- | |
-void | |
-find(Client *c, const Arg *a) | |
-{ | |
- const char *s, *f; | |
- | |
- if (a && a->i) { | |
- if (a->i > 0) | |
- webkit_find_controller_search_next(c->finder); | |
- else | |
- webkit_find_controller_search_previous(c->finder); | |
- } else { | |
- s = getatom(c, AtomFind); | |
- f = webkit_find_controller_get_search_text(c->finder); | |
- | |
- if (g_strcmp0(f, s) == 0) /* reset search */ | |
- webkit_find_controller_search(c->finder, "", findopts,… | |
- | |
- webkit_find_controller_search(c->finder, s, findopts, G_MAXUIN… | |
- | |
- if (strcmp(s, "") == 0) | |
- webkit_find_controller_search_finish(c->finder); | |
- } | |
-} | |
- | |
-void | |
-togglefullscreen(Client *c, const Arg *a) | |
-{ | |
- /* toggling value is handled in winevent() */ | |
- if (c->fullscreen) | |
- gtk_window_unfullscreen(GTK_WINDOW(c->win)); | |
- else | |
- gtk_window_fullscreen(GTK_WINDOW(c->win)); | |
-} | |
- | |
-gboolean | |
-permissionrequested(WebKitWebView *v, WebKitPermissionRequest *r, Client *c) | |
-{ | |
- if (WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST(r)) { | |
- if (allowgeolocation) | |
- webkit_permission_request_allow(r); | |
- else | |
- webkit_permission_request_deny(r); | |
- return TRUE; | |
- } | |
- | |
- return FALSE; | |
-} | |
- | |
-const char * | |
-getatom(Client *c, int a) | |
-{ | |
- static char buf[BUFSIZ]; | |
- Atom adummy; | |
- int idummy; | |
- unsigned long ldummy; | |
- unsigned char *p = NULL; | |
- | |
- XGetWindowProperty(dpy, c->xid, | |
- atoms[a], 0L, BUFSIZ, False, XA_STRING, | |
- &adummy, &idummy, &ldummy, &ldummy, &p); | |
- if (p) | |
- strncpy(buf, (char *)p, LENGTH(buf)-1); | |
- else | |
- buf[0] = '\0'; | |
- XFree(p); | |
- | |
- return buf; | |
-} | |
- | |
-char * | |
-geturi(Client *c) | |
-{ | |
- char *uri; | |
- | |
- if (!(uri = (char *)webkit_web_view_get_uri(c->view))) | |
- uri = "about:blank"; | |
- return uri; | |
-} | |
- | |
-const gchar * | |
-getstyle(const char *uri) | |
-{ | |
- int i; | |
- | |
- if (stylefile != NULL) | |
- return stylefile; | |
- | |
- for (i = 0; i < LENGTH(styles); i++) { | |
- if (styles[i].regex && !regexec(&(styles[i].re), uri, 0, | |
- NULL, 0)) | |
- return styles[i].style; | |
- } | |
- | |
- return ""; | |
-} | |
+ arg = (Arg)PLUMB(uri); | |
+ spawn(c, &arg); | |
+} | |
void | |
-setstyle(Client *c, const char *stylefile) | |
-{ | |
- gchar *style; | |
- | |
- if (!g_file_get_contents(stylefile, &style, NULL, NULL)) { | |
- fprintf(stderr, "Could not read style file: %s\n", stylefile); | |
- return; | |
- } | |
- | |
- webkit_user_content_manager_add_style_sheet( | |
- webkit_web_view_get_user_content_manager(c->view), | |
- webkit_user_style_sheet_new(style, | |
- WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, | |
- WEBKIT_USER_STYLE_LEVEL_USER, | |
- NULL, NULL)); | |
- | |
- g_free(style); | |
-} | |
- | |
-void | |
-handleplumb(Client *c, const gchar *uri) | |
-{ | |
- Arg arg; | |
- | |
- arg = (Arg)PLUMB(uri); | |
- spawn(c, &arg); | |
-} | |
- | |
-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) | |
+newwindow(Client *c, const Arg *a, int noembed) | |
{ | |
- Arg a; | |
- | |
- a = (Arg)DOWNLOAD(webkit_uri_response_get_uri(r), geturi(c)); | |
- spawn(c, &a); | |
-} | |
+ int i = 0; | |
+ char tmp[64]; | |
+ const char *cmd[26], *uri; | |
+ const Arg arg = { .v = cmd }; | |
-void | |
-toggleinspector(Client *c, const Arg *a) | |
-{ | |
- if (enableinspector) { | |
- if (webkit_web_inspector_is_attached(c->inspector)) | |
- webkit_web_inspector_close(c->inspector); | |
- else | |
- webkit_web_inspector_show(c->inspector); | |
+ cmd[i++] = argv0; | |
+ cmd[i++] = "-a"; | |
+ cmd[i++] = cookiepolicies; | |
+ cmd[i++] = enablescrollbars ? "-B" : "-b"; | |
+ if (cookiefile && g_strcmp0(cookiefile, "")) { | |
+ cmd[i++] = "-c"; | |
+ cmd[i++] = cookiefile; | |
} | |
-} | |
- | |
-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; | |
- } | |
+ cmd[i++] = enablecache ? "-D" : "-d"; | |
+ if (embed && !noembed) { | |
+ cmd[i++] = "-e"; | |
+ snprintf(tmp, LENGTH(tmp), "%lu", embed); | |
+ cmd[i++] = tmp; | |
} | |
- | |
- return processed; | |
-} | |
- | |
-void | |
-mousetargetchanged(WebKitWebView *v, WebKitHitTestResult *h, guint modifiers, | |
- Client *c) | |
-{ | |
- WebKitHitTestResultContext hc; | |
- | |
- /* Keep the hit test to know where is the pointer on the next click */ | |
- c->mousepos = h; | |
- | |
- hc = webkit_hit_test_result_get_context(h); | |
- | |
- if (hc & OnLink) | |
- c->targeturi = webkit_hit_test_result_get_link_uri(h); | |
- else if (hc & OnImg) | |
- c->targeturi = webkit_hit_test_result_get_image_uri(h); | |
- else if (hc & OnMedia) | |
- c->targeturi = webkit_hit_test_result_get_media_uri(h); | |
- else | |
- c->targeturi = NULL; | |
- updatetitle(c); | |
-} | |
- | |
-void | |
-loadchanged(WebKitWebView *v, WebKitLoadEvent e, Client *c) | |
-{ | |
- switch (e) { | |
- case WEBKIT_LOAD_STARTED: | |
- c->tlsflags = G_TLS_CERTIFICATE_VALIDATE_ALL + 1; | |
- break; | |
- case WEBKIT_LOAD_REDIRECTED: | |
- setatom(c, AtomUri, geturi(c)); | |
- break; | |
- case WEBKIT_LOAD_COMMITTED: | |
- if (!webkit_web_view_get_tls_info(c->view, NULL, &(c->tlsflags… | |
- c->tlsflags = G_TLS_CERTIFICATE_VALIDATE_ALL + 1; | |
- | |
- setatom(c, AtomUri, geturi(c)); | |
- | |
- if (enablestyle) | |
- setstyle(c, getstyle(geturi(c))); | |
- break; | |
- case WEBKIT_LOAD_FINISHED: | |
- /* Disabled until we write some WebKitWebExtension for | |
- * manipulating the DOM directly. | |
- evalscript(c, "document.documentElement.style.overflow = '%s'", | |
- enablescrollbars ? "auto" : "hidden"); | |
- */ | |
- runscript(c); | |
- break; | |
+ cmd[i++] = runinfullscreen ? "-F" : "-f"; | |
+ cmd[i++] = allowgeolocation ? "-G" : "-g"; | |
+ cmd[i++] = loadimages ? "-I" : "-i"; | |
+ cmd[i++] = kioskmode ? "-K" : "-k"; | |
+ cmd[i++] = enablestyle ? "-M" : "-m"; | |
+ cmd[i++] = enableinspector ? "-N" : "-n"; | |
+ cmd[i++] = enableplugins ? "-P" : "-p"; | |
+ if (scriptfile && g_strcmp0(scriptfile, "")) { | |
+ cmd[i++] = "-r"; | |
+ cmd[i++] = scriptfile; | |
} | |
- updatetitle(c); | |
-} | |
- | |
-void | |
-loaduri(Client *c, const Arg *a) | |
-{ | |
- struct stat st; | |
- char *url, *path; | |
- const char *uri = (char *)a->v; | |
- | |
- if (g_strcmp0(uri, "") == 0) | |
- return; | |
- | |
- if (g_strrstr(uri, "://") || g_str_has_prefix(uri, "about:")) { | |
- url = g_strdup(uri); | |
- } else if (!stat(uri, &st) && (path = realpath(uri, NULL))) { | |
- url = g_strdup_printf("file://%s", path); | |
- free(path); | |
- } else { | |
- url = g_strdup_printf("http://%s", uri); | |
+ cmd[i++] = enablescripts ? "-S" : "-s"; | |
+ if (stylefile && g_strcmp0(stylefile, "")) { | |
+ cmd[i++] = "-t"; | |
+ cmd[i++] = stylefile; | |
} | |
- | |
- setatom(c, AtomUri, url); | |
- | |
- if (strcmp(url, geturi(c)) == 0) { | |
- reload(c, a); | |
- } else { | |
- webkit_web_view_load_uri(c->view, url); | |
- c->title = geturi(c); | |
- updatetitle(c); | |
+ if (fulluseragent && g_strcmp0(fulluseragent, "")) { | |
+ cmd[i++] = "-u"; | |
+ cmd[i++] = fulluseragent; | |
} | |
- | |
- g_free(url); | |
-} | |
- | |
-void | |
-navigate(Client *c, const Arg *a) | |
-{ | |
- if (a->i < 0) | |
- webkit_web_view_go_back(c->view); | |
- else if (a->i > 0) | |
- webkit_web_view_go_forward(c->view); | |
+ if (showxid) | |
+ cmd[i++] = "-x"; | |
+ /* do not keep zoom level */ | |
+ cmd[i++] = "--"; | |
+ if ((uri = a->v)) | |
+ cmd[i++] = uri; | |
+ cmd[i] = NULL; | |
+ | |
+ spawn(c, &arg); | |
} | |
void | |
-clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h) | |
+spawn(Client *c, const Arg *arg) | |
{ | |
- navigate(c, a); | |
+ if (fork() == 0) { | |
+ if (dpy) | |
+ close(ConnectionNumber(dpy)); | |
+ setsid(); | |
+ execvp(((char **)arg->v)[0], (char **)arg->v); | |
+ fprintf(stderr, "surf: execvp %s", ((char **)arg->v)[0]); | |
+ perror(" failed"); | |
+ exit(0); | |
+ } | |
} | |
-Client * | |
-newclient(Client *rc) | |
+void | |
+destroyclient(Client *c) | |
{ | |
- Client *c; | |
- | |
- if (!(c = calloc(1, sizeof(Client)))) | |
- die("Cannot malloc!\n"); | |
- | |
- c->title = NULL; | |
- c->progress = 100; | |
+ Client *p; | |
- c->next = clients; | |
- clients = c; | |
+ webkit_web_view_stop_loading(c->view); | |
+ /* Not needed, has already been called | |
+ gtk_widget_destroy(c->win); | |
+ */ | |
- c->view = newview(c, rc ? rc->view : NULL); | |
- c->tlsflags = G_TLS_CERTIFICATE_VALIDATE_ALL + 1; | |
+ for (p = clients; p && p->next != c; p = p->next) | |
+ ; | |
+ if (p) | |
+ p->next = c->next; | |
+ else | |
+ clients = c->next; | |
+ free(c); | |
+} | |
- return c; | |
+void | |
+cleanup(void) | |
+{ | |
+ while (clients) | |
+ destroyclient(clients); | |
+ g_free(cookiefile); | |
+ g_free(scriptfile); | |
+ g_free(stylefile); | |
+ g_free(cachedir); | |
} | |
WebKitWebView * | |
t@@ -983,109 +793,178 @@ newview(Client *c, WebKitWebView *rv) | |
return v; | |
} | |
-void | |
-showview(WebKitWebView *v, Client *c) | |
+GtkWidget * | |
+createview(WebKitWebView *v, WebKitNavigationAction *a, Client *c) | |
{ | |
- GdkGeometry hints = { 1, 1 }; | |
- GdkRGBA bgcolor = { 0 }; | |
- GdkWindow *gwin; | |
+ Client *n; | |
- c->win = createwindow(c); | |
+ switch (webkit_navigation_action_get_navigation_type(a)) { | |
+ case WEBKIT_NAVIGATION_TYPE_OTHER: /* fallthrough */ | |
+ /* | |
+ * popup windows of type “other” are almost always trigger… | |
+ * by user gesture, so inverse the logic here | |
+ */ | |
+/* instead of this, compare destination uri to mouse-over uri for validating w… | |
+ if (webkit_navigation_action_is_user_gesture(a)) { | |
+ return NULL; | |
+ break; | |
+ } | |
+ 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: | |
+ n = newclient(c); | |
+ break; | |
+ default: | |
+ return NULL; | |
+ break; | |
+ } | |
- if (enableinspector) | |
- c->inspector = webkit_web_view_get_inspector(c->view); | |
+ return GTK_WIDGET(n->view); | |
+} | |
- c->finder = webkit_web_view_get_find_controller(c->view); | |
+gboolean | |
+buttonreleased(GtkWidget *w, GdkEventKey *e, Client *c) | |
+{ | |
+ WebKitHitTestResultContext element; | |
+ GdkEventButton *eb = (GdkEventButton*)e; | |
+ int i; | |
- if (!kioskmode) | |
- addaccelgroup(c); | |
+ element = webkit_hit_test_result_get_context(c->mousepos); | |
- /* Arranging */ | |
- gtk_container_add(GTK_CONTAINER(c->win), GTK_WIDGET(c->view)); | |
+ for (i = 0; i < LENGTH(buttons); ++i) { | |
+ if (element & buttons[i].target && | |
+ eb->button == buttons[i].button && | |
+ CLEANMASK(eb->state) == CLEANMASK(buttons[i].mask) && | |
+ buttons[i].func) { | |
+ buttons[i].func(c, &buttons[i].arg, c->mousepos); | |
+ return buttons[i].stopevent; | |
+ } | |
+ } | |
- /* Setup */ | |
- gtk_widget_grab_focus(GTK_WIDGET(c->view)); | |
- gtk_widget_show(GTK_WIDGET(c->view)); | |
- gtk_widget_show(c->win); | |
- gwin = gtk_widget_get_window(GTK_WIDGET(c->win)); | |
- c->xid = gdk_x11_window_get_xid(gwin); | |
- gtk_window_set_geometry_hints(GTK_WINDOW(c->win), NULL, &hints, | |
- GDK_HINT_MIN_SIZE); | |
- gdk_window_set_events(gwin, GDK_ALL_EVENTS_MASK); | |
- gdk_window_add_filter(gwin, processx, c); | |
+ return FALSE; | |
+} | |
- if (zoomlevel != 1.0) | |
- webkit_web_view_set_zoom_level(c->view, zoomlevel); | |
+gboolean | |
+keypress(GtkAccelGroup *group, GObject *obj, guint key, GdkModifierType mods, | |
+ Client *c) | |
+{ | |
+ guint i; | |
+ gboolean processed = FALSE; | |
- if (runinfullscreen) | |
- togglefullscreen(c, NULL); | |
+ 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; | |
+ } | |
+ } | |
- setatom(c, AtomFind, ""); | |
- setatom(c, AtomUri, "about:blank"); | |
- if (hidebackground) | |
- webkit_web_view_set_background_color(c->view, &bgcolor); | |
+ return processed; | |
+} | |
- if (showxid) { | |
- gdk_display_sync(gtk_widget_get_display(c->win)); | |
- printf("%lu\n", c->xid); | |
- fflush(NULL); | |
- if (fclose(stdout) != 0) { | |
- die("Error closing stdout"); | |
- } | |
+GdkFilterReturn | |
+processx(GdkXEvent *e, GdkEvent *event, gpointer d) | |
+{ | |
+ Client *c = (Client *)d; | |
+ XPropertyEvent *ev; | |
+ Arg arg; | |
+ | |
+ if (((XEvent *)e)->type == PropertyNotify) { | |
+ ev = &((XEvent *)e)->xproperty; | |
+ if (ev->state == PropertyNewValue) { | |
+ if (ev->atom == atoms[AtomFind]) { | |
+ find(c, NULL); | |
+ | |
+ return GDK_FILTER_REMOVE; | |
+ } else if (ev->atom == atoms[AtomGo]) { | |
+ arg.v = getatom(c, AtomGo); | |
+ loaduri(c, &arg); | |
+ | |
+ return GDK_FILTER_REMOVE; | |
+ } | |
+ } | |
+ } | |
+ return GDK_FILTER_CONTINUE; | |
+} | |
+ | |
+gboolean | |
+winevent(GtkWidget *w, GdkEvent *e, Client *c) | |
+{ | |
+ switch (e->type) { | |
+ case GDK_LEAVE_NOTIFY: | |
+ c->targeturi = NULL; | |
+ updatetitle(c); | |
+ break; | |
+ case GDK_WINDOW_STATE: /* fallthrough */ | |
+ if (e->window_state.changed_mask == | |
+ GDK_WINDOW_STATE_FULLSCREEN) { | |
+ c->fullscreen = e->window_state.new_window_state & | |
+ GDK_WINDOW_STATE_FULLSCREEN; | |
+ break; | |
+ } | |
+ default: | |
+ return FALSE; | |
} | |
+ | |
+ return TRUE; | |
} | |
void | |
-newwindow(Client *c, const Arg *a, int noembed) | |
+showview(WebKitWebView *v, Client *c) | |
{ | |
- int i = 0; | |
- char tmp[64]; | |
- const char *cmd[26], *uri; | |
- const Arg arg = { .v = cmd }; | |
+ GdkGeometry hints = { 1, 1 }; | |
+ GdkRGBA bgcolor = { 0 }; | |
+ GdkWindow *gwin; | |
- cmd[i++] = argv0; | |
- cmd[i++] = "-a"; | |
- cmd[i++] = cookiepolicies; | |
- cmd[i++] = enablescrollbars ? "-B" : "-b"; | |
- if (cookiefile && g_strcmp0(cookiefile, "")) { | |
- cmd[i++] = "-c"; | |
- cmd[i++] = cookiefile; | |
- } | |
- cmd[i++] = enablecache ? "-D" : "-d"; | |
- if (embed && !noembed) { | |
- cmd[i++] = "-e"; | |
- snprintf(tmp, LENGTH(tmp), "%lu", embed); | |
- cmd[i++] = tmp; | |
- } | |
- cmd[i++] = runinfullscreen ? "-F" : "-f"; | |
- cmd[i++] = allowgeolocation ? "-G" : "-g"; | |
- cmd[i++] = loadimages ? "-I" : "-i"; | |
- cmd[i++] = kioskmode ? "-K" : "-k"; | |
- cmd[i++] = enablestyle ? "-M" : "-m"; | |
- cmd[i++] = enableinspector ? "-N" : "-n"; | |
- cmd[i++] = enableplugins ? "-P" : "-p"; | |
- if (scriptfile && g_strcmp0(scriptfile, "")) { | |
- cmd[i++] = "-r"; | |
- cmd[i++] = scriptfile; | |
- } | |
- cmd[i++] = enablescripts ? "-S" : "-s"; | |
- if (stylefile && g_strcmp0(stylefile, "")) { | |
- cmd[i++] = "-t"; | |
- cmd[i++] = stylefile; | |
- } | |
- if (fulluseragent && g_strcmp0(fulluseragent, "")) { | |
- cmd[i++] = "-u"; | |
- cmd[i++] = fulluseragent; | |
- } | |
- if (showxid) | |
- cmd[i++] = "-x"; | |
- /* do not keep zoom level */ | |
- cmd[i++] = "--"; | |
- if ((uri = a->v)) | |
- cmd[i++] = uri; | |
- cmd[i] = NULL; | |
+ c->win = createwindow(c); | |
+ | |
+ if (enableinspector) | |
+ c->inspector = webkit_web_view_get_inspector(c->view); | |
+ | |
+ c->finder = webkit_web_view_get_find_controller(c->view); | |
+ | |
+ if (!kioskmode) | |
+ addaccelgroup(c); | |
- spawn(c, &arg); | |
+ /* Arranging */ | |
+ gtk_container_add(GTK_CONTAINER(c->win), GTK_WIDGET(c->view)); | |
+ | |
+ /* Setup */ | |
+ gtk_widget_grab_focus(GTK_WIDGET(c->view)); | |
+ gtk_widget_show(GTK_WIDGET(c->view)); | |
+ gtk_widget_show(c->win); | |
+ gwin = gtk_widget_get_window(GTK_WIDGET(c->win)); | |
+ c->xid = gdk_x11_window_get_xid(gwin); | |
+ gtk_window_set_geometry_hints(GTK_WINDOW(c->win), NULL, &hints, | |
+ GDK_HINT_MIN_SIZE); | |
+ gdk_window_set_events(gwin, GDK_ALL_EVENTS_MASK); | |
+ gdk_window_add_filter(gwin, processx, c); | |
+ | |
+ if (zoomlevel != 1.0) | |
+ webkit_web_view_set_zoom_level(c->view, zoomlevel); | |
+ | |
+ if (runinfullscreen) | |
+ togglefullscreen(c, NULL); | |
+ | |
+ setatom(c, AtomFind, ""); | |
+ setatom(c, AtomUri, "about:blank"); | |
+ if (hidebackground) | |
+ webkit_web_view_set_background_color(c->view, &bgcolor); | |
+ | |
+ if (showxid) { | |
+ gdk_display_sync(gtk_widget_get_display(c->win)); | |
+ printf("%lu\n", c->xid); | |
+ fflush(NULL); | |
+ if (fclose(stdout) != 0) { | |
+ die("Error closing stdout"); | |
+ } | |
+ } | |
} | |
GtkWidget * | |
t@@ -1126,60 +1005,254 @@ createwindow(Client *c) | |
} | |
void | |
-pasteuri(GtkClipboard *clipboard, const char *text, gpointer d) | |
+loadchanged(WebKitWebView *v, WebKitLoadEvent e, Client *c) | |
{ | |
- Arg arg = {.v = text }; | |
- if (text != NULL) | |
- loaduri((Client *) d, &arg); | |
+ switch (e) { | |
+ case WEBKIT_LOAD_STARTED: | |
+ c->tlsflags = G_TLS_CERTIFICATE_VALIDATE_ALL + 1; | |
+ break; | |
+ case WEBKIT_LOAD_REDIRECTED: | |
+ setatom(c, AtomUri, geturi(c)); | |
+ break; | |
+ case WEBKIT_LOAD_COMMITTED: | |
+ if (!webkit_web_view_get_tls_info(c->view, NULL, &(c->tlsflags… | |
+ c->tlsflags = G_TLS_CERTIFICATE_VALIDATE_ALL + 1; | |
+ | |
+ setatom(c, AtomUri, geturi(c)); | |
+ | |
+ if (enablestyle) | |
+ setstyle(c, getstyle(geturi(c))); | |
+ break; | |
+ case WEBKIT_LOAD_FINISHED: | |
+ /* Disabled until we write some WebKitWebExtension for | |
+ * manipulating the DOM directly. | |
+ evalscript(c, "document.documentElement.style.overflow = '%s'", | |
+ enablescrollbars ? "auto" : "hidden"); | |
+ */ | |
+ runscript(c); | |
+ break; | |
+ } | |
+ updatetitle(c); | |
} | |
void | |
-print(Client *c, const Arg *a) | |
+progresschanged(WebKitWebView *v, GParamSpec *ps, Client *c) | |
{ | |
- webkit_print_operation_run_dialog(webkit_print_operation_new(c->view), | |
- GTK_WINDOW(c->win)); | |
+ c->progress = webkit_web_view_get_estimated_load_progress(c->view) * | |
+ 100; | |
+ updatetitle(c); | |
} | |
-GdkFilterReturn | |
-processx(GdkXEvent *e, GdkEvent *event, gpointer d) | |
+void | |
+titlechanged(WebKitWebView *view, GParamSpec *ps, Client *c) | |
{ | |
- Client *c = (Client *)d; | |
- XPropertyEvent *ev; | |
+ c->title = webkit_web_view_get_title(c->view); | |
+ updatetitle(c); | |
+} | |
+ | |
+void | |
+mousetargetchanged(WebKitWebView *v, WebKitHitTestResult *h, guint modifiers, | |
+ Client *c) | |
+{ | |
+ WebKitHitTestResultContext hc; | |
+ | |
+ /* Keep the hit test to know where is the pointer on the next click */ | |
+ c->mousepos = h; | |
+ | |
+ hc = webkit_hit_test_result_get_context(h); | |
+ | |
+ if (hc & OnLink) | |
+ c->targeturi = webkit_hit_test_result_get_link_uri(h); | |
+ else if (hc & OnImg) | |
+ c->targeturi = webkit_hit_test_result_get_image_uri(h); | |
+ else if (hc & OnMedia) | |
+ c->targeturi = webkit_hit_test_result_get_media_uri(h); | |
+ else | |
+ c->targeturi = NULL; | |
+ updatetitle(c); | |
+} | |
+ | |
+gboolean | |
+permissionrequested(WebKitWebView *v, WebKitPermissionRequest *r, Client *c) | |
+{ | |
+ if (WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST(r)) { | |
+ if (allowgeolocation) | |
+ 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; | |
+ | |
+ 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: | |
+ 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 windo… | |
+ * on Ctrl+Click ? */ | |
+ webkit_policy_decision_use(d); | |
+ } | |
+ break; | |
+ } | |
+} | |
+ | |
+void | |
+decidenewwindow(WebKitPolicyDecision *d, Client *c) | |
+{ | |
+ WebKitNavigationAction *a; | |
Arg arg; | |
- if (((XEvent *)e)->type == PropertyNotify) { | |
- ev = &((XEvent *)e)->xproperty; | |
- if (ev->state == PropertyNewValue) { | |
- if (ev->atom == atoms[AtomFind]) { | |
- find(c, NULL); | |
+ 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 trigge… | |
+ * 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) | |
+{ | |
+ const gchar *uri; | |
+ int i, isascii = 1; | |
+ WebKitResponsePolicyDecision *r = WEBKIT_RESPONSE_POLICY_DECISION(d); | |
+ WebKitURIResponse *res; | |
+ | |
+ res = webkit_response_policy_decision_get_response(r); | |
+ 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_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); | |
+ } | |
+ } | |
+ | |
+ 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 | |
+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); | |
+} | |
- return GDK_FILTER_REMOVE; | |
- } else if (ev->atom == atoms[AtomGo]) { | |
- arg.v = getatom(c, AtomGo); | |
- loaduri(c, &arg); | |
+void | |
+download(Client *c, WebKitURIResponse *r) | |
+{ | |
+ Arg a; | |
- return GDK_FILTER_REMOVE; | |
- } | |
- } | |
- } | |
- return GDK_FILTER_CONTINUE; | |
+ a = (Arg)DOWNLOAD(webkit_uri_response_get_uri(r), geturi(c)); | |
+ spawn(c, &a); | |
} | |
void | |
-progresschanged(WebKitWebView *v, GParamSpec *ps, Client *c) | |
+closeview(WebKitWebView *v, Client *c) | |
{ | |
- c->progress = webkit_web_view_get_estimated_load_progress(c->view) * | |
- 100; | |
- updatetitle(c); | |
+ gtk_widget_destroy(c->win); | |
} | |
void | |
-clicknewwindow(Client *c, const Arg *a, WebKitHitTestResult *h) | |
+destroywin(GtkWidget* w, Client *c) | |
{ | |
- Arg arg; | |
+ destroyclient(c); | |
+ if (clients == NULL) | |
+ gtk_main_quit(); | |
+} | |
- arg.v = webkit_hit_test_result_get_link_uri(h); | |
- newwindow(c, &arg, a->b); | |
+void | |
+pasteuri(GtkClipboard *clipboard, const char *text, gpointer d) | |
+{ | |
+ Arg arg = {.v = text }; | |
+ if (text != NULL) | |
+ loaduri((Client *) d, &arg); | |
} | |
void | |
t@@ -1193,88 +1266,60 @@ reload(Client *c, const Arg *arg) | |
} | |
void | |
-scroll_h(Client *c, const Arg *a) | |
+print(Client *c, const Arg *a) | |
{ | |
- evalscript(c, "window.scrollBy(%d * (window.innerWidth / 100), 0)", | |
- a->i); | |
+ webkit_print_operation_run_dialog(webkit_print_operation_new(c->view), | |
+ GTK_WINDOW(c->win)); | |
} | |
void | |
-scroll_v(Client *c, const Arg *a) | |
+clipboard(Client *c, const Arg *a) | |
{ | |
- evalscript(c, "window.scrollBy(0, %d * (window.innerHeight / 100))", | |
- a->i); | |
+ 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 | |
-setatom(Client *c, int a, const char *v) | |
+zoom(Client *c, const Arg *a) | |
{ | |
- XSync(dpy, False); | |
- XChangeProperty(dpy, c->xid, | |
- atoms[a], XA_STRING, 8, PropModeReplace, | |
- (unsigned char *)v, strlen(v) + 1); | |
+ if (a->i > 0) | |
+ webkit_web_view_set_zoom_level(c->view, zoomlevel + 0.1); | |
+ else if (a->i < 0) | |
+ webkit_web_view_set_zoom_level(c->view, zoomlevel - 0.1); | |
+ else | |
+ webkit_web_view_set_zoom_level(c->view, 1.0); | |
+ | |
+ zoomlevel = webkit_web_view_get_zoom_level(c->view); | |
} | |
void | |
-setup(void) | |
+scroll_v(Client *c, const Arg *a) | |
{ | |
- int i; | |
- | |
- /* clean up any zombies immediately */ | |
- sigchld(0); | |
- gtk_init(NULL, NULL); | |
- | |
- dpy = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); | |
- | |
- /* atoms */ | |
- atoms[AtomFind] = XInternAtom(dpy, "_SURF_FIND", False); | |
- atoms[AtomGo] = XInternAtom(dpy, "_SURF_GO", False); | |
- atoms[AtomUri] = XInternAtom(dpy, "_SURF_URI", False); | |
- | |
- /* dirs and files */ | |
- cookiefile = buildfile(cookiefile); | |
- scriptfile = buildfile(scriptfile); | |
- cachedir = buildpath(cachedir); | |
- | |
- if (stylefile == NULL) { | |
- styledir = buildpath(styledir); | |
- for (i = 0; i < LENGTH(styles); i++) { | |
- if (regcomp(&(styles[i].re), styles[i].regex, | |
- REG_EXTENDED)) { | |
- fprintf(stderr, | |
- "Could not compile regex: %s\n", | |
- styles[i].regex); | |
- styles[i].regex = NULL; | |
- } | |
- styles[i].style = g_strconcat(styledir, "/", | |
- styles[i].style, NULL); | |
- } | |
- g_free(styledir); | |
- } else { | |
- stylefile = buildfile(stylefile); | |
- } | |
+ evalscript(c, "window.scrollBy(0, %d * (window.innerHeight / 100))", | |
+ a->i); | |
} | |
void | |
-sigchld(int unused) | |
+scroll_h(Client *c, const Arg *a) | |
{ | |
- if (signal(SIGCHLD, sigchld) == SIG_ERR) | |
- die("Can't install SIGCHLD handler"); | |
- while (0 < waitpid(-1, NULL, WNOHANG)); | |
+ evalscript(c, "window.scrollBy(%d * (window.innerWidth / 100), 0)", | |
+ a->i); | |
} | |
void | |
-spawn(Client *c, const Arg *arg) | |
+navigate(Client *c, const Arg *a) | |
{ | |
- if (fork() == 0) { | |
- if (dpy) | |
- close(ConnectionNumber(dpy)); | |
- setsid(); | |
- execvp(((char **)arg->v)[0], (char **)arg->v); | |
- fprintf(stderr, "surf: execvp %s", ((char **)arg->v)[0]); | |
- perror(" failed"); | |
- exit(0); | |
- } | |
+ if (a->i < 0) | |
+ webkit_web_view_go_back(c->view); | |
+ else if (a->i > 0) | |
+ webkit_web_view_go_forward(c->view); | |
} | |
void | |
t@@ -1284,35 +1329,6 @@ stop(Client *c, const Arg *arg) | |
} | |
void | |
-titlechanged(WebKitWebView *view, GParamSpec *ps, Client *c) | |
-{ | |
- c->title = webkit_web_view_get_title(c->view); | |
- updatetitle(c); | |
-} | |
- | |
-gboolean | |
-winevent(GtkWidget *w, GdkEvent *e, Client *c) | |
-{ | |
- switch (e->type) { | |
- case GDK_LEAVE_NOTIFY: | |
- c->targeturi = NULL; | |
- updatetitle(c); | |
- break; | |
- case GDK_WINDOW_STATE: /* fallthrough */ | |
- if (e->window_state.changed_mask == | |
- GDK_WINDOW_STATE_FULLSCREEN) { | |
- c->fullscreen = e->window_state.new_window_state & | |
- GDK_WINDOW_STATE_FULLSCREEN; | |
- break; | |
- } | |
- default: | |
- return FALSE; | |
- } | |
- | |
- return TRUE; | |
-} | |
- | |
-void | |
toggle(Client *c, const Arg *a) | |
{ | |
WebKitSettings *s; | |
t@@ -1363,6 +1379,16 @@ toggle(Client *c, const Arg *a) | |
} | |
void | |
+togglefullscreen(Client *c, const Arg *a) | |
+{ | |
+ /* toggling value is handled in winevent() */ | |
+ if (c->fullscreen) | |
+ gtk_window_unfullscreen(GTK_WINDOW(c->win)); | |
+ else | |
+ gtk_window_fullscreen(GTK_WINDOW(c->win)); | |
+} | |
+ | |
+void | |
togglecookiepolicy(Client *c, const Arg *arg) | |
{ | |
++cookiepolicy; | |
t@@ -1387,80 +1413,53 @@ togglestyle(Client *c, const Arg *arg) | |
} | |
void | |
-gettogglestats(Client *c) | |
+toggleinspector(Client *c, const Arg *a) | |
{ | |
- togglestats[0] = cookiepolicy_set(cookiepolicy_get()); | |
- togglestats[1] = enablecaretbrowsing ? 'C' : 'c'; | |
- togglestats[2] = allowgeolocation ? 'G' : 'g'; | |
- togglestats[3] = enablecache ? 'D' : 'd'; | |
- togglestats[4] = loadimages ? 'I' : 'i'; | |
- togglestats[5] = enablescripts ? 'S': 's'; | |
- togglestats[6] = enableplugins ? 'V' : 'v'; | |
- togglestats[7] = enablestyle ? 'M' : 'm'; | |
- togglestats[8] = enableframeflattening ? 'F' : 'f'; | |
- togglestats[9] = '\0'; | |
+ if (enableinspector) { | |
+ if (webkit_web_inspector_is_attached(c->inspector)) | |
+ webkit_web_inspector_close(c->inspector); | |
+ else | |
+ webkit_web_inspector_show(c->inspector); | |
+ } | |
} | |
void | |
-getpagestats(Client *c) | |
+find(Client *c, const Arg *a) | |
{ | |
- pagestats[0] = c->tlsflags > G_TLS_CERTIFICATE_VALIDATE_ALL ? '-' : | |
- c->tlsflags > 0 ? 'U' : 'T'; | |
- pagestats[1] = '\0'; | |
-} | |
+ const char *s, *f; | |
-void | |
-updatetitle(Client *c) | |
-{ | |
- char *title; | |
+ if (a && a->i) { | |
+ if (a->i > 0) | |
+ webkit_find_controller_search_next(c->finder); | |
+ else | |
+ webkit_find_controller_search_previous(c->finder); | |
+ } else { | |
+ s = getatom(c, AtomFind); | |
+ f = webkit_find_controller_get_search_text(c->finder); | |
- if (showindicators) { | |
- gettogglestats(c); | |
- getpagestats(c); | |
+ if (g_strcmp0(f, s) == 0) /* reset search */ | |
+ webkit_find_controller_search(c->finder, "", findopts,… | |
- if (c->progress != 100) { | |
- title = g_strdup_printf("[%i%%] %s:%s | %s", | |
- c->progress, togglestats, pagestats, | |
- c->targeturi ? c->targeturi : c->title); | |
- } else { | |
- title = g_strdup_printf("%s:%s | %s", | |
- togglestats, pagestats, | |
- c->targeturi ? c->targeturi : c->title); | |
- } | |
+ webkit_find_controller_search(c->finder, s, findopts, G_MAXUIN… | |
- 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 : ""); | |
+ if (strcmp(s, "") == 0) | |
+ webkit_find_controller_search_finish(c->finder); | |
} | |
} | |
void | |
-updatewinid(Client *c) | |
-{ | |
- snprintf(winid, LENGTH(winid), "%lu", c->xid); | |
-} | |
- | |
-void | |
-usage(void) | |
+clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h) | |
{ | |
- die("usage: %s [-bBdDfFgGiIkKmMnNpPsSvx] [-a cookiepolicies ] " | |
- "[-c cookiefile] [-e xid] [-r scriptfile] [-t stylefile] " | |
- "[-u useragent] [-z zoomlevel] [uri]\n", basename(argv0)); | |
+ navigate(c, a); | |
} | |
void | |
-zoom(Client *c, const Arg *a) | |
+clicknewwindow(Client *c, const Arg *a, WebKitHitTestResult *h) | |
{ | |
- if (a->i > 0) | |
- webkit_web_view_set_zoom_level(c->view, zoomlevel + 0.1); | |
- else if (a->i < 0) | |
- webkit_web_view_set_zoom_level(c->view, zoomlevel - 0.1); | |
- else | |
- webkit_web_view_set_zoom_level(c->view, 1.0); | |
+ Arg arg; | |
- zoomlevel = webkit_web_view_get_zoom_level(c->view); | |
+ arg.v = webkit_hit_test_result_get_link_uri(h); | |
+ newwindow(c, &arg, a->b); | |
} | |
int | |
t@@ -1579,4 +1578,3 @@ main(int argc, char *argv[]) | |
return EXIT_SUCCESS; | |
} | |
- |