Merge commit 'rob/config-refactor' into experimental
[uzbl-mobile] / uzbl.c
diff --git a/uzbl.c b/uzbl.c
index c55c572..0a11099 100644 (file)
--- a/uzbl.c
+++ b/uzbl.c
@@ -272,12 +272,26 @@ progress_change_cb (WebKitWebView* page, gint progress, gpointer data) {
 }
 
 static void
+load_finish_cb (WebKitWebView* page, WebKitWebFrame* frame, gpointer data) {
+    (void) page;
+    (void) data;
+    if (uzbl.behave.load_finish_handler) {
+        run_command_async(uzbl.behave.load_finish_handler, NULL);
+    }
+}
+
+static void
 load_commit_cb (WebKitWebView* page, WebKitWebFrame* frame, gpointer data) {
     (void) page;
     (void) data;
     free (uzbl.state.uri);
     GString* newuri = g_string_new (webkit_web_frame_get_uri (frame));
     uzbl.state.uri = g_string_free (newuri, FALSE);
+    if ((!uzbl.behave.never_reset_mode) && (uzbl.behave.insert_mode)) {
+        uzbl.behave.insert_mode = uzbl.behave.always_insert_mode;
+        update_title();
+    }    
+    g_string_truncate(uzbl.state.keycmd, 0); // don't need old commands to remain on new page?
 }
 
 static void
@@ -676,7 +690,10 @@ setup_regex() {
             G_REGEX_OPTIMIZE, 0, &err);
     uzbl.comm.bind_regex = g_regex_new("^[Bb][a-zA-Z]*\\s+?(.*[^ ])\\s*?=\\s*([a-z][^\\n].+)$", 
             G_REGEX_UNGREEDY|G_REGEX_OPTIMIZE, 0, &err);
+    uzbl.comm.cmd_regex = g_regex_new("^CMD\\s+([^ \\n]+)\\s*([^\\n]*)?$",
+            G_REGEX_OPTIMIZE, 0, &err);
 }
+
 static gboolean
 get_var_value(gchar *name) {
     void **p = NULL;
@@ -758,6 +775,16 @@ parse_cmd_line(char *ctl_line) {
         else 
             printf("Error in command: %s\n", tokens[0]);
     }
+    /* CMD command */
+    else if(ctl_line[0] == 'C') {
+        tokens = g_regex_split(uzbl.comm.cmd_regex, ctl_line, 0);
+        if(tokens[0][0] == 0) {
+            parse_command(tokens[1], tokens[2]);
+            g_strfreev(tokens);
+        }
+        else
+            printf("Error in command: %s\n", tokens[0]);
+    }
     /* Comments */
     else if(   (ctl_line[0] == '#')
             || (ctl_line[0] == ' ')
@@ -1044,7 +1071,7 @@ key_press_cb (WebKitWebView* page, GdkEventKey* event)
     Action *action;
 
     if (event->type != GDK_KEY_PRESS || event->keyval == GDK_Page_Up || event->keyval == GDK_Page_Down
-        || event->keyval == GDK_Up || event->keyval == GDK_Down || event->keyval == GDK_Left || event->keyval == GDK_Right)
+        || event->keyval == GDK_Up || event->keyval == GDK_Down || event->keyval == GDK_Left || event->keyval == GDK_Right || event->keyval == GDK_Shift_L || event->keyval == GDK_Shift_R)
         return FALSE;
 
     /* turn off insert mode (if always_insert_mode is not used) */
@@ -1054,7 +1081,7 @@ key_press_cb (WebKitWebView* page, GdkEventKey* event)
         return TRUE;
     }
 
