34 Commits

Author SHA1 Message Date
eeeck 85d2bb6cad Install on global path 2025-12-30 11:35:30 +01:00
eeeck 1fcada4536 Change cronjob to once a week
Sync less regularly since upstream repo is updated seldom
2025-11-11 15:41:32 +01:00
eeeck 1d1cbc83f5 Fix issue with pathspec 'master' 2025-11-11 15:01:15 +01:00
eeeck 3f21829810 Fix master branch name 2025-11-11 14:56:44 +01:00
eeeck 63fe59c7de Regularly fetch from upstream 2025-10-19 23:53:53 +02:00
Quentin Rameau 48517e586c Fix (2) some typo for kiosk mode in the man-page
Looks like I didn't pay enough attention the first time,
that's what you get for pushing without review!

Thanks to Hiltjo for spotting this!
2025-04-19 12:02:45 +02:00
Quentin Rameau ca380ccb93 Add configuration option for PDF-JS-viewer 2025-04-18 13:56:14 +02:00
Artyom Bologov 22cc5ceee2 Support PDFs 2025-04-18 13:38:56 +02:00
Quentin Rameau c3b3b95f4a Fix some typo for kiosk mode in the man-page
Thanks to Tim Dickson <dickson.tim@googlemail.com> for spotting it!
2025-01-05 12:02:38 +01:00
Quentin Rameau 7f1156f9b0 Build against Webkit 4.1
Seems that this is needed for libsoup3.
2025-01-05 12:02:38 +01:00
Quentin Rameau b3ba9f5991 Request HTTPS by default instead of HTTP
This might be more reasonable privacy-wise in 2025.
2025-01-05 12:02:38 +01:00
Quentin Rameau 9ef79bf710 webext: Process full messages
Piped messages would not always be fully sent in a single read.
Do a bit of message reassembly.
2024-03-24 15:27:20 +01:00
Quentin Rameau d5f45bffe0 webext: Free JavaScript objects
Webkit documentation says JavaScript objects refcount is always
increased, and has to be released always.
2024-03-24 15:27:20 +01:00
Quentin Rameau b48be75179 Fix message sizes for web extension communication 2024-03-17 09:13:56 +01:00
Quentin Rameau 2ea91766bb webext: Remove unused functions
Communication from web extension to surf isn't used,
this code can always be brought back if needed.
2024-03-17 08:22:18 +01:00
Quentin Rameau 7513a622e3 Update get frame name function
webkit_navigation_policy_decision_get_frame_name has been deprecated
since 2.40.
2024-03-17 08:22:18 +01:00
Quentin Rameau 4bab57968d Remove setting processing model
The processing model we want is actually the only one supported
since 2.40.
2024-03-17 08:22:18 +01:00
Quentin Rameau 5e591b89a1 Update deprecated JavaScript eval function
Function webkit_web_view_run_javascript has been deprecated since 2.40.
2024-03-17 08:22:18 +01:00
Quentin Rameau 85bfff1083 Move TLS parameters handling to datamanager
Using web context is deprecated since 2.32.
2024-03-17 08:22:18 +01:00
Quentin Rameau 3f4292b7cc Remove Java support toggle
This has been deprecated since 2.38.
2024-03-17 08:22:18 +01:00
Quentin Rameau 175710126c Remove frame flattening toggle
This has been deprecated since 2.38.
2024-03-17 08:22:18 +01:00
Quentin Rameau f1d47112d6 Add webkit URI scheme 2024-03-17 08:22:17 +01:00
Quentin Rameau 30f5464eb1 Fix usage message: -Pp don't exist anymore
Thanks to Eric Pruitt <eric.pruitt@gmail.com> for reporting!
2023-11-18 12:48:19 +01:00
Petr Vaněk e9b7ec6722 webext: add missing gio/gunixfdlist.h includes
This resolves two set of warnings pointed by compiler
-Wimplicit-function-declaration and -Wint-conversion, where the later
one can result with segfault caused by invalid cast from int to pointer.

