Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bb01475018 | |||
| d4b030eeb4 | |||
| 101f2d6455 | |||
| 3083ef4031 | |||
| cf75bf2777 | |||
| 96041e5ba2 | |||
| 6af15aa636 | |||
| a0e269b6bd | |||
| 3da24a7481 | |||
| 7c7a3b58cf | |||
| e75753775f | |||
| fc31616141 | |||
| b8f45a588d | |||
| 590a9bb19d | |||
| df96fe4171 | |||
| 543d0c77ee | |||
| bc73b48743 | |||
| 2e62372969 | |||
| 3b104416d3 | |||
| 62f54a3745 | |||
| f1299dcfc1 | |||
| a1db4e9bf5 | |||
| db72e066d1 | |||
| 86c230c2bb | |||
| d1eb8253b1 | |||
| 54df460866 | |||
| 1005ea0ac9 |
@@ -5,3 +5,5 @@ d8628fc93353faa411c9fc7eef82d11a84d26ae2 0.1
|
||||
bffb0c3c23410ac7f260d167f4b9771497fc1127 0.1.2
|
||||
a5db79d487c85615be2ecf30815c6b4977e88000 0.2
|
||||
46d516fd216731adf91740496e6823c1be4f6199 0.3
|
||||
ac8e058003ed2c0974529808752e5da7692fd7d8 0.4
|
||||
71388899ac09d21e6c93518cc57a28395034f63c 0.4.1
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
MIT/X Consortium License
|
||||
|
||||
© 2009 Enno Boland <g s01 de>
|
||||
© 2011-2012 Troels Henriksen <athas@sigkill.at>
|
||||
© 2009-2011 Enno Boland <g s01 de>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
||||
+18
-9
@@ -1,21 +1,26 @@
|
||||
/* modifier 0 means no modifier */
|
||||
static char *useragent = "Surf/"VERSION" (X11; U; Unix; en-US) AppleWebKit/531.2+ Compatible (Safari)";
|
||||
static char *progress = "#FF0000";
|
||||
static char *progress = "#0066FF";
|
||||
static char *progress_untrust = "#FF6600";
|
||||
static char *progress_trust = "#00FF00";
|
||||
static char *stylefile = ".surf/style.css";
|
||||
static char *scriptfile = ".surf/script.js";
|
||||
static char *cookiefile = ".surf/cookies.txt";
|
||||
static time_t sessiontime = 0;
|
||||
#define NOBACKGROUND 0
|
||||
static time_t sessiontime = 3600;
|
||||
static char *cafile = "/etc/ssl/certs/ca-certificates.crt";
|
||||
static char *strictssl = FALSE; /* Refuse untrusted SSL connections */
|
||||
#define HIDE_BACKGROUND FALSE
|
||||
#define SPATIAL_BROWSING TRUE
|
||||
|
||||
#define SETPROP(p, q) { .v = (char *[]){ "/bin/sh", "-c", \
|
||||
"prop=\"`xprop -id $2 $0 | cut -d '\"' -f 2 | dmenu`\" &&" \
|
||||
"xprop -id $2 -f $1 8s -set $1 \"$prop\"", \
|
||||
p, q, winid, NULL } }
|
||||
#define DOWNLOAD(d) { \
|
||||
#define DOWNLOAD(d) { \
|
||||
.v = (char *[]){ "/bin/sh", "-c", \
|
||||
"xterm -e \"wget --load-cookies ~/.surf/cookies.txt '$0';\"", \
|
||||
d, NULL } }
|
||||
"xterm -e \"wget '$0' \
|
||||
--load-cookies ~/.surf/cookies.txt \
|
||||
--user-agent '$1' ; sleep 5\"", d, useragent, NULL } }
|
||||
#define MODKEY GDK_CONTROL_MASK
|
||||
static Key keys[] = {
|
||||
/* modifier keyval function arg Focus */
|
||||
@@ -29,12 +34,16 @@ static Key keys[] = {
|
||||
{ MODKEY|GDK_SHIFT_MASK,GDK_i, zoom, { .i = 0 } },
|
||||
{ MODKEY, GDK_l, navigate, { .i = +1 } },
|
||||
{ MODKEY, GDK_h, navigate, { .i = -1 } },
|
||||
{ MODKEY, GDK_j, scroll, { .i = +1 } },
|
||||
{ MODKEY, GDK_k, scroll, { .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_space, scroll_v, { .i = +10000 } },
|
||||
{ MODKEY, GDK_i, scroll_h, { .i = +1 } },
|
||||
{ MODKEY, GDK_u, scroll_h, { .i = -1 } },
|
||||
{ 0, GDK_Escape, stop, { 0 } },
|
||||
{ MODKEY, GDK_o, source, { 0 } },
|
||||
{ MODKEY, GDK_g, spawn, SETPROP("_SURF_URI", "_SURF_GO") },
|
||||
{ MODKEY, GDK_slash, spawn, SETPROP("_SURF_FIND", "_SURF_FIND") },
|
||||
{ MODKEY, GDK_f, spawn, SETPROP("_SURF_FIND", "_SURF_FIND") },
|
||||
{ MODKEY, GDK_n, find, { .b = TRUE } },
|
||||
{ MODKEY|GDK_SHIFT_MASK,GDK_n, find, { .b = FALSE } },
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# surf version
|
||||
VERSION = 0.4
|
||||
VERSION = 0.5
|
||||
|
||||
# Customize below to fit your system
|
||||
|
||||
@@ -7,13 +7,16 @@ VERSION = 0.4
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
GTKINC=$(shell pkg-config --cflags gtk+-2.0 webkit-1.0)
|
||||
GTKLIB=$(shell pkg-config --libs gtk+-2.0 webkit-1.0)
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
|
||||
GTKINC = `pkg-config --cflags gtk+-2.0 webkit-1.0`
|
||||
GTKLIB = `pkg-config --libs gtk+-2.0 webkit-1.0`
|
||||
|
||||
# includes and libs
|
||||
INCS = -I. -I/usr/include ${GTKINC}
|
||||
LIBS = -L/usr/lib -lc ${GTKLIB} -lgthread-2.0
|
||||
INCS = -I. -I/usr/include -I${X11INC} ${GTKINC}
|
||||
LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${GTKLIB} -lgthread-2.0 \
|
||||
-ljavascriptcoregtk-1.0
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -DVERSION=\"${VERSION}\"
|
||||
|
||||
@@ -60,7 +60,7 @@ Zooms page out
|
||||
.B Ctrl\-Shift\-i
|
||||
Resets Zoom
|
||||
.TP
|
||||
.B Ctrl\-/
|
||||
.B Ctrl\-f
|
||||
Opens the search-bar.
|
||||
.TP
|
||||
.B Ctrl\-n
|
||||
@@ -89,8 +89,16 @@ Copies current URI to primary selection.
|
||||
.TP
|
||||
.B Ctrl\-o
|
||||
show the sourcecode of the current page.
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
.B SURF_USERAGENT
|
||||
If this variable is set upon startup, surf will use it as the useragent string
|
||||
.TP
|
||||
.B http_proxy
|
||||
If this variable is set and not empty upon startup, surf will use it as the http proxy
|
||||
.SH SEE ALSO
|
||||
.BR dmenu(1)
|
||||
.BR xprop(1)
|
||||
.BR dmenu(1),
|
||||
.BR xprop(1),
|
||||
.BR tabbed(1)
|
||||
.SH BUGS
|
||||
Please report them!
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <sys/file.h>
|
||||
|
||||
#define LENGTH(x) (sizeof x / sizeof x[0])
|
||||
#define CLEANMASK(mask) (mask & ~(GDK_MOD2_MASK))
|
||||
|
||||
enum { AtomFind, AtomGo, AtomUri, AtomLast };
|
||||
|
||||
@@ -38,6 +37,7 @@ typedef struct Client {
|
||||
char *title, *linkhover;
|
||||
const char *uri, *needle;
|
||||
gint progress;
|
||||
gboolean sslfailed;
|
||||
struct Client *next;
|
||||
gboolean zoomed;
|
||||
} Client;
|
||||
@@ -95,14 +95,16 @@ static void print(Client *c, const Arg *arg);
|
||||
static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event, gpointer d);
|
||||
static void progresschange(WebKitWebView *view, GParamSpec *pspec, Client *c);
|
||||
static void reload(Client *c, const Arg *arg);
|
||||
static void resize(GtkWidget *w, GtkAllocation *a, Client *c);
|
||||
static void scroll(Client *c, const Arg *arg);
|
||||
static void scroll_h(Client *c, const Arg *arg);
|
||||
static void scroll_v(Client *c, const Arg *arg);
|
||||
static void scroll(GtkAdjustment *a, const Arg *arg);
|
||||
static void setatom(Client *c, int a, const char *v);
|
||||
static void setcookie(SoupCookie *c);
|
||||
static void setup(void);
|
||||
static void sigchld(int unused);
|
||||
static void source(Client *c, const Arg *arg);
|
||||
static void spawn(Client *c, const Arg *arg);
|
||||
static void eval(Client *c, const Arg *arg);
|
||||
static void stop(Client *c, const Arg *arg);
|
||||
static void titlechange(WebKitWebView *v, WebKitWebFrame* frame, const char* title, Client *c);
|
||||
static void update(Client *c);
|
||||
@@ -126,12 +128,15 @@ buildpath(const char *path) {
|
||||
apath = g_strconcat(g_get_home_dir(), "/", path, NULL);
|
||||
if((p = strrchr(apath, '/'))) {
|
||||
*p = '\0';
|
||||
g_mkdir_with_parents(apath, 0755);
|
||||
g_mkdir_with_parents(apath, 0700);
|
||||
g_chmod(apath, 0700); /* in case it existed */
|
||||
*p = '/';
|
||||
}
|
||||
/* creating file (gives error when apath ends with "/") */
|
||||
if((f = fopen(apath, "a")))
|
||||
if((f = fopen(apath, "a"))) {
|
||||
g_chmod(apath, 0600); /* always */
|
||||
fclose(f);
|
||||
}
|
||||
return apath;
|
||||
}
|
||||
|
||||
@@ -145,15 +150,24 @@ cleanup(void) {
|
||||
}
|
||||
|
||||
void
|
||||
runscript(WebKitWebFrame *frame, JSContextRef js) {
|
||||
JSStringRef jsscript;
|
||||
char *script;
|
||||
evalscript(JSContextRef js, char *script, char* scriptname) {
|
||||
JSStringRef jsscript, jsscriptname;
|
||||
JSValueRef exception = NULL;
|
||||
|
||||
jsscript = JSStringCreateWithUTF8CString(script);
|
||||
jsscriptname = JSStringCreateWithUTF8CString(scriptname);
|
||||
JSEvaluateScript(js, jsscript, JSContextGetGlobalObject(js), jsscriptname, 0, &exception);
|
||||
JSStringRelease(jsscript);
|
||||
JSStringRelease(jsscriptname);
|
||||
}
|
||||
|
||||
void
|
||||
runscript(WebKitWebFrame *frame) {
|
||||
char *script;
|
||||
GError *error;
|
||||
|
||||
|
||||
if(g_file_get_contents(scriptfile, &script, NULL, &error)) {
|
||||
jsscript = JSStringCreateWithUTF8CString(script);
|
||||
JSEvaluateScript(js, jsscript, JSContextGetGlobalObject(js), NULL, 0, &exception);
|
||||
evalscript(webkit_web_frame_get_global_context(frame), script, scriptfile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,6 +225,7 @@ void
|
||||
destroyclient(Client *c) {
|
||||
Client *p;
|
||||
|
||||
webkit_web_view_stop_loading(c->view);
|
||||
gtk_widget_destroy(c->indicator);
|
||||
gtk_widget_destroy(GTK_WIDGET(c->view));
|
||||
gtk_widget_destroy(c->scroll);
|
||||
@@ -250,8 +265,11 @@ drawindicator(Client *c) {
|
||||
w = c->indicator;
|
||||
width = c->progress * w->allocation.width / 100;
|
||||
gc = gdk_gc_new(w->window);
|
||||
gdk_color_parse(strstr(uri, "https://") == uri ?
|
||||
progress_trust : progress, &fg);
|
||||
if(strstr(uri, "https://") == uri)
|
||||
gdk_color_parse(c->sslfailed ?
|
||||
progress_untrust : progress_trust, &fg);
|
||||
else
|
||||
gdk_color_parse(progress, &fg);
|
||||
gdk_gc_set_rgb_fg_color(gc, &fg);
|
||||
gdk_draw_rectangle(w->window,
|
||||
w->style->bg_gc[GTK_WIDGET_STATE(w)],
|
||||
@@ -315,10 +333,8 @@ geturi(Client *c) {
|
||||
|
||||
void
|
||||
gotheaders(SoupMessage *msg, gpointer v) {
|
||||
SoupURI *uri;
|
||||
GSList *l, *p;
|
||||
|
||||
uri = soup_message_get_uri(msg);
|
||||
for(p = l = soup_cookies_from_response(msg); p;
|
||||
p = g_slist_next(p)) {
|
||||
setcookie((SoupCookie *)p->data);
|
||||
@@ -344,7 +360,7 @@ keypress(GtkWidget* w, GdkEventKey *ev, Client *c) {
|
||||
updatewinid(c);
|
||||
for(i = 0; i < LENGTH(keys); i++) {
|
||||
if(gdk_keyval_to_lower(ev->keyval) == keys[i].keyval
|
||||
&& CLEANMASK(ev->state) == keys[i].mod
|
||||
&& (ev->state & keys[i].mod) == keys[i].mod
|
||||
&& keys[i].func) {
|
||||
keys[i].func(c, &(keys[i].arg));
|
||||
processed = TRUE;
|
||||
@@ -367,9 +383,24 @@ linkhover(WebKitWebView *v, const char* t, const char* l, Client *c) {
|
||||
|
||||
void
|
||||
loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c) {
|
||||
WebKitWebFrame *frame;
|
||||
WebKitWebDataSource *src;
|
||||
WebKitNetworkRequest *request;
|
||||
SoupMessage *msg;
|
||||
char *uri;
|
||||
|
||||
switch(webkit_web_view_get_load_status (c->view)) {
|
||||
case WEBKIT_LOAD_COMMITTED:
|
||||
setatom(c, AtomUri, geturi(c));
|
||||
uri = geturi(c);
|
||||
if(strstr(uri, "https://") == uri) {
|
||||
frame = webkit_web_view_get_main_frame(c->view);
|
||||
src = webkit_web_frame_get_data_source(frame);
|
||||
request = webkit_web_data_source_get_request(src);
|
||||
msg = webkit_network_request_get_message(request);
|
||||
c->sslfailed = soup_message_get_flags(msg)
|
||||
^ SOUP_MESSAGE_CERTIFICATE_TRUSTED;
|
||||
}
|
||||
setatom(c, AtomUri, uri);
|
||||
break;
|
||||
case WEBKIT_LOAD_FINISHED:
|
||||
c->progress = 0;
|
||||
@@ -432,7 +463,7 @@ newclient(void) {
|
||||
* window class (WM_CLASS) is capped, while the resource is in
|
||||
* lowercase. Both these values come as a pair.
|
||||
*/
|
||||
gtk_window_set_wmclass(GTK_WINDOW(c->win), "surf", "surf");
|
||||
gtk_window_set_wmclass(GTK_WINDOW(c->win), "surf", "Surf");
|
||||
|
||||
/* TA: 20091214: And set the role here as well -- so that
|
||||
* sessions can pick this up.
|
||||
@@ -442,7 +473,6 @@ newclient(void) {
|
||||
gtk_window_set_default_size(GTK_WINDOW(c->win), 800, 600);
|
||||
g_signal_connect(G_OBJECT(c->win), "destroy", G_CALLBACK(destroywin), c);
|
||||
g_signal_connect(G_OBJECT(c->win), "key-press-event", G_CALLBACK(keypress), c);
|
||||
g_signal_connect(G_OBJECT(c->win), "size-allocate", G_CALLBACK(resize), c);
|
||||
|
||||
/* VBox */
|
||||
c->vbox = gtk_vbox_new(FALSE, 0);
|
||||
@@ -490,7 +520,7 @@ newclient(void) {
|
||||
gdk_window_add_filter(GTK_WIDGET(c->win)->window, processx, c);
|
||||
webkit_web_view_set_full_content_zoom(c->view, TRUE);
|
||||
frame = webkit_web_view_get_main_frame(c->view);
|
||||
runscript(frame, webkit_web_frame_get_global_context(frame));
|
||||
runscript(frame);
|
||||
settings = webkit_web_view_get_settings(c->view);
|
||||
if(!(ua = getenv("SURF_USERAGENT")))
|
||||
ua = useragent;
|
||||
@@ -500,13 +530,13 @@ newclient(void) {
|
||||
g_object_set(G_OBJECT(settings), "auto-load-images", loadimage, NULL);
|
||||
g_object_set(G_OBJECT(settings), "enable-plugins", plugin, NULL);
|
||||
g_object_set(G_OBJECT(settings), "enable-scripts", script, NULL);
|
||||
g_object_set(G_OBJECT(settings), "enable-spatial-navigation", true, NULL);
|
||||
g_object_set(G_OBJECT(settings), "enable-spatial-navigation", SPATIAL_BROWSING, NULL);
|
||||
|
||||
g_free(uri);
|
||||
|
||||
setatom(c, AtomFind, "");
|
||||
setatom(c, AtomUri, "about:blank");
|
||||
if(NOBACKGROUND)
|
||||
if(HIDE_BACKGROUND)
|
||||
webkit_web_view_set_transparent(c->view, TRUE);
|
||||
|
||||
c->title = NULL;
|
||||
@@ -516,6 +546,9 @@ newclient(void) {
|
||||
gdk_display_sync(gtk_widget_get_display(c->win));
|
||||
printf("%u\n", (guint)GDK_WINDOW_XID(GTK_WIDGET(c->win)->window));
|
||||
fflush(NULL);
|
||||
if (fclose(stdout) != 0) {
|
||||
die("Error closing stdout");
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
@@ -614,29 +647,32 @@ reload(Client *c, const Arg *arg) {
|
||||
}
|
||||
|
||||
void
|
||||
resize(GtkWidget *w, GtkAllocation *a, Client *c) {
|
||||
double zoom;
|
||||
|
||||
if(c->zoomed)
|
||||
return;
|
||||
zoom = webkit_web_view_get_zoom_level(c->view);
|
||||
if(a->width * a->height < 300 * 400 && zoom != 0.2)
|
||||
webkit_web_view_set_zoom_level(c->view, 0.2);
|
||||
else if(zoom != 1.0)
|
||||
webkit_web_view_set_zoom_level(c->view, 1.0);
|
||||
scroll_h(Client *c, const Arg *arg) {
|
||||
scroll(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(c->scroll)), arg);
|
||||
}
|
||||
|
||||
void
|
||||
scroll(Client *c, const Arg *arg) {
|
||||
gdouble v;
|
||||
GtkAdjustment *a;
|
||||
scroll_v(Client *c, const Arg *arg) {
|
||||
scroll(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(c->scroll)), arg);
|
||||
}
|
||||
|
||||
a = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(c->scroll));
|
||||
v = gtk_adjustment_get_value(a);
|
||||
v += gtk_adjustment_get_step_increment(a) * arg->i;
|
||||
v = MAX(v, 0.0);
|
||||
v = MIN(v, gtk_adjustment_get_upper(a) - gtk_adjustment_get_page_size(a));
|
||||
gtk_adjustment_set_value(a, v);
|
||||
void
|
||||
scroll(GtkAdjustment *a, const Arg *arg) {
|
||||
gdouble v;
|
||||
|
||||
v = gtk_adjustment_get_value(a);
|
||||
switch (arg->i){
|
||||
case +10000:
|
||||
case -10000:
|
||||
v += gtk_adjustment_get_page_increment(a) * (arg->i / 10000); break;
|
||||
case +20000:
|
||||
case -20000:
|
||||
default:
|
||||
v += gtk_adjustment_get_step_increment(a) * arg->i;
|
||||
}
|
||||
v = MAX(v, 0.0);
|
||||
v = MIN(v, gtk_adjustment_get_upper(a) - gtk_adjustment_get_page_size(a));
|
||||
gtk_adjustment_set_value(a, v);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -698,6 +734,10 @@ setup(void) {
|
||||
soup_session_remove_feature_by_type(s, soup_cookie_jar_get_type());
|
||||
g_signal_connect_after(G_OBJECT(s), "request-started", G_CALLBACK(newrequest), NULL);
|
||||
|
||||
/* ssl */
|
||||
g_object_set(G_OBJECT(s), "ssl-ca-file", cafile, NULL);
|
||||
g_object_set(G_OBJECT(s), "ssl-strict", strictssl, NULL);
|
||||
|
||||
/* proxy */
|
||||
if((proxy = getenv("http_proxy")) && strcmp(proxy, "")) {
|
||||
new_proxy = g_strrstr(proxy, "http://") ? g_strdup(proxy) :
|
||||
@@ -739,6 +779,12 @@ spawn(Client *c, const Arg *arg) {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
eval(Client *c, const Arg *arg) {
|
||||
WebKitWebFrame *frame = webkit_web_view_get_main_frame(c->view);
|
||||
evalscript(webkit_web_frame_get_global_context(frame), ((char **)arg->v)[0], "");
|
||||
}
|
||||
|
||||
void
|
||||
stop(Client *c, const Arg *arg) {
|
||||
webkit_web_view_stop_loading(c->view);
|
||||
@@ -754,10 +800,10 @@ void
|
||||
update(Client *c) {
|
||||
char *t;
|
||||
|
||||
if(c->progress != 100)
|
||||
t = g_strdup_printf("[%i%%] %s", c->progress, c->title);
|
||||
else if(c->linkhover)
|
||||
if(c->linkhover)
|
||||
t = g_strdup(c->linkhover);
|
||||
else if(c->progress != 100)
|
||||
t = g_strdup_printf("[%i%%] %s", c->progress, c->title);
|
||||
else
|
||||
t = g_strdup(c->title);
|
||||
drawindicator(c);
|
||||
@@ -779,7 +825,7 @@ usage(void) {
|
||||
|
||||
void
|
||||
windowobjectcleared(GtkWidget *w, WebKitWebFrame *frame, JSContextRef js, JSObjectRef win, Client *c) {
|
||||
runscript(frame, js);
|
||||
runscript(frame);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -828,7 +874,7 @@ main(int argc, char *argv[]) {
|
||||
showxid = TRUE;
|
||||
break;
|
||||
case 'v':
|
||||
die("surf-"VERSION", © 2009 surf engineers, see LICENSE for details\n");
|
||||
die("surf-"VERSION", ©2009-2012 surf engineers, see LICENSE for details\n");
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user