diff options
author | Dieter Plaetinck <dieter@plaetinck.be> | 2010-01-24 14:33:28 +0100 |
---|---|---|
committer | Dieter Plaetinck <dieter@plaetinck.be> | 2010-01-24 14:33:28 +0100 |
commit | 27b23bc15985aea687aecec580d668b7f9701eb3 (patch) | |
tree | b82659a8350c09d85e85e74af639ee909892d37e | |
parent | 6d4547a49805b552e9b56d41a653a0912e7b0534 (diff) | |
parent | c8fb24d1069aa776bccdf3141adb9d3c3f6e8101 (diff) |
merge in experimental
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | Makefile | 47 | ||||
-rw-r--r-- | README | 6 | ||||
-rw-r--r-- | docs/FAQ | 85 | ||||
-rw-r--r-- | examples/config/config (renamed from examples/config/uzbl/config) | 2 | ||||
-rw-r--r-- | examples/config/cookies (renamed from examples/config/uzbl/cookies) | 0 | ||||
-rw-r--r-- | examples/data/bookmarks (renamed from examples/data/uzbl/bookmarks) | 0 | ||||
-rw-r--r-- | examples/data/forms/bbs.archlinux.org (renamed from examples/data/uzbl/forms/bbs.archlinux.org) | 0 | ||||
-rw-r--r-- | examples/data/plugins/bind.py (renamed from examples/data/uzbl/plugins/bind.py) | 0 | ||||
-rw-r--r-- | examples/data/plugins/cmd_expand.py (renamed from examples/data/uzbl/plugins/cmd_expand.py) | 0 | ||||
-rw-r--r-- | examples/data/plugins/completion.py (renamed from examples/data/uzbl/plugins/completion.py) | 0 | ||||
-rw-r--r-- | examples/data/plugins/config.py (renamed from examples/data/uzbl/plugins/config.py) | 0 | ||||
-rw-r--r-- | examples/data/plugins/keycmd.py (renamed from examples/data/uzbl/plugins/keycmd.py) | 0 | ||||
-rw-r--r-- | examples/data/plugins/mode.py (renamed from examples/data/uzbl/plugins/mode.py) | 0 | ||||
-rw-r--r-- | examples/data/plugins/on_event.py (renamed from examples/data/uzbl/plugins/on_event.py) | 0 | ||||
-rw-r--r-- | examples/data/plugins/plugin_template.py (renamed from examples/data/uzbl/plugins/plugin_template.py) | 0 | ||||
-rw-r--r-- | examples/data/plugins/progress_bar.py (renamed from examples/data/uzbl/plugins/progress_bar.py) | 0 | ||||
-rwxr-xr-x | examples/data/scripts/cookies.sh (renamed from examples/data/uzbl/scripts/cookies.sh) | 0 | ||||
-rwxr-xr-x | examples/data/scripts/download.sh (renamed from examples/data/uzbl/scripts/download.sh) | 0 | ||||
-rw-r--r-- | examples/data/scripts/extedit.js (renamed from examples/data/uzbl/scripts/extedit.js) | 0 | ||||
-rw-r--r-- | examples/data/scripts/follow_Numbers.js (renamed from examples/data/uzbl/scripts/follow_Numbers.js) | 0 | ||||
-rw-r--r-- | examples/data/scripts/follow_Numbers_Strings.js (renamed from examples/data/uzbl/scripts/follow_Numbers_Strings.js) | 0 | ||||
-rwxr-xr-x | examples/data/scripts/formfiller.pl (renamed from examples/data/uzbl/scripts/formfiller.pl) | 6 | ||||
-rwxr-xr-x | examples/data/scripts/formfiller.sh (renamed from examples/data/uzbl/scripts/formfiller.sh) | 0 | ||||
-rw-r--r-- | examples/data/scripts/hint.js (renamed from examples/data/uzbl/scripts/hint.js) | 0 | ||||
-rwxr-xr-x | examples/data/scripts/history.sh (renamed from examples/data/uzbl/scripts/history.sh) | 0 | ||||
-rwxr-xr-x | examples/data/scripts/insert_bookmark.sh (renamed from examples/data/uzbl/scripts/insert_bookmark.sh) | 0 | ||||
-rwxr-xr-x | examples/data/scripts/instance-select-wmii.sh (renamed from examples/data/uzbl/scripts/instance-select-wmii.sh) | 0 | ||||
-rw-r--r-- | examples/data/scripts/linkfollow.js (renamed from examples/data/uzbl/scripts/linkfollow.js) | 4 | ||||
-rwxr-xr-x | examples/data/scripts/load_url_from_bookmarks.sh (renamed from examples/data/uzbl/scripts/load_url_from_bookmarks.sh) | 0 | ||||
-rwxr-xr-x | examples/data/scripts/load_url_from_history.sh (renamed from examples/data/uzbl/scripts/load_url_from_history.sh) | 0 | ||||
-rwxr-xr-x | examples/data/scripts/scheme.py (renamed from examples/data/uzbl/scripts/scheme.py) | 0 | ||||
-rw-r--r-- | examples/data/scripts/scroll-percentage.js (renamed from examples/data/uzbl/scripts/scroll-percentage.js) | 0 | ||||
-rwxr-xr-x | examples/data/scripts/session.sh (renamed from examples/data/uzbl/scripts/session.sh) | 0 | ||||
-rwxr-xr-x | examples/data/scripts/uzbl-cookie-daemon (renamed from examples/data/uzbl/scripts/uzbl-cookie-daemon) | 0 | ||||
-rwxr-xr-x | examples/data/scripts/uzbl-event-manager (renamed from examples/data/uzbl/scripts/uzbl-event-manager) | 19 | ||||
-rwxr-xr-x | examples/data/scripts/uzbl-tabbed (renamed from examples/data/uzbl/scripts/uzbl-tabbed) | 853 | ||||
-rwxr-xr-x | examples/data/scripts/uzblcat (renamed from examples/data/uzbl/scripts/uzblcat) | 0 | ||||
-rw-r--r-- | examples/data/style.css (renamed from examples/data/uzbl/style.css) | 0 | ||||
-rw-r--r-- | examples/data/uzbl.png (renamed from examples/data/uzbl/uzbl.png) | bin | 2185 -> 2185 bytes | |||
-rwxr-xr-x | misc/hash.sh (renamed from hash.sh) | 0 | ||||
-rwxr-xr-x | sandbox/env.sh | 9 | ||||
-rw-r--r-- | src/callbacks.c (renamed from callbacks.c) | 13 | ||||
-rw-r--r-- | src/callbacks.h (renamed from callbacks.h) | 3 | ||||
-rw-r--r-- | src/config.h (renamed from config.h) | 0 | ||||
-rw-r--r-- | src/events.c (renamed from events.c) | 4 | ||||
-rw-r--r-- | src/events.h (renamed from events.h) | 0 | ||||
-rw-r--r-- | src/inspector.c (renamed from inspector.c) | 0 | ||||
-rw-r--r-- | src/inspector.h (renamed from inspector.h) | 0 | ||||
-rwxr-xr-x | src/uzbl-browser (renamed from uzbl-browser) | 4 | ||||
-rw-r--r-- | src/uzbl-core.c (renamed from uzbl-core.c) | 36 | ||||
-rw-r--r-- | src/uzbl-core.h (renamed from uzbl-core.h) | 2 |
53 files changed, 581 insertions, 516 deletions
@@ -1,6 +1,5 @@ uzbl-core *.o +*.pyc *~ tags -examples/data -examples/config/enchant @@ -55,6 +55,7 @@ In alphabetical order: Přemysl Hrubý (anydot) <email is dfenze AT gmail.com> - several C contributions and cleanups Robert Manea (robm) <email is rob DOT manea AT gmail DOT com> - C code all over the place Sergey Shepelev (temoto) - doc patch + Simon Lipp (sloonz) - various patches, EM contributions Sylvester Johansson (scj) - form filler script & different take on link follower Tassilo Horn (tsdh) - $VISUAL patch Thorsten Wilms - logo design @@ -1,13 +1,15 @@ # first entries are for gnu make, 2nd for BSD make. see http://lists.uzbl.org/pipermail/uzbl-dev-uzbl.org/2009-July/000177.html -CFLAGS:=-std=c99 $(shell pkg-config --cflags gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0) -ggdb -Wall -W -DARCH="\"$(shell uname -m)\"" -lgthread-2.0 -DCOMMIT="\"$(shell ./hash.sh)\"" $(CPPFLAGS) -fPIC -W -Wall -Wextra -pedantic -CFLAGS!=echo -std=c99 `pkg-config --cflags gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0` -ggdb -Wall -W -DARCH='"\""'`uname -m`'"\""' -lgthread-2.0 -DCOMMIT='"\""'`./hash.sh`'"\""' $(CPPFLAGS) -fPIC -W -Wall -Wextra -pedantic +CFLAGS:=-std=c99 $(shell pkg-config --cflags gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0) -ggdb -Wall -W -DARCH="\"$(shell uname -m)\"" -lgthread-2.0 -DCOMMIT="\"$(shell ./misc/hash.sh)\"" $(CPPFLAGS) -fPIC -W -Wall -Wextra -pedantic +CFLAGS!=echo -std=c99 `pkg-config --cflags gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0` -ggdb -Wall -W -DARCH='"\""'`uname -m`'"\""' -lgthread-2.0 -DCOMMIT='"\""'`./misc/hash.sh`'"\""' $(CPPFLAGS) -fPIC -W -Wall -Wextra -pedantic LDFLAGS:=$(shell pkg-config --libs gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0) -pthread $(LDFLAGS) LDFLAGS!=echo `pkg-config --libs gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0` -pthread $(LDFLAGS) -SRC = uzbl-core.c events.c callbacks.c inspector.c -OBJ = ${SRC:.c=.o} +SRC = $(wildcard src/*.c) +HEAD = $(wildcard src/*.h) +TOBJ = $(SRC:.c=.o) +OBJ = $(foreach obj, $(TOBJ), $(notdir $(obj))) all: uzbl-browser options @@ -25,9 +27,9 @@ options: @${CC} -c ${CFLAGS} $< @echo ... done. -${OBJ}: uzbl-core.h events.h callbacks.h inspector.h config.h +${OBJ}: ${HEAD} -uzbl-core: ${OBJ} +uzbl-core: ${TOBJ} # why doesn't ${OBJ} work? @echo @echo LINKING object files @${CC} -o $@ ${OBJ} ${LDFLAGS} @@ -59,16 +61,19 @@ test-uzbl-core: uzbl-core ./uzbl-core --uri http://www.uzbl.org --verbose test-uzbl-browser: uzbl-browser - ./uzbl-browser --uri http://www.uzbl.org --verbose + ./src/uzbl-browser --uri http://www.uzbl.org --verbose test-uzbl-core-sandbox: uzbl-core make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-core + make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-example-data source ./sandbox/env.sh && uzbl-core --uri http://www.uzbl.org --verbose make DESTDIR=./sandbox uninstall rm -rf ./sandbox/usr test-uzbl-browser-sandbox: uzbl-browser + make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-core make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-browser + make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-example-data source ./sandbox/env.sh && uzbl-cookie-daemon restart -nv & source ./sandbox/env.sh && uzbl-event-manager restart -nav & source ./sandbox/env.sh && uzbl-browser --uri http://www.uzbl.org --verbose @@ -93,25 +98,33 @@ install-uzbl-core: all install -d $(INSTALLDIR)/bin install -d $(INSTALLDIR)/share/uzbl/docs install -d $(INSTALLDIR)/share/uzbl/examples - cp -rp docs $(INSTALLDIR)/share/uzbl/ - cp -rp config.h $(INSTALLDIR)/share/uzbl/docs/ - cp -rp examples $(INSTALLDIR)/share/uzbl/ + cp -rp docs $(INSTALLDIR)/share/uzbl/ + cp -rp src/config.h $(INSTALLDIR)/share/uzbl/docs/ + cp -rp examples $(INSTALLDIR)/share/uzbl/ install -m755 uzbl-core $(INSTALLDIR)/bin/uzbl-core install -m644 AUTHORS $(INSTALLDIR)/share/uzbl/docs install -m644 README $(INSTALLDIR)/share/uzbl/docs - sed -i 's#^set prefix.*=.*#set prefix = $(RUN_PREFIX)#' $(INSTALLDIR)/share/uzbl/examples/config/uzbl/config + sed -i 's#^set prefix.*=.*#set prefix = $(RUN_PREFIX)#' $(INSTALLDIR)/share/uzbl/examples/config/config -install-uzbl-browser: install-uzbl-core +install-uzbl-browser: install -d $(INSTALLDIR)/bin - install -m755 uzbl-browser $(INSTALLDIR)/bin/uzbl-browser - install -m755 examples/data/uzbl/scripts/uzbl-cookie-daemon $(INSTALLDIR)/bin/uzbl-cookie-daemon - install -m755 examples/data/uzbl/scripts/uzbl-event-manager $(INSTALLDIR)/bin/uzbl-event-manager + install -m755 src/uzbl-browser $(INSTALLDIR)/bin/uzbl-browser + install -m755 examples/data/scripts/uzbl-cookie-daemon $(INSTALLDIR)/bin/uzbl-cookie-daemon + install -m755 examples/data/scripts/uzbl-event-manager $(INSTALLDIR)/bin/uzbl-event-manager sed -i 's#^PREFIX=.*#PREFIX=$(RUN_PREFIX)#' $(INSTALLDIR)/bin/uzbl-browser sed -i "s#^PREFIX = .*#PREFIX = '$(RUN_PREFIX)'#" $(INSTALLDIR)/bin/uzbl-event-manager -install-uzbl-tabbed: install-uzbl-browser +install-uzbl-tabbed: install -d $(INSTALLDIR)/bin - install -m755 examples/data/uzbl/scripts/uzbl-tabbed $(INSTALLDIR)/bin/uzbl-tabbed + install -m755 examples/data/scripts/uzbl-tabbed $(INSTALLDIR)/bin/uzbl-tabbed + +# you probably only want to do this manually when testing and/or to the sandbox. not meant for distributors +install-example-data: + install -d $(INSTALLDIR)/home/.config/uzbl + install -d $(INSTALLDIR)/home/.cache/uzbl + install -d $(INSTALLDIR)/home/.local/share/uzbl + cp -rp examples/config/* $(INSTALLDIR)/home/.config/uzbl/ + cp -rp examples/data/* $(INSTALLDIR)/home/.local/share/uzbl/ uninstall: rm -rf $(INSTALLDIR)/bin/uzbl-* @@ -311,7 +311,10 @@ file). * `fifo_dir`: location to store FIFOs. * `socket_dir`: location to store sockets. * `http_debug`: HTTP debug mode (value 0-3). +* `scrollbars_visible`: set to 1 to have GTK scrollbars if the document + doesn't fit into the window (defaults to 0) * `shell_cmd`: Alias which will be expanded to use shell commands (eg `sh -c`). +* `print_events`: show events on stdout * `proxy_url`: HTTP traffic SOCKS proxy (eg: `http://<host>:<port>`). * `max_conns`: Max simultaneous connections (default: 100). * `max_conns_host`: max simultaneous connections per hostname (default: 6) @@ -704,10 +707,11 @@ where `arguments` and `uri` are both optional. `arguments` can be: uri = URI` after `uzbl` has launched. * `-v`, `--verbose`: Whether to print all messages or just errors. * `-n`, `--name=NAME`: Name of the current instance (defaults to Xorg window - id). + id or random for GtkSocket mode). * `-c`, `--config=FILE`: Path to config file or `-` for stdin. * `-s`, `--socket=SOCKET`: Xembed socket ID. * `--connect-socket=SOCKET`: Connect to server socket for event managing. +* `-p`, `--print-events`: Whether to print events to stdout * `-g`, `--geometry=GEOMETRY`: Set window geometry (format: `WIDTHxHEIGHT+-X+-Y` or `maximized`). * `-V`, `--version`: Print the version and exit. @@ -24,21 +24,66 @@ tools and scripts, by itself doesn't do many usefull things. See README. The layout of uzbl (and derivatives) only contains what you really need to see. we only have a statusbar, which even can also be disabled. There are no buttons, but we do have lots of keybinding possibilities. -### Why can uzbl-browser only show one page? -Among uzbl hackers, there are 2 groups: some people prefer tabs, they use -uzbl-tabbed. The others stick to "one page per uzbl-browser instance" because -it's a very flexible approach. They believe "multiple instances management" is something that must -be handled outside of uzbl by a separate/different program. Here are some solutions: - - * Many window managers can handle this by default. Xmonads tabbed layout, Wmii's stacked layout, fluxbox or kwin tabs and so on. - * Uzbl supports acting as a GtkPlug to plug into GtkSockets (Xembed) so you can embed uzbl instances in other Gtk applications. - (This is also what uzbl-tabbed does) - * If you want highest customizablity, you need the 3rd option: - You can also write a custom script. The only thing you need to do is focus/maximize the instance you want, - keep the others out of sight and use tools like dmenu and wmctrl to switch instances. - This allows you to use application-specific properties (such as uzbl tag, name etc). - For more information about this approach, see docs/multiple-instances-management. - (If you want to work on such script, let us know and we might include it along with the other sample scripts) +### Why can uzbl-core/uzbl-browser only show one page? +It is nearly unanimously agreed that one page per uzbl-core is best. +It allows a simple implementation of both uzbl-core and +uzbl-browser, and it makes things more robust. +But read the next entry... + +### How to have multiple pages in one window? +So, given that uzbl-core and uzbl-browser only deal with one page at a time (see +above), how can you have a window with multiple pages? + +Basically this is involves concerns on two sides: + +* window management + - can I keep all pages together in 1 X window so that I can move all at once to a different workspace + - can I "split off" pages into separate windows (i.e. move only one specific page/window to a different desktop) + or merge windows together? + - can I integrate uzbl pages/windows into WM features? (alt-tab, tiling layouts, taskbar, ...) + - ... +* application-level + - realtime overview of all page titles of all uzbl instances + - representation styles which are tightly coupled to the application such as treeviews that show from which you page you opened + others, or page state (loading etc) + - ... + +Uzbl itself can hardly be a limiting factor, as it supports/has: + +* Xembed (GtkPlug mode) so you can embed a uzbl-browser or uzbl-core into another window +* an events system you can have realtime updates of window title, pageload state, etc. +* command interface to programmatically change it's behavior. + +And then there is the style of representation (tabs, tree overviews, visual +thumbnails etc) which can be handled from the WM side or the application +side. + +There are multiple approaches, each with pros and cons. + +* Tabbing in the WM: Xmonads tabbed layout, Wmii's stacked layout, fluxbox or kwin tabs and so on. +* Visual overview in the WM: commonly used with dwm or Awesome's tiling layouts with master/slave areas. + The [dynamic zoom script](http://www.uzbl.org/wiki/dynamic_zooming) is useful here. +* A container application whih embeds multiple uzbl-browsers and provide tablists, tree views, and more. + Examples: + - [uzbl-tabbed](http://www.uzbl.org/wiki/uzbl_tabbed) (officially supported) + - [uzbltreetab](http://www.uzbl.org/wiki/uzbltreetab) + - [uzbltab](http://www.uzbl.org/wiki/uzbltab) + - [suckless tabbed](http://tools.suckless.org/tabbed) +* An application to mimic tabbing independently of WM support. + The only thing you need to do is focus/maximize the instance you want, + keep the others out of sight and use tools like dmenu/xbindkeys and wmctrl to switch instances. + This allows you to use application-specific properties (such as uzbl tag, name etc). + For more ideas on such an approach, see docs/multiple-instances-management. + Examples: + - [wmctrl-based](http://www.uzbl.org/wiki/metacity-tabs) (works on at least Metacity) + - [wmii](http://www.uzbl.org/wiki/wmii) + +There are really a lot of options. You need to think about what you need, +what you want and what you don't care about. +On the wiki you'll find a lot of related scripts, some of them providing new +workflows (do you really need open windows for all pages you intend to read, or is a list enough? +[articlecue](http://www.uzbl.org/wiki/article_queue.py)), some providing integration with WM's such as +[awesome](http://www.uzbl.org/wiki/awesome), and more. ### Okay, what can I actually do? What commands are there? How do I get more information? * Commands and other features are documented in README. Read it. @@ -64,8 +109,10 @@ we prefer being reasonably assured that things work as they are supposed to rath That's why we picked the Gtk variant of Webkit. Note that we do *not* depend on any Gnome libraries such as gconf. _That_ would be something worth complaining about :) -### Do you support flash? javascript? Ajax? Recent html/css/.. standards? +### Do you support flash? javascript? Ajax? Recent html/css/.. standards? Java/media plugins? Yes, Webkit takes care of all of that. Not that we like all of these, but you can use them if you want. +We use the NPAPI plugin architecture (just like mozilla, opera, etc) so just +install the plugins normally, and things should work. ### What's the difference between the socket file and the fifo? They both have advantages and disadvantages: @@ -75,6 +122,12 @@ They both have advantages and disadvantages: So, when writing scripts, using fifo's is usually the fastest method (because you do not need to fork another process), so fifo is preferred unless you need a response. +### Uzbl uses too much memory! Especially when having multiple windows (i.e. with uzbl-tabbed) +Don't be fooled with how memory usage is measured and reported on Linux. (or other systems) +You need to be aware of the difference between RSS and VSS. +And dynamic libraries (libwebkit, libgtk, etc) that are used by multiple processes are only stored in RAM once. +See [this page](http://virtualthreads.blogspot.com/2006/02/understanding-memory-usage-on-linux.html) for a good explanation. + ### What the hell is this 'XDG' stuff?? You'll notice our example/default scripts and configs use variables such as `$XDG_CONFIG_HOME` and `$XDG_DATA_HOME`. Most of us really like the [xdg basedir spec](http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html). diff --git a/examples/config/uzbl/config b/examples/config/config index 3edb36c..eb17813 100644 --- a/examples/config/uzbl/config +++ b/examples/config/config @@ -32,7 +32,7 @@ set set_status = set status_message = set shell_cmd = sh -c # Spawn path shortcuts. In spawn the first dir+path match is used in "dir1:dir2:dir3:executable" -set scripts_dir = $XDG_DATA_HOME/uzbl:@prefix/share/uzbl/examples/data/uzbl:scripts +set scripts_dir = $XDG_DATA_HOME/uzbl:@prefix/share/uzbl/examples/data:scripts # Javascipt helpers. set jsh = js var run=Uzbl.run; function get(k){return run("print \\\@"+k)}; function set(k, v) {run("set "+k+" = "+v)}; diff --git a/examples/config/uzbl/cookies b/examples/config/cookies index 9b7374a..9b7374a 100644 --- a/examples/config/uzbl/cookies +++ b/examples/config/cookies diff --git a/examples/data/uzbl/bookmarks b/examples/data/bookmarks index 13fcd48..13fcd48 100644 --- a/examples/data/uzbl/bookmarks +++ b/examples/data/bookmarks diff --git a/examples/data/uzbl/forms/bbs.archlinux.org b/examples/data/forms/bbs.archlinux.org index 73c1539..73c1539 100644 --- a/examples/data/uzbl/forms/bbs.archlinux.org +++ b/examples/data/forms/bbs.archlinux.org diff --git a/examples/data/uzbl/plugins/bind.py b/examples/data/plugins/bind.py index 9e09337..9e09337 100644 --- a/examples/data/uzbl/plugins/bind.py +++ b/examples/data/plugins/bind.py diff --git a/examples/data/uzbl/plugins/cmd_expand.py b/examples/data/plugins/cmd_expand.py index 3f6ae2b..3f6ae2b 100644 --- a/examples/data/uzbl/plugins/cmd_expand.py +++ b/examples/data/plugins/cmd_expand.py diff --git a/examples/data/uzbl/plugins/completion.py b/examples/data/plugins/completion.py index 8cea203..8cea203 100644 --- a/examples/data/uzbl/plugins/completion.py +++ b/examples/data/plugins/completion.py diff --git a/examples/data/uzbl/plugins/config.py b/examples/data/plugins/config.py index 4a848a3..4a848a3 100644 --- a/examples/data/uzbl/plugins/config.py +++ b/examples/data/plugins/config.py diff --git a/examples/data/uzbl/plugins/keycmd.py b/examples/data/plugins/keycmd.py index c119077..c119077 100644 --- a/examples/data/uzbl/plugins/keycmd.py +++ b/examples/data/plugins/keycmd.py diff --git a/examples/data/uzbl/plugins/mode.py b/examples/data/plugins/mode.py index 54d865a..54d865a 100644 --- a/examples/data/uzbl/plugins/mode.py +++ b/examples/data/plugins/mode.py diff --git a/examples/data/uzbl/plugins/on_event.py b/examples/data/plugins/on_event.py index b9c504a..b9c504a 100644 --- a/examples/data/uzbl/plugins/on_event.py +++ b/examples/data/plugins/on_event.py diff --git a/examples/data/uzbl/plugins/plugin_template.py b/examples/data/plugins/plugin_template.py index 565a999..565a999 100644 --- a/examples/data/uzbl/plugins/plugin_template.py +++ b/examples/data/plugins/plugin_template.py diff --git a/examples/data/uzbl/plugins/progress_bar.py b/examples/data/plugins/progress_bar.py index 89ba175..89ba175 100644 --- a/examples/data/uzbl/plugins/progress_bar.py +++ b/examples/data/plugins/progress_bar.py diff --git a/examples/data/uzbl/scripts/cookies.sh b/examples/data/scripts/cookies.sh index ee2ce51..ee2ce51 100755 --- a/examples/data/uzbl/scripts/cookies.sh +++ b/examples/data/scripts/cookies.sh diff --git a/examples/data/uzbl/scripts/download.sh b/examples/data/scripts/download.sh index 1c7d039..1c7d039 100755 --- a/examples/data/uzbl/scripts/download.sh +++ b/examples/data/scripts/download.sh diff --git a/examples/data/uzbl/scripts/extedit.js b/examples/data/scripts/extedit.js index 8ed346d..8ed346d 100644 --- a/examples/data/uzbl/scripts/extedit.js +++ b/examples/data/scripts/extedit.js diff --git a/examples/data/uzbl/scripts/follow_Numbers.js b/examples/data/scripts/follow_Numbers.js index 00b279e..00b279e 100644 --- a/examples/data/uzbl/scripts/follow_Numbers.js +++ b/examples/data/scripts/follow_Numbers.js diff --git a/examples/data/uzbl/scripts/follow_Numbers_Strings.js b/examples/data/scripts/follow_Numbers_Strings.js index e50da5d..e50da5d 100644 --- a/examples/data/uzbl/scripts/follow_Numbers_Strings.js +++ b/examples/data/scripts/follow_Numbers_Strings.js diff --git a/examples/data/uzbl/scripts/formfiller.pl b/examples/data/scripts/formfiller.pl index 23da347..74dcc80 100755 --- a/examples/data/uzbl/scripts/formfiller.pl +++ b/examples/data/scripts/formfiller.pl @@ -10,9 +10,9 @@ # new: fetch new file # usage example: -# bind LL = spawn /usr/share/uzbl/examples/scripts/formfiller.pl load -# bind LN = spawn /usr/share/uzbl/examples/scripts/formfiller.pl new -# bind LE = spawn /usr/share/uzbl/examples/scripts/formfiller.pl edit +# bind LL = spawn /usr/share/uzbl/examples/data/scripts/formfiller.pl load +# bind LN = spawn /usr/share/uzbl/examples/data/scripts/formfiller.pl new +# bind LE = spawn /usr/share/uzbl/examples/data/scripts/formfiller.pl edit use strict; use warnings; diff --git a/examples/data/uzbl/scripts/formfiller.sh b/examples/data/scripts/formfiller.sh index 10afaba..10afaba 100755 --- a/examples/data/uzbl/scripts/formfiller.sh +++ b/examples/data/scripts/formfiller.sh diff --git a/examples/data/uzbl/scripts/hint.js b/examples/data/scripts/hint.js index ec7f1e2..ec7f1e2 100644 --- a/examples/data/uzbl/scripts/hint.js +++ b/examples/data/scripts/hint.js diff --git a/examples/data/uzbl/scripts/history.sh b/examples/data/scripts/history.sh index 7c83aa6..7c83aa6 100755 --- a/examples/data/uzbl/scripts/history.sh +++ b/examples/data/scripts/history.sh diff --git a/examples/data/uzbl/scripts/insert_bookmark.sh b/examples/data/scripts/insert_bookmark.sh index c34e7db..c34e7db 100755 --- a/examples/data/uzbl/scripts/insert_bookmark.sh +++ b/examples/data/scripts/insert_bookmark.sh diff --git a/examples/data/uzbl/scripts/instance-select-wmii.sh b/examples/data/scripts/instance-select-wmii.sh index 2bf13ba..2bf13ba 100755 --- a/examples/data/uzbl/scripts/instance-select-wmii.sh +++ b/examples/data/scripts/instance-select-wmii.sh diff --git a/examples/data/uzbl/scripts/linkfollow.js b/examples/data/scripts/linkfollow.js index 0eb629b..3109cda 100644 --- a/examples/data/uzbl/scripts/linkfollow.js +++ b/examples/data/scripts/linkfollow.js @@ -3,14 +3,14 @@ // // first, it needs to be loaded before every time it is used. // One way would be to use the load_commit_handler: -// set load_commit_handler = sh 'echo "script /usr/share/uzbl/examples/scripts/linkfollow.js" > "$4"' +// set load_commit_handler = sh 'echo "script /usr/share/uzbl/examples/data/scripts/linkfollow.js" > "$4"' // // when script is loaded, it can be invoked with // bind f* = js hints.set("%s", hints.open) // bind f_ = js hints.follow("%s",hints.open) // // At the moment, it may be useful to have way of forcing uzbl to load the script -// bind :lf = script /usr/share/uzbl/examples/scripts/linkfollow.js +// bind :lf = script /usr/share/uzbl/examples/data/scripts/linkfollow.js // // The default style for the hints are pretty ugly, so it is recommended to add the following // to config file diff --git a/examples/data/uzbl/scripts/load_url_from_bookmarks.sh b/examples/data/scripts/load_url_from_bookmarks.sh index 1e9f9e7..1e9f9e7 100755 --- a/examples/data/uzbl/scripts/load_url_from_bookmarks.sh +++ b/examples/data/scripts/load_url_from_bookmarks.sh diff --git a/examples/data/uzbl/scripts/load_url_from_history.sh b/examples/data/scripts/load_url_from_history.sh index 62e02ac..62e02ac 100755 --- a/examples/data/uzbl/scripts/load_url_from_history.sh +++ b/examples/data/scripts/load_url_from_history.sh diff --git a/examples/data/uzbl/scripts/scheme.py b/examples/data/scripts/scheme.py index 0916466..0916466 100755 --- a/examples/data/uzbl/scripts/scheme.py +++ b/examples/data/scripts/scheme.py diff --git a/examples/data/uzbl/scripts/scroll-percentage.js b/examples/data/scripts/scroll-percentage.js index c9a51aa..c9a51aa 100644 --- a/examples/data/uzbl/scripts/scroll-percentage.js +++ b/examples/data/scripts/scroll-percentage.js diff --git a/examples/data/uzbl/scripts/session.sh b/examples/data/scripts/session.sh index 1059b5e..1059b5e 100755 --- a/examples/data/uzbl/scripts/session.sh +++ b/examples/data/scripts/session.sh diff --git a/examples/data/uzbl/scripts/uzbl-cookie-daemon b/examples/data/scripts/uzbl-cookie-daemon index fde8b8e..fde8b8e 100755 --- a/examples/data/uzbl/scripts/uzbl-cookie-daemon +++ b/examples/data/scripts/uzbl-cookie-daemon diff --git a/examples/data/uzbl/scripts/uzbl-event-manager b/examples/data/scripts/uzbl-event-manager index afef6fd..99b215a 100755 --- a/examples/data/uzbl/scripts/uzbl-event-manager +++ b/examples/data/scripts/uzbl-event-manager @@ -41,13 +41,6 @@ from traceback import print_exc from functools import partial -# ============================================================================ -# ::: Default configuration section :::::::::::::::::::::::::::::::::::::::::: -# ============================================================================ - -# `make install` will put the correct value here for your system -PREFIX = '/usr/local/' - def xdghome(key, default): '''Attempts to use the environ XDG_*_HOME paths if they exist otherwise use $HOME and the default path.''' @@ -58,11 +51,18 @@ def xdghome(key, default): return os.path.join(os.environ['HOME'], default) + +# ============================================================================ +# ::: Default configuration section :::::::::::::::::::::::::::::::::::::::::: +# ============================================================================ + +# `make install` will put the correct value here for your system +PREFIX = '/usr/local/' + # Setup xdg paths. DATA_DIR = os.path.join(xdghome('DATA', '.local/share/'), 'uzbl/') CACHE_DIR = os.path.join(xdghome('CACHE', '.cache/'), 'uzbl/') - # Event manager config dictionary. This is not to be confused with the config # dict that tracks variables in the uzbl instance. CONFIG = { @@ -74,13 +74,12 @@ CONFIG = { 'plugins_ignore': [], 'plugin_dirs': [os.path.join(DATA_DIR, 'plugins/'), - os.path.join(PREFIX, 'share/uzbl/examples/data/uzbl/plugins/')], + os.path.join(PREFIX, 'share/uzbl/examples/data/plugins/')], 'server_socket': os.path.join(CACHE_DIR, 'event_daemon'), 'pid_file': os.path.join(CACHE_DIR, 'event_daemon.pid'), } - # ============================================================================ # ::: End of configuration section ::::::::::::::::::::::::::::::::::::::::::: # ============================================================================ diff --git a/examples/data/uzbl/scripts/uzbl-tabbed b/examples/data/scripts/uzbl-tabbed index d93a3f4..7bd90d5 100755 --- a/examples/data/uzbl/scripts/uzbl-tabbed +++ b/examples/data/scripts/uzbl-tabbed @@ -44,6 +44,9 @@ # # Devon Jones <devon.jones@gmail.com> # Fifo command bring_to_front which brings the gtk window to focus. +# +# Simon Lipp (sloonz) +# Various # Dependencies: @@ -77,6 +80,7 @@ # # Tab title options: # tab_titles = 1 +# tab_indexes = 1 # new_tab_title = Loading # max_title_len = 50 # show_ellipsis = 1 @@ -96,25 +100,6 @@ # window_size = 800,800 # verbose = 0 # -# And the key bindings: -# bind_new_tab = gn -# bind_tab_from_clip = gY -# bind_tab_from_uri = go _ -# bind_close_tab = gC -# bind_next_tab = gt -# bind_prev_tab = gT -# bind_goto_tab = gi_ -# bind_goto_first = g< -# bind_goto_last = g> -# bind_clean_slate = gQ -# bind_exit = gZ -# -# Session preset key bindings: -# bind_save_preset = gsave _ -# bind_load_preset = gload _ -# bind_del_preset = gdel _ -# bind_list_presets = glist -# # And uzbl_tabbed.py takes care of the actual binding of the commands via each # instances fifo socket. # @@ -202,18 +187,10 @@ def xdghome(key, default): # Setup xdg paths. DATA_DIR = os.path.join(xdghome('DATA', '.local/share/'), 'uzbl/') -CONFIG_DIR = os.path.join(xdghome('CONFIG', '.config/'), 'uzbl/') # Ensure uzbl xdg paths exist -for path in [DATA_DIR, CONFIG_DIR]: - if not os.path.exists(path): - os.makedirs(path) - -# Path to uzbl config -UZBL_CONFIG = os.path.join(CONFIG_DIR, 'config') -if not os.path.exists(UZBL_CONFIG): - error("cannot find uzbl config file at %r" % UZBL_CONFIG) - sys.exit(1) +if not os.path.exists(DATA_DIR): + os.makedirs(DATA_DIR) # All of these settings can be inherited from your uzbl config file. config = { @@ -229,6 +206,7 @@ config = { # Tab title options 'tab_titles': True, # Display tab titles (else only tab-nums) + 'tab_indexes': True, # Display tab nums (else only tab titles) 'new_tab_title': 'Loading', # New tab title 'max_title_len': 50, # Truncate title at n characters 'show_ellipsis': True, # Show ellipsis when truncating titles @@ -249,25 +227,6 @@ config = { 'window_size': "800,800", # width,height in pixels. 'verbose': False, # Print verbose output. - # Key bindings - 'bind_new_tab': 'gn', # Open new tab. - 'bind_tab_from_clip': 'gY', # Open tab from clipboard. - 'bind_tab_from_uri': 'go _', # Open new tab and goto entered uri. - 'bind_close_tab': 'gC', # Close tab. - 'bind_next_tab': 'gt', # Next tab. - 'bind_prev_tab': 'gT', # Prev tab. - 'bind_goto_tab': 'gi_', # Goto tab by tab-number (in title). - 'bind_goto_first': 'g<', # Goto first tab. - 'bind_goto_last': 'g>', # Goto last tab. - 'bind_clean_slate': 'gQ', # Close all tabs and open new tab. - 'bind_exit': 'gZ', # Exit nicely. - - # Session preset key bindings - 'bind_save_preset': 'gsave _', # Save session to file %s. - 'bind_load_preset': 'gload _', # Load preset session from file %s. - 'bind_del_preset': 'gdel _', # Delete preset session %s. - 'bind_list_presets': 'glist', # List all session presets. - # Add custom tab style definitions to be used by the tab colour policy # handler here. Because these are added to the config dictionary like # any other uzbl_tabbed configuration option remember that they can @@ -284,6 +243,8 @@ config = { } # End of config dict. +UZBL_TABBED_VARS = config.keys() + # This is the tab style policy handler. Every time the tablist is updated # this function is called to determine how to colourise that specific tab # according the simple/complex rules as defined here. You may even wish to @@ -323,37 +284,6 @@ def echo(msg): sys.stderr.write("%s: %s\n" % (_SCRIPTNAME, msg)) -def readconfig(uzbl_config, config): - '''Loads relevant config from the users uzbl config file into the global - config dictionary.''' - - if not os.path.exists(uzbl_config): - error("Unable to load config %r" % uzbl_config) - return None - - # Define parsing regular expressions - isint = re.compile("^(\-|)[0-9]+$").match - findsets = re.compile("^set\s+([^\=]+)\s*\=\s*(.+)$",\ - re.MULTILINE).findall - - h = open(os.path.expandvars(uzbl_config), 'r') - rawconfig = h.read() - h.close() - - configkeys, strip = config.keys(), str.strip - for (key, value) in findsets(rawconfig): - key, value = strip(key), strip(value) - if key not in configkeys: continue - if isint(value): value = int(value) - config[key] = value - - # Ensure that config keys that relate to paths are expanded. - pathkeys = ['fifo_dir', 'socket_dir', 'session_file', 'icon_path', - 'saved_sessions_dir'] - for key in pathkeys: - config[key] = os.path.expandvars(config[key]) - - def counter(): '''To infinity and beyond!''' @@ -371,138 +301,233 @@ def escape(s): return s -def gen_endmarker(): - '''Generates a random md5 for socket message-termination endmarkers.''' +class SocketClient: + '''Represents a Uzbl instance, which is not necessarly linked with a UzblInstance''' - return hashlib.md5(str(random.random()*time.time())).hexdigest() + # List of UzblInstance objects not already linked with a SocketClient + instances_queue = {} + def __init__(self, socket): + self._buffer = "" + self._socket = socket + self._watchers = [io_add_watch(socket, IO_IN, self._socket_recv),\ + io_add_watch(socket, IO_HUP, self._socket_closed)] + self.uzbl = None -class UzblTabbed: - '''A tabbed version of uzbl using gtk.Notebook''' - class UzblInstance: - '''Uzbl instance meta-data/meta-action object.''' - - def __init__(self, parent, tab, fifo_socket, socket_file, pid,\ - uri, title, switch): - - self.parent = parent - self.tab = tab - self.fifo_socket = fifo_socket - self.socket_file = socket_file - self.pid = pid - self.title = title - self.uri = uri - self.timers = {} - self._lastprobe = 0 - self._fifoout = [] - self._socketout = [] + def _socket_recv(self, fd, condition): + '''Data available on socket, process it''' + + self._feed(self._socket.recv(1024)) #TODO: is io_add_watch edge or level-triggered ? + return True + + + def _socket_closed(self, fd, condition): + '''Remote client exited''' + self.uzbl.close() + return False + + + def _feed(self, data): + '''An Uzbl instance sent some data, parse it''' + + self._buffer += data + if self.uzbl: + if "\n" in self._buffer: + cmds = self._buffer.split("\n") + + if cmds[-1]: # Last command has been received incomplete, don't process it + self._buffer, cmds = cmds[-1], cmds[:-1] + else: + self._buffer = "" + + for cmd in cmds: + if cmd: + self.uzbl.parse_command(cmd) + else: + name = re.findall('^EVENT \[(\d+-\d+)\] INSTANCE_START \d+$', self._buffer, re.M) + uzbl = self.instances_queue.get(name[0]) + if uzbl: + del self.instances_queue[name[0]] + self.uzbl = uzbl + self.uzbl.got_socket(self) + self._feed("") + + def send(self, data): + '''Child socket send function.''' + + self._socket.send(data + "\n") + + def close(self): + '''Close the connection''' + + if self._socket: + self._socket.close() self._socket = None - self._buffer = "" - # Switch to tab after loading - self._switch = switch - # fifo/socket files exists and socket connected. - self._connected = False - # The kill switch - self._kill = False - - # Message termination endmarker. - self._marker = gen_endmarker() - - # Gen probe commands string - probes = [] - probe = probes.append - probe('print uri %d @uri %s' % (self.pid, self._marker)) - probe('print title %d @<document.title>@ %s' % (self.pid,\ - self._marker)) - self._probecmds = '\n'.join(probes) - - # Enqueue keybinding config for child uzbl instance - self.parent.config_uzbl(self) - - - def flush(self, timer_call=False): - '''Flush messages from the socket-out and fifo-out queues.''' - - if self._kill: - if self._socket: - self._socket.close() - self._socket = None - - error("Flush called on dead tab.") - return False - - if len(self._fifoout): - if os.path.exists(self.fifo_socket): - h = open(self.fifo_socket, 'w') - while len(self._fifoout): - msg = self._fifoout.pop(0) - h.write("%s\n"%msg) - h.close() - - if len(self._socketout): - if not self._socket and os.path.exists(self.socket_file): - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - sock.connect(self.socket_file) - self._socket = sock - - if self._socket: - while len(self._socketout): - msg = self._socketout.pop(0) - self._socket.send("%s\n"%msg) - - if not self._connected and timer_call: - if not len(self._fifoout + self._socketout): - self._connected = True - - if timer_call in self.timers.keys(): - source_remove(self.timers[timer_call]) - del self.timers[timer_call] - - if self._switch: - self.grabfocus() - - return len(self._fifoout + self._socketout) - - - def grabfocus(self): - '''Steal parent focus and switch the notebook to my own tab.''' - - tabs = list(self.parent.notebook) - tabid = tabs.index(self.tab) + map(source_remove, self._watchers) + self._watchers = [] + + +class UzblInstance: + '''Uzbl instance meta-data/meta-action object.''' + + def __init__(self, parent, tab, name, uri, title, switch): + + self.parent = parent + self.tab = tab + self.name = name + self.title = title + self.tabtitle = "" + self.uri = uri + self._client = None + self._switch = switch # Switch to tab after loading ? + self.title_changed() + + + def got_socket(self, client): + '''Uzbl instance is now connected''' + + self._client = client + self.parent.config_uzbl(self) + if self._switch: + tabid = self.parent.notebook.page_num(self.tab) self.parent.goto_tab(tabid) - def probe(self): - '''Probes the client for information about its self.''' + def title_changed(self, gtk_only = True): # GTK-only is for indexes + '''self.title has changed, update the tabs list''' + + tab_titles = config['tab_titles'] + tab_indexes = config['tab_indexes'] + show_ellipsis = config['show_ellipsis'] + max_title_len = config['max_title_len'] + + # Unicode heavy strings do not like being truncated/sliced so by + # re-encoding the string sliced of limbs are removed. + self.tabtitle = self.title[:max_title_len + int(show_ellipsis)] + if type(self.tabtitle) != types.UnicodeType: + self.tabtitle = unicode(self.tabtitle, 'utf-8', 'ignore') - if self._connected: - self.send(self._probecmds) - self._lastprobe = time.time() + self.tabtitle = self.tabtitle.encode('utf-8', 'ignore').strip() + + if show_ellipsis and len(self.tabtitle) != len(self.title): + self.tabtitle += "\xe2\x80\xa6" + + gtk_tab_format = "%d %s" + index = self.parent.notebook.page_num(self.tab) + if tab_titles and tab_indexes: + self.parent.notebook.set_tab_label_text(self.tab, + gtk_tab_format % (index, self.tabtitle)) + elif tab_titles: + self.parent.notebook.set_tab_label_text(self.tab, self.tabtitle) + else: + self.parent.notebook.set_tab_label_text(self.tab, str(index)) + # If instance is current tab, update window title + if index == self.parent.notebook.get_current_page(): + title_format = "%s - Uzbl Browser" + self.parent.window.set_title(title_format % self.title) - def write(self, msg): - '''Child fifo write function.''' + # Non-GTK tabs + if not gtk_only: + self.parent.update_tablist() - self._fifoout.append(msg) - # Flush messages from the queue if able. - return self.flush() + def set(self, key, val): + ''' Send the SET command to Uzbl ''' - def send(self, msg): - '''Child socket send function.''' + if self._client: + self._client.send('set %s = %s') #TODO: escape chars ? - self._socketout.append(msg) - # Flush messages from queue if able. - return self.flush() + def exit(self): + ''' Ask the Uzbl instance to close ''' + + if self._client: + self._client.send('exit') + + + def parse_command(self, cmd): + ''' Parse event givent by the Uzbl instance ''' + + type, _, args = cmd.split(" ", 2) + if type == "EVENT": + type, args = args.split(" ", 1) + if type == "TITLE_CHANGED": + self.title = args + self.title_changed() + elif type == "VARIABLE_SET": + var, _, val = args.split(" ", 2) + try: + val = int(val) + except: + pass + + if var in UZBL_TABBED_VARS: + if config[var] != val: + config[var] = val + if var == "show_gtk_tabs": + self.parent.notebook.set_show_tabs(bool(val)) + elif var == "show_tablist" or var == "tablist_top": + self.parent.update_tablist_display() + elif var == "gtk_tab_pos": + self.parent.update_gtk_tab_pos() + elif var == "status_background": + col = gtk.gdk.color_parse(config['status_background']) + self.parent.ebox.modify_bg(gtk.STATE_NORMAL, col) + elif var == "tab_titles" or var == "tab_indexes": + for tab in self.parent.notebook: + self.parent.tabs[tab].title_changed(True) + + self.parent.update_tablist() + else: + config[var] = val + + if var == "uri": + self.uri = var + self.parent.update_tablist() + elif type == "NEW_TAB": + self.parent.new_tab(args) + elif type == "NEXT_TAB": + if args: + self.parent.next_tab(int(args)) + else: + self.parent.next_tab() + elif type == "PREV_TAB": + if args: + self.parent.prev_tab(int(args)) + else: + self.parent.prev_tab() + elif type == "GOTO_TAB": + self.parent.goto_tab(int(args)) + elif type == "FIRST_TAB": + self.parent.goto_tab(0) + elif type == "LAST_TAB": + self.parent.goto_tab(-1) + elif type == "PRESET_TABS": + self.parent.parse_command(["preset"] + args.split()) + elif type == "BRING_TO_FRONT": + self.parent.window.present() + elif type == "CLEAN_TABS": + self.parent.clean_slate() + elif type == "EXIT_ALL_TABS": + self.parent.quitrequest() + + + def close(self): + '''The remote instance exited''' + + if self._client: + self._client.close() + self._client = None + + +class UzblTabbed: + '''A tabbed version of uzbl using gtk.Notebook''' def __init__(self): '''Create tablist, window and notebook.''' - # Store information about the applications fifo_socket. - self._fifo = None - self._timers = {} self._buffer = "" self._killed = False @@ -513,6 +538,9 @@ class UzblTabbed: # Holds metadata on the uzbl childen open. self.tabs = {} + # Uzbl sockets (socket => SocketClient) + self.clients = {} + # Generates a unique id for uzbl socket filenames. self.next_pid = counter().next @@ -534,7 +562,7 @@ class UzblTabbed: self.window.set_icon(gtk.gdk.pixbuf_new_from_file(icon_path)) else: - icon_path = '/usr/share/uzbl/examples/data/uzbl/uzbl.png' + icon_path = '/usr/share/uzbl/examples/data/uzbl.png' if os.path.exists(icon_path): self.window.set_icon(gtk.gdk.pixbuf_new_from_file(icon_path)) @@ -542,35 +570,33 @@ class UzblTabbed: self.window.connect("delete-event", self.quitrequest) # Create tab list - if config['show_tablist']: - vbox = gtk.VBox() - self.window.add(vbox) - ebox = gtk.EventBox() - self.tablist = gtk.Label() - - self.tablist.set_use_markup(True) - self.tablist.set_justify(gtk.JUSTIFY_LEFT) - self.tablist.set_line_wrap(False) - self.tablist.set_selectable(False) - self.tablist.set_padding(2,2) - self.tablist.set_alignment(0,0) - self.tablist.set_ellipsize(pango.ELLIPSIZE_END) - self.tablist.set_text(" ") - self.tablist.show() - ebox.add(self.tablist) - ebox.show() - bgcolor = gtk.gdk.color_parse(config['status_background']) - ebox.modify_bg(gtk.STATE_NORMAL, bgcolor) + vbox = gtk.VBox() + self.vbox = vbox + self.window.add(vbox) + ebox = gtk.EventBox() + self.ebox = ebox + self.tablist = gtk.Label() + + self.tablist.set_use_markup(True) + self.tablist.set_justify(gtk.JUSTIFY_LEFT) + self.tablist.set_line_wrap(False) + self.tablist.set_selectable(False) + self.tablist.set_padding(2,2) + self.tablist.set_alignment(0,0) + self.tablist.set_ellipsize(pango.ELLIPSIZE_END) + self.tablist.set_text(" ") + self.tablist.show() + ebox.add(self.tablist) + ebox.show() + bgcolor = gtk.gdk.color_parse(config['status_background']) + ebox.modify_bg(gtk.STATE_NORMAL, bgcolor) # Create notebook self.notebook = gtk.Notebook() self.notebook.set_show_tabs(config['show_gtk_tabs']) # Set tab position - allposes = {'left': gtk.POS_LEFT, 'right':gtk.POS_RIGHT, - 'top':gtk.POS_TOP, 'bottom':gtk.POS_BOTTOM} - if config['gtk_tab_pos'] in allposes.keys(): - self.notebook.set_tab_pos(allposes[config['gtk_tab_pos']]) + self.update_gtk_tab_pos() self.notebook.set_show_border(False) self.notebook.set_scrollable(True) @@ -581,28 +607,25 @@ class UzblTabbed: self.notebook.connect("page-added", self.tab_opened) self.notebook.show() - if config['show_tablist']: - if config['tablist_top']: - vbox.pack_start(ebox, False, False, 0) - vbox.pack_end(self.notebook, True, True, 0) - - else: - vbox.pack_start(self.notebook, True, True, 0) - vbox.pack_end(ebox, False, False, 0) - - vbox.show() - - else: - self.window.add(self.notebook) + vbox.pack_start(self.notebook, True, True, 0) + vbox.reorder_child(self.notebook, 1) + self.update_tablist_display() + self.vbox.show() self.window.show() self.wid = self.notebook.window.xid - # Generate the fifo socket filename. - fifo_filename = 'uzbltabbed_%d' % os.getpid() - self.fifo_socket = os.path.join(config['fifo_dir'], fifo_filename) - # Now initialise the fifo socket at self.fifo_socket - self.init_fifo_socket() + # Store information about the applications fifo and socket. + fifo_filename = 'uzbltabbed_%d.fifo' % os.getpid() + socket_filename = 'uzbltabbed_%d.socket' % os.getpid() + self._fifo = None + self._socket = None + self.fifo_path = os.path.join(config['fifo_dir'], fifo_filename) + self.socket_path = os.path.join(config['socket_dir'], socket_filename) + + # Now initialise the fifo and the socket + self.init_fifo() + self.init_socket() # If we are using sessions then load the last one if it exists. if config['save_session']: @@ -612,21 +635,13 @@ class UzblTabbed: def run(self): '''UzblTabbed main function that calls the gtk loop.''' - if not len(self.tabs): + if not self.clients and not SocketClient.instances_queue and not self.tabs: self.new_tab() gtk_refresh = int(config['gtk_refresh']) if gtk_refresh < 100: gtk_refresh = 100 - # Update tablist timer - timerid = timeout_add(gtk_refresh, self.update_tablist) - self._timers["update-tablist"] = timerid - - # Probe clients every second for window titles and location - timerid = timeout_add(gtk_refresh, self.probe_clients) - self._timers["probe-clients"] = timerid - # Make SIGTERM act orderly. signal(SIGTERM, lambda signum, stack_frame: self.terminate(SIGTERM)) @@ -640,7 +655,8 @@ class UzblTabbed: error("encounted error %r" % sys.exc_info()[1]) # Unlink fifo socket - self.unlink_fifo_socket() + self.unlink_fifo() + self.close_socket() # Attempt to close all uzbl instances nicely. self.quitrequest() @@ -671,40 +687,75 @@ class UzblTabbed: self.quitrequest() - def init_fifo_socket(self): - '''Create interprocess communication fifo socket.''' + def init_socket(self): + '''Create interprocess communication socket.''' + + def accept(sock, condition): + '''A new uzbl instance was created''' + + client, _ = sock.accept() + self.clients[client] = SocketClient(client) + + return True + + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.bind(self.socket_path) + sock.listen(1) + + # Add event handler for IO_IN event. + self._socket = (sock, io_add_watch(sock, IO_IN, accept)) + + echo("[socket] listening at %r" % self.socket_path) + + # Add atexit register to destroy the socket on program termination. + atexit.register(self.close_socket) + + + def close_socket(self): + '''Close the socket when closing the application''' + + if self._socket: + (fd, watcher) = self._socket + source_remove(watcher) + fd.close() + os.unlink(self.socket_path) + self._socket = None + - if os.path.exists(self.fifo_socket): - if not os.access(self.fifo_socket, os.F_OK | os.R_OK | os.W_OK): - os.mkfifo(self.fifo_socket) + def init_fifo(self): + '''Create interprocess communication fifo.''' + + if os.path.exists(self.fifo_path): + if not os.access(self.fifo_path, os.F_OK | os.R_OK | os.W_OK): + os.mkfifo(self.fifo_path) else: - basedir = os.path.dirname(self.fifo_socket) + basedir = os.path.dirname(self.fifo_path) if not os.path.exists(basedir): os.makedirs(basedir) - os.mkfifo(self.fifo_socket) + os.mkfifo(self.fifo_path) # Add event handlers for IO_IN & IO_HUP events. self.setup_fifo_watchers() - echo("listening at %r" % self.fifo_socket) + echo("[fifo] listening at %r" % self.fifo_path) - # Add atexit register to destroy the socket on program termination. - atexit.register(self.unlink_fifo_socket) + # Add atexit register to destroy the fifo on program termination. + atexit.register(self.unlink_fifo) - def unlink_fifo_socket(self): + def unlink_fifo(self): '''Unlink the fifo socket. Note: This function is called automatically on exit by an atexit register.''' - # Make sure the fifo_socket fd is closed. + # Make sure the fifo fd is closed. self.close_fifo() - # And unlink if the real fifo_socket exists. - if os.path.exists(self.fifo_socket): - os.unlink(self.fifo_socket) - echo("unlinked %r" % self.fifo_socket) + # And unlink if the real fifo exists. + if os.path.exists(self.fifo_path): + os.unlink(self.fifo_path) + echo("unlinked %r" % self.fifo_path) def close_fifo(self): @@ -727,10 +778,10 @@ class UzblTabbed: '''Open fifo socket fd and setup gobject IO_IN & IO_HUP event handlers.''' - # Close currently open fifo_socket fd and kill all watchers + # Close currently open fifo fd and kill all watchers self.close_fifo() - fd = os.open(self.fifo_socket, os.O_RDONLY | os.O_NONBLOCK) + fd = os.open(self.fifo_path, os.O_RDONLY | os.O_NONBLOCK) # Add gobject io event handlers to the fifo socket. watchers = [io_add_watch(fd, IO_IN, self.main_fifo_read),\ @@ -769,43 +820,6 @@ class UzblTabbed: return True - def probe_clients(self): - '''Probe all uzbl clients for up-to-date window titles and uri's.''' - - save_session = config['save_session'] - - sockd = {} - tabskeys = self.tabs.keys() - notebooklist = list(self.notebook) - - for tab in notebooklist: - if tab not in tabskeys: continue - uzbl = self.tabs[tab] - uzbl.probe() - if uzbl._socket: - sockd[uzbl._socket] = uzbl - - sockets = sockd.keys() - (reading, _, errors) = select.select(sockets, [], sockets, 0) - - for sock in reading: - uzbl = sockd[sock] - uzbl._buffer = sock.recv(1024).replace('\n',' ') - temp = uzbl._buffer.split(uzbl._marker) - self._buffer = temp.pop() - cmds = [s.strip().split() for s in temp if len(s.strip())] - for cmd in cmds: - try: - #print cmd - self.parse_command(cmd) - - except: - error("parse_command: invalid command %s" % ' '.join(cmd)) - raise - - return True - - def parse_command(self, cmd): '''Parse instructions from uzbl child processes.''' @@ -878,7 +892,7 @@ class UzblTabbed: elif cmd[0] in ["title", "uri"]: if len(cmd) > 2: - uzbl = self.get_tab_by_pid(int(cmd[1])) + uzbl = self.get_tab_by_name(int(cmd[1])) if uzbl: old = getattr(uzbl, cmd[0]) new = ' '.join(cmd[2:]) @@ -887,7 +901,7 @@ class UzblTabbed: self.update_tablist() else: - error("parse_command: no uzbl with pid %r" % int(cmd[1])) + error("parse_command: no uzbl with name %r" % int(cmd[1])) elif cmd[0] == "preset": if len(cmd) < 3: @@ -910,20 +924,20 @@ class UzblTabbed: error("parse_command: preset %r does not exist." % path) elif cmd[1] == "list": - uzbl = self.get_tab_by_pid(int(cmd[2])) + uzbl = self.get_tab_by_name(int(cmd[2])) if uzbl: if not os.path.isdir(config['saved_sessions_dir']): js = "js alert('No saved presets.');" - uzbl.send(js) + uzbl._client.send(js) else: listdir = os.listdir(config['saved_sessions_dir']) listdir = "\\n".join(listdir) js = "js alert('Session presets:\\n\\n%s');" % listdir - uzbl.send(js) + uzbl._client.send(js) else: - error("parse_command: unknown tab pid.") + error("parse_command: unknown tab name.") else: error("parse_command: unknown parse command %r"\ @@ -942,11 +956,11 @@ class UzblTabbed: error("parse_command: unknown command %r" % ' '.join(cmd)) - def get_tab_by_pid(self, pid): - '''Return uzbl instance by pid.''' + def get_tab_by_name(self, name): + '''Return uzbl instance by name.''' for (tab, uzbl) in self.tabs.items(): - if uzbl.pid == pid: + if uzbl.name == name: return uzbl return False @@ -958,17 +972,12 @@ class UzblTabbed: when you need to load multiple tabs at a time (I.e. like when restoring a session from a file).''' - pid = self.next_pid() tab = gtk.Socket() tab.show() self.notebook.append_page(tab) sid = tab.get_id() uri = uri.strip() - - fifo_filename = 'uzbl_fifo_%s_%0.2d' % (self.wid, pid) - fifo_socket = os.path.join(config['fifo_dir'], fifo_filename) - socket_filename = 'uzbl_socket_%s_%0.2d' % (self.wid, pid) - socket_file = os.path.join(config['socket_dir'], socket_filename) + name = "%d-%d" % (os.getpid(), self.next_pid()) if switch is None: switch = config['switch_to_new_tabs'] @@ -976,22 +985,13 @@ class UzblTabbed: if not title: title = config['new_tab_title'] - uzbl = self.UzblInstance(self, tab, fifo_socket, socket_file, pid,\ - uri, title, switch) - - if len(uri): - uri = "--uri %r" % uri + cmd = ['uzbl-browser', '-n', name, '-s', str(sid), + '--connect-socket', self.socket_path, '--uri', uri] + subprocess.Popen(cmd) # TODO: do i need close_fds=True ? + uzbl = UzblInstance(self, tab, name, uri, title, switch) + SocketClient.instances_queue[name] = uzbl self.tabs[tab] = uzbl - cmd = 'uzbl-browser -s %s -n %s_%0.2d %s &' % (sid, self.wid, pid, uri) - subprocess.Popen([cmd], shell=True) # TODO: do i need close_fds=True ? - - # Add gobject timer to make sure the config is pushed when fifo socket - # has been created. - timerid = timeout_add(100, uzbl.flush, "flush-initial-config") - uzbl.timers['flush-initial-config'] = timerid - - self.update_tablist() def clean_slate(self): @@ -1002,56 +1002,29 @@ class UzblTabbed: for tab in list(self.notebook)[:-1]: if tab not in tabs: continue uzbl = self.tabs[tab] - uzbl.send("exit") + uzbl.exit() def config_uzbl(self, uzbl): '''Send bind commands for tab new/close/next/prev to a uzbl instance.''' - binds = [] - bind_format = r'@bind %s = sh "echo \"%s\" > \"%s\""' - bind = lambda key, action: binds.append(bind_format % (key, action,\ - self.fifo_socket)) - - sets = [] - set_format = r'set %s = sh \"echo \\"%s\\" > \\"%s\\""' - set = lambda key, action: binds.append(set_format % (key, action,\ - self.fifo_socket)) - - # Bind definitions here - # bind(key, command back to fifo) - bind(config['bind_new_tab'], 'new') - bind(config['bind_tab_from_clip'], 'newfromclip') - bind(config['bind_tab_from_uri'], 'new %s') - bind(config['bind_close_tab'], 'close') - bind(config['bind_next_tab'], 'next') - bind(config['bind_prev_tab'], 'prev') - bind(config['bind_goto_tab'], 'goto %s') - bind(config['bind_goto_first'], 'goto 0') - bind(config['bind_goto_last'], 'goto -1') - bind(config['bind_clean_slate'], 'clean') - bind(config['bind_save_preset'], 'preset save %s') - bind(config['bind_load_preset'], 'preset load %s') - bind(config['bind_del_preset'], 'preset del %s') - bind(config['bind_list_presets'], 'preset list %d' % uzbl.pid) - bind(config['bind_exit'], 'exit') - # Set definitions here # set(key, command back to fifo) if config['capture_new_windows']: - set("new_window", r'new $8') - - # Send config to uzbl instance via its socket file. - uzbl.send("\n".join(binds+sets)) + uzbl.set("new_window", r'new $8') def goto_tab(self, index): '''Goto tab n (supports negative indexing).''' + title_format = "%s - Uzbl Browser" + tabs = list(self.notebook) if 0 <= index < len(tabs): self.notebook.set_current_page(index) + uzbl = self.tabs[self.notebook.get_nth_page(index)] + self.window.set_title(title_format % uzbl.title) self.update_tablist() return None @@ -1061,6 +1034,8 @@ class UzblTabbed: # negative index. index = tabs.index(tab) self.notebook.set_current_page(index) + uzbl = self.tabs[self.notebook.get_nth_page(index)] + self.window.set_title(title_format % uzbl.title) self.update_tablist() except IndexError: @@ -1076,8 +1051,7 @@ class UzblTabbed: ntabs = self.notebook.get_n_pages() tabn = (self.notebook.get_current_page() + step) % ntabs - self.notebook.set_current_page(tabn) - self.update_tablist() + self.goto_tab(tabn) def prev_tab(self, step=1): @@ -1090,8 +1064,7 @@ class UzblTabbed: ntabs = self.notebook.get_n_pages() tabn = self.notebook.get_current_page() - step while tabn < 0: tabn += ntabs - self.notebook.set_current_page(tabn) - self.update_tablist() + self.goto_tab(tabn) def close_tab(self, tabn=None): @@ -1129,18 +1102,8 @@ class UzblTabbed: if tab in self.tabs.keys(): uzbl = self.tabs[tab] - for (timer, gid) in uzbl.timers.items(): - error("tab_closed: removing timer %r" % timer) - source_remove(gid) - del uzbl.timers[timer] - - if uzbl._socket: - uzbl._socket.close() - uzbl._socket = None - - uzbl._fifoout = [] - uzbl._socketout = [] - uzbl._kill = True + uzbl.close() + self._closed.append((uzbl.uri, uzbl.title)) self._closed = self._closed[-10:] del self.tabs[tab] @@ -1152,6 +1115,8 @@ class UzblTabbed: self.quit() + for tab in self.notebook: + self.tabs[tab].title_changed(True) self.update_tablist() return True @@ -1166,105 +1131,85 @@ class UzblTabbed: return True + def update_tablist_display(self): + '''Called when show_tablist or tablist_top has changed''' + + if self.ebox in self.vbox.get_children(): + self.vbox.remove(self.ebox) + + if config['show_tablist']: + self.vbox.pack_start(self.ebox, False, False, 0) + if config['tablist_top']: + self.vbox.reorder_child(self.ebox, 0) + else: + self.vbox.reorder_child(self.ebox, 2) + + def update_gtk_tab_pos(self): + ''' Called when gtk_tab_pos has changed ''' + + allposes = {'left': gtk.POS_LEFT, 'right':gtk.POS_RIGHT, + 'top':gtk.POS_TOP, 'bottom':gtk.POS_BOTTOM} + if config['gtk_tab_pos'] in allposes.keys(): + self.notebook.set_tab_pos(allposes[config['gtk_tab_pos']]) + + def update_tablist(self, curpage=None): '''Upate tablist status bar.''' - show_tablist = config['show_tablist'] - show_gtk_tabs = config['show_gtk_tabs'] + if not config['show_tablist']: + return True + tab_titles = config['tab_titles'] - show_ellipsis = config['show_ellipsis'] + tab_indexes = config['tab_indexes'] multiline_tabs = config['multiline_tabs'] if multiline_tabs: multiline = [] - if not show_tablist and not show_gtk_tabs: - return True - tabs = self.tabs.keys() if curpage is None: curpage = self.notebook.get_current_page() - title_format = "%s - Uzbl Browser" - max_title_len = config['max_title_len'] - - if show_tablist: - pango = "" - normal = (config['tab_colours'], config['tab_text_colours']) - selected = (config['selected_tab'], config['selected_tab_text']) + pango = "" + normal = (config['tab_colours'], config['tab_text_colours']) + selected = (config['selected_tab'], config['selected_tab_text']) - if tab_titles: - tab_format = "<span %s> [ %d <span %s> %s</span> ] </span>" - - else: - tab_format = "<span %s> [ <span %s>%d</span> ] </span>" - - if show_gtk_tabs: - gtk_tab_format = "%d %s" + if tab_titles and tab_indexes: + tab_format = "<span %(tabc)s> [ %(index)d <span %(textc)s> %(title)s</span> ] </span>" + elif tab_titles: + tab_format = "<span %(tabc)s> [ <span %(textc)s>%(title)s</span> ] </span>" + else: + tab_format = "<span %(tabc)s> [ <span %(textc)s>%(index)d</span> ] </span>" for index, tab in enumerate(self.notebook): if tab not in tabs: continue uzbl = self.tabs[tab] + title = escape(uzbl.tabtitle) - if index == curpage: - self.window.set_title(title_format % uzbl.title) - - # Unicode heavy strings do not like being truncated/sliced so by - # re-encoding the string sliced of limbs are removed. - tabtitle = uzbl.title[:max_title_len + int(show_ellipsis)] - if type(tabtitle) != types.UnicodeType: - tabtitle = unicode(tabtitle, 'utf-8', 'ignore') + style = colour_selector(index, curpage, uzbl) + (tabc, textc) = style - tabtitle = tabtitle.encode('utf-8', 'ignore').strip() - - if show_ellipsis and len(tabtitle) != len(uzbl.title): - tabtitle += "\xe2\x80\xa6" - - if show_gtk_tabs: - if tab_titles: - self.notebook.set_tab_label_text(tab, - gtk_tab_format % (index, tabtitle)) - - else: - self.notebook.set_tab_label_text(tab, str(index)) - - if show_tablist: - style = colour_selector(index, curpage, uzbl) - (tabc, textc) = style - - if multiline_tabs: - opango = pango - - if tab_titles: - pango += tab_format % (tabc, index, textc, - escape(tabtitle)) - - else: - pango += tab_format % (tabc, textc, index) - - self.tablist.set_markup(pango) - listwidth = self.tablist.get_layout().get_pixel_size()[0] - winwidth = self.window.get_size()[0] + if multiline_tabs: + opango = pango - if listwidth > (winwidth - 20): - multiline.append(opango) - pango = tab_format % (tabc, index, textc, - escape(tabtitle)) + pango += tab_format % locals() - elif tab_titles: - pango += tab_format % (tabc, index, textc, - escape(tabtitle)) + self.tablist.set_markup(pango) + listwidth = self.tablist.get_layout().get_pixel_size()[0] + winwidth = self.window.get_size()[0] - else: - pango += tab_format % (tabc, textc, index) + if listwidth > (winwidth - 20): + multiline.append(opango) + pango = tab_format % locals() + else: + pango += tab_format % locals() - if show_tablist: - if multiline_tabs: - multiline.append(pango) - self.tablist.set_markup(' '.join(multiline)) + if multiline_tabs: + multiline.append(pango) + self.tablist.set_markup(' '.join(multiline)) - else: - self.tablist.set_markup(pango) + else: + self.tablist.set_markup(pango) return True @@ -1398,7 +1343,7 @@ class UzblTabbed: os.remove(config['session_file']) for (tab, uzbl) in self.tabs.items(): - uzbl.send("exit") + uzbl.exit() # Add a gobject timer to make sure the application force-quits after a # reasonable period. Calling quit when all the tabs haven't had time to @@ -1413,7 +1358,8 @@ class UzblTabbed: # Close the fifo socket, remove any gobject io event handlers and # delete socket. - self.unlink_fifo_socket() + self.unlink_fifo() + self.close_socket() # Remove all gobject timers that are still ticking. for (timerid, gid) in self._timers.items(): @@ -1429,9 +1375,6 @@ class UzblTabbed: if __name__ == "__main__": - # Read from the uzbl config into the global config dictionary. - readconfig(UZBL_CONFIG, config) - # Build command line parser usage = "usage: %prog [OPTIONS] {URIS}..." parser = OptionParser(usage=usage) diff --git a/examples/data/uzbl/scripts/uzblcat b/examples/data/scripts/uzblcat index e955608..e955608 100755 --- a/examples/data/uzbl/scripts/uzblcat +++ b/examples/data/scripts/uzblcat diff --git a/examples/data/uzbl/style.css b/examples/data/style.css index f9b111e..f9b111e 100644 --- a/examples/data/uzbl/style.css +++ b/examples/data/style.css diff --git a/examples/data/uzbl/uzbl.png b/examples/data/uzbl.png Binary files differindex 773ea84..773ea84 100644 --- a/examples/data/uzbl/uzbl.png +++ b/examples/data/uzbl.png diff --git a/sandbox/env.sh b/sandbox/env.sh index 0bf812a..122a7f2 100755 --- a/sandbox/env.sh +++ b/sandbox/env.sh @@ -5,8 +5,9 @@ # - executing limits scope of variables too much (even with exporting) # maybe we should spawn processes from here with an 'exec' at the end? -export XDG_DATA_HOME=./sandbox/examples/data -export XDG_CACHE_HOME=./sandbox/examples/cache -export XDG_CONFIG_HOME=./sandbox/examples/config -#export PATH="./sandbox/usr/local/share/uzbl/examples/data/uzbl/scripts/:$PATH" # needed when running uzbl-browser from here? don't think so.. +export HOME=./sandbox/home +export XDG_DATA_HOME=$HOME/.local/share +export XDG_CACHE_HOME=$HOME/.cache +export XDG_CONFIG_HOME=$HOME/.config +#export PATH="./sandbox/usr/local/share/uzbl/examples/data/scripts/:$PATH" # needed when running uzbl-browser from here? don't think so.. export PATH="./sandbox/usr/local/bin:$PATH" # needed to run uzbl-browser etc from here diff --git a/callbacks.c b/src/callbacks.c index dab92c1..9130f5f 100644 --- a/callbacks.c +++ b/src/callbacks.c @@ -270,6 +270,19 @@ cmd_useragent() { } } +void +cmd_scrollbars_visibility() { + if(uzbl.gui.scrollbars_visible) { + uzbl.gui.bar_h = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (uzbl.gui.scrolled_win)); + uzbl.gui.bar_v = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (uzbl.gui.scrolled_win)); + } + else { + uzbl.gui.bar_v = gtk_range_get_adjustment (GTK_RANGE (uzbl.gui.scbar_v)); + uzbl.gui.bar_h = gtk_range_get_adjustment (GTK_RANGE (uzbl.gui.scbar_h)); + } + gtk_widget_set_scroll_adjustments (GTK_WIDGET (uzbl.gui.web_view), uzbl.gui.bar_h, uzbl.gui.bar_v); +} + /* requires webkit >=1.1.14 */ void cmd_view_source() { diff --git a/callbacks.h b/src/callbacks.h index 3f318f2..882ffa4 100644 --- a/callbacks.h +++ b/src/callbacks.h @@ -113,6 +113,9 @@ void cmd_view_source(); void +cmd_scrollbars_visibility(); + +void cmd_load_start(); WebKitWebSettings* @@ -169,8 +169,8 @@ send_event(int type, const gchar *details, const gchar *custom_event) { } if(event_message->str) { - /* TODO: a means to select the interface to which events are sent */ - send_event_stdout(event_message); + if(uzbl.state.events_stdout) + send_event_stdout(event_message); send_event_socket(event_message); g_string_free(event_message, TRUE); diff --git a/inspector.c b/src/inspector.c index de3dbcd..de3dbcd 100644 --- a/inspector.c +++ b/src/inspector.c diff --git a/inspector.h b/src/inspector.h index 57d0ca9..57d0ca9 100644 --- a/inspector.h +++ b/src/inspector.h diff --git a/uzbl-browser b/src/uzbl-browser index eebf9e3..8a7ab36 100755 --- a/uzbl-browser +++ b/src/uzbl-browser @@ -40,7 +40,7 @@ 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 ! cp $PREFIX/share/uzbl/examples/config/uzbl/config $XDG_CONFIG_HOME/uzbl/config + if ! cp $PREFIX/share/uzbl/examples/config/config $XDG_CONFIG_HOME/uzbl/config then echo "Could not copy default config to $XDG_CONFIG_HOME/uzbl/config" >&2 exit 3 @@ -63,4 +63,4 @@ DAEMON_PID=${DAEMON_SOCKET}.pid uzbl-event-manager -va start #fi -uzbl-core "$@" --connect-socket $DAEMON_SOCKET | grep -v ^EVENT +uzbl-core "$@" --connect-socket $DAEMON_SOCKET diff --git a/uzbl-core.c b/src/uzbl-core.c index da644f4..da61093 100644 --- a/uzbl-core.c +++ b/src/uzbl-core.c @@ -53,6 +53,8 @@ GOptionEntry entries[] = "Xembed Socket ID", "SOCKET" }, { "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, + "Whether to print events to stdout.", NULL }, { "geometry", 'g', 0, G_OPTION_ARG_STRING, &uzbl.gui.geometry, "Set window geometry (format: 'WIDTHxHEIGHT+-X+-Y' or 'maximized')", "GEOMETRY" }, { "version", 'V', 0, G_OPTION_ARG_NONE, &uzbl.behave.print_version, @@ -85,6 +87,7 @@ const struct var_name_to_ptr_t { /* ---------------------------------------------------------------------------------------------- */ { "uri", PTR_V_STR(uzbl.state.uri, 1, cmd_load_uri)}, { "verbose", PTR_V_INT(uzbl.state.verbose, 1, NULL)}, + { "print_events", PTR_V_INT(uzbl.state.events_stdout, 1, NULL)}, { "inject_html", PTR_V_STR(uzbl.behave.inject_html, 0, cmd_inject_html)}, { "geometry", PTR_V_STR(uzbl.gui.geometry, 1, cmd_set_geometry)}, { "keycmd", PTR_V_STR(uzbl.state.keycmd, 1, NULL)}, @@ -135,6 +138,7 @@ const struct var_name_to_ptr_t { { "default_encoding", PTR_V_STR(uzbl.behave.default_encoding, 1, cmd_default_encoding)}, { "enforce_96_dpi", PTR_V_INT(uzbl.behave.enforce_96dpi, 1, cmd_enforce_96dpi)}, { "caret_browsing", PTR_V_INT(uzbl.behave.caret_browsing, 1, cmd_caret_browsing)}, + { "scrollbars_visible", PTR_V_INT(uzbl.gui.scrollbars_visible, 1, cmd_scrollbars_visibility)}, /* constants (not dumpable or writeable) */ { "WEBKIT_MAJOR", PTR_C_INT(uzbl.info.webkit_major, NULL)}, @@ -1049,6 +1053,7 @@ eval_js(WebKitWebView * web_view, gchar *script, GString *result) { JSStringRef js_script; JSValueRef js_result; + JSValueRef js_exc = NULL; JSStringRef js_result_string; size_t js_result_size; @@ -1060,7 +1065,7 @@ eval_js(WebKitWebView * web_view, gchar *script, GString *result) { /* evaluate the script and get return value*/ js_script = JSStringCreateWithUTF8CString(script); - js_result = JSEvaluateScript(context, js_script, globalobject, NULL, 0, NULL); + js_result = JSEvaluateScript(context, js_script, globalobject, NULL, 0, &js_exc); if (js_result && !JSValueIsUndefined(context, js_result)) { js_result_string = JSValueToStringCopy(context, js_result, NULL); js_result_size = JSStringGetMaximumUTF8CStringSize(js_result_string); @@ -1073,6 +1078,35 @@ eval_js(WebKitWebView * web_view, gchar *script, GString *result) { JSStringRelease(js_result_string); } + else if (js_exc) { + size_t size; + JSStringRef prop, val; + JSObjectRef exc = JSValueToObject(context, js_exc, NULL); + + printf("Exception occured while executing script:\n"); + + /* Print line */ + prop = JSStringCreateWithUTF8CString("line"); + val = JSValueToStringCopy(context, JSObjectGetProperty(context, exc, prop, NULL), NULL); + size = JSStringGetMaximumUTF8CStringSize(val); + if(size) { + char cstr[size]; + JSStringGetUTF8CString(val, cstr, size); + printf("At line %s: ", cstr); + } + JSStringRelease(prop); + JSStringRelease(val); + + /* Print message */ + val = JSValueToStringCopy(context, exc, NULL); + size = JSStringGetMaximumUTF8CStringSize(val); + if(size) { + char cstr[size]; + JSStringGetUTF8CString(val, cstr, size); + printf("%s\n", cstr); + } + JSStringRelease(val); + } /* cleanup */ JSStringRelease(js_script); diff --git a/uzbl-core.h b/src/uzbl-core.h index 83fa4b2..70a383c 100644 --- a/uzbl-core.h +++ b/src/uzbl-core.h @@ -54,6 +54,7 @@ typedef struct { GtkScrollbar* scbar_h; // (These are still hidden) GtkAdjustment* bar_v; // Information about document length GtkAdjustment* bar_h; // and scrolling position + int scrollbars_visible; WebKitWebView* web_view; gchar* main_title; gchar* icon; @@ -93,6 +94,7 @@ typedef struct { gchar* keycmd; gchar* searchtx; gboolean verbose; + gboolean events_stdout; GPtrArray *event_buffer; gchar** connect_socket_names; GdkEventButton *last_button; |