aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Brendan Taylor <whateley@gmail.com>2011-04-30 08:17:40 -0600
committerGravatar Brendan Taylor <whateley@gmail.com>2011-04-30 08:17:40 -0600
commitceeba25242492db44091a4c87b046a25527d2f59 (patch)
tree5687dda2e9847b28ba48974d5246654eca281311 /src
parentb0d2559157d0b060e2a2c2c33f08bed5f9cfaf51 (diff)
parentcd7ff839afd2af2ec78868d91eca7fd4a2d4f117 (diff)
Merge branch 'experimental' into scrollbars
Diffstat (limited to 'src')
-rw-r--r--src/callbacks.c19
-rw-r--r--src/events.c91
-rw-r--r--src/events.h8
-rwxr-xr-xsrc/uzbl-browser75
-rw-r--r--src/uzbl-core.c58
-rw-r--r--src/uzbl-core.h6
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);