-    if (uzbl.behave.insert_mode && ((event->state & uzbl.behave.modmask) != uzbl.behave.modmask))
+    if (uzbl.behave.insert_mode && (((event->state & uzbl.behave.modmask) != uzbl.behave.modmask) || (!uzbl.behave.modmask)))
         return FALSE;
 
     if (event->keyval == GDK_Escape) {
@@ -1082,49 +1109,61 @@ key_press_cb (WebKitWebView* page, GdkEventKey* event)
     if ((event->keyval == GDK_BackSpace) && (uzbl.state.keycmd->len > 0)) {
         g_string_truncate(uzbl.state.keycmd, uzbl.state.keycmd->len - 1);
         update_title();
-        return TRUE;
     }
 
-    if ((event->keyval == GDK_Return) || (event->keyval == GDK_KP_Enter)) {
-        GString* short_keys = g_string_new ("");
-        unsigned int i;
-        for (i=0; i<(uzbl.state.keycmd->len); i++) {
-            g_string_append_c(short_keys, uzbl.state.keycmd->str[i]);
-            g_string_append_c(short_keys, '_');
-            
-            //printf("\nTesting string: @%s@\n", short_keys->str);
-            if ((action = g_hash_table_lookup(uzbl.bindings, short_keys->str))) {
-                GString* parampart = g_string_new (uzbl.state.keycmd->str);
-                g_string_erase (parampart, 0, i+1);
-                //printf("\nParameter: @%s@\n", parampart->str);
-                GString* actionname = g_string_new ("");
-                if (action->name)
-                    g_string_printf (actionname, action->name, parampart->str);
-                GString* actionparam = g_string_new ("");
-                if (action->param)
-                    g_string_printf (actionparam, action->param, parampart->str);
-                parse_command(actionname->str, actionparam->str);
-                g_string_free (actionname, TRUE);
-                g_string_free (actionparam, TRUE);
-                g_string_free (parampart, TRUE);
-                g_string_truncate(uzbl.state.keycmd, 0);
-                update_title();
-            }          
-
-            g_string_truncate(short_keys, short_keys->len - 1);
-        }
-        g_string_free (short_keys, TRUE);
-        return (!uzbl.behave.insert_mode);
-    }
+    gboolean key_ret = FALSE;
+    if ((event->keyval == GDK_Return) || (event->keyval == GDK_KP_Enter))
+        key_ret = TRUE;
 
-    g_string_append(uzbl.state.keycmd, event->string);
+    if (!key_ret) g_string_append(uzbl.state.keycmd, event->string);
     if ((action = g_hash_table_lookup(uzbl.bindings, uzbl.state.keycmd->str))) {
         g_string_truncate(uzbl.state.keycmd, 0);
         parse_command(action->name, action->param);
     }
 
-    update_title();
+    GString* short_keys = g_string_new ("");
+    GString* short_keys_inc = g_string_new ("");
+    unsigned int i;
+    for (i=0; i<(uzbl.state.keycmd->len); i++) {
+        g_string_append_c(short_keys, uzbl.state.keycmd->str[i]);
+        g_string_assign(short_keys_inc, short_keys->str);
+        g_string_append_c(short_keys, '_');
+        g_string_append_c(short_keys_inc, '*');
+            
+        gboolean exec_now = FALSE;
+        if ((action = g_hash_table_lookup(uzbl.bindings, short_keys->str))) {
+            if (key_ret) exec_now = TRUE; // run normal cmds only if return was pressed
+        } else if ((action = g_hash_table_lookup(uzbl.bindings, short_keys_inc->str))) {
+            if (key_ret) { // just quit the incremental command on return
+                g_string_truncate(uzbl.state.keycmd, 0);
+                break;
+            } else exec_now = TRUE; // always exec inc. commands on keys other than return
+        }
 
+        if (exec_now) {
+            GString* parampart = g_string_new (uzbl.state.keycmd->str);
+            GString* actionname = g_string_new ("");
+            GString* actionparam = g_string_new ("");
+            g_string_erase (parampart, 0, i+1);
+            if (action->name)
+                g_string_printf (actionname, action->name, parampart->str);
+            if (action->param)
+                g_string_printf (actionparam, action->param, parampart->str);
+            parse_command(actionname->str, actionparam->str);
+            g_string_free (actionname, TRUE);
+            g_string_free (actionparam, TRUE);
+            g_string_free (parampart, TRUE);
+            if (key_ret)
+                g_string_truncate(uzbl.state.keycmd, 0);
+            break;
+        }      
+        
+        g_string_truncate(short_keys, short_keys->len - 1);
+    }
+    g_string_free (short_keys, TRUE);
+    g_string_free (short_keys_inc, TRUE);
+    update_title();
+    if (key_ret) return (!uzbl.behave.insert_mode);
     return TRUE;
 }
 
