surf

A surf web browser [kocotian build]
git clone git://git.kocotian.pl/surf.git
Log | Files | Refs | README | LICENSE

commit dc965f4d65d262401b0e1630d0e37f77a7961b72
parent 7dcce9e1b9dbd2be198c19abd36e71eba7d09063
Author: kocotian <kocotian@kocotian.pl>
Date:   Wed, 16 Dec 2020 18:22:14 +0100

.surf -> .config/surf; patches add

Diffstat:
Mconfig.def.h | 10+++++-----
Aconfig.h | 2++
Apatches/surf-0.1-chromebar.diff | 321+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/surf-0.5-download.diff | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/surf-0.6-chromekeys.diff | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/surf-2.0-externalpipe.diff | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/surf-2.0-homepage.diff | 24++++++++++++++++++++++++
Apatches/surf-2.0-notifications.diff | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/surf-bookmarks-20170722-723ff26.diff | 42++++++++++++++++++++++++++++++++++++++++++
Apatches/surf-clipboard-20200112-a6a8878.diff | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/surf-dlconsole-20190919-d068a38.diff | 226+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/surf-externalpipe-signal-2.0.diff | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/surf-history-20181009-2b71a22.diff | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/surf-startgo-20200913-d068a38.diff | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14 files changed, 1411 insertions(+), 5 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -1,11 +1,11 @@ /* modifier 0 means no modifier */ static int surfuseragent = 1; /* Append Surf version to default WebKit user agent */ static char *fulluseragent = ""; /* Or override the whole user agent string */ -static char *scriptfile = "~/.surf/script.js"; -static char *styledir = "~/.surf/styles/"; -static char *certdir = "~/.surf/certificates/"; -static char *cachedir = "~/.surf/cache/"; -static char *cookiefile = "~/.surf/cookies.txt"; +static char *scriptfile = "~/.config/surf/script.js"; +static char *styledir = "~/.config/surf/styles/"; +static char *certdir = "~/.config/surf/certificates/"; +static char *cachedir = "~/.config/surf/cache/"; +static char *cookiefile = "~/.config/surf/cookies.txt"; static char **plugindirs = (char*[]){ "~/.surf/plugins/", LIBPREFIX "/mozilla/plugins/", diff --git a/config.h b/config.h @@ -0,0 +1 @@ +config.def.h+ \ No newline at end of file diff --git a/patches/surf-0.1-chromebar.diff b/patches/surf-0.1-chromebar.diff @@ -0,0 +1,321 @@ +diff --git a/surf.c b/surf.c +index 53dda18..38c15a4 100644 +--- a/surf.c ++++ b/surf.c +@@ -17,6 +17,7 @@ + #include <limits.h> + #include <stdlib.h> + #include <stdio.h> ++#include <ctype.h> + #include <webkit/webkit.h> + #include <glib/gstdio.h> + #include <JavaScriptCore/JavaScript.h> +@@ -71,6 +72,12 @@ typedef struct { + + G_DEFINE_TYPE(CookieJar, cookiejar, SOUP_TYPE_COOKIE_JAR_TEXT) + ++typedef struct { ++ char *token; ++ char *uri; ++ int nr; ++} SearchEngine; ++ + static Display *dpy; + static Atom atoms[AtomLast]; + static Client *clients = NULL; +@@ -141,6 +148,9 @@ static void loaduri(Client *c, const Arg *arg); + static void navigate(Client *c, const Arg *arg); + static Client *newclient(void); + static void newwindow(Client *c, const Arg *arg, gboolean noembed); ++static const gchar *parseuri(const gchar *uri, char **parsed_uri); ++static char **parse_address(const char *url); ++static char **parse_url(char *str); + static void pasteuri(GtkClipboard *clipboard, const char *text, gpointer d); + static void populatepopup(WebKitWebView *web, GtkMenu *menu, Client *c); + static void popupactivate(GtkMenuItem *menu, Client *); +@@ -166,6 +176,7 @@ static void togglescrollbars(Client *c, const Arg *arg); + static void togglestyle(Client *c, const Arg *arg); + static void updatetitle(Client *c); + static void updatewinid(Client *c); ++static int url_has_domain(char *url, char **parsed_uri); + static void usage(void); + static void windowobjectcleared(GtkWidget *w, WebKitWebFrame *frame, + JSContextRef js, JSObjectRef win, Client *c); +@@ -616,32 +627,63 @@ loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c) { + + static void + loaduri(Client *c, const Arg *arg) { +- char *u, *rp; +- const char *uri = (char *)arg->v; ++ const gchar *u; ++ char *rp, *pt; ++ const gchar *uri = arg->v; ++ char **parsed_uri; ++ char *home; ++ char *path; ++ int i; ++ FILE *f; + Arg a = { .b = FALSE }; +- struct stat st; + +- if(strcmp(uri, "") == 0) ++ if (*uri == '\0') + return; + ++ pt=malloc(strlen(uri)+1); ++ pt=strdup((char *)uri); ++ parsed_uri = parse_url(pt); ++ + /* In case it's a file path. */ +- if(stat(uri, &st) == 0) { +- rp = realpath(uri, NULL); ++ if(strncmp(parsed_uri[0], "file://", 6) == 0 || ++ ( strlen(parsed_uri[0]) == 0 && strlen(parsed_uri[1]) == 0)) { ++ path=malloc(strlen(parsed_uri[1])+strlen(parsed_uri[2])+strlen(parsed_uri[3])+1); ++ path=strcpy(path, parsed_uri[1]); ++ path=strcat(path, parsed_uri[2]); ++ path=strcat(path, parsed_uri[3]); ++ ++ if (path[0] == '~') ++ { ++ home = getenv("HOME"); ++ home = realloc(home, strlen(path)+strlen(home)); ++ home = strcat(home, path+1); ++ free(path); ++ path = home; ++ } ++ rp = realpath(path, NULL); + u = g_strdup_printf("file://%s", rp); ++ free(path); + free(rp); + } else { +- u = g_strrstr(uri, "://") ? g_strdup(uri) +- : g_strdup_printf("http://%s", uri); ++ u = parseuri(pt,parsed_uri); + } + ++ free(pt); ++ for (i=0;i<4;i++) ++ free(parsed_uri[i]); ++ free(parsed_uri); ++ + /* prevents endless loop */ + if(c->uri && strcmp(u, c->uri) == 0) { + reload(c, &a); + } else { + webkit_web_view_load_uri(c->view, u); ++ f = fopen(historyfile, "a+"); ++ fprintf(f, "%s", u); ++ fclose(f); + c->progress = 0; + c->title = copystr(&c->title, u); +- g_free(u); ++ g_free((gpointer )u); + updatetitle(c); + } + } +@@ -912,6 +954,196 @@ popupactivate(GtkMenuItem *menu, Client *c) { + } + } + ++#define SCHEME_CHAR(ch) (isalnum (ch) || (ch) == '-' || (ch) == '+') ++ ++/* ++ * This function takes an url and chop it into three part: sheme, domain, the ++ * rest, e.g. http://www.google.co.uk/search?q=hello will produce a triple ++ * ('http://', 'www.google.co.uk', '/search?q=hello') ++ */ ++static char ** ++parse_url(char *str) { ++ /* Return the position of ':' - last element of a scheme, or 0 if there ++ * is no scheme. */ ++ char *sch=""; ++ char *pt; ++ char **ret; ++ char **dret; ++ int k,i = 0; ++ ++ pt=malloc(strlen(str)+1); ++ pt=strcpy(pt, str); ++ ++ while (*pt == ' ') ++ pt+=1; ++ ret=malloc(4*sizeof(char *)); ++ ++ /* The first char must be a scheme char. */ ++ if (!*pt || !SCHEME_CHAR (*pt)) ++ { ++ ret[0]=malloc(1); ++ ret[0][0]='\0'; ++ dret=parse_address(pt); ++ for (k=0;k<3;k++) ++ ret[k+1]=dret[k]; ++ return ret; ++ } ++ ++i; ++ /* Followed by 0 or more scheme chars. */ ++ while (*(pt+i) && SCHEME_CHAR (*(pt+i))) ++ { ++ ++i; ++ } ++ sch=malloc(i+4); ++ sch=strncpy(sch, pt, i); ++ sch[i]='\0'; ++ if (strlen(sch)) { ++ sch=strcat(sch, "://"); ++ } ++ ++ /* Terminated by "://". */ ++ if (strncmp(sch, pt, strlen(sch)) == 0) { ++ ret[0]=sch; ++ /* dret=malloc(strlen(str)); */ ++ dret=parse_address(pt+i+3); ++ for (k=0;k<3;k++) ++ ret[k+1]=dret[k]; ++ return ret; ++ } ++ ret[0]=malloc(1); ++ ret[0][0]='\0'; ++ dret=parse_address(str); ++ for (k=0;k<3;k++) ++ ret[k+1]=dret[k]; ++ return ret; ++} ++ ++#define DOMAIN_CHAR(ch) (isalnum (ch) || (ch) == '-' || (ch) == '.') ++ ++/* ++ * This function takes an url without a scheme and outputs a pair: domain and ++ * the rest. ++ */ ++static char ** ++parse_address(const char *url) ++{ ++ int n; ++ size_t i=0; ++ size_t u=strlen(url); ++ char *domain; ++ char *port; ++ char **res=malloc(3*sizeof (char *)); ++ ++ if (isalnum(*url)) { ++ ++i; ++ while (*(url+i) && DOMAIN_CHAR (*(url+i))) ++ ++i; ++ } ++ domain=malloc(i+1); ++ domain=strncpy(domain, url, i); ++ domain[i]='\0'; ++ ++ // check for a port number ++ if ( (u > i) && *(url+i) == ':' ) ++ { ++ n=i+1; ++ while ( (n<=u) && (n<i+1+5) && isdigit(*(url+n)) ) ++ n++; ++ if (n>i+1) ++ { ++ port=malloc(n-i+1); ++ port=strncpy(port, (url+i), n-i); ++ port[n-i+1]='\0'; ++ } ++ else ++ { ++ port=malloc(1); ++ port[0]='\0'; ++ } ++ } ++ else ++ { ++ n=i; ++ port=malloc(1); ++ port[0] = '\0'; ++ } ++ ++ ++ res[0]=domain; ++ res[1]=port; ++ res[2]=malloc(strlen(url+n)+1); ++ res[2]=strcpy(res[2], (url+n)); ++ return res; ++} ++ ++/* ++ * This function tests if the url has a qualified domain name. ++ */ ++static int ++url_has_domain(char *url, char **parsed_uri) { ++ char *domain=parsed_uri[1]; ++ char *rest=parsed_uri[3]; ++ ++ if (strstr(domain, " ") != NULL) ++ return false; ++ ++ if (! *domain || ++ (*rest && rest[0] != '/')) ++ return false; ++ ++ // the domain name should contain at least one '.', ++ // unless it is "localhost" ++ if (strcmp(domain, "localhost") == 0) ++ return true; ++ ++ if (strstr(domain, ".") != NULL) ++ return true; ++ ++ return false; ++} ++ ++static const gchar * ++parseuri(const gchar *uri, char **parsed_uri) { ++ guint i; ++ gchar *pt = g_strdup(uri); ++ ++ while (*pt == ' ') ++ pt+=1; ++ ++ bool hdm = url_has_domain((char *) pt, parsed_uri); ++ ++ if (hdm) ++ return g_strrstr(pt, "://") ? g_strdup(pt) : g_strdup_printf("http://%s", pt); ++ ++ for (i = 0; i < LENGTH(searchengines); i++) { ++ if (searchengines[i].token == NULL ++ || searchengines[i].uri == NULL) ++ continue; ++ ++ if ((*(pt + strlen(searchengines[i].token)) == ' ' && g_str_has_prefix(pt, searchengines[i].token))) ++ { ++ switch (searchengines[i].nr) ++ { ++ case 0: ++ return g_strdup_printf("%s", searchengines[i].uri); ++ break; ++ case 2: ++ return g_strdup_printf(searchengines[i].uri, pt + strlen(searchengines[i].token) + 1, pt + strlen(searchengines[i].token) + 1); ++ break; ++ default: ++ return g_strdup_printf(searchengines[i].uri, pt + strlen(searchengines[i].token) + 1); ++ break; ++ } ++ } ++ ++ if (strcmp(pt, searchengines[i].token) == 0 && strstr(searchengines[i].token, "%s") == NULL) ++ { ++ return g_strdup_printf(searchengines[i].uri, ""); ++ } ++ } ++ return g_strdup_printf(defaultsearchengine, pt); ++} ++ + static void + pasteuri(GtkClipboard *clipboard, const char *text, gpointer d) { + Arg arg = {.v = text }; +@@ -1028,6 +1260,7 @@ setup(void) { + + /* dirs and files */ + cookiefile = buildpath(cookiefile); ++ historyfile = buildpath(historyfile); + scriptfile = buildpath(scriptfile); + stylefile = buildpath(stylefile); + diff --git a/patches/surf-0.5-download.diff b/patches/surf-0.5-download.diff @@ -0,0 +1,186 @@ +diff --git a/config.def.h b/config.def.h +index 1cba4d7..3065c73 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -11,6 +11,7 @@ static char *progress_proxy_untrust = "#FF6600"; + static char *stylefile = "~/.surf/style.css"; + static char *scriptfile = "~/.surf/script.js"; + static char *cookiefile = "~/.surf/cookies.txt"; ++static char *downdir = "/tmp"; + static time_t sessiontime = 3600; + static char *cafile = "/etc/ssl/certs/ca-certificates.crt"; + static char *strictssl = FALSE; /* Refuse untrusted SSL connections */ +diff --git a/surf.c b/surf.c +index c9fa08d..4d589aa 100644 +--- a/surf.c ++++ b/surf.c +@@ -114,6 +114,7 @@ static void destroyclient(Client *c); + static void destroywin(GtkWidget* w, Client *c); + static void die(const char *errstr, ...); + static void drawindicator(Client *c); ++static void download(WebKitDownload *o, GParamSpec *pspec, Client *c); + static void eval(Client *c, const Arg *arg); + static gboolean exposeindicator(GtkWidget *w, GdkEventExpose *e, Client *c); + static void find(Client *c, const Arg *arg); +@@ -289,6 +290,50 @@ cookiejar_set_property(GObject *self, guint prop_id, const GValue *value, + flock(COOKIEJAR(self)->lock, LOCK_UN); + } + ++struct client_size_tuple { ++ Client* c; ++ gint s; ++}; ++ ++static void ++late_download_update(WebKitWebView* view, GParamSpec *pspec, struct client_size_tuple* t){ ++ char script[1024]; char* s= script; ++ snprintf(script, 1024, "c(%d, %d)", t->s, t->s); ++ const Arg a= {.v = (void*) &s}; ++ eval(t->c, &a); ++ free(t); ++} ++ ++static void ++download(WebKitDownload *o, GParamSpec *pspec, Client *c) { ++ WebKitDownloadStatus status; ++ char script[2048]; char* s= script; ++ ++ status = webkit_download_get_status(o); ++ if(status == WEBKIT_DOWNLOAD_STATUS_STARTED || status == WEBKIT_DOWNLOAD_STATUS_CREATED) { ++ snprintf(script, 2048, "u(%d, %d, %d)", ++ (gint)webkit_download_get_current_size(o), ++ (gint)webkit_download_get_total_size(o), ++ (gint)(webkit_download_get_progress(o) * 100)); ++ const Arg a= {.v = (void*) &s}; ++ eval(c, &a); ++ } ++ else if (status == WEBKIT_DOWNLOAD_STATUS_FINISHED){ ++ if( webkit_web_view_get_load_status(c->view) == WEBKIT_LOAD_FINISHED ){ ++ snprintf(script, 2048, "c(%d, %d)", ++ (gint)webkit_download_get_current_size(o), ++ (gint)webkit_download_get_total_size(o)); ++ const Arg a= {.v = (void*) &s}; ++ eval(c, &a); ++ } ++ else { ++ struct client_size_tuple* t= calloc(1, sizeof(struct client_size_tuple)); ++ t->c= c; t->s= (gint)webkit_download_get_current_size(o); ++ g_signal_connect(c->view, "document-load-finished", G_CALLBACK(late_download_update), t); ++ } ++ } ++} ++ + static void + evalscript(JSContextRef js, char *script, char* scriptname) { + JSStringRef jsscript, jsscriptname; +@@ -496,12 +541,105 @@ geturi(Client *c) { + + static gboolean + initdownload(WebKitWebView *view, WebKitDownload *o, Client *c) { +- Arg arg; ++ gchar *uri, *path; ++ const gchar *filename; ++ Client *n; ++ const char template[] = ++"<html>" \ ++"<head>" \ ++"<title>Download - %s</title>" \ ++"<script>" \ ++"function formText(x){" \ ++" if(x >= 1073741824) { return (Math.floor(x/10737418.24)/100) + \"G\"; }" \ ++" else if(x >= 1048576){ return (Math.floor(x/10485.76)/100) + \"M\"; }" \ ++" else if(x >= 1024) { return (Math.floor(x/10.24)/100) + \"k\"; }" \ ++" else { return x+\"b\"; }" \ ++"}" \ ++"function updateText(c,t){" \ ++" txt= formText(c) + \"/\" + formText(t);" \ ++" DLTEXT.textContent= txt;" \ ++" /* center text in bar */" \ ++" DLTEXT.setAttribute('x', 102-4.4*txt.length)" \ ++"}" \ ++"function c(c, t){" \ ++" DLGRAD.setAttribute('x2', 230);" \ ++" DLGRAD.setAttribute('x1', 205);" \ ++" updateText(c,t);" \ ++" document.getElementById('stop1').setAttribute('style', \"stop-color:#2020ff;\");" \ ++"}" \ ++"function u(c,t,p){" \ ++" DLGRAD.setAttribute('x2', Math.floor(p*205/100) + 25);" \ ++" DLGRAD.setAttribute('x1', Math.floor(p*205/100));" \ ++" updateText(c,t);" \ ++"}" \ ++"</script>" \ ++"</head>" \ ++"<body>" \ ++"<center>" \ ++"<h2>Downloading</h2>" \ ++"<h3>%s</h3>" \ ++"to %s<br/>" \ ++"<svg" \ ++" xmlns:cc=\"http://creativecommons.org/ns#\"" \ ++" xmlns:svg=\"http://www.w3.org/2000/svg\"" \ ++" xmlns=\"http://www.w3.org/2000/svg\"" \ ++" xmlns:xlink=\"http://www.w3.org/1999/xlink\"" \ ++" width=\"210\"" \ ++" height=\"60\"" \ ++" id=\"download\">" \ ++" <defs>" \ ++" <linearGradient" \ ++" id=\"dlgradient\"" \ ++" x1=\"0\"" \ ++" y1=\"0\"" \ ++" x2=\"25\"" \ ++" y2=\"0\"" \ ++" gradientUnits=\"userSpaceOnUse\">" \ ++" <stop style=\"stop-color:#00ff00;\" offset=\"0\" id=\"stop1\" />" \ ++" <stop style=\"stop-color:#00ff00;stop-opacity:0;\" offset=\"1\" id=\"stop2\" />" \ ++" </linearGradient>" \ ++" </defs>" \ ++" <rect" \ ++" style=\"fill:url(#dlgradient);stroke:#000000;stroke-width:3\"" \ ++" id=\"rect2985\"" \ ++" width=\"200\"" \ ++" height=\"50\"" \ ++" x=\"5\"" \ ++" y=\"5\"" \ ++" ry=\"25\" />" \ ++" <text id=\"dltext\" x=\"92\" y=\"35\">0/0</text>" \ ++"</svg>" \ ++"</center>" \ ++"<script>" \ ++"DLGRAD= document.getElementById('dlgradient');" \ ++"DLTEXT= document.getElementById('dltext');" \ ++"</script>" \ ++"</body>" \ ++"</html>"; ++ char html[sizeof(template)+2048]; ++ filename = webkit_download_get_suggested_filename(o); ++ ++ path = g_build_filename(downdir, filename, NULL); ++ uri = g_filename_to_uri(path, NULL, NULL); ++ ++ webkit_download_set_destination_uri(o, uri); ++ webkit_download_start(o); ++ ++ n = newclient(); ++ snprintf(html, sizeof(template)+2048, template, filename, filename, path); ++ webkit_web_view_load_string(n->view, html, NULL, NULL, NULL); ++ ++ g_signal_connect(o, "notify::progress", G_CALLBACK(download), n); ++ g_signal_connect(o, "notify::status", G_CALLBACK(download), n); ++ ++ n->title = g_strdup_printf("Downloading %s", filename); ++ n->progress = 0; ++ update(n); ++ ++ g_free(path); ++ g_free(uri); + +- updatewinid(c); +- arg = (Arg)DOWNLOAD((char *)webkit_download_get_uri(o), geturi(c)); +- spawn(c, &arg); +- return FALSE; ++ return TRUE; + } + + static void diff --git a/patches/surf-0.6-chromekeys.diff b/patches/surf-0.6-chromekeys.diff @@ -0,0 +1,106 @@ +diff --git a/config.def.h b/config.def.h +index 80a0feb..f8dc533 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -71,23 +71,23 @@ static Key keys[] = { + { MODKEY, GDK_minus, zoom, { .i = -1 } }, + { MODKEY, GDK_plus, zoom, { .i = +1 } }, + +- { MODKEY, GDK_l, navigate, { .i = +1 } }, +- { MODKEY, GDK_h, navigate, { .i = -1 } }, ++ { MODKEY, GDK_i, navigate, { .i = +1 } }, ++ { MODKEY, GDK_o, navigate, { .i = -1 } }, + + { MODKEY, GDK_j, scroll_v, { .i = +1 } }, + { MODKEY, GDK_k, scroll_v, { .i = -1 } }, + { MODKEY, GDK_b, scroll_v, { .i = -10000 } }, ++ { MODKEY, GDK_f, scroll_v, { .i = +10000 } }, + { MODKEY, GDK_space, scroll_v, { .i = +10000 } }, +- { MODKEY, GDK_i, scroll_h, { .i = +1 } }, +- { MODKEY, GDK_u, scroll_h, { .i = -1 } }, ++ { MODKEY, GDK_l, scroll_h, { .i = +1 } }, ++ { MODKEY, GDK_h, scroll_h, { .i = -1 } }, + + { 0, GDK_F11, fullscreen, { 0 } }, + { 0, GDK_Escape, stop, { 0 } }, +- { MODKEY, GDK_o, source, { 0 } }, +- { MODKEY|GDK_SHIFT_MASK,GDK_o, inspector, { 0 } }, ++ { MODKEY, GDK_u, source, { 0 } }, ++ { MODKEY|GDK_SHIFT_MASK,GDK_u, inspector, { 0 } }, + + { MODKEY, GDK_g, spawn, SETPROP("_SURF_URI", "_SURF_GO") }, +- { MODKEY, GDK_f, spawn, SETPROP("_SURF_FIND", "_SURF_FIND") }, + { MODKEY, GDK_slash, spawn, SETPROP("_SURF_FIND", "_SURF_FIND") }, + + { MODKEY, GDK_n, find, { .b = TRUE } }, +diff --git a/surf.1 b/surf.1 +index 1530ec6..8d1caf4 100644 +--- a/surf.1 ++++ b/surf.1 +@@ -114,10 +114,10 @@ which surf should use. + .B Escape + Stops loading current page or stops download. + .TP +-.B Ctrl\-h ++.B Ctrl\-o + Walks back the history. + .TP +-.B Ctrl\-l ++.B Ctrl\-i + Walks forward the history. + .TP + .B Ctrl\-k +@@ -126,17 +126,20 @@ Scrolls page upwards. + .B Ctrl\-j + Scrolls page downwards. + .TP ++.B Ctrl\-h ++Scroll horizontally to the left. ++.TP ++.B Ctrl\-l ++Scroll horizontally to the right. ++.TP + .B Ctrl\-b + Scroll up one whole page view. + .TP +-.B Ctrl\-Space ++.B Ctrl\-f or Ctrl\-Space + Scroll down one whole page view. + .TP +-.B Ctrl\-i +-Scroll horizontally to the right. +-.TP + .B Ctrl\-u +-Scroll horizontally to the left. ++Show the sourcecode of the current page. + .TP + .B Ctrl\-Shift\-k or Ctrl\-+ + Zooms page in. +@@ -147,7 +150,7 @@ Zooms page out + .B Ctrl\-Shift\-q + Resets Zoom + .TP +-.B Ctrl\-f and Ctrl\-\e ++.B Ctrl\-/ + Opens the search-bar. + .TP + .B Ctrl\-n +@@ -174,9 +177,6 @@ Reloads the website without using the cache. + .B Ctrl\-y + Copies current URI to primary selection. + .TP +-.B Ctrl\-o +-Show the sourcecode of the current page. +-.TP + .B Ctrl\-Shift\-a + Toggle through the the + .I cookie policies. +@@ -196,7 +196,7 @@ Toggle if the + .I stylefile + file should be loaded. This will reload the page. + .TP +-.B Ctrl\-Shift\-o ++.B Ctrl\-Shift\-u + Open the Web Inspector (Developer Tools) window for the current page. + .TP + .B Ctrl\-Shift\-s diff --git a/patches/surf-2.0-externalpipe.diff b/patches/surf-2.0-externalpipe.diff @@ -0,0 +1,93 @@ +diff --git a/surf.c b/surf.c +index 93a1629..ba53b94 100644 +--- a/surf.c ++++ b/surf.c +@@ -217,6 +217,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); +@@ -241,6 +242,80 @@ char *argv0; + /* configuration, allows nested code to access above variables */ + #include "config.h" + ++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) ++{ ++ 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 + usage(void) + { diff --git a/patches/surf-2.0-homepage.diff b/patches/surf-2.0-homepage.diff @@ -0,0 +1,24 @@ +diff --git a/config.def.h b/config.def.h +--- a/config.def.h ++++ b/config.def.h +@@ -164,3 +164,5 @@ static Button buttons[] = { + { OnAny, 0, 9, clicknavigate, { .i = +1 }, 1 }, + { OnMedia, MODKEY, 1, clickexternplayer, { 0 }, 1 }, + }; ++ ++#define HOMEPAGE "https://duckduckgo.com/" +diff --git a/surf.c b/surf.c +--- a/surf.c ++++ b/surf.c +@@ -1751,7 +1751,11 @@ main(int argc, char *argv[]) + if (argc > 0) + arg.v = argv[0]; + else ++#ifdef HOMEPAGE ++ arg.v = HOMEPAGE; ++#else + arg.v = "about:blank"; ++#endif + + setup(); + c = newclient(NULL); diff --git a/patches/surf-2.0-notifications.diff b/patches/surf-2.0-notifications.diff @@ -0,0 +1,88 @@ +diff --git a/config.def.h b/config.def.h +index 6d3135e..2b3a14f 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -22,6 +22,7 @@ static Parameter defconfig[ParameterLast] = { + SETB(KioskMode, 0), + SETB(LoadImages, 1), + SETB(MediaManualPlay, 0), ++ SETB(Notifications, 0), + SETB(Plugins, 1), + SETV(PreferredLanguages, ((char *[]){ NULL })), + SETB(RunInFullscreen, 0), +@@ -148,6 +149,7 @@ static Key keys[] = { + { 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_i, toggle, { .i = LoadImages } }, ++ { MODKEY|GDK_SHIFT_MASK, GDK_KEY_l, toggle, { .i = Notifications } }, + { 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_m, toggle, { .i = Style } }, +diff --git a/surf.c b/surf.c +index 93a1629..d47dc60 100644 +--- a/surf.c ++++ b/surf.c +@@ -72,6 +72,7 @@ typedef enum { + KioskMode, + LoadImages, + MediaManualPlay, ++ Notifications, + Plugins, + PreferredLanguages, + RunInFullscreen, +@@ -568,7 +569,8 @@ gettogglestats(Client *c) + togglestats[6] = curconfig[Plugins].val.b ? 'V' : 'v'; + togglestats[7] = curconfig[Style].val.b ? 'M' : 'm'; + togglestats[8] = curconfig[FrameFlattening].val.b ? 'F' : 'f'; +- togglestats[9] = '\0'; ++ togglestats[9] = curconfig[Notifications].val.b ? 'L' : 'l'; ++ togglestats[10] = '\0'; + } + + void +@@ -681,6 +683,9 @@ setparameter(Client *c, int refresh, ParamName p, const Arg *a) + case MediaManualPlay: + webkit_settings_set_media_playback_requires_user_gesture(s, a->b); + break; ++ case Notifications: ++ refresh = 0; ++ return; + case Plugins: + webkit_settings_set_enable_plugins(s, a->b); + break; +@@ -834,6 +839,7 @@ newwindow(Client *c, const Arg *a, int noembed) + cmd[i++] = curconfig[Geolocation].val.b ? "-G" : "-g" ; + cmd[i++] = curconfig[LoadImages].val.b ? "-I" : "-i" ; + cmd[i++] = curconfig[KioskMode].val.b ? "-K" : "-k" ; ++ cmd[i++] = curconfig[Notifications].val.b ? "-L" : "-l" ; + cmd[i++] = curconfig[Style].val.b ? "-M" : "-m" ; + cmd[i++] = curconfig[Inspector].val.b ? "-N" : "-n" ; + cmd[i++] = curconfig[Plugins].val.b ? "-P" : "-p" ; +@@ -1301,6 +1307,14 @@ permissionrequested(WebKitWebView *v, WebKitPermissionRequest *r, Client *c) + return TRUE; + } + ++ if (WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(r)) { ++ if (curconfig[Notifications].val.b) ++ webkit_permission_request_allow(r); ++ else ++ webkit_permission_request_deny(r); ++ return TRUE; ++ } ++ + return FALSE; + } + +@@ -1703,6 +1717,12 @@ main(int argc, char *argv[]) + case 'K': + defconfig CSETB(KioskMode, 1); + break; ++ case 'l': ++ defconfig CSETB(Notifications, 0); ++ break; ++ case 'L': ++ defconfig CSETB(Notifications, 1); ++ break; + case 'm': + defconfig CSETB(Style, 0); + break; diff --git a/patches/surf-bookmarks-20170722-723ff26.diff b/patches/surf-bookmarks-20170722-723ff26.diff @@ -0,0 +1,42 @@ +diff --git a/config.def.h b/config.def.h +index 2e735bf..43ad9ab 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -69,8 +69,9 @@ static WebKitFindOptions findopts = WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE | + #define SETPROP(r, s, p) { \ + .v = (const char *[]){ "/bin/sh", "-c", \ + "prop=\"$(printf '%b' \"$(xprop -id $1 $2 " \ +- "| sed \"s/^$2(STRING) = //;s/^\\\"\\(.*\\)\\\"$/\\1/\")\" " \ +- "| dmenu -p \"$4\" -w $1)\" && xprop -id $1 -f $3 8s -set $3 \"$prop\"", \ ++ "| sed \"s/^$2(STRING) = //;s/^\\\"\\(.*\\)\\\"$/\\1/\" && cat ~/.surf/bookmarks)\" " \ ++ "| dmenu -l 10 -p \"$4\" -w $1)\" && " \ ++ "xprop -id $1 -f $3 8s -set $3 \"$prop\"", \ + "surf-setprop", winid, r, s, p, NULL \ + } \ + } +@@ -101,6 +102,17 @@ static WebKitFindOptions findopts = WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE | + } \ + } + ++/* BM_ADD(readprop) */ ++#define BM_ADD(r) {\ ++ .v = (const char *[]){ "/bin/sh", "-c", \ ++ "(echo $(xprop -id $0 $1) | cut -d '\"' -f2 " \ ++ "| sed 's/.*https*:\\/\\/\\(www\\.\\)\\?//' && cat ~/.surf/bookmarks) " \ ++ "| awk '!seen[$0]++' > ~/.surf/bookmarks.tmp && " \ ++ "mv ~/.surf/bookmarks.tmp ~/.surf/bookmarks", \ ++ winid, r, NULL \ ++ } \ ++} ++ + /* styles */ + /* + * The iteration will stop at the first match, beginning at the beginning of +@@ -132,6 +144,7 @@ static Key keys[] = { + { MODKEY, GDK_KEY_g, spawn, SETPROP("_SURF_URI", "_SURF_GO", PROMPT_GO) }, + { MODKEY, GDK_KEY_f, spawn, SETPROP("_SURF_FIND", "_SURF_FIND", PROMPT_FIND) }, + { MODKEY, GDK_KEY_slash, spawn, SETPROP("_SURF_FIND", "_SURF_FIND", PROMPT_FIND) }, ++ { MODKEY, GDK_KEY_m, spawn, BM_ADD("_SURF_URI") }, + + { 0, GDK_KEY_Escape, stop, { 0 } }, + { MODKEY, GDK_KEY_c, stop, { 0 } }, diff --git a/patches/surf-clipboard-20200112-a6a8878.diff b/patches/surf-clipboard-20200112-a6a8878.diff @@ -0,0 +1,67 @@ +From a6a8878bb6a203b589d559025b94a78214f22878 Mon Sep 17 00:00:00 2001 +From: Olivier Moreau <m242@protonmail.com> +Date: Sun, 12 Jan 2020 11:23:11 +0000 +Subject: [PATCH] Added choice between PRIMARY and CLIPBOARD Gtk selections, as + a config option + +--- + config.def.h | 1 + + surf.c | 11 +++++++++-- + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 34265f6..03bbe2b 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -48,6 +48,7 @@ static Parameter defconfig[ParameterLast] = { + [Style] = { { .i = 1 }, }, + [WebGL] = { { .i = 0 }, }, + [ZoomLevel] = { { .f = 1.0 }, }, ++ [ClipboardNotPrimary] = { { .i = 1 }, }, + }; + + static UriParameters uriparams[] = { +diff --git a/surf.c b/surf.c +index 2b54e3c..b8a9b2f 100644 +--- a/surf.c ++++ b/surf.c +@@ -82,6 +82,7 @@ typedef enum { + Style, + WebGL, + ZoomLevel, ++ ClipboardNotPrimary, + ParameterLast + } ParamName; + +@@ -291,6 +292,7 @@ static ParamName loadcommitted[] = { + SpellLanguages, + Style, + ZoomLevel, ++ ClipboardNotPrimary, + ParameterLast + }; + +@@ -1816,13 +1818,18 @@ showcert(Client *c, const Arg *a) + void + clipboard(Client *c, const Arg *a) + { ++ /* User defined choice of selection, see config.h */ ++ GdkAtom selection = GDK_SELECTION_PRIMARY; ++ if (curconfig[ClipboardNotPrimary].val.i > 0) ++ selection = GDK_SELECTION_CLIPBOARD; ++ + if (a->i) { /* load clipboard uri */ + gtk_clipboard_request_text(gtk_clipboard_get( +- GDK_SELECTION_PRIMARY), ++ selection), + pasteuri, c); + } else { /* copy uri */ + gtk_clipboard_set_text(gtk_clipboard_get( +- GDK_SELECTION_PRIMARY), c->targeturi ++ selection), c->targeturi + ? c->targeturi : geturi(c), -1); + } + } +-- +2.24.1 + diff --git a/patches/surf-dlconsole-20190919-d068a38.diff b/patches/surf-dlconsole-20190919-d068a38.diff @@ -0,0 +1,226 @@ +From 0ea5ecb238b932c533413b912b7981a737af56cf Mon Sep 17 00:00:00 2001 +From: danoloan10 <danoloan10@tutanota.com> +Date: Thu, 19 Sep 2019 18:25:59 +0200 +Subject: [PATCH] Basic integrated downloads via console display + +--- + config.def.h | 16 ++++--- + surf.c | 118 +++++++++++++++++++++++++++++++++++++++------------ + 2 files changed, 101 insertions(+), 33 deletions(-) + +diff --git a/config.def.h b/config.def.h +index 34265f6..375be93 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -6,6 +6,8 @@ static char *styledir = "~/.surf/styles/"; + static char *certdir = "~/.surf/certificates/"; + static char *cachedir = "~/.surf/cache/"; + static char *cookiefile = "~/.surf/cookies.txt"; ++static char *dldir = "~/dl/"; ++static char *dlstatus = "~/.surf/dlstatus/"; + + /* Webkit default features */ + /* Highest priority value will be used. +@@ -76,13 +78,12 @@ static WebKitFindOptions findopts = WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE | + } \ + } + +-/* DOWNLOAD(URI, referer) */ +-#define DOWNLOAD(u, r) { \ ++#define DLSTATUS { \ + .v = (const char *[]){ "st", "-e", "/bin/sh", "-c",\ +- "curl -g -L -J -O -A \"$1\" -b \"$2\" -c \"$2\"" \ +- " -e \"$3\" \"$4\"; read", \ +- "surf-download", useragent, cookiefile, r, u, NULL \ +- } \ ++ "while true; do cat $1/* 2>/dev/null || echo \"no hay descargas\";"\ ++ "A=; read A; "\ ++ "if [ $A = \"clean\" ]; then rm $1/*; fi; clear; done",\ ++ "surf-dlstatus", dlstatus, NULL } \ + } + + /* PLUMB(URI) */ +@@ -180,6 +181,9 @@ static Key keys[] = { + { 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_m, toggle, { .i = Style } }, ++ ++ /* download-console */ ++ { MODKEY, GDK_KEY_d, spawndls, { 0 } }, + }; + + /* button definitions */ +diff --git a/surf.c b/surf.c +index 2b54e3c..771858e 100644 +--- a/surf.c ++++ b/surf.c +@@ -205,10 +205,6 @@ static void decidenewwindow(WebKitPolicyDecision *d, Client *c); + static void decideresource(WebKitPolicyDecision *d, Client *c); + static void insecurecontent(WebKitWebView *v, WebKitInsecureContentEvent e, + Client *c); +-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); +@@ -237,6 +233,17 @@ static void clicknavigate(Client *c, const Arg *a, WebKitHitTestResult *h); + static void clicknewwindow(Client *c, const Arg *a, WebKitHitTestResult *h); + static void clickexternplayer(Client *c, const Arg *a, WebKitHitTestResult *h); + ++/* download-console */ ++static void downloadstarted(WebKitWebContext *wc, WebKitDownload *d, ++ Client *c); ++static void downloadfailed(WebKitDownload *d, GParamSpec *ps, void *arg); ++static void downloadfinished(WebKitDownload *d, GParamSpec *ps, void *arg); ++static gboolean decidedestination(WebKitDownload *d, ++ gchar *suggested_filename, void *arg); ++static void printprogress(WebKitDownload *d, GParamSpec *ps, void *arg); ++static void logdownload(WebKitDownload *d, gchar *tail); ++static void spawndls(Client *c, const Arg *a); ++ + static char winid[64]; + static char togglestats[12]; + static char pagestats[2]; +@@ -340,6 +347,8 @@ setup(void) + scriptfile = buildfile(scriptfile); + cachedir = buildpath(cachedir); + certdir = buildpath(certdir); ++ dlstatus = buildpath(dlstatus); ++ dldir = buildpath(dldir); + + gdkkb = gdk_seat_get_keyboard(gdk_display_get_default_seat(gdpy)); + +@@ -1079,6 +1088,8 @@ cleanup(void) + g_free(scriptfile); + g_free(stylefile); + g_free(cachedir); ++ g_free(dldir); ++ g_free(dlstatus); + XCloseDisplay(dpy); + } + +@@ -1710,8 +1721,7 @@ decideresource(WebKitPolicyDecision *d, Client *c) + if (webkit_response_policy_decision_is_mime_type_supported(r)) { + webkit_policy_decision_use(d); + } else { +- webkit_policy_decision_ignore(d); +- download(c, res); ++ webkit_policy_decision_download(d); + } + } + +@@ -1721,27 +1731,6 @@ insecurecontent(WebKitWebView *v, WebKitInsecureContentEvent e, Client *c) + c->insecure = 1; + } + +-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) +-{ +- Arg a = (Arg)DOWNLOAD(webkit_uri_response_get_uri(r), geturi(c)); +- spawn(c, &a); +-} +- + void + webprocessterminated(WebKitWebView *v, WebKitWebProcessTerminationReason r, + Client *c) +@@ -1971,6 +1960,81 @@ clickexternplayer(Client *c, const Arg *a, WebKitHitTestResult *h) + spawn(c, &arg); + } + ++/* download-console */ ++ ++void ++downloadstarted(WebKitWebContext *wc, WebKitDownload *d, Client *c) ++{ ++ webkit_download_set_allow_overwrite(d, TRUE); ++ g_signal_connect(G_OBJECT(d), "decide-destination", ++ G_CALLBACK(decidedestination), NULL); ++ g_signal_connect(G_OBJECT(d), "notify::estimated-progress", ++ G_CALLBACK(printprogress), NULL); ++ g_signal_connect(G_OBJECT(d), "failed", ++ G_CALLBACK(downloadfailed), NULL); ++ g_signal_connect(G_OBJECT(d), "finished", ++ G_CALLBACK(downloadfinished), NULL); ++} ++ ++void ++downloadfailed(WebKitDownload *d, GParamSpec *ps, void *arg) ++{ ++ logdownload(d, " -- FAILED"); ++} ++ ++void ++downloadfinished(WebKitDownload *d, GParamSpec *ps, void *arg) ++{ ++ logdownload(d, " -- COMPLETED"); ++} ++ ++gboolean ++decidedestination(WebKitDownload *d, gchar *suggested_filename, void *arg) ++{ ++ gchar *dest; ++ dest = g_strdup_printf("file://%s/%s", dldir, suggested_filename); ++ webkit_download_set_destination(d, dest); ++ return TRUE; ++} ++ ++void ++printprogress(WebKitDownload *d, GParamSpec *ps, void *arg) ++{ ++ logdownload(d, ""); ++} ++ ++void ++logdownload(WebKitDownload *d, gchar *tail) ++{ ++ gchar *filename, *statfile; ++ FILE *stat; ++ ++ filename = g_path_get_basename(webkit_download_get_destination(d)); ++ statfile = g_strdup_printf("%s/%s", dlstatus, filename); ++ ++ if ((stat = fopen(statfile, "w")) == NULL) { ++ perror("dlstatus"); ++ } else { ++ fprintf(stat, "%s: %d%% (%d.%ds)%s\n", ++ filename, ++ (int)(webkit_download_get_estimated_progress(d) * 100), ++ (int) webkit_download_get_elapsed_time(d), ++ (int)(webkit_download_get_elapsed_time(d) * 100), ++ tail); ++ fclose(stat); ++ } ++ ++ g_free(statfile); ++ g_free(filename); ++} ++ ++void ++spawndls(Client *c, const Arg *a) ++{ ++ Arg arg = (Arg)DLSTATUS; ++ spawn(c, &arg); ++} ++ + int + main(int argc, char *argv[]) + { +-- +2.22.1 + diff --git a/patches/surf-externalpipe-signal-2.0.diff b/patches/surf-externalpipe-signal-2.0.diff @@ -0,0 +1,66 @@ +From 84a41d036329c7599024b7cb0f613400d7484cec Mon Sep 17 00:00:00 2001 +From: Miles Alan <m@milesalan.com> +Date: Sun, 11 Aug 2019 21:36:58 -0500 +Subject: [PATCH] Add handler for SIGUSR1 signal to run an externalpipe command + +--- + config.def.h | 1 + + surf.c | 16 ++++++++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/config.def.h b/config.def.h +index 6d3135e..a7363d9 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -5,6 +5,7 @@ static char *scriptfile = "~/.surf/script.js"; + static char *styledir = "~/.surf/styles/"; + static char *cachedir = "~/.surf/cache/"; + static char *cookiefile = "~/.surf/cookies.txt"; ++static char *externalpipe_sigusr1[] = {"/bin/sh", "-c", "externalpipe_buffer.sh surf_strings_read"}; + + /* Webkit default features */ + static Parameter defconfig[ParameterLast] = { +diff --git a/surf.c b/surf.c +index 93a1629..0e402ca 100644 +--- a/surf.c ++++ b/surf.c +@@ -146,6 +146,7 @@ static void die(const char *errstr, ...); + static void setup(void); + static void sigchld(int unused); + static void sighup(int unused); ++static void sigusr1(int unused); + static char *buildfile(const char *path); + static char *buildpath(const char *path); + static const char *getuserhomedir(const char *user); +@@ -338,6 +339,15 @@ sigchld(int unused) + ; + } + ++void ++sigusr1(int unused) ++{ ++ static Arg a = {.v = externalpipe_sigusr1}; ++ Client *c; ++ for (c = clients; c; c = c->next) ++ externalpipe(c, &a); ++} ++ + void + sighup(int unused) + { +@@ -1757,6 +1767,12 @@ main(int argc, char *argv[]) + c = newclient(NULL); + showview(NULL, c); + ++ struct sigaction sa; ++ sa.sa_handler = sigusr1; ++ sigemptyset(&sa.sa_mask); ++ sa.sa_flags = SA_RESTART; ++ sigaction(SIGUSR1, &sa, NULL); ++ + loaduri(c, &arg); + updatetitle(c); + +-- +2.19.2 + diff --git a/patches/surf-history-20181009-2b71a22.diff b/patches/surf-history-20181009-2b71a22.diff @@ -0,0 +1,107 @@ +diff -up surf-2.0/config.def.h surf-2.0-history/config.def.h +--- surf-2.0/config.def.h 2017-11-26 14:29:37.963786915 +0100 ++++ surf-2.0-history/config.def.h 2017-11-26 19:48:31.300096237 +0100 +@@ -6,6 +6,7 @@ static char *styledir = "~/.surf/s + static char *certdir = "~/.surf/certificates/"; + static char *cachedir = "~/.surf/cache/"; + static char *cookiefile = "~/.surf/cookies.txt"; ++static char *historyfile = "~/.surf/history.txt"; + + /* Webkit default features */ + /* Highest priority value will be used. +@@ -101,6 +102,11 @@ static WebKitFindOptions findopts = WEBK + } \ + } + ++#define SETURI(p) { .v = (char *[]){ "/bin/sh", "-c", \ ++"prop=\"`surf_history_dmenu.sh`\" &&" \ ++"xprop -id $1 -f $0 8s -set $0 \"$prop\"", \ ++p, winid, NULL } } ++ + /* styles */ + /* + * The iteration will stop at the first match, beginning at the beginning of +@@ -181,6 +187,7 @@ static Key keys[] = { + { 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_m, toggle, { .i = Style } }, ++ { MODKEY , GDK_KEY_Return, spawn, SETURI("_SURF_GO") }, + }; + + /* button definitions */ +Only in surf-2.0-history/: config.h +Only in surf-2.0: .git +Only in surf-2.0-history/: surf +diff -up surf-2.0/surf.c surf-2.0-history/surf.c +--- surf-2.0/surf.c 2017-11-26 14:29:37.963786915 +0100 ++++ surf-2.0-history/surf.c 2017-11-26 14:20:36.757100476 +0100 +@@ -171,6 +171,7 @@ static void newwindow(Client *c, const A + static void spawn(Client *c, const Arg *a); + static void destroyclient(Client *c); + static void cleanup(void); ++static void updatehistory(const char *u, const char *t); + + /* GTK/WebKit */ + static WebKitWebView *newview(Client *c, WebKitWebView *rv); +@@ -336,10 +337,11 @@ setup(void) + curconfig = defconfig; + + /* dirs and files */ +- cookiefile = buildfile(cookiefile); +- scriptfile = buildfile(scriptfile); +- cachedir = buildpath(cachedir); +- certdir = buildpath(certdir); ++ cookiefile = buildfile(cookiefile); ++ historyfile = buildfile(historyfile); ++ scriptfile = buildfile(scriptfile); ++ cachedir = buildpath(cachedir); ++ certdir = buildpath(certdir); + + gdkkb = gdk_seat_get_keyboard(gdk_display_get_default_seat(gdpy)); + +@@ -1042,12 +1044,28 @@ cleanup(void) + while (clients) + destroyclient(clients); + g_free(cookiefile); ++ g_free(historyfile); + g_free(scriptfile); + g_free(stylefile); + g_free(cachedir); + XCloseDisplay(dpy); + } + ++void ++updatehistory(const char *u, const char *t) ++{ ++ FILE *f; ++ f = fopen(historyfile, "a+"); ++ ++ char b[20]; ++ time_t now = time (0); ++ strftime (b, 20, "%Y-%m-%d %H:%M:%S", localtime (&now)); ++ fputs(b, f); ++ ++ fprintf(f, " %s %s\n", u, t); ++ fclose(f); ++} ++ + WebKitWebView * + newview(Client *c, WebKitWebView *rv) + { +@@ -1417,6 +1435,7 @@ loadfailedtls(WebKitWebView *v, gchar *u + return TRUE; + } + ++ + void + loadchanged(WebKitWebView *v, WebKitLoadEvent e, Client *c) + { +@@ -1445,6 +1464,7 @@ loadchanged(WebKitWebView *v, WebKitLoad + break; + case WEBKIT_LOAD_FINISHED: + seturiparameters(c, uri, loadfinished); ++ updatehistory(uri, c->title); + /* Disabled until we write some WebKitWebExtension for + * manipulating the DOM directly. + evalscript(c, "document.documentElement.style.overflow = '%s'", +Only in surf-2.0-history/: surf.o diff --git a/patches/surf-startgo-20200913-d068a38.diff b/patches/surf-startgo-20200913-d068a38.diff @@ -0,0 +1,78 @@ +From 950f05fca48ab3adf0ec955b06c8e7dad3ee2c32 Mon Sep 17 00:00:00 2001 +From: Luca Wellmeier <luca_wellmeier@gmx.de> +Date: Sun, 13 Sep 2020 11:33:25 +0200 +Subject: [PATCH] add option to start the go prompt immediately after startup + +--- + config.def.h | 3 +++ + surf.1 | 5 ++++- + surf.c | 9 +++++++++ + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/config.def.h b/config.def.h +index 34265f6..3da943d 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -7,6 +7,9 @@ static char *certdir = "~/.surf/certificates/"; + static char *cachedir = "~/.surf/cache/"; + static char *cookiefile = "~/.surf/cookies.txt"; + ++/* enable to open GO prompt on startup */ ++static int startgo = 0; ++ + /* Webkit default features */ + /* Highest priority value will be used. + * Default parameters are priority 0 +diff --git a/surf.1 b/surf.1 +index 45c31bb..54f2dbd 100644 +--- a/surf.1 ++++ b/surf.1 +@@ -3,7 +3,7 @@ + surf \- simple webkit-based browser + .SH SYNOPSIS + .B surf +-.RB [-bBdDfFgGiIkKmMnNpPsStTvwxX] ++.RB [-bBdDfFgGhiIkKmMnNpPsStTvwxX] + .RB [-a\ cookiepolicies] + .RB [-c\ cookiefile] + .RB [-C\ stylefile] +@@ -67,6 +67,9 @@ Disable giving the geolocation to websites. + .B \-G + Enable giving the geolocation to websites. + .TP ++.B \-h ++Start the GO prompt immediately. ++.TP + .B \-i + Disable Images. + .TP +diff --git a/surf.c b/surf.c +index 2b54e3c..f5fae45 100644 +--- a/surf.c ++++ b/surf.c +@@ -2026,6 +2026,9 @@ main(int argc, char *argv[]) + defconfig[Geolocation].val.i = 1; + defconfig[Geolocation].prio = 2; + break; ++ case 'h': ++ startgo = 1; ++ break; + case 'i': + defconfig[LoadImages].val.i = 0; + defconfig[LoadImages].prio = 2; +@@ -2120,6 +2123,12 @@ main(int argc, char *argv[]) + loaduri(c, &arg); + updatetitle(c); + ++ if (startgo) { ++ /* start directly into GO prompt */ ++ Arg a = (Arg)SETPROP("_SURF_URI", "_SURF_GO", PROMPT_GO); ++ spawn(c, &a); ++ } ++ + gtk_main(); + cleanup(); + +-- +2.28.0 +