Merge commit 'Dieterbe/experimental' into experimental
[uzbl-mobile] / uzbl.c
diff --git a/uzbl.c b/uzbl.c
index d986a42..77a403c 100644 (file)
--- a/uzbl.c
+++ b/uzbl.c
@@ -67,12 +67,14 @@ GOptionEntry entries[] =
         "Uri to load at startup (equivalent to 'set uri = URI')", "URI" },
     { "verbose", 'v', 0, G_OPTION_ARG_NONE,   &uzbl.state.verbose,
         "Whether to print all messages or just errors.", NULL },
-    { "name",    'n', 0, G_OPTION_ARG_STRING, &uzbl.state.instance_name, 
+    { "name",    'n', 0, G_OPTION_ARG_STRING, &uzbl.state.instance_name,
         "Name of the current instance (defaults to Xorg window id)", "NAME" },
-    { "config",  'c', 0, G_OPTION_ARG_STRING, &uzbl.state.config_file,   
+    { "config",  'c', 0, G_OPTION_ARG_STRING, &uzbl.state.config_file,
         "Config file (this is pretty much equivalent to uzbl < FILE )", "FILE" },
-    { "socket",  's', 0, G_OPTION_ARG_INT, &uzbl.state.socket_id,   
+    { "socket",  's', 0, G_OPTION_ARG_INT, &uzbl.state.socket_id,
         "Socket ID", "SOCKET" },
+    { "version",  'V', 0, G_OPTION_ARG_NONE, &uzbl.behave.print_version,
+        "Print the version and exit", NULL },
     { NULL,      0, 0, 0, NULL, NULL, NULL }
 };
 
@@ -127,6 +129,7 @@ const struct {
     { "history_handler",     PTR(uzbl.behave.history_handler,     STR,  1,   NULL)},
     { "download_handler",    PTR(uzbl.behave.download_handler,    STR,  1,   NULL)},
     { "cookie_handler",      PTR(uzbl.behave.cookie_handler,      STR,  1,   cmd_cookie_handler)},
+    { "new_window",          PTR(uzbl.behave.new_window,          STR,  1,   cmd_new_window)},
     { "fifo_dir",            PTR(uzbl.behave.fifo_dir,            STR,  1,   cmd_fifo_dir)},
     { "socket_dir",          PTR(uzbl.behave.socket_dir,          STR,  1,   cmd_socket_dir)},
     { "http_debug",          PTR(uzbl.behave.http_debug,          INT,  1,   cmd_http_debug)},
@@ -192,7 +195,7 @@ make_var_to_name_hash() {
 
 /* --- UTILITY FUNCTIONS --- */
 enum {EXP_ERR, EXP_SIMPLE_VAR, EXP_BRACED_VAR, EXP_EXPR, EXP_JS};
-static guint
+guint
 get_exp_type(gchar *s) {
     /* variables */
     if(*(s+1) == '(')
@@ -207,11 +210,11 @@ get_exp_type(gchar *s) {
 return EXP_ERR;
 }
 
-/* 
+/*
  * recurse == 1: don't expand '@(command)@'
  * recurse == 2: don't expand '@<java script>@'
  */
-static gchar *
+gchar *
 expand(char *s, guint recurse) {
     uzbl_cmdprop *c;
     guint etype;
@@ -263,7 +266,7 @@ expand(char *s, guint recurse) {
                             ret[vend-s] = '\0';
                         }
                         break;
-                    case EXP_JS: 
+                    case EXP_JS:
                         s++;
                         strcpy(str_end, ">@");
                         str_end[2] = '\0';
@@ -275,7 +278,7 @@ expand(char *s, guint recurse) {
                         break;
                 }
 
-                if(etype == EXP_SIMPLE_VAR || 
+                if(etype == EXP_SIMPLE_VAR ||
                    etype == EXP_BRACED_VAR) {
                     if( (c = g_hash_table_lookup(uzbl.comm.proto_var, ret)) ) {
                         if(c->type == TYPE_STR)
@@ -292,7 +295,7 @@ expand(char *s, guint recurse) {
                     else
                         s = vend+1;
                 }
-                else if(recurse != 1 && 
+                else if(recurse != 1 &&
                         etype == EXP_EXPR) {
                     mycmd = expand(ret, 1);
                     g_spawn_command_line_sync(mycmd, &cmd_stdout, NULL, NULL, &err);
@@ -308,7 +311,7 @@ expand(char *s, guint recurse) {
                     }
                     s = vend+2;
                 }
-                else if(recurse != 2 && 
+                else if(recurse != 2 &&
                         etype == EXP_JS) {
                     mycmd = expand(ret, 2);
                     eval_js(uzbl.gui.web_view, mycmd, js_ret);
@@ -366,9 +369,9 @@ read_file_by_line (gchar *path) {
     gsize len;
     GArray *lines = g_array_new(TRUE, FALSE, sizeof(gchar*));
     int i = 0;
-    
+
     chan = g_io_channel_new_file(path, "r", NULL);
-    
+
     if (chan) {
         while (g_io_channel_read_line(chan, &readbuf, &len, NULL, NULL) == G_IO_STATUS_NORMAL) {
             const gchar* val = g_strdup (readbuf);
@@ -376,12 +379,12 @@ read_file_by_line (gchar *path) {
             g_free (readbuf);
             i ++;
         }
-        
+
         g_io_channel_unref (chan);
     } else {
         fprintf(stderr, "File '%s' not be read.\n", path);
     }
-    
+
     return lines;
 }
 
@@ -390,7 +393,7 @@ parseenv (char* string) {
     extern char** environ;
     gchar* tmpstr = NULL;
     int i = 0;
-    
+
 
     while (environ[i] != NULL) {
         gchar** env = g_strsplit (environ[i], "=", 2);
@@ -439,7 +442,7 @@ clean_up(void) {
     g_scanner_destroy(uzbl.scan);
 }
 
-/* used for html_mode_timeout 
+/* used for html_mode_timeout
  * be sure to extend this function to use
  * more timers if needed in other places
 */
@@ -489,8 +492,8 @@ new_window_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequ
     const gchar* uri = webkit_network_request_get_uri (request);
     if (uzbl.state.verbose)
         printf("New window requested -> %s \n", uri);
-    new_window_load_uri(uri);
-    return (FALSE);
+    webkit_web_policy_decision_use(policy_decision);
+    return TRUE;
 }
 
 gboolean
@@ -569,20 +572,20 @@ scroll_begin(WebKitWebView* page, GArray *argv, GString *result) {
     gtk_adjustment_set_value (uzbl.gui.bar_v, gtk_adjustment_get_lower(uzbl.gui.bar_v));
 }
 
-static void
+void
 scroll_end(WebKitWebView* page, GArray *argv, GString *result) {
     (void) page; (void) argv; (void) result;
     gtk_adjustment_set_value (uzbl.gui.bar_v, gtk_adjustment_get_upper(uzbl.gui.bar_v) -
                               gtk_adjustment_get_page_size(uzbl.gui.bar_v));
 }
 
-static void
+void
 scroll_vert(WebKitWebView* page, GArray *argv, GString *result) {
     (void) page; (void) result;
     scroll(uzbl.gui.bar_v, argv);
 }
 
-static void
+void
 scroll_horz(WebKitWebView* page, GArray *argv, GString *result) {
     (void) page; (void) result;
     scroll(uzbl.gui.bar_h, argv);
@@ -598,7 +601,7 @@ cmd_set_status() {
     update_title();
 }
 
-static void
+void
 toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result) {
     (void)page;
     (void)argv;
@@ -637,13 +640,13 @@ link_hover_cb (WebKitWebView* page, const gchar* title, const gchar* link, gpoin
 }
 
 void
-title_change_cb (WebKitWebView* web_view, WebKitWebFrame* web_frame, const gchar* title, gpointer data) {
+title_change_cb (WebKitWebView* web_view, GParamSpec param_spec) {
     (void) web_view;
-    (void) web_frame;
-    (void) data;
+    (void) param_spec;
+    const gchar *title = webkit_web_view_get_title(web_view);
     if (uzbl.gui.main_title)
         g_free (uzbl.gui.main_title);
-    uzbl.gui.main_title = g_strdup (title);
+    uzbl.gui.main_title = title ? g_strdup (title) : g_strdup ("(no title)");
     update_title();
 }
 
@@ -714,7 +717,7 @@ log_history_cb () {
 
 
 /* VIEW funcs (little webkit wrappers) */
-#define VIEWFUNC(name) static void view_##name(WebKitWebView *page, GArray *argv, GString *result){(void)argv; (void)result; webkit_web_view_##name(page);}
+#define VIEWFUNC(name) void view_##name(WebKitWebView *page, GArray *argv, GString *result){(void)argv; (void)result; webkit_web_view_##name(page);}
 VIEWFUNC(reload)
 VIEWFUNC(reload_bypass_cache)
 VIEWFUNC(stop_loading)
@@ -725,7 +728,7 @@ VIEWFUNC(go_forward)
 #undef VIEWFUNC
 
 /* -- command to callback/function map for things we cannot attach to any signals */
-static struct {char *key; CommandInfo value;} cmdlist[] =
+struct {char *key; CommandInfo value;} cmdlist[] =
 {   /* key                   function      no_split      */
     { "back",               {view_go_back, 0}              },
     { "forward",            {view_go_forward, 0}           },
@@ -803,17 +806,19 @@ file_exists (const char * filename) {
     return (access(filename, F_OK) == 0);
 }
 
-static void
+void
 set_var(WebKitWebView *page, GArray *argv, GString *result) {
     (void) page; (void) result;
     gchar **split = g_strsplit(argv_idx(argv, 0), "=", 2);
-    gchar *value = parseenv(g_strdup(split[1] ? g_strchug(split[1]) : " "));
-    set_var_value(g_strstrip(split[0]), value);
-    g_free(value);
+    if (split[0] != NULL) {
+        gchar *value = parseenv(g_strdup(split[1] ? g_strchug(split[1]) : " "));
+        set_var_value(g_strstrip(split[0]), value);
+        g_free(value);
+    }
     g_strfreev(split);
 }
 
-static void
+void
 print(WebKitWebView *page, GArray *argv, GString *result) {
     (void) page; (void) result;
     gchar* buf;
@@ -823,7 +828,7 @@ print(WebKitWebView *page, GArray *argv, GString *result) {
     g_free(buf);
 }
 
-static void
+void
 act_bind(WebKitWebView *page, GArray *argv, GString *result) {
     (void) page; (void) result;
     gchar **split = g_strsplit(argv_idx(argv, 0), " = ", 2);
@@ -839,7 +844,7 @@ act_dump_config() {
     dump_config();
 }
 
-static void
+void
 toggle_insert_mode(WebKitWebView *page, GArray *argv, GString *result) {
     (void) page; (void) result;
 
@@ -856,7 +861,7 @@ toggle_insert_mode(WebKitWebView *page, GArray *argv, GString *result) {
     update_title();
 }
 
-static void
+void
 load_uri (WebKitWebView *web_view, GArray *argv, GString *result) {
     (void) result;
 
@@ -876,14 +881,14 @@ load_uri (WebKitWebView *web_view, GArray *argv, GString *result) {
 
 /* Javascript*/
 
-static JSValueRef
+JSValueRef
 js_run_command (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
                 size_t argumentCount, const JSValueRef arguments[],
                 JSValueRef* exception) {
     (void) function;
     (void) thisObject;
     (void) exception;
-    
+
     JSStringRef js_result_string;
     GString *result = g_string_new("");
 
@@ -904,11 +909,11 @@ js_run_command (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject,
     return JSValueMakeString(ctx, js_result_string);
 }
 
-static JSStaticFunction js_static_functions[] = {
+JSStaticFunction js_static_functions[] = {
     {"run", js_run_command, kJSPropertyAttributeNone},
 };
 
-static void
+void
 js_init() {
     /* This function creates the class and its definition, only once */
     if (!uzbl.js.initialized) {
@@ -921,7 +926,7 @@ js_init() {
 }
 
 
-static void 
+void 
 eval_js(WebKitWebView * web_view, gchar *script, GString *result) {
     WebKitWebFrame *frame;
     JSGlobalContextRef context;
@@ -932,20 +937,20 @@ eval_js(WebKitWebView * web_view, gchar *script, GString *result) {
     JSValueRef js_result;
     JSStringRef js_result_string;
     size_t js_result_size;
-    
+
     js_init();
 
     frame = webkit_web_view_get_main_frame(WEBKIT_WEB_VIEW(web_view));
     context = webkit_web_frame_get_global_context(frame);
     globalobject = JSContextGetGlobalObject(context);
-    
+
     /* uzbl javascript namespace */
     var_name = JSStringCreateWithUTF8CString("Uzbl");
     JSObjectSetProperty(context, globalobject, var_name,
-                        JSObjectMake(context, uzbl.js.classref, NULL),  
+                        JSObjectMake(context, uzbl.js.classref, NULL),
                         kJSClassAttributeNone, NULL);
-    
-    /* evaluate the script and get return value*/ 
+
+    /* evaluate the script and get return value*/
     js_script = JSStringCreateWithUTF8CString(script);
     js_result = JSEvaluateScript(context, js_script, globalobject, NULL, 0, NULL);
     if (js_result && !JSValueIsUndefined(context, js_result)) {
@@ -968,13 +973,13 @@ eval_js(WebKitWebView * web_view, gchar *script, GString *result) {
     JSStringRelease(js_script);
 }
 
-static void
+void
 run_js (WebKitWebView * web_view, GArray *argv, GString *result) {
     if (argv_idx(argv, 0))
         eval_js(web_view, argv_idx(argv, 0), result);
 }
 
-static void
+void
 run_external_js (WebKitWebView * web_view, GArray *argv, GString *result) {
     (void) result;
     if (argv_idx(argv, 0)) {
@@ -993,7 +998,7 @@ run_external_js (WebKitWebView * web_view, GArray *argv, GString *result) {
             i ++;
             g_free (line);
         }
-        
+
         if (uzbl.state.verbose)
             printf ("External JavaScript file %s loaded\n", argv_idx(argv, 0));
 
@@ -1017,7 +1022,7 @@ search_text (WebKitWebView *page, GArray *argv, const gboolean forward) {
             uzbl.state.searchtx = g_strdup(argv_idx(argv, 0));
         }
     }
-    
+
     if (uzbl.state.searchtx) {
         if (uzbl.state.verbose)
             printf ("Searching: %s\n", uzbl.state.searchtx);
@@ -1026,19 +1031,19 @@ search_text (WebKitWebView *page, GArray *argv, const gboolean forward) {
     }
 }
 
-static void
+void
 search_forward_text (WebKitWebView *page, GArray *argv, GString *result) {
     (void) result;
     search_text(page, argv, TRUE);
 }
 
-static void
+void
 search_reverse_text (WebKitWebView *page, GArray *argv, GString *result) {
     (void) result;
     search_text(page, argv, FALSE);
 }
 
-static void
+void
 dehilight (WebKitWebView *page, GArray *argv, GString *result) {
     (void) argv; (void) result;
     webkit_web_view_set_highlight_text_matches (page, FALSE);
@@ -1047,6 +1052,12 @@ dehilight (WebKitWebView *page, GArray *argv, GString *result) {
 
 void
 new_window_load_uri (const gchar * uri) {
+    if (uzbl.behave.new_window) {
+        GString *s = g_string_new ("");
+        g_string_printf(s, "'%s'", uri);
+        run_handler(uzbl.behave.new_window, s->str);
+        return;
+    }
     GString* to_execute = g_string_new ("");
     g_string_append_printf (to_execute, "%s --uri '%s'", uzbl.state.executable_path, uri);
     int i;
@@ -1064,20 +1075,21 @@ new_window_load_uri (const gchar * uri) {
     g_string_free (to_execute, TRUE);
 }
 
-static void
+void
 chain (WebKitWebView *page, GArray *argv, GString *result) {
     (void) page; (void) result;
     gchar *a = NULL;
     gchar **parts = NULL;
-    guint i = 0;    
+    guint i = 0;
     while ((a = argv_idx(argv, i++))) {
         parts = g_strsplit (a, " ", 2);
-        parse_command(parts[0], parts[1], result);
+        if (parts[0])
+          parse_command(parts[0], parts[1], result);
         g_strfreev (parts);
     }
 }
 
-static void
+void
 keycmd (WebKitWebView *page, GArray *argv, GString *result) {
     (void)page;
     (void)argv;
@@ -1087,7 +1099,7 @@ keycmd (WebKitWebView *page, GArray *argv, GString *result) {
     update_title();
 }
 
-static void
+void
 keycmd_nl (WebKitWebView *page, GArray *argv, GString *result) {
     (void)page;
     (void)argv;
@@ -1097,7 +1109,7 @@ keycmd_nl (WebKitWebView *page, GArray *argv, GString *result) {
     update_title();
 }
 
-static void
+void
 keycmd_bs (WebKitWebView *page, GArray *argv, GString *result) {
     gchar *prev;
     (void)page;
@@ -1109,7 +1121,7 @@ keycmd_bs (WebKitWebView *page, GArray *argv, GString *result) {
     update_title();
 }
 
-static void
+void
 close_uzbl (WebKitWebView *page, GArray *argv, GString *result) {
     (void)page;
     (void)argv;
@@ -1356,7 +1368,7 @@ run_command (const gchar *command, const guint npre, const gchar **args,
              const gboolean sync, char **output_stdout) {
    //command <uzbl conf> <uzbl pid> <uzbl win id> <uzbl fifo file> <uzbl socket file> [args]
     GError *err = NULL;
-    
+
     GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
     gchar *pid = itos(getpid());
     gchar *xwin = itos(uzbl.xwin);
@@ -1374,11 +1386,11 @@ run_command (const gchar *command, const guint npre, const gchar **args,
 
     for (i = npre; i < g_strv_length((gchar**)args); i++)
         sharg_append(a, args[i]);
-    
+
     gboolean result;
     if (sync) {
         if (*output_stdout) *output_stdout = strfree(*output_stdout);
-        
+
         result = g_spawn_sync(NULL, (gchar **)a->data, NULL, G_SPAWN_SEARCH_PATH,
                               NULL, NULL, output_stdout, NULL, NULL, &err);
     } else result = g_spawn_async(NULL, (gchar **)a->data, NULL, G_SPAWN_SEARCH_PATH,
@@ -1413,7 +1425,7 @@ split_quoted(const gchar* src, const gboolean unquote) {
     /* split on unquoted space, return array of strings;
        remove a layer of quotes and backslashes if unquote */
     if (!src) return NULL;
-    
+
     gboolean dq = FALSE;
     gboolean sq = FALSE;
     GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
@@ -1445,7 +1457,7 @@ split_quoted(const gchar* src, const gboolean unquote) {
     return ret;
 }
 
-static void
+void
 spawn(WebKitWebView *web_view, GArray *argv, GString *result) {
     (void)web_view; (void)result;
     //TODO: allow more control over argument order so that users can have some arguments before the default ones from run_command, and some after
@@ -1453,23 +1465,23 @@ spawn(WebKitWebView *web_view, GArray *argv, GString *result) {
         run_command(argv_idx(argv, 0), 0, ((const gchar **) (argv->data + sizeof(gchar*))), FALSE, NULL);
 }
 
-static void
+void
 spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result) {
     (void)web_view; (void)result;
-    
+
     if (argv_idx(argv, 0))
         run_command(argv_idx(argv, 0), 0, ((const gchar **) (argv->data + sizeof(gchar*))),
                     TRUE, &uzbl.comm.sync_stdout);
 }
 
-static void
+void
 spawn_sh(WebKitWebView *web_view, GArray *argv, GString *result) {
     (void)web_view; (void)result;
     if (!uzbl.behave.shell_cmd) {
         g_printerr ("spawn_sh: shell_cmd is not set!\n");
         return;
     }
-    
+
     guint i;
     gchar *spacer = g_strdup("");
     g_array_insert_val(argv, 1, spacer);
@@ -1483,14 +1495,14 @@ spawn_sh(WebKitWebView *web_view, GArray *argv, GString *result) {
     g_strfreev (cmd);
 }
 
-static void
+void
 spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) {
     (void)web_view; (void)result;
     if (!uzbl.behave.shell_cmd) {
         g_printerr ("spawn_sh_sync: shell_cmd is not set!\n");
         return;
     }
-    
+
     guint i;
     gchar *spacer = g_strdup("");
     g_array_insert_val(argv, 1, spacer);
@@ -1498,14 +1510,14 @@ spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) {
 
     for (i = 1; i < g_strv_length(cmd); i++)
         g_array_prepend_val(argv, cmd[i]);
-         
+
     if (cmd) run_command(cmd[0], g_strv_length(cmd) + 1, (const gchar **) argv->data,
                          TRUE, &uzbl.comm.sync_stdout);
     g_free (spacer);
     g_strfreev (cmd);
 }
 
-static void
+void
 parse_command(const char *cmd, const char *param, GString *result) {
     CommandInfo *c;
 
@@ -1618,7 +1630,7 @@ cmd_font_size() {
     if (uzbl.behave.font_size > 0) {
         g_object_set (G_OBJECT(ws), "default-font-size", uzbl.behave.font_size, NULL);
     }
-    
+
     if (uzbl.behave.monospace_size > 0) {
         g_object_set (G_OBJECT(ws), "default-monospace-font-size",
                       uzbl.behave.monospace_size, NULL);
@@ -1635,7 +1647,7 @@ cmd_zoom_level() {
 
 void
 cmd_disable_plugins() {
-    g_object_set (G_OBJECT(view_settings()), "enable-plugins", 
+    g_object_set (G_OBJECT(view_settings()), "enable-plugins",
             !uzbl.behave.disable_plugins, NULL);
 }
 
@@ -1726,6 +1738,19 @@ cmd_cookie_handler() {
 }
 
 void
+cmd_new_window() {
+    gchar **split = g_strsplit(uzbl.behave.new_window, " ", 2);
+    /* pitfall: doesn't handle chain actions; must the sync_ action manually */
+    if ((g_strcmp0(split[0], "sh") == 0) ||
+        (g_strcmp0(split[0], "spawn") == 0)) {
+        g_free (uzbl.behave.new_window);
+        uzbl.behave.new_window =
+            g_strdup_printf("%s %s", split[0], split[1]);
+    }
+    g_strfreev (split);
+}
+
+void
 cmd_fifo_dir() {
     uzbl.behave.fifo_dir = init_fifo(uzbl.behave.fifo_dir);
 }
@@ -1751,7 +1776,7 @@ cmd_modkey() {
     buf = g_utf8_strup(uzbl.behave.modkey, -1);
     uzbl.behave.modmask = 0;
 
-    if(uzbl.behave.modkey) 
+    if(uzbl.behave.modkey)
         g_free(uzbl.behave.modkey);
     uzbl.behave.modkey = buf;
 
@@ -1839,7 +1864,7 @@ render_html() {
 }
 
 enum {M_CMD, M_HTML};
-static void
+void
 parse_cmd_line(const char *ctl_line, GString *result) {
     Behaviour *b = &uzbl.behave;
     size_t len=0;
@@ -1997,7 +2022,7 @@ control_socket(GIOChannel *chan) {
 
     clientsock = accept (g_io_channel_unix_get_fd(chan),
                          (struct sockaddr *) &remote, &t);
-    
+
     if ((clientchan = g_io_channel_unix_new(clientsock))) {
         g_io_add_watch(clientchan, G_IO_IN|G_IO_HUP,
                        (GIOFunc) control_client_socket, clientchan);
@@ -2006,7 +2031,7 @@ control_socket(GIOChannel *chan) {
     return TRUE;
 }
 
-static gboolean
+gboolean
 control_client_socket(GIOChannel *clientchan) {
     char *ctl_line;
     GString *result = g_string_new("");
@@ -2111,9 +2136,11 @@ update_title (void) {
         if (b->status_background) {
             GdkColor color;
             gdk_color_parse (b->status_background, &color);
-            //labels and hboxes do not draw their own background.  applying this on the window is ok as we the statusbar is the only affected widget.  (if not, we could also use GtkEventBox)
+            //labels and hboxes do not draw their own background. applying this on the vbox/main_window is ok as the statusbar is the only affected widget. (if not, we could also use GtkEventBox)
             if (uzbl.gui.main_window)
                 gtk_widget_modify_bg (uzbl.gui.main_window, GTK_STATE_NORMAL, &color);
+            else if (uzbl.gui.plug)
+                gtk_widget_modify_bg (GTK_WIDGET(uzbl.gui.plug), GTK_STATE_NORMAL, &color);
         }
     } else {
         if (b->title_format_long) {
@@ -2214,7 +2241,7 @@ run_keycmd(const gboolean key_ret) {
             else exec_paramcmd(act, i); /* otherwise execute the incremental */
             break;
         }
-        
+
         g_string_truncate(short_keys, short_keys->len - 1);
     }
     g_string_free (short_keys, TRUE);
@@ -2249,7 +2276,7 @@ create_browser () {
     g->web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ());
     gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (g->web_view));
 
-    g_signal_connect (G_OBJECT (g->web_view), "title-changed", G_CALLBACK (title_change_cb), g->web_view);
+    g_signal_connect (G_OBJECT (g->web_view), "notify::title", G_CALLBACK (title_change_cb), NULL);
     g_signal_connect (G_OBJECT (g->web_view), "load-progress-changed", G_CALLBACK (progress_change_cb), g->web_view);
     g_signal_connect (G_OBJECT (g->web_view), "load-committed", G_CALLBACK (load_commit_cb), g->web_view);
     g_signal_connect (G_OBJECT (g->web_view), "load-started", G_CALLBACK (load_start_cb), g->web_view);
@@ -2294,8 +2321,8 @@ create_window () {
     return window;
 }
 
-static
-GtkPlug* create_plug () {
+GtkPlug* 
+create_plug () {
     GtkPlug* plug = GTK_PLUG (gtk_plug_new (uzbl.state.socket_id));
     g_signal_connect (G_OBJECT (plug), "destroy", G_CALLBACK (destroy_cb), NULL);
     g_signal_connect (G_OBJECT (plug), "key-press-event", G_CALLBACK (key_press_cb), NULL);
@@ -2304,7 +2331,7 @@ GtkPlug* create_plug () {
 }
 
 
-static gchar**
+gchar**
 inject_handler_args(const gchar *actname, const gchar *origargs, const gchar *newargs) {
     /*
       If actname is one that calls an external command, this function will inject
@@ -2368,7 +2395,7 @@ run_handler (const gchar *act, const gchar *args) {
     if (g_strcmp0(parts[0], "chain") == 0) {
         GString *newargs = g_string_new("");
         gchar **chainparts = split_quoted(parts[1], FALSE);
-        
+
         /* for every argument in the chain, inject the handler args
            and make sure the new parts are wrapped in quotes */
         gchar **cp = chainparts;
@@ -2376,7 +2403,7 @@ run_handler (const gchar *act, const gchar *args) {
         gchar *quotless = NULL;
         gchar **spliced_quotless = NULL; // sigh -_-;
         gchar **inpart = NULL;
-        
+
         while (*cp) {
             if ((**cp == '\'') || (**cp == '\"')) { /* strip old quotes */
                 quot = **cp;
@@ -2386,7 +2413,7 @@ run_handler (const gchar *act, const gchar *args) {
             spliced_quotless = g_strsplit(quotless, " ", 2);
             inpart = inject_handler_args(spliced_quotless[0], spliced_quotless[1], args);
             g_strfreev(spliced_quotless);
-            
+
             g_string_append_printf(newargs, " %c%s %s%c", quot, inpart[0], inpart[1], quot);
             g_free(quotless);
             g_strfreev(inpart);
@@ -2396,7 +2423,7 @@ run_handler (const gchar *act, const gchar *args) {
         parse_command(parts[0], &(newargs->str[1]), NULL);
         g_string_free(newargs, TRUE);
         g_strfreev(chainparts);
-        
+
     } else {
         gchar **inparts = inject_handler_args(parts[0], parts[1], args);
         parse_command(inparts[0], inparts[1], NULL);
@@ -2468,7 +2495,7 @@ find_xdg_file (int xdg_type, char* filename) {
             temporary_file = g_strconcat (temporary_string, filename, NULL);
         }
     }
-    
+
     //g_free (temporary_string); - segfaults.
 
     if (file_exists (temporary_file)) {
@@ -2485,8 +2512,13 @@ settings_init () {
     for (i = 0; default_config[i].command != NULL; i++) {
         parse_cmd_line(default_config[i].command, NULL);
     }
+    
+    if (g_strcmp0(s->config_file, "-") == 0) {
+        s->config_file = NULL;
+        create_stdin();
+    }
 
-    if (!s->config_file) {
+    else if (!s->config_file) {
         s->config_file = find_xdg_file (0, "/uzbl/config");
     }
 
@@ -2518,7 +2550,7 @@ void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data)
     soup_message_add_header_handler(msg, "got-headers", "Set-Cookie", G_CALLBACK(save_cookies), NULL);
     GString *s = g_string_new ("");
     SoupURI * soup_uri = soup_message_get_uri(msg);
-    g_string_printf(s, "GET '%s' '%s'", soup_uri->host, soup_uri->path);
+    g_string_printf(s, "GET '%s' '%s' '%s'", soup_uri->scheme, soup_uri->host, soup_uri->path);
     run_handler(uzbl.behave.cookie_handler, s->str);
 
     if(uzbl.comm.sync_stdout && strcmp (uzbl.comm.sync_stdout, "") != 0) {
@@ -2528,7 +2560,7 @@ void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data)
     }
     if (uzbl.comm.sync_stdout)
         uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
-        
+
     g_string_free(s, TRUE);
 }
 
@@ -2541,7 +2573,7 @@ save_cookies (SoupMessage *msg, gpointer user_data){
         cookie = soup_cookie_to_set_cookie_header(ck->data);
         SoupURI * soup_uri = soup_message_get_uri(msg);
         GString *s = g_string_new ("");
-        g_string_printf(s, "PUT '%s' '%s' '%s'", soup_uri->host, soup_uri->path, cookie);
+        g_string_printf(s, "PUT '%s' '%s' '%s' '%s'", soup_uri->scheme, soup_uri->host, soup_uri->path, cookie);
         run_handler(uzbl.behave.cookie_handler, s->str);
         g_free (cookie);
         g_string_free(s, TRUE);
@@ -2683,13 +2715,20 @@ main (int argc, char* argv[]) {
     uzbl.state.selected_url = NULL;
     uzbl.state.searchtx = NULL;
 
-    GOptionContext* context = g_option_context_new ("- some stuff here maybe someday");
+    GOptionContext* context = g_option_context_new ("[ uri ] - load a uri by default");
     g_option_context_add_main_entries (context, entries, NULL);
     g_option_context_add_group (context, gtk_get_option_group (TRUE));
     g_option_context_parse (context, &argc, &argv, NULL);
     g_option_context_free(context);
-    
+
+    if (uzbl.behave.print_version) {
+        printf("Commit: %s\n", COMMIT);
+        exit(0);
+    }
+
     gchar *uri_override = (uzbl.state.uri ? g_strdup(uzbl.state.uri) : NULL);
+    if (argc > 1 && !uzbl.state.uri)
+        uri_override = g_strdup(argv[1]);
     gboolean verbose_override = uzbl.state.verbose;
 
     /* initialize hash table */
@@ -2775,11 +2814,9 @@ main (int argc, char* argv[]) {
     /* WebInspector */
     set_up_inspector();
 
-    create_stdin();
-
     if (verbose_override > uzbl.state.verbose)
         uzbl.state.verbose = verbose_override;
-    
+
     if (uri_override) {
         set_var_value("uri", uri_override);
         g_free(uri_override);