diff --git a/config.def.h b/config.def.h index 0e2a0d3..406a255 100644 --- a/config.def.h +++ b/config.def.h @@ -121,6 +121,9 @@ static WebKitFindOptions findopts = WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE | } \ } +static char *savescreen[] = { "/bin/sh", "-c", "~/suckless/surf/save_screen.sh $(xprop -id $0 _SURF_URI | cut -d '\"' -f2)", winid, NULL }; +static char *editscreen[] = { "/bin/sh", "-c", "~/suckless/surf/edit_screen.sh", NULL }; + /* styles */ /* * The iteration will stop at the first match, beginning at the beginning of @@ -185,6 +188,9 @@ static Key keys[] = { { MODKEY, GDK_KEY_p, print, { 0 } }, { MODKEY, GDK_KEY_t, showcert, { 0 } }, + { MODKEY, GDK_KEY_o, externalpipe, { .v = editscreen } }, + { MODKEY, GDK_KEY_s, externalpipe, { .v = savescreen } }, + { MODKEY|GDK_SHIFT_MASK, GDK_KEY_a, togglecookiepolicy, { 0 } }, { 0, GDK_KEY_F11, togglefullscreen, { 0 } }, diff --git a/edit_screen.sh b/edit_screen.sh new file mode 100755 index 0000000..3326666 --- /dev/null +++ b/edit_screen.sh @@ -0,0 +1,5 @@ +#!/bin/sh +tmpfile=$(mktemp /tmp/st-edit.XXXXXX) +trap 'rm "$tmpfile"' 0 1 15 +cat > "$tmpfile" +st -e "$EDITOR" "$tmpfile" diff --git a/save_screen.sh b/save_screen.sh new file mode 100755 index 0000000..1a1fe7e --- /dev/null +++ b/save_screen.sh @@ -0,0 +1,7 @@ +#!/bin/sh +filename=$(basename "$1") +file=$(zenity --file-selection --save --filename="$filename") +if [ -n "$file" ]; then + cat > "$file" +fi + diff --git a/surf.c b/surf.c index d5fe0b6..9e83c8b 100644 --- a/surf.c +++ b/surf.c @@ -234,6 +234,7 @@ static void togglefullscreen(Client *c, const Arg *a); static void togglecookiepolicy(Client *c, const Arg *a); static void toggleinspector(Client *c, const Arg *a); static void find(Client *c, const Arg *a); +static void externalpipe(Client *c, const Arg *a); /* Buttons */ static void clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h); @@ -1981,6 +1982,79 @@ find(Client *c, const Arg *a) } } +static void +externalpipe_execute(char* buffer, Arg *arg) { + int to[2]; + void (*oldsigpipe)(int); + + if (pipe(to) == -1) + return; + + switch (fork()) { + case -1: + close(to[0]); + close(to[1]); + return; + case 0: + dup2(to[0], STDIN_FILENO); close(to[0]); close(to[1]); + execvp(((char **)arg->v)[0], (char **)arg->v); + fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]); + perror("failed"); + exit(0); + } + + close(to[0]); + oldsigpipe = signal(SIGPIPE, SIG_IGN); + write(to[1], buffer, strlen(buffer)); + close(to[1]); + signal(SIGPIPE, oldsigpipe); +} + +static void +externalpipe_resource_done(WebKitWebResource *r, GAsyncResult *s, Arg *arg) +{ + GError *gerr = NULL; + guchar *buffer = webkit_web_resource_get_data_finish(r, s, NULL, &gerr); + if (gerr == NULL) { + externalpipe_execute((char *) buffer, arg); + } else { + g_error_free(gerr); + } + g_free(buffer); +} + +static void +externalpipe_js_done(WebKitWebView *wv, GAsyncResult *s, Arg *arg) +{ + WebKitJavascriptResult *j = webkit_web_view_run_javascript_finish(wv, s, NULL); + if (!j) { + return; + } + JSCValue *v = webkit_javascript_result_get_js_value(j); + if (jsc_value_is_string(v)) { + char *buffer = jsc_value_to_string(v); + externalpipe_execute(buffer, arg); + g_free(buffer); + } + webkit_javascript_result_unref(j); +} + +void +externalpipe(Client *c, const Arg *arg) +{ + setatom(c, AtomUri, geturi(c)); + if (curconfig[JavaScript].val.i) { + webkit_web_view_run_javascript( + c->view, "window.document.documentElement.outerHTML", + NULL, externalpipe_js_done, arg); + } else { + WebKitWebResource *resource = webkit_web_view_get_main_resource(c->view); + if (resource != NULL) { + webkit_web_resource_get_data(resource, NULL, externalpipe_resource_done, arg); + } + } +} + void clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h) {