diff options
author | Brendan Taylor <whateley@gmail.com> | 2011-04-30 08:17:40 -0600 |
---|---|---|
committer | Brendan Taylor <whateley@gmail.com> | 2011-04-30 08:17:40 -0600 |
commit | ceeba25242492db44091a4c87b046a25527d2f59 (patch) | |
tree | 5687dda2e9847b28ba48974d5246654eca281311 /src | |
parent | b0d2559157d0b060e2a2c2c33f08bed5f9cfaf51 (diff) | |
parent | cd7ff839afd2af2ec78868d91eca7fd4a2d4f117 (diff) |
Merge branch 'experimental' into scrollbars
Diffstat (limited to 'src')
-rw-r--r-- | src/callbacks.c | 19 | ||||
-rw-r--r-- | src/events.c | 91 | ||||
-rw-r--r-- | src/events.h | 8 | ||||
-rwxr-xr-x | src/uzbl-browser | 75 | ||||
-rw-r--r-- | src/uzbl-core.c | 58 | ||||
-rw-r--r-- | src/uzbl-core.h | 6 |
6 files changed, 161 insertions, 96 deletions
diff --git a/src/callbacks.c b/src/callbacks.c index bd50d81..bce399f 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -292,8 +292,11 @@ cmd_caret_browsing() { void set_current_encoding() { - webkit_web_view_set_custom_encoding(uzbl.gui.web_view, - uzbl.behave.current_encoding); + gchar *encoding = uzbl.behave.current_encoding; + if(strlen(encoding) == 0) + encoding = NULL; + + webkit_web_view_set_custom_encoding(uzbl.gui.web_view, encoding); } @@ -550,7 +553,7 @@ key_press_cb (GtkWidget* window, GdkEventKey* event) { (void) window; if(event->type == GDK_KEY_PRESS) - key_to_event(event->keyval, GDK_KEY_PRESS); + key_to_event(event->keyval, event->state, event->is_modifier, GDK_KEY_PRESS); return uzbl.behave.forward_keys ? FALSE : TRUE; } @@ -560,7 +563,7 @@ key_release_cb (GtkWidget* window, GdkEventKey* event) { (void) window; if(event->type == GDK_KEY_RELEASE) - key_to_event(event->keyval, GDK_KEY_RELEASE); + key_to_event(event->keyval, event->state, event->is_modifier, GDK_KEY_RELEASE); return uzbl.behave.forward_keys ? FALSE : TRUE; } @@ -838,6 +841,11 @@ download_cb(WebKitWebView *web_view, WebKitDownload *download, gpointer user_dat /* get the URI being downloaded */ const gchar *uri = webkit_download_get_uri(download); + /* get the destination path, if specified. + * this is only intended to be set when this function is trigger by an + * explicit download using uzbl's 'download' action. */ + const gchar *destination = user_data; + if (uzbl.state.verbose) printf("Download requested -> %s\n", uri); @@ -884,6 +892,9 @@ download_cb(WebKitWebView *web_view, WebKitDownload *download, gpointer user_dat gchar *total_size_s = g_strdup_printf("%d", total_size); g_array_append_val(a, total_size_s); + if(destination) + g_array_append_val(a, destination); + GString *result = g_string_new (""); run_parsed_command(c, a, result); diff --git a/src/events.c b/src/events.c index 58dddfc..62d6414 100644 --- a/src/events.c +++ b/src/events.c @@ -23,6 +23,8 @@ const char *event_table[LAST_EVENT] = { "REQUEST_STARTING" , "KEY_PRESS" , "KEY_RELEASE" , + "MOD_PRESS" , + "MOD_RELEASE" , "COMMAND_EXECUTED" , "LINK_HOVER" , "TITLE_CHANGED" , @@ -158,11 +160,13 @@ vsend_event(int type, const gchar *custom_event, va_list vargs) { g_string_append_printf (event_message, "%d", va_arg (vargs, int)); break; case TYPE_STR: + /* a string that needs to be escaped */ g_string_append_c (event_message, '\''); append_escaped (event_message, va_arg (vargs, char*)); g_string_append_c (event_message, '\''); break; case TYPE_FORMATTEDSTR: + /* a string has already been escaped */ g_string_append (event_message, va_arg (vargs, char*)); break; case TYPE_NAME: @@ -200,31 +204,106 @@ send_event(int type, const gchar *custom_event, ...) { va_end (vargs); } +gchar * +get_modifier_mask(guint state) { + GString *modifiers = g_string_new(""); + + if(state & GDK_MODIFIER_MASK) { + if(state & GDK_SHIFT_MASK) + g_string_append(modifiers, "Shift|"); + if(state & GDK_LOCK_MASK) + g_string_append(modifiers, "ScrollLock|"); + if(state & GDK_CONTROL_MASK) + g_string_append(modifiers, "Ctrl|"); + if(state & GDK_MOD1_MASK) + g_string_append(modifiers,"Mod1|"); + if(state & GDK_MOD2_MASK) + g_string_append(modifiers,"Mod2|"); + if(state & GDK_MOD3_MASK) + g_string_append(modifiers,"Mod3|"); + if(state & GDK_MOD4_MASK) + g_string_append(modifiers,"Mod4|"); + if(state & GDK_MOD5_MASK) + g_string_append(modifiers,"Mod5|"); + if(state & GDK_BUTTON1_MASK) + g_string_append(modifiers,"Button1|"); + if(state & GDK_BUTTON2_MASK) + g_string_append(modifiers,"Button2|"); + if(state & GDK_BUTTON3_MASK) + g_string_append(modifiers,"Button3|"); + if(state & GDK_BUTTON4_MASK) + g_string_append(modifiers,"Button4|"); + if(state & GDK_BUTTON5_MASK) + g_string_append(modifiers,"Button5|"); + + if(modifiers->str[modifiers->len-1] == '|') + g_string_truncate(modifiers, modifiers->len-1); + } + + return g_string_free(modifiers, FALSE); +} + +guint key_to_modifier(guint keyval) { + /* FIXME + * Should really use XGetModifierMapping and/or Xkb to get actual mod keys + */ + switch(keyval) { + case GDK_KEY_Shift_L: + case GDK_KEY_Shift_R: + return GDK_SHIFT_MASK; + case GDK_KEY_Control_L: + case GDK_KEY_Control_R: + return GDK_CONTROL_MASK; + case GDK_KEY_Alt_L: + case GDK_KEY_Alt_R: + return GDK_MOD1_MASK; + case GDK_KEY_Super_L: + case GDK_KEY_Super_R: + return GDK_MOD4_MASK; + case GDK_KEY_ISO_Level3_Shift: + return GDK_MOD5_MASK; + default: + return 0; + } +} + /* Transform gdk key events to our own events */ void -key_to_event(guint keyval, gint mode) { +key_to_event(guint keyval, guint state, guint is_modifier, gint mode) { gchar ucs[7]; gint ulen; gchar *keyname; guint32 ukval = gdk_keyval_to_unicode(keyval); + gchar *modifiers = NULL; + guint mod = key_to_modifier (keyval); + /* Get modifier state including this key press/release */ + modifiers = get_modifier_mask(mode == GDK_KEY_PRESS ? state | mod : state & ~mod); + + if(is_modifier && mod) { + send_event(mode == GDK_KEY_PRESS ? MOD_PRESS : MOD_RELEASE, NULL, + TYPE_STR, modifiers, + TYPE_NAME, get_modifier_mask (mod), + NULL); + } /* check for printable unicode char */ /* TODO: Pass the keyvals through a GtkIMContext so that * we also get combining chars right */ - if(g_unichar_isgraph(ukval)) { + else if(g_unichar_isgraph(ukval)) { ulen = g_unichar_to_utf8(ukval, ucs); ucs[ulen] = 0; - send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE, - NULL, TYPE_FORMATTEDSTR, ucs, NULL); + send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE, NULL, + TYPE_STR, modifiers, TYPE_STR, ucs, NULL); } /* send keysym for non-printable chars */ else if((keyname = gdk_keyval_name(keyval))){ - send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE, - NULL, TYPE_NAME, keyname , NULL); + send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE, NULL, + TYPE_STR, modifiers, TYPE_NAME, keyname, NULL); } + g_free(modifiers); } /* vi: set et ts=4: */ diff --git a/src/events.h b/src/events.h index bd519a6..0c40206 100644 --- a/src/events.h +++ b/src/events.h @@ -13,7 +13,8 @@ enum event_type { LOAD_START, LOAD_COMMIT, LOAD_FINISH, LOAD_ERROR, REQUEST_STARTING, - KEY_PRESS, KEY_RELEASE, COMMAND_EXECUTED, + KEY_PRESS, KEY_RELEASE, MOD_PRESS, MOD_RELEASE, + COMMAND_EXECUTED, LINK_HOVER, TITLE_CHANGED, GEOMETRY_CHANGED, WEBINSPECTOR, NEW_WINDOW, SELECTION_CHANGED, VARIABLE_SET, FIFO_SET, SOCKET_SET, @@ -41,7 +42,10 @@ vsend_event(int type, const gchar *custom_event, va_list vargs); void send_event(int type, const gchar *custom_event, ...) G_GNUC_NULL_TERMINATED; +gchar * +get_modifier_mask(guint state); + void -key_to_event(guint keyval, gint mode); +key_to_event(guint keyval, guint state, guint is_modifier, int mode); #endif diff --git a/src/uzbl-browser b/src/uzbl-browser deleted file mode 100755 index 81645ca..0000000 --- a/src/uzbl-browser +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh -# -# This script implements a more useful out-of-the-box "browsing experience". -# It does so by combining uzbl-core with a set of "recommended" tools and -# practices. See docs for more info. -# -# If you want to customize the behavior any of the helper tools, copy them -# to your $XDG_DATA_HOME/uzbl/scripts/ and edit them - -PREFIX=/usr/local -export PREFIX - -EXAMPLES=$PREFIX/share/uzbl/examples - -XDG_DATA_HOME=${XDG_DATA_HOME:-$HOME/.local/share} -export XDG_DATA_HOME - -XDG_CACHE_HOME=${XDG_CACHE_HOME:-$HOME/.cache} -export XDG_CACHE_HOME - -XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config} -export XDG_CONFIG_HOME - -# assure the relevant directories exist. -for dir in "$XDG_CACHE_HOME"/uzbl "$XDG_DATA_HOME"/uzbl "$XDG_CONFIG_HOME"/uzbl -do - if [ ! -d "$dir" ] - then - if ! mkdir -p "$dir" - then - echo "could not create $dir" >&2 - exit 2 - fi - fi -done - -# if no config exists yet in the recommended location, put the default (recommended) config there -if [ ! -f "$XDG_CONFIG_HOME"/uzbl/config ] -then - if [ ! -r "$EXAMPLES"/config/config ] - then - echo "Error: Global config not found; please check if your distribution ships them separately" - exit 3 - fi - if ! cp "$EXAMPLES"/config/config "$XDG_CONFIG_HOME"/uzbl/config - then - echo "Could not copy default config to $XDG_CONFIG_HOME/uzbl/config" >&2 - # Run with the global config as a last resort - config_file=$EXAMPLES/config/config - fi -fi - -# this variable is used by the default helper scripts as a location to -# load shared code from -if [ -z "$UZBL_UTIL_DIR" ] -then - if [ -d "$XDG_DATA_HOME"/uzbl/scripts/util ] - then - UZBL_UTIL_DIR=$XDG_DATA_HOME/uzbl/scripts/util - elif [ -d $EXAMPLES/data/scripts/util ] - then - UZBL_UTIL_DIR=$EXAMPLES/data/scripts/util - fi - export UZBL_UTIL_DIR -fi - -# uzbl-event-manager will exit if one is already running. -# we could also check if its pid file exists to avoid having to spawn it. -DAEMON_SOCKET="$XDG_CACHE_HOME"/uzbl/event_daemon -#if [ ! -f "$DAEMON_SOCKET".pid ] -#then - ${UZBL_EVENT_MANAGER:-uzbl-event-manager -va start} -#fi - -exec uzbl-core "$@" ${config_file:+--config "$config_file"} --connect-socket $DAEMON_SOCKET diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 6ea54a9..56d2f86 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -47,12 +47,15 @@ GOptionEntry entries[] = { "Uri to load at startup (equivalent to 'uzbl <uri>' or 'set uri = URI' after uzbl has launched)", "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, + { "named", 'n', 0, G_OPTION_ARG_STRING, &uzbl.state.instance_name, "Name of the current instance (defaults to Xorg window id or random for GtkSocket mode)", "NAME" }, { "config", 'c', 0, G_OPTION_ARG_STRING, &uzbl.state.config_file, "Path to config file or '-' for stdin", "FILE" }, + /* TODO: explain the difference between these two options */ { "socket", 's', 0, G_OPTION_ARG_INT, &uzbl.state.socket_id, - "Xembed Socket ID", "SOCKET" }, + "Xembed socket ID, this window should embed itself", "SOCKET" }, + { "embed", 'e', 0, G_OPTION_ARG_NONE, &uzbl.state.embed, + "Whether this window should expect to be embedded", NULL }, { "connect-socket", 0, 0, G_OPTION_ARG_STRING_ARRAY, &uzbl.state.connect_socket_names, "Connect to server socket for event managing", "CSOCKET" }, { "print-events", 'p', 0, G_OPTION_ARG_NONE, &uzbl.state.events_stdout, @@ -546,7 +549,9 @@ CommandInfo cmdlist[] = { "include", include, TRUE }, { "show_inspector", show_inspector, 0 }, { "add_cookie", add_cookie, 0 }, - { "delete_cookie", delete_cookie, 0 } + { "delete_cookie", delete_cookie, 0 }, + { "clear_cookies", clear_cookies, 0 }, + { "download", download, 0 } }; void @@ -720,6 +725,42 @@ delete_cookie(WebKitWebView *page, GArray *argv, GString *result) { uzbl.net.soup_cookie_jar->in_manual_add = 0; } + +void +clear_cookies(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) argv; (void) result; + + // Replace the current cookie jar with a new empty jar + soup_session_remove_feature (uzbl.net.soup_session, + SOUP_SESSION_FEATURE (uzbl.net.soup_cookie_jar)); + g_object_unref (G_OBJECT (uzbl.net.soup_cookie_jar)); + uzbl.net.soup_cookie_jar = uzbl_cookie_jar_new (); + soup_session_add_feature(uzbl.net.soup_session, + SOUP_SESSION_FEATURE (uzbl.net.soup_cookie_jar)); +} + +void +download(WebKitWebView *web_view, GArray *argv, GString *result) { + (void) result; + + const gchar *uri = argv_idx(argv, 0); + const gchar *destination = NULL; + if(argv->len > 1) + destination = argv_idx(argv, 1); + + WebKitNetworkRequest *req = webkit_network_request_new(uri); + WebKitDownload *download = webkit_download_new(req); + + download_cb(web_view, download, destination); + + if(webkit_download_get_destination_uri(download)) + webkit_download_start(download); + else + g_object_unref(download); + + g_object_unref(req); +} + void act_dump_config() { dump_config(); @@ -1111,8 +1152,6 @@ spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) { void run_parsed_command(const CommandInfo *c, GArray *a, GString *result) { - c->function(uzbl.gui.web_view, a, result); - /* send the COMMAND_EXECUTED event, except for set and event/request commands */ if(strcmp("set", c->key) && strcmp("event", c->key) && @@ -1123,12 +1162,18 @@ run_parsed_command(const CommandInfo *c, GArray *a, GString *result) { guint i = 0; while ((p = argv_idx(a, i++))) g_string_append_printf(param, " '%s'", p); + + /* might be destructive on array a */ + c->function(uzbl.gui.web_view, a, result); + send_event(COMMAND_EXECUTED, NULL, TYPE_NAME, c->key, TYPE_FORMATTEDSTR, param->str, NULL); g_string_free(param, TRUE); } + else + c->function(uzbl.gui.web_view, a, result); if(result) { g_free(uzbl.state.last_result); @@ -1498,6 +1543,7 @@ create_window() { GtkPlug* create_plug() { + if(uzbl.state.embed) uzbl.state.socket_id = 0; 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); @@ -1682,7 +1728,7 @@ initialize(int argc, char** argv) { } /* Embedded mode */ - if (uzbl.state.socket_id) + if (uzbl.state.socket_id || uzbl.state.embed) uzbl.state.plug_mode = TRUE; if (!g_thread_supported()) diff --git a/src/uzbl-core.h b/src/uzbl-core.h index d8f8375..3fde5dc 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -107,6 +107,7 @@ typedef struct { gchar* executable_path; gchar* searchtx; gboolean verbose; + gboolean embed; GdkEventButton* last_button; gchar* last_result; gboolean plug_mode; @@ -301,9 +302,6 @@ void handle_authentication (SoupSession *session, SoupAuth *auth, gboolean retrying, gpointer user_data); -void handle_cookies (SoupSession *session, - SoupMessage *msg, - gpointer user_data); gboolean valid_name(const gchar* name); void set_var(WebKitWebView *page, GArray *argv, GString *result); void act_dump_config(); @@ -324,6 +322,8 @@ void include(WebKitWebView *page, GArray *argv, GString *result); void show_inspector(WebKitWebView *page, GArray *argv, GString *result); void add_cookie(WebKitWebView *page, GArray *argv, GString *result); void delete_cookie(WebKitWebView *page, GArray *argv, GString *result); +void clear_cookies(WebKitWebView *pag, GArray *argv, GString *result); +void download(WebKitWebView *pag, GArray *argv, GString *result); void builtins(); typedef void (*Command)(WebKitWebView*, GArray *argv, GString *result); |