summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2018-11-05 23:04:32 +0100
committerKarel Kočí <cynerd@email.cz>2018-11-05 23:04:32 +0100
commitd7f641d5dd6c099d4a9274a18fcfb89df00d4b4c (patch)
treefa46c7ec3902a9549393df154f24b25ef7517875
parent78d9d66ad6ce6455690670173623ad420d12170d (diff)
parent2b71a22755bae132a639fe10475a0d42e582d244 (diff)
downloadsurf-d7f641d5dd6c099d4a9274a18fcfb89df00d4b4c.tar.gz
surf-d7f641d5dd6c099d4a9274a18fcfb89df00d4b4c.tar.bz2
surf-d7f641d5dd6c099d4a9274a18fcfb89df00d4b4c.zip
Merge branch 'surf-webkit2' into mysurfv2.0.7
-rw-r--r--FAQ.md10
-rw-r--r--Makefile94
-rw-r--r--common.c15
-rw-r--r--common.h3
-rw-r--r--config.h16
-rw-r--r--config.mk23
-rw-r--r--libsurf-webext.c123
-rw-r--r--surf.c214
8 files changed, 350 insertions, 148 deletions
diff --git a/FAQ.md b/FAQ.md
index 0a71e41..48e6097 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -1,10 +1,10 @@
# Frequently Asked Questions
-## Surf is starting up slowly. What might happen?
+## Surf is starting up slowly. What might be causing this?
-The first suspect for such a behaviour is the plugin handling. Run surf
-on the commandline and see if there are errors because of »nspluginwrap‐
-per« or failed RPCs to them. If that is true, go to ~/.mozilla/plugins
-and try removing stale links to plugins not on your system anymore. This
+The first suspect for such behaviour is the plugin handling. Run surf on
+the commandline and see if there are errors because of “nspluginwrapper”
+or failed RPCs to them. If that is true, go to ~/.mozilla/plugins and
+try removing stale links to plugins not on your system anymore. This
will stop surf from trying to load them.
diff --git a/Makefile b/Makefile
index 45274aa..af17f07 100644
--- a/Makefile
+++ b/Makefile
@@ -4,72 +4,72 @@
include config.mk
-SRC = surf.c
+SRC = surf.c common.c
OBJ = $(SRC:.c=.o)
+WEBEXTSRC = libsurf-webext.c
+WEBEXTOBJ = $(WEBEXTSRC:.c=.o)
-all: options surf
+all: options libsurf-webext.so surf
options:
@echo surf build options:
- @echo "CFLAGS = $(SURF_CFLAGS)"
- @echo "LDFLAGS = $(SURF_LDFLAGS)"
- @echo "CC = $(CC)"
+ @echo "CC = $(CC)"
+ @echo "CFLAGS = $(SURFCFLAGS) $(CFLAGS)"
+ @echo "WEBEXTCFLAGS = $(WEBEXTCFLAGS) $(CFLAGS)"
+ @echo "LDFLAGS = $(LDFLAGS)"
.c.o:
- @echo CC -c $<
- @$(CC) $(SURF_CFLAGS) -c $<
-
-$(OBJ): config.h config.mk
+ $(CC) $(SURFCFLAGS) $(CFLAGS) -c $<
config.h:
- @echo creating $@ from config.def.h
- @cp config.def.h $@
+ cp config.def.h $@
+
+$(OBJ): config.h common.h config.mk
+
+$(WEBEXTOBJ): $(WEBEXTSRC) config.h common.h config.mk
+ $(CC) $(WEBEXTCFLAGS) $(CFLAGS) -c $(WEBEXTSRC)
+
+libsurf-webext.so: $(WEBEXTOBJ)
+ $(CC) -shared -Wl,-soname,$@ $(LDFLAGS) -o $@ $< $(WEBEXTLIBS) -lc
surf: $(OBJ)
- @echo CC -o $@
- @$(CC) $(SURF_CFLAGS) -o $@ $(OBJ) $(SURF_LDFLAGS)
+ $(CC) $(SURFLDLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
clean:
- @echo cleaning
- @rm -f surf $(OBJ)
+ rm -f surf $(OBJ)
+ rm -f libsurf-webext.so $(WEBEXTOBJ)
distclean: clean
- @echo cleaning dist
- @rm -f config.h surf-$(VERSION).tar.gz
+ rm -f config.h surf-$(VERSION).tar.gz
dist: distclean
- @echo creating dist tarball
- @mkdir -p surf-$(VERSION)
- @cp -R LICENSE Makefile config.mk config.def.h README \
+ mkdir -p surf-$(VERSION)
+ cp -R LICENSE Makefile config.mk config.def.h README \
surf-open.sh arg.h TODO.md surf.png \
- surf.1 $(SRC) surf-$(VERSION)
- @tar -cf surf-$(VERSION).tar surf-$(VERSION)
- @gzip surf-$(VERSION).tar
- @rm -rf surf-$(VERSION)
+ surf.1 $(SRC) $(WEBEXTSRC) surf-$(VERSION)
+ tar -cf surf-$(VERSION).tar surf-$(VERSION)
+ gzip surf-$(VERSION).tar
+ rm -rf surf-$(VERSION)
install: all
- @echo installing executable file to $(DESTDIR)$(PREFIX)/bin
- @mkdir -p $(DESTDIR)$(PREFIX)/bin
- @cp -f surf $(DESTDIR)$(PREFIX)/bin
- @chmod 755 $(DESTDIR)$(PREFIX)/bin/surf
- @echo installing surf-menu to $(DESTDIR)$(PREFIX)/bin
- @cp -f surf-menu $(DESTDIR)$(PREFIX)/bin
- @chmod 755 $(DESTDIR)$(PREFIX)/bin/surf-menu
- @echo installing manual page to $(DESTDIR)$(MANPREFIX)/man1
- @mkdir -p $(DESTDIR)$(MANPREFIX)/man1
- @sed "s/VERSION/$(VERSION)/g" < surf.1 > $(DESTDIR)$(MANPREFIX)/man1/surf.1
- @chmod 644 $(DESTDIR)$(MANPREFIX)/man1/surf.1
- @echo installing desktop file to $(DESTDIR)/usr/share/applications
- @mkdir -p $(DESTDIR)/usr/share/applications
- @cp -f surf.desktop $(DESTDIR)/usr/share/applications/surf.desktop
+ mkdir -p $(DESTDIR)$(PREFIX)/bin
+ cp -f surf $(DESTDIR)$(PREFIX)/bin
+ chmod 755 $(DESTDIR)$(PREFIX)/bin/surf
+ cp -f surf-menu $(DESTDIR)$(PREFIX)/bin
+ chmod 755 $(DESTDIR)$(PREFIX)/bin/surf-menu
+ mkdir -p $(DESTDIR)$(LIBDIR)
+ cp -f libsurf-webext.so $(DESTDIR)$(LIBDIR)
+ chmod 644 $(DESTDIR)$(LIBDIR)/libsurf-webext.so
+ mkdir -p $(DESTDIR)$(MANPREFIX)/man1
+ sed "s/VERSION/$(VERSION)/g" < surf.1 > $(DESTDIR)$(MANPREFIX)/man1/surf.1
+ chmod 644 $(DESTDIR)$(MANPREFIX)/man1/surf.1
uninstall:
- @echo removing executable file from $(DESTDIR)$(PREFIX)/bin
- @rm -f $(DESTDIR)$(PREFIX)/bin/surf
- @rm -f $(DESTDIR)$(PREFIX)/bin/surf-menu
- @echo removing manual page from $(DESTDIR)$(MANPREFIX)/man1
- @rm -f $(DESTDIR)$(MANPREFIX)/man1/surf.1
- @echo removing desktop page from $(DESTDIR)/usr/share/applications
- @rm -f $(DESTDIR)/usr/share/applications/surf.desktop
-
-.PHONY: all options clean dist install uninstall
+ rm -f $(DESTDIR)$(PREFIX)/bin/surf
+ rm -f $(DESTDIR)$(PREFIX)/bin/surf-menu
+ rm -f $(DESTDIR)$(MANPREFIX)/man1/surf.1
+ rm -f $(DESTDIR)$(LIBDIR)/libsurf-webext.so
+ - rmdir $(DESTDIR)$(LIBDIR)
+
+.SUFFIXES: .so .o .c
+.PHONY: all options clean-dist clean dist install uninstall
diff --git a/common.c b/common.c
new file mode 100644
index 0000000..42662ed
--- /dev/null
+++ b/common.c
@@ -0,0 +1,15 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+die(const char *errstr, ...)
+{
+ va_list ap;
+
+ va_start(ap, errstr);
+ vfprintf(stderr, errstr, ap);
+ va_end(ap);
+ exit(1);
+}
+
diff --git a/common.h b/common.h
new file mode 100644
index 0000000..527c4f7
--- /dev/null
+++ b/common.h
@@ -0,0 +1,3 @@
+#define MSGBUFSZ 32
+
+void die(char *, ...);
diff --git a/config.h b/config.h
index a14fb4b..b7077cb 100644
--- a/config.h
+++ b/config.h
@@ -147,15 +147,13 @@ static Key keys[] = {
{ MODKEY, GDK_KEY_l, navigate, { .i = +1 } },
{ MODKEY, GDK_KEY_h, navigate, { .i = -1 } },
- /* Currently we have to use scrolling steps that WebKit2GTK+ gives us
- * d: step down, u: step up, r: step right, l:step left
- * D: page down, U: page up */
- { MODKEY, GDK_KEY_j, scroll, { .i = 'd' } },
- { MODKEY, GDK_KEY_k, scroll, { .i = 'u' } },
- { MODKEY, GDK_KEY_b, scroll, { .i = 'U' } },
- { MODKEY, GDK_KEY_space, scroll, { .i = 'D' } },
- { MODKEY, GDK_KEY_i, scroll, { .i = 'r' } },
- { MODKEY, GDK_KEY_u, scroll, { .i = 'l' } },
+ /* vertical and horizontal scrolling, in viewport percentage */
+ { MODKEY, GDK_KEY_j, scrollv, { .i = +10 } },
+ { MODKEY, GDK_KEY_k, scrollv, { .i = -10 } },
+ { MODKEY, GDK_KEY_b, scrollv, { .i = +50 } },
+ { MODKEY, GDK_KEY_space, scrollv, { .i = -50 } },
+ { MODKEY, GDK_KEY_i, scrollh, { .i = +10 } },
+ { MODKEY, GDK_KEY_u, scrollh, { .i = -10 } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_j, zoom, { .i = -1 } },
diff --git a/config.mk b/config.mk
index 8a6eabe..2b6314f 100644
--- a/config.mk
+++ b/config.mk
@@ -6,27 +6,26 @@ PKG_CONFIG ?= pkg-config
# paths
PREFIX = /usr
MANPREFIX = $(PREFIX)/share/man
-LIBPREFIX = $(PREFIX)/lib/surf
+LIBPREFIX = $(PREFIX)/lib
+LIBDIR = $(LIBPREFIX)/surf
X11INC = $(shell $(PKG_CONFIG) --cflags x11)
X11LIB = $(shell $(PKG_CONFIG) --libs x11)
-GTKINC = $(shell $(PKG_CONFIG) --cflags gtk+-3.0 gthread-2.0 gcr-3 webkit2gtk-4.0)
-GTKLIB = $(shell $(PKG_CONFIG) --libs gtk+-3.0 gthread-2.0 gcr-3 webkit2gtk-4.0)
+GTKINC = $(shell $(PKG_CONFIG) --cflags gtk+-3.0 gcr-3 webkit2gtk-4.0)
+GTKLIB = $(shell $(PKG_CONFIG) --libs gtk+-3.0 gcr-3 webkit2gtk-4.0)
+WEBEXTINC = $(shell $(PKG_CONFIG) --cflags webkit2gtk-4.0 webkit2gtk-web-extension-4.0)
+WEBEXTLIBS = $(shell $(PKG_CONFIG) --libs webkit2gtk-4.0 webkit2gtk-web-extension-4.0)
# includes and libs
INCS = $(X11INC) $(GTKINC)
-LIBS = $(X11LIB) $(GTKLIB)
+LIBS = $(X11LIB) $(GTKLIB) -lgthread-2.0
# flags
-CPPFLAGS = -DVERSION=\"${VERSION}\" -DWEBEXTDIR=\"${LIBPREFIX}\" \
+CPPFLAGS = -DVERSION=\"$(VERSION)\" -DWEBEXTDIR=\"$(LIBDIR)\" \
-D_DEFAULT_SOURCE -DGCR_API_SUBJECT_TO_CHANGE
-SURF_CFLAGS = $(INCS) $(CPPFLAGS) $(CFLAGS)
-SURF_LDFLAGS = $(LIBS) $(LDFLAGS)
+SURFCFLAGS = $(INCS) $(CPPFLAGS)
+WEBEXTCFLAGS = -fPIC $(WEBEXTINC)
-# Solaris
-#CFLAGS = -fast $(INCS) -DVERSION=\"$(VERSION)\"
-#LDFLAGS = $(LIBS)
-
-# compiler and linker
+# compiler
#CC = c99
diff --git a/libsurf-webext.c b/libsurf-webext.c
new file mode 100644
index 0000000..684d4a5
--- /dev/null
+++ b/libsurf-webext.c
@@ -0,0 +1,123 @@
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include <gio/gio.h>
+#include <webkit2/webkit-web-extension.h>
+#include <webkitdom/webkitdom.h>
+#include <webkitdom/WebKitDOMDOMWindowUnstable.h>
+
+#include "common.h"
+
+#define LENGTH(x) (sizeof(x) / sizeof(x[0]))
+
+typedef struct Page {
+ guint64 id;
+ WebKitWebPage *webpage;
+ struct Page *next;
+} Page;
+
+static int pipein, pipeout;
+static Page *pages;
+
+Page *
+newpage(WebKitWebPage *page)
+{
+ Page *p;
+
+ if (!(p = calloc(1, sizeof(Page))))
+ die("Cannot malloc!\n");
+
+ p->next = pages;
+ pages = p;
+
+ p->id = webkit_web_page_get_id(page);
+ p->webpage = page;
+
+ return p;
+}
+
+static void
+msgsurf(Page *p, const char *s)
+{
+ char msg[MSGBUFSZ];
+ int ret;
+
+ msg[0] = p ? p->id : 0;
+ ret = snprintf(&msg[1], sizeof(msg) - 1, "%s", s);
+ if (ret >= sizeof(msg)) {
+ fprintf(stderr, "webext: message too long: %d\n", ret);
+ return;
+ }
+
+ if (pipeout) {
+ if (write(pipeout, msg, sizeof(msg)) < 0)
+ fprintf(stderr, "webext: error sending: %s\n", msg);
+ }
+}
+
+static gboolean
+readpipe(GIOChannel *s, GIOCondition c, gpointer unused)
+{
+ char msg[MSGBUFSZ];
+ gsize msgsz;
+ WebKitDOMDOMWindow *view;
+ GError *gerr = NULL;
+ glong wh, ww;
+ Page *p;
+
+ if (g_io_channel_read_chars(s, msg, LENGTH(msg), &msgsz, &gerr) !=
+ G_IO_STATUS_NORMAL) {
+ fprintf(stderr, "webext: error reading pipe: %s\n",
+ gerr->message);
+ g_error_free(gerr);
+ return TRUE;
+ }
+ msg[msgsz] = '\0';
+
+ for (p = pages; p; p = p->next) {
+ if (p->id == msg[0])
+ break;
+ }
+ if (!p || !(view = webkit_dom_document_get_default_view(
+ webkit_web_page_get_dom_document(p->webpage))))
+ return TRUE;
+
+ switch (msg[1]) {
+ case 'h':
+ ww = webkit_dom_dom_window_get_inner_width(view);
+ webkit_dom_dom_window_scroll_by(view,
+ (ww / 100) * msg[2], 0);
+ break;
+ case 'v':
+ wh = webkit_dom_dom_window_get_inner_height(view);
+ webkit_dom_dom_window_scroll_by(view,
+ 0, (wh / 100) * msg[2]);
+ break;
+ }
+
+ return TRUE;
+}
+
+static void
+webpagecreated(WebKitWebExtension *e, WebKitWebPage *wp, gpointer unused)
+{
+ Page *p = newpage(wp);
+}
+
+G_MODULE_EXPORT void
+webkit_web_extension_initialize_with_user_data(WebKitWebExtension *e, GVariant *gv)
+{
+ GIOChannel *gchanpipe;
+
+ g_signal_connect(e, "page-created", G_CALLBACK(webpagecreated), NULL);
+
+ g_variant_get(gv, "(ii)", &pipein, &pipeout);
+ msgsurf(NULL, "i");
+
+ gchanpipe = g_io_channel_unix_new(pipein);
+ g_io_channel_set_encoding(gchanpipe, NULL, NULL);
+ g_io_channel_set_close_on_unref(gchanpipe, TRUE);
+ g_io_add_watch(gchanpipe, G_IO_IN, readpipe, NULL);
+}
diff --git a/surf.c b/surf.c
index b42fb3d..a3f141c 100644
--- a/surf.c
+++ b/surf.c
@@ -11,7 +11,6 @@
#include <pwd.h>
#include <regex.h>
#include <signal.h>
-#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -28,8 +27,10 @@
#include <webkit2/webkit2.h>
#include <X11/X.h>
#include <X11/Xatom.h>
+#include <glib.h>
#include "arg.h"
+#include "common.h"
#define LENGTH(x) (sizeof(x) / sizeof(x[0]))
#define CLEANMASK(mask) (mask & (MODKEY|GDK_SHIFT_MASK))
@@ -104,6 +105,7 @@ typedef struct Client {
GTlsCertificate *cert, *failedcert;
GTlsCertificateFlags tlserr;
Window xid;
+ unsigned long pageid;
int progress, fullscreen, https, insecure, errorpage;
const char *title, *overtitle, *targeturi;
const char *needle;
@@ -140,12 +142,12 @@ typedef struct {
/* Surf */
static void usage(void);
-static void die(const char *errstr, ...);
static void setup(void);
static void sigchld(int unused);
static void sighup(int unused);
static char *buildfile(const char *path);
static char *buildpath(const char *path);
+static char *untildepath(const char *path);
static const char *getuserhomedir(const char *user);
static const char *getcurrentuserhomedir(void);
static Client *newclient(Client *c);
@@ -170,6 +172,7 @@ static void updatewinid(Client *c);
static void handleplumb(Client *c, const char *uri);
static void newwindow(Client *c, const Arg *a, int noembed);
static void spawn(Client *c, const Arg *a);
+static void msgext(Client *c, char type, const Arg *a);
static void destroyclient(Client *c);
static void cleanup(void);
@@ -182,6 +185,7 @@ static gboolean buttonreleased(GtkWidget *w, GdkEvent *e, Client *c);
static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event,
gpointer d);
static gboolean winevent(GtkWidget *w, GdkEvent *e, Client *c);
+static gboolean readpipe(GIOChannel *s, GIOCondition ioc, gpointer unused);
static void showview(WebKitWebView *v, Client *c);
static GtkWidget *createwindow(Client *c);
static gboolean loadfailedtls(WebKitWebView *v, gchar *uri,
@@ -205,6 +209,9 @@ 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 webprocessterminated(WebKitWebView *v,
+ WebKitWebProcessTerminationReason r,
+ Client *c);
static void closeview(WebKitWebView *v, Client *c);
static void destroywin(GtkWidget* w, Client *c);
@@ -215,7 +222,8 @@ static void print(Client *c, const Arg *a);
static void showcert(Client *c, const Arg *a);
static void clipboard(Client *c, const Arg *a);
static void zoom(Client *c, const Arg *a);
-static void scroll(Client *c, const Arg *a);
+static void scrollv(Client *c, const Arg *a);
+static void scrollh(Client *c, const Arg *a);
static void navigate(Client *c, const Arg *a);
static void stop(Client *c, const Arg *a);
static void toggle(Client *c, const Arg *a);
@@ -243,6 +251,7 @@ static char *stylefile;
static const char *useragent;
static Parameter *curconfig;
static int modparams[ParameterLast];
+static int pipein[2], pipeout[2];
char *argv0;
static ParamName loadtransient[] = {
@@ -301,19 +310,9 @@ usage(void)
}
void
-die(const char *errstr, ...)
-{
- va_list ap;
-
- va_start(ap, errstr);
- vfprintf(stderr, errstr, ap);
- va_end(ap);
- exit(1);
-}
-
-void
setup(void)
{
+ GIOChannel *gchanin;
GdkDisplay *gdpy;
int i, j;
@@ -344,6 +343,16 @@ setup(void)
gdkkb = gdk_seat_get_keyboard(gdk_display_get_default_seat(gdpy));
+ if (pipe(pipeout) < 0 || pipe(pipein) < 0) {
+ fputs("Unable to create pipes\n", stderr);
+ } else {
+ gchanin = g_io_channel_unix_new(pipein[0]);
+ g_io_channel_set_encoding(gchanin, NULL, NULL);
+ g_io_channel_set_close_on_unref(gchanin, TRUE);
+ g_io_add_watch(gchanin, G_IO_IN, readpipe, NULL);
+ }
+
+
for (i = 0; i < LENGTH(certs); ++i) {
if (!regcomp(&(certs[i].re), certs[i].regex, REG_EXTENDED)) {
certs[i].file = g_strconcat(certdir, "/", certs[i].file,
@@ -470,26 +479,12 @@ getcurrentuserhomedir(void)
char *
buildpath(const char *path)
{
- char *apath, *name, *p, *fpath;
- const char *homedir;
+ char *apath, *fpath;
- if (path[0] == '~') {
- if (path[1] == '/' || path[1] == '\0') {
- p = (char *)&path[1];
- homedir = getcurrentuserhomedir();
- } else {
- if ((p = strchr(path, '/')))
- name = g_strndup(&path[1], --p - path);
- else
- name = g_strdup(&path[1]);
-
- homedir = getuserhomedir(name);
- g_free(name);
- }
- apath = g_build_filename(homedir, p, NULL);
- } else {
+ if (path[0] == '~')
+ apath = untildepath(path);
+ else
apath = g_strdup(path);
- }
/* creating directory */
if (g_mkdir_with_parents(apath, 0700) < 0)
@@ -501,6 +496,28 @@ buildpath(const char *path)
return fpath;
}
+char *
+untildepath(const char *path)
+{
+ char *apath, *name, *p;
+ const char *homedir;
+
+ if (path[1] == '/' || path[1] == '\0') {
+ p = (char *)&path[1];
+ homedir = getcurrentuserhomedir();
+ } else {
+ if ((p = strchr(path, '/')))
+ name = g_strndup(&path[1], p - (path + 1));
+ else
+ name = g_strdup(&path[1]);
+
+ homedir = getuserhomedir(name);
+ g_free(name);
+ }
+ apath = g_build_filename(homedir, p, NULL);
+ return apath;
+}
+
Client *
newclient(Client *rc)
{
@@ -522,7 +539,7 @@ void
loaduri(Client *c, const Arg *a)
{
struct stat st;
- char *url, *path;
+ char *url, *path, *apath;
const char *uri = a->v;
if (g_strcmp0(uri, "") == 0)
@@ -533,11 +550,19 @@ loaduri(Client *c, const Arg *a)
g_str_has_prefix(uri, "file://") ||
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);
+ if (uri[0] == '~')
+ apath = untildepath(uri);
+ else
+ apath = (char *)uri;
+ if (!stat(apath, &st) && (path = realpath(apath, NULL))) {
+ url = g_strdup_printf("file://%s", path);
+ free(path);
+ } else {
+ url = g_strdup_printf("http://%s", uri);
+ }
+ if (apath != uri)
+ free(apath);
}
setatom(c, AtomUri, url);
@@ -1013,6 +1038,8 @@ spawn(Client *c, const Arg *a)
if (fork() == 0) {
if (dpy)
close(ConnectionNumber(dpy));
+ close(pipein[0]);
+ close(pipeout[1]);
setsid();
execvp(((char **)a->v)[0], (char **)a->v);
fprintf(stderr, "%s: execvp %s", argv0, ((char **)a->v)[0]);
@@ -1045,6 +1072,9 @@ cleanup(void)
{
while (clients)
destroyclient(clients);
+
+ close(pipein[0]);
+ close(pipeout[1]);
g_free(cookiefile);
g_free(scriptfile);
g_free(stylefile);
@@ -1057,13 +1087,13 @@ newview(Client *c, WebKitWebView *rv)
{
WebKitWebView *v;
WebKitSettings *settings;
- WebKitUserContentManager *contentmanager;
WebKitWebContext *context;
+ WebKitCookieManager *cookiemanager;
+ WebKitUserContentManager *contentmanager;
/* Webview */
if (rv) {
- v = WEBKIT_WEB_VIEW(
- webkit_web_view_new_with_related_view(rv));
+ v = WEBKIT_WEB_VIEW(webkit_web_view_new_with_related_view(rv));
} else {
settings = webkit_settings_new_with_settings(
"allow-file-access-from-file-urls", curconfig[FileURLsCrossAccess].val.i,
@@ -1105,6 +1135,8 @@ newview(Client *c, WebKitWebView *rv)
"base-data-directory", cachedir,
NULL));
+ cookiemanager = webkit_web_context_get_cookie_manager(context);
+
/* rendering process model, can be a shared unique one
* or one for each view */
webkit_web_context_set_process_model(context,
@@ -1119,12 +1151,10 @@ newview(Client *c, WebKitWebView *rv)
WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER);
/* Currently only works with text file to be compatible with curl */
- webkit_cookie_manager_set_persistent_storage(
- webkit_web_context_get_cookie_manager(context), cookiefile,
- WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT);
+ webkit_cookie_manager_set_persistent_storage(cookiemanager,
+ cookiefile, WEBKIT_COOKIE_PERSISTENT_STORAGE_TEXT);
/* cookie policy */
- webkit_cookie_manager_set_accept_policy(
- webkit_web_context_get_cookie_manager(context),
+ webkit_cookie_manager_set_accept_policy(cookiemanager,
cookiepolicy_get());
/* languages */
webkit_web_context_set_preferred_languages(context,
@@ -1170,13 +1200,49 @@ newview(Client *c, WebKitWebView *rv)
G_CALLBACK(permissionrequested), c);
g_signal_connect(G_OBJECT(v), "ready-to-show",
G_CALLBACK(showview), c);
+ g_signal_connect(G_OBJECT(v), "web-process-terminated",
+ G_CALLBACK(webprocessterminated), c);
return v;
}
+static gboolean
+readpipe(GIOChannel *s, GIOCondition ioc, gpointer unused)
+{
+ char msg[MSGBUFSZ];
+ gsize msgsz;
+ GError *gerr = NULL;
+
+ if (g_io_channel_read_chars(s, msg, sizeof(msg), &msgsz, &gerr) !=
+ G_IO_STATUS_NORMAL) {
+ fprintf(stderr, "surf: error reading pipe: %s\n",
+ gerr->message);
+ g_error_free(gerr);
+ return TRUE;
+ }
+ msg[msgsz] = '\0';
+
+ switch (msg[1]) {
+ case 'i':
+ close(pipein[1]);
+ close(pipeout[0]);
+ break;
+ }
+
+ return TRUE;
+}
+
void
initwebextensions(WebKitWebContext *wc, Client *c)
{
+ GVariant *gv;
+
+ if (!pipeout[0] || !pipein[1])
+ return;
+
+ gv = g_variant_new("(ii)", pipeout[0], pipein[1]);
+
+ webkit_web_context_set_web_extensions_initialization_user_data(wc, gv);
webkit_web_context_set_web_extensions_directory(wc, WEBEXTDIR);
}
@@ -1303,6 +1369,7 @@ showview(WebKitWebView *v, Client *c)
c->finder = webkit_web_view_get_find_controller(c->view);
c->inspector = webkit_web_view_get_inspector(c->view);
+ c->pageid = webkit_web_view_get_page_id(c->view);
c->win = createwindow(c);
gtk_container_add(GTK_CONTAINER(c->win), GTK_WIDGET(c->view));
@@ -1352,8 +1419,7 @@ createwindow(Client *c)
gtk_window_set_wmclass(GTK_WINDOW(w), wmstr, "Surf");
g_free(wmstr);
- wmstr = g_strdup_printf("%s[%lu]", "Surf",
- webkit_web_view_get_page_id(c->view));
+ wmstr = g_strdup_printf("%s[%lu]", "Surf", c->pageid);
gtk_window_set_role(GTK_WINDOW(w), wmstr);
g_free(wmstr);
@@ -1675,6 +1741,15 @@ download(Client *c, WebKitURIResponse *r)
}
void
+webprocessterminated(WebKitWebView *v, WebKitWebProcessTerminationReason r,
+ Client *c)
+{
+ fprintf(stderr, "web process terminated: %s\n",
+ r == WEBKIT_WEB_PROCESS_CRASHED ? "crashed" : "no memory");
+ closeview(v, c);
+}
+
+void
closeview(WebKitWebView *v, Client *c)
{
gtk_widget_destroy(c->win);
@@ -1765,38 +1840,27 @@ zoom(Client *c, const Arg *a)
curconfig[ZoomLevel].val.f = webkit_web_view_get_zoom_level(c->view);
}
-void
-scroll(Client *c, const Arg *a)
+static void
+msgext(Client *c, char type, const Arg *a)
{
- GdkEvent *ev = gdk_event_new(GDK_KEY_PRESS);
-
- gdk_event_set_device(ev, gdkkb);
- ev->key.window = gtk_widget_get_window(GTK_WIDGET(c->win));
- ev->key.state = GDK_CONTROL_MASK;
- ev->key.time = GDK_CURRENT_TIME;
+ char msg[MSGBUFSZ] = { c->pageid, type, a->i, '\0' };
- switch (a->i) {
- case 'd':
- ev->key.keyval = GDK_KEY_Down;
- break;
- case 'D':
- ev->key.keyval = GDK_KEY_Page_Down;
- break;
- case 'l':
- ev->key.keyval = GDK_KEY_Left;
- break;
- case 'r':
- ev->key.keyval = GDK_KEY_Right;
- break;
- case 'U':
- ev->key.keyval = GDK_KEY_Page_Up;
- break;
- case 'u':
- ev->key.keyval = GDK_KEY_Up;
- break;
+ if (pipeout[1]) {
+ if (write(pipeout[1], msg, sizeof(msg)) < 0)
+ fprintf(stderr, "surf: error sending: %s\n", msg);
}
+}
+
+void
+scrollv(Client *c, const Arg *a)
+{
+ msgext(c, 'v', a);
+}
- gdk_event_put(ev);
+void
+scrollh(Client *c, const Arg *a)
+{
+ msgext(c, 'h', a);
}
void