Fixes: 665a709b52 ("webext: Exchange fd over webkit messages")
2022-10-22 13:07:19 +02:00
Quentin Rameau 665a709b52 webext: Exchange fd over webkit messages
This is more complex, but webkit2gtk prevents passing file descriptors
to processes in 2.38.0.
2022-10-16 17:39:05 +02:00
Quentin Rameau 609ea1c8e6 Do not reload page when toggling dark mode
This change had actually been applied in previous commit d3ee652
by mistake.
2022-05-04 03:31:58 +02:00
Quentin Rameau 38cb1632bf Fix dark mode parameter application 2022-04-10 18:50:02 +02:00
Quentin Rameau d3ee652860 Only get webkit context and settings once 2022-04-10 18:49:35 +02:00
Quentin Rameau 1f5b8f3bd1 Add dark mode toggle
This sets dark gtk theme variant,
which should make webkit2gtk use dark css variant
from websites that provide it.
2022-04-10 16:35:24 +02:00
Quentin Rameau 11dca18a2d Improve non-ASCII character search handling
Before, the XA_STRING would only let use ASCII characters properly.
Now UTF-8 characters should be handled correctly.
2021-07-19 22:27:50 +02:00
Quentin Rameau 238d2273b5 Improve SETPROP xprop parsing
This handles correctly quotes, backslashes, etc.
2021-07-19 22:27:32 +02:00
Quentin Rameau 761ea9e4c6 Fix togglestats array 2021-05-21 00:16:17 +02:00
Quentin Rameau bcd7d74e61 Update LICENSE file 2021-05-10 00:44:36 +02:00
Quentin Rameau 327cca048b Fix distfile generation 2021-05-10 00:37:46 +02:00
8 changed files with 266 additions and 161 deletions
+31
View File
@@ -0,0 +1,31 @@
name: Sync Upstream (12h)
on:
schedule:
- cron: "0 0 * * 0"
workflow_dispatch:
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Checkout fork
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: surf-webkit2
- name: Add upstream remote
run: |
git remote add upstream https://git.suckless.org/surf || true
git fetch upstream
- name: Merge upstream into surf-webkit2
run: |
git config user.name "gitea-runner[bot]"
git config user.email "gitea-runner[bot]@noreply.erickahmed.com"
git merge upstream/surf-webkit2 --strategy-option ours --no-edit || true
- name: Push merged branch
run: |
git push origin surf-webkit2
+11 -2
View File
@@ -15,18 +15,27 @@ MIT/X Consortium License
© 2013 Alexander Sedov <alex0player@gmail.com> © 2013 Alexander Sedov <alex0player@gmail.com>
© 2013 Nick White <git@njw.me.uk> © 2013 Nick White <git@njw.me.uk>
© 2013 David Dufberg <david@dufberg.se> © 2013 David Dufberg <david@dufberg.se>
© 2014-2017 Quentin Rameau <quinq@fifth.space> © 2014-2021 Quentin Rameau <quinq@fifth.space>
© 2014-2016 Markus Teich <markus.teich@stusta.mhn.de> © 2014-2016 Markus Teich <markus.teich@stusta.mhn.de>
© 2015 Jakukyo Friel <weakish@gmail.com> © 2015 Jakukyo Friel <weakish@gmail.com>
© 2015 Ben Woolley <tautolog@gmail.com> © 2015 Ben Woolley <tautolog@gmail.com>
© 2015 Greg Reagle <greg.reagle@umbc.edu> © 2015 Greg Reagle <greg.reagle@umbc.edu>
© 2015 GhostAV <ghostav@riseup.net> © 2015 GhostAV <ghostav@riseup.net>
© 2015 Ivan Tham <pickfire@riseup.net> © 2015-2017 Ivan Tham <pickfire@riseup.net>
© 2015 Alexander Huemer <alexander.huemer@xx.vu> © 2015 Alexander Huemer <alexander.huemer@xx.vu>
© 2015 Michael Stevens <mstevens@etla.org> © 2015 Michael Stevens <mstevens@etla.org>
© 2015 Felix Janda <felix.janda@posteo.de> © 2015 Felix Janda <felix.janda@posteo.de>
© 2016 Charles Lehner <cel@celehner.com> © 2016 Charles Lehner <cel@celehner.com>
© 2016 Dmitry Bogatov <KAction@gnu.org> © 2016 Dmitry Bogatov <KAction@gnu.org>
© 2017 Hiltjo Posthuma <hiltjo@codemadness.org>
© 2017 ssd <ssd@mailless.org>
© 2017 Constantine Bytensky <kostya3@gmail.com>
© 2017 Eon S. Jeon <esjeon@hyunmu.am>
© 2017 Jochen Sprickerhof <git@jochen.sprickerhof.de>
© 2018 nzl <uruabi@gmail.com>
© 2018 Eddie Thieda <eddie.thieda@gmail.com>
© 2018 Leonardo Taccari <iamleot@gmail.com>
© 2019 efe <efe@efe.kim>
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),
+1 -1
View File
@@ -47,7 +47,7 @@ dist: distclean
mkdir -p surf-$(VERSION) mkdir -p surf-$(VERSION)
cp -R LICENSE Makefile config.mk config.def.h README \ cp -R LICENSE Makefile config.mk config.def.h README \
surf-open.sh arg.h TODO.md surf.png \ surf-open.sh arg.h TODO.md surf.png \
surf.1 $(SRC) $(CSRC) $(WSRC) surf-$(VERSION) surf.1 common.h $(SRC) $(WSRC) surf-$(VERSION)
tar -cf surf-$(VERSION).tar surf-$(VERSION) tar -cf surf-$(VERSION).tar surf-$(VERSION)
gzip surf-$(VERSION).tar gzip surf-$(VERSION).tar
rm -rf surf-$(VERSION) rm -rf surf-$(VERSION)
+9 -7
View File
@@ -20,21 +20,21 @@ static Parameter defconfig[ParameterLast] = {
[Certificate] = { { .i = 0 }, }, [Certificate] = { { .i = 0 }, },
[CaretBrowsing] = { { .i = 0 }, }, [CaretBrowsing] = { { .i = 0 }, },
[CookiePolicies] = { { .v = "@Aa" }, }, [CookiePolicies] = { { .v = "@Aa" }, },
[DarkMode] = { { .i = 0 }, },
[DefaultCharset] = { { .v = "UTF-8" }, }, [DefaultCharset] = { { .v = "UTF-8" }, },
[DiskCache] = { { .i = 1 }, }, [DiskCache] = { { .i = 1 }, },
[DNSPrefetch] = { { .i = 0 }, }, [DNSPrefetch] = { { .i = 0 }, },
[Ephemeral] = { { .i = 0 }, }, [Ephemeral] = { { .i = 0 }, },
[FileURLsCrossAccess] = { { .i = 0 }, }, [FileURLsCrossAccess] = { { .i = 0 }, },
[FontSize] = { { .i = 12 }, }, [FontSize] = { { .i = 12 }, },
[FrameFlattening] = { { .i = 0 }, },
[Geolocation] = { { .i = 0 }, }, [Geolocation] = { { .i = 0 }, },
[HideBackground] = { { .i = 0 }, }, [HideBackground] = { { .i = 0 }, },
[Inspector] = { { .i = 0 }, }, [Inspector] = { { .i = 0 }, },
[Java] = { { .i = 1 }, },
[JavaScript] = { { .i = 1 }, }, [JavaScript] = { { .i = 1 }, },
[KioskMode] = { { .i = 0 }, }, [KioskMode] = { { .i = 0 }, },
[LoadImages] = { { .i = 1 }, }, [LoadImages] = { { .i = 1 }, },
[MediaManualPlay] = { { .i = 1 }, }, [MediaManualPlay] = { { .i = 1 }, },
[PDFJSviewer] = { { .i = 1 }, },
[PreferredLanguages] = { { .v = (char *[]){ NULL } }, }, [PreferredLanguages] = { { .v = (char *[]){ NULL } }, },
[RunInFullscreen] = { { .i = 0 }, }, [RunInFullscreen] = { { .i = 0 }, },
[ScrollBars] = { { .i = 1 }, }, [ScrollBars] = { { .i = 1 }, },
@@ -67,10 +67,12 @@ static WebKitFindOptions findopts = WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE |
/* SETPROP(readprop, setprop, prompt)*/ /* SETPROP(readprop, setprop, prompt)*/
#define SETPROP(r, s, p) { \ #define SETPROP(r, s, p) { \
.v = (const char *[]){ "/bin/sh", "-c", \ .v = (const char *[]){ "/bin/sh", "-c", \
"prop=\"$(printf '%b' \"$(xprop -id $1 $2 " \ "prop=\"$(printf '%b' \"$(xprop -id $1 "r" " \
"| sed \"s/^$2(STRING) = //;s/^\\\"\\(.*\\)\\\"$/\\1/\")\" " \ "| sed -e 's/^"r"(UTF8_STRING) = \"\\(.*\\)\"/\\1/' " \
"| dmenu -p \"$4\" -w $1)\" && xprop -id $1 -f $3 8s -set $3 \"$prop\"", \ " -e 's/\\\\\\(.\\)/\\1/g')\" " \
"surf-setprop", winid, r, s, p, NULL \ "| dmenu -p '"p"' -w $1)\" " \
"&& xprop -id $1 -f "s" 8u -set "s" \"$prop\"", \
"surf-setprop", winid, NULL \
} \ } \
} }
@@ -170,13 +172,13 @@ static Key keys[] = {
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_o, toggleinspector, { 0 } }, { MODKEY|GDK_SHIFT_MASK, GDK_KEY_o, toggleinspector, { 0 } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_c, toggle, { .i = CaretBrowsing } }, { MODKEY|GDK_SHIFT_MASK, GDK_KEY_c, toggle, { .i = CaretBrowsing } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_f, toggle, { .i = FrameFlattening } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_g, toggle, { .i = Geolocation } }, { MODKEY|GDK_SHIFT_MASK, GDK_KEY_g, toggle, { .i = Geolocation } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_s, toggle, { .i = JavaScript } }, { MODKEY|GDK_SHIFT_MASK, GDK_KEY_s, toggle, { .i = JavaScript } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_i, toggle, { .i = LoadImages } }, { MODKEY|GDK_SHIFT_MASK, GDK_KEY_i, toggle, { .i = LoadImages } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_b, toggle, { .i = ScrollBars } }, { MODKEY|GDK_SHIFT_MASK, GDK_KEY_b, toggle, { .i = ScrollBars } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_t, toggle, { .i = StrictTLS } }, { MODKEY|GDK_SHIFT_MASK, GDK_KEY_t, toggle, { .i = StrictTLS } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_m, toggle, { .i = Style } }, { MODKEY|GDK_SHIFT_MASK, GDK_KEY_m, toggle, { .i = Style } },
{ MODKEY|GDK_SHIFT_MASK, GDK_KEY_d, toggle, { .i = DarkMode } },
}; };
/* button definitions */ /* button definitions */
+5 -5
View File
@@ -4,7 +4,7 @@ VERSION = 2.1
# Customize below to fit your system # Customize below to fit your system
# paths # paths
PREFIX = /usr/local PREFIX = /usr
MANPREFIX = $(PREFIX)/share/man MANPREFIX = $(PREFIX)/share/man
LIBPREFIX = $(PREFIX)/lib LIBPREFIX = $(PREFIX)/lib
LIBDIR = $(LIBPREFIX)/surf LIBDIR = $(LIBPREFIX)/surf
@@ -12,10 +12,10 @@ LIBDIR = $(LIBPREFIX)/surf
X11INC = `pkg-config --cflags x11` X11INC = `pkg-config --cflags x11`
X11LIB = `pkg-config --libs x11` X11LIB = `pkg-config --libs x11`
GTKINC = `pkg-config --cflags gtk+-3.0 gcr-3 webkit2gtk-4.0` GTKINC = `pkg-config --cflags gtk+-3.0 gcr-3 webkit2gtk-4.1`
GTKLIB = `pkg-config --libs gtk+-3.0 gcr-3 webkit2gtk-4.0` GTKLIB = `pkg-config --libs gtk+-3.0 gcr-3 webkit2gtk-4.1`
WEBEXTINC = `pkg-config --cflags webkit2gtk-4.0 webkit2gtk-web-extension-4.0 gio-2.0` WEBEXTINC = `pkg-config --cflags webkit2gtk-4.1 webkit2gtk-web-extension-4.1 gio-2.0`
WEBEXTLIBS = `pkg-config --libs webkit2gtk-4.0 webkit2gtk-web-extension-4.0 gio-2.0` WEBEXTLIBS = `pkg-config --libs webkit2gtk-4.1 webkit2gtk-web-extension-4.1 gio-2.0`
# includes and libs # includes and libs
INCS = $(X11INC) $(GTKINC) INCS = $(X11INC) $(GTKINC)
+4 -4
View File
@@ -74,7 +74,7 @@ Disable Images.
Enable Images. Enable Images.
.TP .TP
.B \-k .B \-k
Disable kiosk mode (disable key strokes and right click). Disable kiosk mode (enable key strokes and right click).
.TP .TP
.B \-K .B \-K
Enable kiosk mode (disable key strokes and right click). Enable kiosk mode (disable key strokes and right click).
@@ -208,6 +208,9 @@ Toggle scrollbars. This will reload the page.
.B Ctrl\-Shift\-c .B Ctrl\-Shift\-c
Toggle caret browsing. This will reload the page. Toggle caret browsing. This will reload the page.
.TP .TP
.B Ctrl\-Shift\-d
Toggle dark mode.
.TP
.B Ctrl\-Shift\-i .B Ctrl\-Shift\-i
Toggle auto-loading of images. This will reload the page. Toggle auto-loading of images. This will reload the page.
.TP .TP
@@ -258,9 +261,6 @@ scripts
.B m M .B m M
styles styles
.TP .TP
.B f F
frame flattening
.TP
.B x X .B x X
custom certificates custom certificates
.TP .TP
+97 -94
View File
@@ -21,6 +21,7 @@
#include <gdk/gdk.h> #include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h> #include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
#include <gio/gunixfdlist.h>
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gtk/gtkx.h> #include <gtk/gtkx.h>
@@ -37,7 +38,7 @@
#define LENGTH(x) (sizeof(x) / sizeof(x[0])) #define LENGTH(x) (sizeof(x) / sizeof(x[0]))
#define CLEANMASK(mask) (mask & (MODKEY|GDK_SHIFT_MASK)) #define CLEANMASK(mask) (mask & (MODKEY|GDK_SHIFT_MASK))
enum { AtomFind, AtomGo, AtomUri, AtomLast }; enum { AtomFind, AtomGo, AtomUri, AtomUTF8, AtomLast };
enum { enum {
OnDoc = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT, OnDoc = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT,
@@ -56,21 +57,21 @@ typedef enum {
CaretBrowsing, CaretBrowsing,
Certificate, Certificate,
CookiePolicies, CookiePolicies,
DarkMode,
DiskCache, DiskCache,
DefaultCharset, DefaultCharset,
DNSPrefetch, DNSPrefetch,
Ephemeral, Ephemeral,
FileURLsCrossAccess, FileURLsCrossAccess,
FontSize, FontSize,
FrameFlattening,
Geolocation, Geolocation,
HideBackground, HideBackground,
Inspector, Inspector,
Java,
JavaScript, JavaScript,
KioskMode, KioskMode,
LoadImages, LoadImages,
MediaManualPlay, MediaManualPlay,
PDFJSviewer,
PreferredLanguages, PreferredLanguages,
RunInFullscreen, RunInFullscreen,
ScrollBars, ScrollBars,
@@ -100,6 +101,8 @@ typedef struct {
typedef struct Client { typedef struct Client {
GtkWidget *win; GtkWidget *win;
WebKitWebView *view; WebKitWebView *view;
WebKitSettings *settings;
WebKitWebContext *context;
WebKitWebInspector *inspector; WebKitWebInspector *inspector;
WebKitFindController *finder; WebKitFindController *finder;
WebKitHitTestResult *mousepos; WebKitHitTestResult *mousepos;
@@ -187,7 +190,6 @@ static gboolean buttonreleased(GtkWidget *w, GdkEvent *e, Client *c);
static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event, static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event,
gpointer d); gpointer d);
static gboolean winevent(GtkWidget *w, GdkEvent *e, Client *c); static gboolean winevent(GtkWidget *w, GdkEvent *e, Client *c);
static gboolean readsock(GIOChannel *s, GIOCondition ioc, gpointer unused);
static void showview(WebKitWebView *v, Client *c); static void showview(WebKitWebView *v, Client *c);
static GtkWidget *createwindow(Client *c); static GtkWidget *createwindow(Client *c);
static gboolean loadfailedtls(WebKitWebView *v, gchar *uri, static gboolean loadfailedtls(WebKitWebView *v, gchar *uri,
@@ -211,6 +213,8 @@ static void downloadstarted(WebKitWebContext *wc, WebKitDownload *d,
Client *c); Client *c);
static void responsereceived(WebKitDownload *d, GParamSpec *ps, Client *c); static void responsereceived(WebKitDownload *d, GParamSpec *ps, Client *c);
static void download(Client *c, WebKitURIResponse *r); static void download(Client *c, WebKitURIResponse *r);
static gboolean viewusrmsgrcv(WebKitWebView *v, WebKitUserMessage *m,
gpointer u);
static void webprocessterminated(WebKitWebView *v, static void webprocessterminated(WebKitWebView *v,
WebKitWebProcessTerminationReason r, WebKitWebProcessTerminationReason r,
Client *c); Client *c);
@@ -240,7 +244,7 @@ static void clicknewwindow(Client *c, const Arg *a, WebKitHitTestResult *h);
static void clickexternplayer(Client *c, const Arg *a, WebKitHitTestResult *h); static void clickexternplayer(Client *c, const Arg *a, WebKitHitTestResult *h);
static char winid[64]; static char winid[64];
static char togglestats[12]; static char togglestats[11];
static char pagestats[2]; static char pagestats[2];
static Atom atoms[AtomLast]; static Atom atoms[AtomLast];
static Window embed; static Window embed;
@@ -274,15 +278,15 @@ static ParamName loadcommitted[] = {
// AccessMicrophone, // AccessMicrophone,
// AccessWebcam, // AccessWebcam,
CaretBrowsing, CaretBrowsing,
DarkMode,
DefaultCharset, DefaultCharset,
FontSize, FontSize,
FrameFlattening,
Geolocation, Geolocation,
HideBackground, HideBackground,
Inspector, Inspector,
Java,
// KioskMode, // KioskMode,
MediaManualPlay, MediaManualPlay,
PDFJSviewer,
RunInFullscreen, RunInFullscreen,
ScrollBars, ScrollBars,
SiteQuirks, SiteQuirks,
@@ -315,7 +319,7 @@ die(const char *errstr, ...)
void void
usage(void) usage(void)
{ {
die("usage: surf [-bBdDfFgGiIkKmMnNpPsStTvwxX]\n" die("usage: surf [-bBdDfFgGiIkKmMnNsStTvwxX]\n"
"[-a cookiepolicies ] [-c cookiefile] [-C stylefile] [-e xid]\n" "[-a cookiepolicies ] [-c cookiefile] [-C stylefile] [-e xid]\n"
"[-r scriptfile] [-u useragent] [-z zoomlevel] [uri]\n"); "[-r scriptfile] [-u useragent] [-z zoomlevel] [uri]\n");
} }
@@ -339,6 +343,7 @@ setup(void)
atoms[AtomFind] = XInternAtom(dpy, "_SURF_FIND", False); atoms[AtomFind] = XInternAtom(dpy, "_SURF_FIND", False);
atoms[AtomGo] = XInternAtom(dpy, "_SURF_GO", False); atoms[AtomGo] = XInternAtom(dpy, "_SURF_GO", False);
atoms[AtomUri] = XInternAtom(dpy, "_SURF_URI", False); atoms[AtomUri] = XInternAtom(dpy, "_SURF_URI", False);
atoms[AtomUTF8] = XInternAtom(dpy, "UTF8_STRING", False);
gtk_init(NULL, NULL); gtk_init(NULL, NULL);
@@ -366,7 +371,6 @@ setup(void)
g_io_channel_set_flags(gchanin, g_io_channel_get_flags(gchanin) g_io_channel_set_flags(gchanin, g_io_channel_get_flags(gchanin)
| G_IO_FLAG_NONBLOCK, NULL); | G_IO_FLAG_NONBLOCK, NULL);
g_io_channel_set_close_on_unref(gchanin, TRUE); g_io_channel_set_close_on_unref(gchanin, TRUE);
g_io_add_watch(gchanin, G_IO_IN, readsock, NULL);
} }
@@ -565,6 +569,7 @@ loaduri(Client *c, const Arg *a)
if (g_str_has_prefix(uri, "http://") || if (g_str_has_prefix(uri, "http://") ||
g_str_has_prefix(uri, "https://") || g_str_has_prefix(uri, "https://") ||
g_str_has_prefix(uri, "file://") || g_str_has_prefix(uri, "file://") ||
g_str_has_prefix(uri, "webkit://") ||
g_str_has_prefix(uri, "about:")) { g_str_has_prefix(uri, "about:")) {
url = g_strdup(uri); url = g_strdup(uri);
} else { } else {
@@ -576,7 +581,7 @@ loaduri(Client *c, const Arg *a)
url = g_strdup_printf("file://%s", path); url = g_strdup_printf("file://%s", path);
free(path); free(path);
} else { } else {
url = g_strdup_printf("http://%s", uri); url = g_strdup_printf("https://%s", uri);
} }
if (apath != uri) if (apath != uri)
free(apath); free(apath);
@@ -608,7 +613,7 @@ void
setatom(Client *c, int a, const char *v) setatom(Client *c, int a, const char *v)
{ {
XChangeProperty(dpy, c->xid, XChangeProperty(dpy, c->xid,
atoms[a], XA_STRING, 8, PropModeReplace, atoms[a], atoms[AtomUTF8], 8, PropModeReplace,
(unsigned char *)v, strlen(v) + 1); (unsigned char *)v, strlen(v) + 1);
XSync(dpy, False); XSync(dpy, False);
} }
@@ -623,7 +628,8 @@ getatom(Client *c, int a)
unsigned char *p = NULL; unsigned char *p = NULL;
XSync(dpy, False); XSync(dpy, False);
XGetWindowProperty(dpy, c->xid, atoms[a], 0L, BUFSIZ, False, XA_STRING, XGetWindowProperty(dpy, c->xid,
atoms[a], 0L, BUFSIZ, False, atoms[AtomUTF8],
&adummy, &idummy, &ldummy, &ldummy, &p); &adummy, &idummy, &ldummy, &ldummy, &p);
if (p) if (p)
strncpy(buf, (char *)p, LENGTH(buf) - 1); strncpy(buf, (char *)p, LENGTH(buf) - 1);
@@ -668,11 +674,9 @@ gettogglestats(Client *c)
togglestats[3] = curconfig[DiskCache].val.i ? 'D' : 'd'; togglestats[3] = curconfig[DiskCache].val.i ? 'D' : 'd';
togglestats[4] = curconfig[LoadImages].val.i ? 'I' : 'i'; togglestats[4] = curconfig[LoadImages].val.i ? 'I' : 'i';
togglestats[5] = curconfig[JavaScript].val.i ? 'S' : 's'; togglestats[5] = curconfig[JavaScript].val.i ? 'S' : 's';
togglestats[7] = curconfig[Style].val.i ? 'M' : 'm'; togglestats[6] = curconfig[Style].val.i ? 'M' : 'm';
togglestats[8] = curconfig[FrameFlattening].val.i ? 'F' : 'f'; togglestats[8] = curconfig[Certificate].val.i ? 'X' : 'x';
togglestats[9] = curconfig[Certificate].val.i ? 'X' : 'x'; togglestats[9] = curconfig[StrictTLS].val.i ? 'T' : 't';
togglestats[10] = curconfig[StrictTLS].val.i ? 'T' : 't';
togglestats[11] = '\0';
} }
void void
@@ -747,7 +751,6 @@ void
setparameter(Client *c, int refresh, ParamName p, const Arg *a) setparameter(Client *c, int refresh, ParamName p, const Arg *a)
{ {
GdkRGBA bgcolor = { 0 }; GdkRGBA bgcolor = { 0 };
WebKitSettings *s = webkit_web_view_get_settings(c->view);
modparams[p] = curconfig[p].prio; modparams[p] = curconfig[p].prio;
@@ -757,7 +760,7 @@ setparameter(Client *c, int refresh, ParamName p, const Arg *a)
case AccessWebcam: case AccessWebcam:
return; /* do nothing */ return; /* do nothing */
case CaretBrowsing: case CaretBrowsing:
webkit_settings_set_enable_caret_browsing(s, a->i); webkit_settings_set_enable_caret_browsing(c->settings, a->i);
refresh = 0; refresh = 0;
break; break;
case Certificate: case Certificate:
@@ -766,33 +769,34 @@ setparameter(Client *c, int refresh, ParamName p, const Arg *a)
return; /* do not update */ return; /* do not update */
case CookiePolicies: case CookiePolicies:
webkit_cookie_manager_set_accept_policy( webkit_cookie_manager_set_accept_policy(
webkit_web_context_get_cookie_manager( webkit_web_context_get_cookie_manager(c->context),
webkit_web_view_get_context(c->view)),
cookiepolicy_get()); cookiepolicy_get());
refresh = 0; refresh = 0;
break; break;
case DarkMode:
g_object_set(gtk_settings_get_default(),
"gtk-application-prefer-dark-theme", a->i, NULL);
return;
case DiskCache: case DiskCache:
webkit_web_context_set_cache_model( webkit_web_context_set_cache_model(c->context, a->i ?
webkit_web_view_get_context(c->view), a->i ?
WEBKIT_CACHE_MODEL_WEB_BROWSER : WEBKIT_CACHE_MODEL_WEB_BROWSER :
WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER); WEBKIT_CACHE_MODEL_DOCUMENT_VIEWER);
return; /* do not update */ return; /* do not update */
case DefaultCharset: case DefaultCharset:
webkit_settings_set_default_charset(s, a->v); webkit_settings_set_default_charset(c->settings, a->v);
return; /* do not update */ return; /* do not update */
case DNSPrefetch: case DNSPrefetch:
webkit_settings_set_enable_dns_prefetching(s, a->i); webkit_settings_set_enable_dns_prefetching(c->settings, a->i);
return; /* do not update */ return; /* do not update */
case FileURLsCrossAccess: case FileURLsCrossAccess:
webkit_settings_set_allow_file_access_from_file_urls(s, a->i); webkit_settings_set_allow_file_access_from_file_urls(
webkit_settings_set_allow_universal_access_from_file_urls(s, a->i); c->settings, a->i);
webkit_settings_set_allow_universal_access_from_file_urls(
c->settings, a->i);
return; /* do not update */ return; /* do not update */
case FontSize: case FontSize:
webkit_settings_set_default_font_size(s, a->i); webkit_settings_set_default_font_size(c->settings, a->i);
return; /* do not update */ return; /* do not update */
case FrameFlattening:
webkit_settings_set_enable_frame_flattening(s, a->i);
break;
case Geolocation: case Geolocation:
refresh = 0; refresh = 0;
break; break;
@@ -801,22 +805,22 @@ setparameter(Client *c, int refresh, ParamName p, const Arg *a)
webkit_web_view_set_background_color(c->view, &bgcolor); webkit_web_view_set_background_color(c->view, &bgcolor);
return; /* do not update */ return; /* do not update */
case Inspector: case Inspector:
webkit_settings_set_enable_developer_extras(s, a->i); webkit_settings_set_enable_developer_extras(c->settings, a->i);
return; /* do not update */
case Java:
webkit_settings_set_enable_java(s, a->i);
return; /* do not update */ return; /* do not update */
case JavaScript: case JavaScript:
webkit_settings_set_enable_javascript(s, a->i); webkit_settings_set_enable_javascript(c->settings, a->i);
break; break;
case KioskMode: case KioskMode:
return; /* do nothing */ return; /* do nothing */
case LoadImages: case LoadImages:
webkit_settings_set_auto_load_images(s, a->i); webkit_settings_set_auto_load_images(c->settings, a->i);
break; break;
case MediaManualPlay: case MediaManualPlay:
webkit_settings_set_media_playback_requires_user_gesture(s, a->i); webkit_settings_set_media_playback_requires_user_gesture(
c->settings, a->i);
break; break;
case PDFJSviewer:
return; /* do nothing */
case PreferredLanguages: case PreferredLanguages:
return; /* do nothing */ return; /* do nothing */
case RunInFullscreen: case RunInFullscreen:
@@ -832,20 +836,21 @@ setparameter(Client *c, int refresh, ParamName p, const Arg *a)
case ShowIndicators: case ShowIndicators:
break; break;
case SmoothScrolling: case SmoothScrolling:
webkit_settings_set_enable_smooth_scrolling(s, a->i); webkit_settings_set_enable_smooth_scrolling(c->settings, a->i);
return; /* do not update */ return; /* do not update */
case SiteQuirks: case SiteQuirks:
webkit_settings_set_enable_site_specific_quirks(s, a->i); webkit_settings_set_enable_site_specific_quirks(
c->settings, a->i);
break; break;
case SpellChecking: case SpellChecking:
webkit_web_context_set_spell_checking_enabled( webkit_web_context_set_spell_checking_enabled(
webkit_web_view_get_context(c->view), a->i); c->context, a->i);
return; /* do not update */ return; /* do not update */
case SpellLanguages: case SpellLanguages:
return; /* do nothing */ return; /* do nothing */
case StrictTLS: case StrictTLS:
webkit_web_context_set_tls_errors_policy( webkit_website_data_manager_set_tls_errors_policy(
webkit_web_view_get_context(c->view), a->i ? webkit_web_view_get_website_data_manager(c->view), a->i ?
WEBKIT_TLS_ERRORS_POLICY_FAIL : WEBKIT_TLS_ERRORS_POLICY_FAIL :
WEBKIT_TLS_ERRORS_POLICY_IGNORE); WEBKIT_TLS_ERRORS_POLICY_IGNORE);
break; break;
@@ -857,7 +862,7 @@ setparameter(Client *c, int refresh, ParamName p, const Arg *a)
refresh = 0; refresh = 0;
break; break;
case WebGL: case WebGL:
webkit_settings_set_enable_webgl(s, a->i); webkit_settings_set_enable_webgl(c->settings, a->i);
break; break;
case ZoomLevel: case ZoomLevel:
webkit_web_view_set_zoom_level(c->view, a->f); webkit_web_view_set_zoom_level(c->view, a->f);
@@ -903,8 +908,8 @@ setcert(Client *c, const char *uri)
if ((uri = strstr(uri, "https://"))) { if ((uri = strstr(uri, "https://"))) {
uri += sizeof("https://") - 1; uri += sizeof("https://") - 1;
host = g_strndup(uri, strchr(uri, '/') - uri); host = g_strndup(uri, strchr(uri, '/') - uri);
webkit_web_context_allow_tls_certificate_for_host( webkit_web_context_allow_tls_certificate_for_host(c->context,
webkit_web_view_get_context(c->view), cert, host); cert, host);
g_free(host); g_free(host);
} }
@@ -970,7 +975,8 @@ evalscript(Client *c, const char *jsstr, ...)
script = g_strdup_vprintf(jsstr, ap); script = g_strdup_vprintf(jsstr, ap);
va_end(ap); va_end(ap);
webkit_web_view_run_javascript(c->view, script, NULL, NULL, NULL); webkit_web_view_evaluate_javascript(c->view, script, -1,
NULL, NULL, NULL, NULL, NULL);
g_free(script); g_free(script);
} }
@@ -1103,6 +1109,8 @@ newview(Client *c, WebKitWebView *rv)
/* Webview */ /* Webview */
if (rv) { 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));
context = webkit_web_view_get_context(v);
settings = webkit_web_view_get_settings(v);
} else { } else {
settings = webkit_settings_new_with_settings( settings = webkit_settings_new_with_settings(
"allow-file-access-from-file-urls", curconfig[FileURLsCrossAccess].val.i, "allow-file-access-from-file-urls", curconfig[FileURLsCrossAccess].val.i,
@@ -1113,10 +1121,8 @@ newview(Client *c, WebKitWebView *rv)
"enable-caret-browsing", curconfig[CaretBrowsing].val.i, "enable-caret-browsing", curconfig[CaretBrowsing].val.i,
"enable-developer-extras", curconfig[Inspector].val.i, "enable-developer-extras", curconfig[Inspector].val.i,
"enable-dns-prefetching", curconfig[DNSPrefetch].val.i, "enable-dns-prefetching", curconfig[DNSPrefetch].val.i,
"enable-frame-flattening", curconfig[FrameFlattening].val.i,
"enable-html5-database", curconfig[DiskCache].val.i, "enable-html5-database", curconfig[DiskCache].val.i,
"enable-html5-local-storage", curconfig[DiskCache].val.i, "enable-html5-local-storage", curconfig[DiskCache].val.i,
"enable-java", curconfig[Java].val.i,
"enable-javascript", curconfig[JavaScript].val.i, "enable-javascript", curconfig[JavaScript].val.i,
"enable-site-specific-quirks", curconfig[SiteQuirks].val.i, "enable-site-specific-quirks", curconfig[SiteQuirks].val.i,
"enable-smooth-scrolling", curconfig[SmoothScrolling].val.i, "enable-smooth-scrolling", curconfig[SmoothScrolling].val.i,
@@ -1146,15 +1152,11 @@ newview(Client *c, WebKitWebView *rv)
NULL)); NULL));
} }
cookiemanager = webkit_web_context_get_cookie_manager(context); 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,
WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES);
/* TLS */ /* TLS */
webkit_web_context_set_tls_errors_policy(context, webkit_website_data_manager_set_tls_errors_policy(
webkit_web_context_get_website_data_manager(context),
curconfig[StrictTLS].val.i ? WEBKIT_TLS_ERRORS_POLICY_FAIL : curconfig[StrictTLS].val.i ? WEBKIT_TLS_ERRORS_POLICY_FAIL :
WEBKIT_TLS_ERRORS_POLICY_IGNORE); WEBKIT_TLS_ERRORS_POLICY_IGNORE);
/* disk cache */ /* disk cache */
@@ -1213,47 +1215,22 @@ newview(Client *c, WebKitWebView *rv)
G_CALLBACK(permissionrequested), c); G_CALLBACK(permissionrequested), c);
g_signal_connect(G_OBJECT(v), "ready-to-show", g_signal_connect(G_OBJECT(v), "ready-to-show",
G_CALLBACK(showview), c); G_CALLBACK(showview), c);
g_signal_connect(G_OBJECT(v), "user-message-received",
G_CALLBACK(viewusrmsgrcv), c);
g_signal_connect(G_OBJECT(v), "web-process-terminated", g_signal_connect(G_OBJECT(v), "web-process-terminated",
G_CALLBACK(webprocessterminated), c); G_CALLBACK(webprocessterminated), c);
c->context = context;
c->settings = settings;
setparameter(c, 0, DarkMode, &curconfig[DarkMode].val);
return v; return v;
} }
static gboolean
readsock(GIOChannel *s, GIOCondition ioc, gpointer unused)
{
static char msg[MSGBUFSZ];
GError *gerr = NULL;
gsize msgsz;
if (g_io_channel_read_chars(s, msg, sizeof(msg), &msgsz, &gerr) !=
G_IO_STATUS_NORMAL) {
if (gerr) {
fprintf(stderr, "surf: error reading socket: %s\n",
gerr->message);
g_error_free(gerr);
}
return TRUE;
}
if (msgsz < 2) {
fprintf(stderr, "surf: message too short: %d\n", msgsz);
return TRUE;
}
return TRUE;
}
void void
initwebextensions(WebKitWebContext *wc, Client *c) initwebextensions(WebKitWebContext *wc, Client *c)
{ {
GVariant *gv;
if (spair[1] < 0)
return;
gv = g_variant_new("i", spair[1]);
webkit_web_context_set_web_extensions_initialization_user_data(wc, gv);
webkit_web_context_set_web_extensions_directory(wc, WEBEXTDIR); webkit_web_context_set_web_extensions_directory(wc, WEBEXTDIR);
} }
@@ -1556,6 +1533,30 @@ titlechanged(WebKitWebView *view, GParamSpec *ps, Client *c)
updatetitle(c); updatetitle(c);
} }
gboolean
viewusrmsgrcv(WebKitWebView *v, WebKitUserMessage *m, gpointer unused)
{
WebKitUserMessage *r;
GUnixFDList *gfd;
const char *name;
name = webkit_user_message_get_name(m);
if (strcmp(name, "page-created") != 0) {
fprintf(stderr, "surf: Unknown UserMessage: %s\n", name);
return TRUE;
}
if (spair[1] < 0)
return TRUE;
gfd = g_unix_fd_list_new_from_array(&spair[1], 1);
r = webkit_user_message_new_with_fd_list("surf-pipe", NULL, gfd);
webkit_user_message_send_reply(m, r);
return TRUE;
}
void void
mousetargetchanged(WebKitWebView *v, WebKitHitTestResult *h, guint modifiers, mousetargetchanged(WebKitWebView *v, WebKitHitTestResult *h, guint modifiers,
Client *c) Client *c)
@@ -1641,8 +1642,7 @@ decidenavigation(WebKitPolicyDecision *d, Client *c)
case WEBKIT_NAVIGATION_TYPE_OTHER: /* fallthrough */ case WEBKIT_NAVIGATION_TYPE_OTHER: /* fallthrough */
default: default:
/* Do not navigate to links with a "_blank" target (popup) */ /* Do not navigate to links with a "_blank" target (popup) */
if (webkit_navigation_policy_decision_get_frame_name( if (webkit_navigation_action_get_frame_name(a)) {
WEBKIT_NAVIGATION_POLICY_DECISION(d))) {
webkit_policy_decision_ignore(d); webkit_policy_decision_ignore(d);
} else { } else {
/* Filter out navigation to different domain ? */ /* Filter out navigation to different domain ? */
@@ -1702,8 +1702,10 @@ decideresource(WebKitPolicyDecision *d, Client *c)
&& !g_str_has_prefix(uri, "https://") && !g_str_has_prefix(uri, "https://")
&& !g_str_has_prefix(uri, "about:") && !g_str_has_prefix(uri, "about:")
&& !g_str_has_prefix(uri, "file://") && !g_str_has_prefix(uri, "file://")
&& !g_str_has_prefix(uri, "webkit://")
&& !g_str_has_prefix(uri, "data:") && !g_str_has_prefix(uri, "data:")
&& !g_str_has_prefix(uri, "blob:") && !g_str_has_prefix(uri, "blob:")
&& !(g_str_has_prefix(uri, "webkit-pdfjs-viewer://") && curconfig[PDFJSviewer].val.i)
&& strlen(uri) > 0) { && strlen(uri) > 0) {
for (i = 0; i < strlen(uri); i++) { for (i = 0; i < strlen(uri); i++) {
if (!g_ascii_isprint(uri[i])) { if (!g_ascii_isprint(uri[i])) {
@@ -1856,21 +1858,22 @@ zoom(Client *c, const Arg *a)
static void static void
msgext(Client *c, char type, const Arg *a) msgext(Client *c, char type, const Arg *a)
{ {
static char msg[MSGBUFSZ]; static unsigned char msg[MSGBUFSZ];
int ret; int ret;
if (spair[0] < 0) if (spair[0] < 0)
return; return;
if ((ret = snprintf(msg, sizeof(msg), "%c%c%c", c->pageid, type, a->i)) ret = snprintf(msg, sizeof(msg), "%c%c%c",
>= sizeof(msg)) { (unsigned char)c->pageid, type, (signed char)a->i);
if (ret >= sizeof(msg)) {
fprintf(stderr, "surf: message too long: %d\n", ret); fprintf(stderr, "surf: message too long: %d\n", ret);
return; return;
} }
if (send(spair[0], msg, ret, 0) != ret) if (send(spair[0], msg, ret, 0) != ret)
fprintf(stderr, "surf: error sending: %u%c%d (%d)\n", fprintf(stderr, "surf: error sending: %hhu/%c/%d (%d)\n",
c->pageid, type, a->i, ret); (unsigned char)c->pageid, type, a->i, ret);
} }
void void
+108 -48
View File
@@ -7,6 +7,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <gio/gio.h> #include <gio/gio.h>
#include <gio/gunixfdlist.h>
#include <webkit2/webkit-web-extension.h> #include <webkit2/webkit-web-extension.h>
#include <webkitdom/webkitdom.h> #include <webkitdom/webkitdom.h>
#include <webkitdom/WebKitDOMDOMWindowUnstable.h> #include <webkitdom/WebKitDOMDOMWindowUnstable.h>
@@ -18,33 +19,73 @@
static WebKitWebExtension *webext; static WebKitWebExtension *webext;
static int sock; static int sock;
static void /*
msgsurf(guint64 pageid, const char *s) * Return:
* 0 No data processed: need more data
* > 0 Amount of data processed or discarded
*/
static size_t
evalmsg(char *msg, size_t sz)
{ {
static char msg[MSGBUFSZ]; char js[48];
size_t sln = strlen(s); WebKitWebPage *page;
int ret; JSCContext *jsc;
JSCValue *jsv;
if ((ret = snprintf(msg, sizeof(msg), "%c%s", pageid, s)) if (!(page = webkit_web_extension_get_page(webext, msg[0])))
>= sizeof(msg)) { return sz;
fprintf(stderr, "webext: msg: message too long: %d\n", ret);
return; if (sz < 2)
return 0;
jsc = webkit_frame_get_js_context(webkit_web_page_get_main_frame(page));
jsv = NULL;
switch (msg[1]) {
case 'h':
if (sz < 3) {
sz = 0;
break;
}
sz = 3;
snprintf(js, sizeof(js),
"window.scrollBy(window.innerWidth/100*%hhd,0);",
msg[2]);
jsv = jsc_context_evaluate(jsc, js, -1);
break;
case 'v':
if (sz < 3) {
sz = 0;
break;
}
sz = 3;
snprintf(js, sizeof(js),
"window.scrollBy(0,window.innerHeight/100*%hhd);",
msg[2]);
jsv = jsc_context_evaluate(jsc, js, -1);
break;
default:
fprintf(stderr, "%s:%d:evalmsg: unknown cmd(%zu): '%#x'\n",
__FILE__, __LINE__, sz, msg[1]);
} }
if (send(sock, msg, ret, 0) < 0) g_object_unref(jsc);
fprintf(stderr, "webext: error sending: %s\n", msg+1); if (jsv)
g_object_unref(jsv);
return sz;
} }
static gboolean static gboolean
readsock(GIOChannel *s, GIOCondition c, gpointer unused) readsock(GIOChannel *s, GIOCondition c, gpointer unused)
{ {
static char js[48], msg[MSGBUFSZ]; static char msg[MSGBUFSZ];
WebKitWebPage *page; static size_t msgoff;
JSCContext *jsc;
GError *gerr = NULL; GError *gerr = NULL;
gsize msgsz; size_t sz;
gsize rsz;
if (g_io_channel_read_chars(s, msg, sizeof(msg), &msgsz, &gerr) != if (g_io_channel_read_chars(s, msg+msgoff, sizeof(msg)-msgoff, &rsz, &gerr) !=
G_IO_STATUS_NORMAL) { G_IO_STATUS_NORMAL) {
if (gerr) { if (gerr) {
fprintf(stderr, "webext: error reading socket: %s\n", fprintf(stderr, "webext: error reading socket: %s\n",
@@ -53,49 +94,50 @@ readsock(GIOChannel *s, GIOCondition c, gpointer unused)
} }
return TRUE; return TRUE;
} }
if (msgoff >= sizeof(msg)) {
if (msgsz < 2) { fprintf(stderr, "%s:%d:%s: msgoff: %zu", __FILE__, __LINE__, __func__, msgoff);
fprintf(stderr, "webext: readsock: message too short: %d\n", return FALSE;
msgsz);
return TRUE;
} }
if (!(page = webkit_web_extension_get_page(webext, msg[0]))) for (rsz += msgoff; rsz; rsz -= sz) {
return TRUE; sz = evalmsg(msg, rsz);
if (sz == 0) {
jsc = webkit_frame_get_js_context(webkit_web_page_get_main_frame(page)); /* need more data */
break;
switch (msg[1]) { }
case 'h': if (sz != rsz) {
if (msgsz != 3) /* continue processing message */
return TRUE; memmove(msg, msg+sz, rsz-sz);
snprintf(js, sizeof(js), }
"window.scrollBy(window.innerWidth/100*%d,0);",
msg[2]);
jsc_context_evaluate(jsc, js, -1);
break;
case 'v':
if (msgsz != 3)
return TRUE;
snprintf(js, sizeof(js),
"window.scrollBy(0,window.innerHeight/100*%d);",
msg[2]);
jsc_context_evaluate(jsc, js, -1);
break;
} }
msgoff = rsz;
return TRUE; return TRUE;
} }
G_MODULE_EXPORT void static void
webkit_web_extension_initialize_with_user_data(WebKitWebExtension *e, pageusermessagereply(GObject *o, GAsyncResult *r, gpointer page)
const GVariant *gv)
{ {
WebKitUserMessage *m;
GUnixFDList *gfd;
GIOChannel *gchansock; GIOChannel *gchansock;
const char *name;
int nfd;
webext = e; m = webkit_web_page_send_message_to_view_finish(page, r, NULL);
name = webkit_user_message_get_name(m);
if (strcmp(name, "surf-pipe") != 0) {
fprintf(stderr, "webext-surf: Unknown User Reply: %s\n", name);
return;
}
g_variant_get(gv, "i", &sock); gfd = webkit_user_message_get_fd_list(m);
if ((nfd = g_unix_fd_list_get_length(gfd)) != 1) {
fprintf(stderr, "webext-surf: Too many file-descriptors: %d\n", nfd);
return;
}
sock = g_unix_fd_list_get(gfd, 0, NULL);
gchansock = g_io_channel_unix_new(sock); gchansock = g_io_channel_unix_new(sock);
g_io_channel_set_encoding(gchansock, NULL, NULL); g_io_channel_set_encoding(gchansock, NULL, NULL);
@@ -104,3 +146,21 @@ webkit_web_extension_initialize_with_user_data(WebKitWebExtension *e,
g_io_channel_set_close_on_unref(gchansock, TRUE); g_io_channel_set_close_on_unref(gchansock, TRUE);
g_io_add_watch(gchansock, G_IO_IN, readsock, NULL); g_io_add_watch(gchansock, G_IO_IN, readsock, NULL);
} }
void
pagecreated(WebKitWebExtension *e, WebKitWebPage *p, gpointer unused)
{
WebKitUserMessage *msg;
msg = webkit_user_message_new("page-created", NULL);
webkit_web_page_send_message_to_view(p, msg, NULL, pageusermessagereply, p);
}
G_MODULE_EXPORT void
webkit_web_extension_initialize(WebKitWebExtension *e)
{
webext = e;
g_signal_connect(G_OBJECT(e), "page-created",
G_CALLBACK(pagecreated), NULL);
}