@@ -1142,6 +1181,7 @@ create_browser () {
     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-committed", G_CALLBACK (log_history_cb), g->web_view);
+    g_signal_connect (G_OBJECT (g->web_view), "load-finished", G_CALLBACK (load_finish_cb), g->web_view);
     g_signal_connect (G_OBJECT (g->web_view), "hovering-over-link", G_CALLBACK (link_hover_cb), g->web_view);
     g_signal_connect (G_OBJECT (g->web_view), "key-press-event", G_CALLBACK (key_press_cb), g->web_view);
     g_signal_connect (G_OBJECT (g->web_view), "new-window-policy-decision-requested", G_CALLBACK (new_window_cb), g->web_view); 
@@ -1252,6 +1292,7 @@ settings_init () {
     }
 
     if (res) {
+        b->load_finish_handler= g_key_file_get_value   (config, "behavior", "load_finish_handler",NULL);
         b->history_handler    = g_key_file_get_value   (config, "behavior", "history_handler",    NULL);
         b->download_handler   = g_key_file_get_value   (config, "behavior", "download_handler",   NULL);
         b->cookie_handler     = g_key_file_get_string  (config, "behavior", "cookie_handler",     NULL);
@@ -1259,6 +1300,7 @@ settings_init () {
         b->show_status        = g_key_file_get_boolean (config, "behavior", "show_status",        NULL);
         b->modkey             = g_key_file_get_value   (config, "behavior", "modkey",             NULL);
         b->status_top         = g_key_file_get_boolean (config, "behavior", "status_top",         NULL);
+        b->never_reset_mode   = g_key_file_get_boolean (config, "behavior", "never_reset_mode",   NULL);
         b->status_format      = g_key_file_get_string  (config, "behavior", "status_format",      NULL);
         b->status_background  = g_key_file_get_string  (config, "behavior", "status_background",  NULL);
         if (! b->fifo_dir)
@@ -1274,10 +1316,11 @@ settings_init () {
     printf ("Fifo directory: %s\n",     (b->fifo_dir           ? b->fifo_dir         : "disabled"));
     printf ("Socket directory: %s\n",   (b->socket_dir         ? b->socket_dir       : "disabled"));
     printf ("Always insert mode: %s\n", (b->always_insert_mode ? "TRUE"              : "FALSE"));
+    printf ("Don't reset mode: %s\n",   (b->never_reset_mode   ? "TRUE"              : "FALSE"));
     printf ("Show status: %s\n",        (b->show_status        ? "TRUE"              : "FALSE"));
     printf ("Status top: %s\n",         (b->status_top         ? "TRUE"              : "FALSE"));
     printf ("Modkey: %s\n",             (b->modkey             ? b->modkey           : "disabled"));
-    printf ("Status format: %s\n",             (b->status_format            ? b->status_format           : "none"));
+    printf ("Status format: %s\n",      (b->status_format      ? b->status_format    : "none"));
 
     if (!b->modkey)
         b->modkey = "";
@@ -1441,7 +1484,7 @@ main (int argc, char* argv[]) {
     /* initialize hash table */
     uzbl.bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_action);
        
-       uzbl.net.soup_session = webkit_get_default_session();
+    uzbl.net.soup_session = webkit_get_default_session();
     uzbl.state.keycmd = g_string_new("");
 
     settings_init ();