Merge branch 'experimental' of git://github.com/Dieterbe/uzbl into experimental
[uzbl-mobile] / examples / data / uzbl / scripts / uzbl_tabbed.py
index ef82374..d384fc6 100755 (executable)
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
-# Author(s): 
+# Author(s):
 #   Tom Adams <tom@holizz.com>
 #       Wrote the original uzbl_tabbed.py as a proof of concept.
 #
 #  Chris van Dijk (quigybo) <cn.vandijk@hotmail.com>
-#       Made signifigant headway on the old uzbl_tabbing.py script on the 
-#       uzbl wiki <http://www.uzbl.org/wiki/uzbl_tabbed> 
+#       Made signifigant headway on the old uzbl_tabbing.py script on the
+#       uzbl wiki <http://www.uzbl.org/wiki/uzbl_tabbed>
 #
 #   Mason Larobina <mason.larobina@gmail.com>
 #       Rewrite of the uzbl_tabbing.py script to use a fifo socket interface
 # example values for each:
 #
 # General tabbing options:
-#   show_tablist            = 1   
-#   show_gtk_tabs           = 0  
-#   tablist_top             = 1   
+#   show_tablist            = 1
+#   show_gtk_tabs           = 0
+#   tablist_top             = 1
 #   gtk_tab_pos             = (top|left|bottom|right)
 #   switch_to_new_tabs      = 1
-#  
+#
 # Tab title options:
 #   tab_titles              = 1
 #   new_tab_title           = Loading
 # Core options:
 #   save_session            = 1
 #   fifo_dir                = /tmp
-#   socket_dir              = /tmp 
+#   socket_dir              = /tmp
 #   icon_path               = $HOME/.local/share/uzbl/uzbl.png
 #   session_file            = $HOME/.local/share/uzbl/session
 #
 # Window options:
 #   status_background       = #303030
 #   window_size             = 800,800
-# 
+#
 # And the key bindings:
-#   bind_new_tab            = gn 
+#   bind_new_tab            = gn
 #   bind_tab_from_clip      = gY
 #   bind_tab_from_uri       = go _
-#   bind_close_tab          = gC  
+#   bind_close_tab          = gC
 #   bind_next_tab           = gt
 #   bind_prev_tab           = gT
 #   bind_goto_tab           = gi_
@@ -81,9 +81,9 @@
 #   bind_goto_last          = g>
 #
 # And uzbl_tabbed.py takes care of the actual binding of the commands via each
-# instances fifo socket. 
+# instances fifo socket.
 #
-# Custom tab styling: 
+# Custom tab styling:
 #   tab_colours             = foreground = "#888" background = "#303030"
 #   tab_text_colours        = foreground = "#bbb"
 #   selected_tab            = foreground = "#fff"
 #
 # How these styling values are used are soley defined by the syling policy
 # handler below (the function in the config section). So you can for example
-# turn the tab text colour Firetruck-Red in the event "error" appears in the 
+# turn the tab text colour Firetruck-Red in the event "error" appears in the
 # tab title or some other arbitrary event. You may wish to make a trusted
-# hosts file and turn tab titles of tabs visiting trusted hosts purple. 
+# hosts file and turn tab titles of tabs visiting trusted hosts purple.
 
 
-# Issues: 
+# Issues:
 #   - new windows are not caught and opened in a new tab.
 #   - when uzbl_tabbed.py crashes it takes all the children with it.
-#   - when a new tab is opened when using gtk tabs the tab button itself 
-#     grabs focus from its child for a few seconds. 
-#   - when switch_to_new_tabs is not selected the notebook page is 
+#   - when a new tab is opened when using gtk tabs the tab button itself
+#     grabs focus from its child for a few seconds.
+#   - when switch_to_new_tabs is not selected the notebook page is
 #     maintained but the new window grabs focus (try as I might to stop it).
 
 
-# Todo: 
+# Todo:
 #   - add command line options to use a different session file, not use a
-#     session file and or open a uri on starup. 
+#     session file and or open a uri on starup.
 #   - ellipsize individual tab titles when the tab-list becomes over-crowded
-#   - add "<" & ">" arrows to tablist to indicate that only a subset of the 
+#   - add "<" & ">" arrows to tablist to indicate that only a subset of the
 #     currently open tabs are being displayed on the tablist.
 #   - add the small tab-list display when both gtk tabs and text vim-like
 #     tablist are hidden (I.e. [ 1 2 3 4 5 ])
 #   - check spelling.
-#   - pass a uzbl socketid to uzbl_tabbed.py and have it assimilated into 
+#   - pass a uzbl socketid to uzbl_tabbed.py and have it assimilated into
 #     the collective. Resistance is futile!
 #   - on demand store the session to file (need binding & command for that)
 
@@ -149,7 +149,7 @@ def error(msg):
 # ::: Default configuration section ::::::::::::::::::::::::::::::::::::::::::
 # ============================================================================
 
-# Location of your uzbl data directory. 
+# Location of your uzbl data directory.
 if 'XDG_DATA_HOME' in os.environ.keys() and os.environ['XDG_DATA_HOME']:
     data_dir = os.path.join(os.environ['XDG_DATA_HOME'], 'uzbl/')
 else:
@@ -166,14 +166,14 @@ if not os.path.exists(uzbl_config):
     error("Warning: Cannot locate your uzbl_config file %r" % uzbl_config)
 
 # All of these settings can be inherited from your uzbl config file.
-config = { 
+config = {
   # Tab options
   'show_tablist':           True,   # Show text uzbl like statusbar tab-list
   'show_gtk_tabs':          False,  # Show gtk notebook tabs
   'tablist_top':            True,   # Display tab-list at top of window
   'gtk_tab_pos':            'top',  # Gtk tab position (top|left|bottom|right)
   'switch_to_new_tabs':     True,   # Upon opening a new tab switch to it
-  
+
   # Tab title options
   'tab_titles':             True,   # Display tab titles (else only tab-nums)
   'new_tab_title':          'Loading', # New tab title
@@ -183,53 +183,53 @@ config = {
   # Core options
   'save_session':           True,   # Save session in file when quit
   'fifo_dir':               '/tmp', # Path to look for uzbl fifo
-  'socket_dir':             '/tmp', # Path to look for uzbl socket 
+  'socket_dir':             '/tmp', # Path to look for uzbl socket
   'icon_path':              os.path.join(data_dir, 'uzbl.png'),
   'session_file':           os.path.join(data_dir, 'session'),
 
   # Window options
   'status_background':      "#303030", # Default background for all panels
   'window_size':            "800,800", # width,height in pixels
-  
+
   # Key bindings.
-  'bind_new_tab':           'gn',   # Open new tab. 
+  '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_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
-  
-  # Add custom tab style definitions to be used by the tab colour policy 
+
+  # 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 
-  # be superseeded from your main uzbl config file. 
+  # any other uzbl_tabbed configuration option remember that they can
+  # be superseeded from your main uzbl config file.
   'tab_colours':            'foreground = "#888" background = "#303030"',
-  'tab_text_colours':       'foreground = "#bbb"',  
+  'tab_text_colours':       'foreground = "#bbb"',
   'selected_tab':           'foreground = "#fff"',
   'selected_tab_text':      'foreground = "green"',
   'tab_indicate_https':     True,
   'https_colours':          'foreground = "#888"',
-  'https_text_colours':     'foreground = "#9c8e2d"', 
+  'https_text_colours':     'foreground = "#9c8e2d"',
   'selected_https':         'foreground = "#fff"',
   'selected_https_text':    'foreground = "gold"',
-  
+
   } # End of config dict.
 
-# This is the tab style policy handler. Every time the tablist is updated 
+# 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 
+# according the simple/complex rules as defined here. You may even wish to
 # move this function into another python script and import it using:
 #   from mycustomtabbingconfig import colour_selector
 # Remember to rename, delete or comment out this function if you do that.
 
 def colour_selector(tabindex, currentpage, uzbl):
-    '''Tablist styling policy handler. This function must return a tuple of 
+    '''Tablist styling policy handler. This function must return a tuple of
     the form (tab style, text style).'''
-    
-    # Just as an example: 
+
+    # Just as an example:
     # if 'error' in uzbl.title:
     #     if tabindex == currentpage:
     #         return ('foreground="#fff"', 'foreground="red"')
@@ -242,11 +242,11 @@ def colour_selector(tabindex, currentpage, uzbl):
         return (config['https_colours'], config['https_text_colours'])
 
     # Style to indicate selected.
-    if tabindex == currentpage: 
+    if tabindex == currentpage:
         return (config['selected_tab'], config['selected_tab_text'])
 
     # Default tab style.
-    return (config['tab_colours'], config['tab_text_colours'])    
+    return (config['tab_colours'], config['tab_text_colours'])
 
 
 # ============================================================================
@@ -261,26 +261,26 @@ def readconfig(uzbl_config, config):
     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()
-    
+
     for (key, value) in findsets(rawconfig):
         key, value = key.strip(), value.strip()
         if key not in config.keys(): continue
         if isint(value): value = int(value)
         config[key] = value
-    
+
     # Ensure that config keys that relate to paths are expanded.
     expand = ['fifo_dir', 'socket_dir', 'session_file', 'icon_path']
     for key in expand:
-        config[key] = os.path.expandvars(config[key]) 
+        config[key] = os.path.expandvars(config[key])
 
 
 def rmkdir(path):
@@ -321,14 +321,14 @@ def gen_endmarker():
 class UzblTabbed:
     '''A tabbed version of uzbl using gtk.Notebook'''
 
-    class UzblInstance: 
+    class UzblInstance:
         '''Uzbl instance meta-data/meta-action object.'''
 
         def __init__(self, parent, tab, fifo_socket, socket_file, pid,\
           uri, switch):
 
             self.parent = parent
-            self.tab = tab 
+            self.tab = tab
             self.fifo_socket = fifo_socket
             self.socket_file = socket_file
             self.pid = pid
@@ -342,12 +342,12 @@ class UzblTabbed:
             self._buffer = ""
             # Switch to tab after loading
             self._switch = switch
-            # fifo/socket files exists and socket connected. 
+            # fifo/socket files exists and socket connected.
             self._connected = False
             # The kill switch
             self._kill = False
 
-            # Message termination endmarker. 
+            # Message termination endmarker.
             self._marker = gen_endmarker()
 
             # Gen probe commands string
@@ -357,16 +357,16 @@ class UzblTabbed:
             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: 
+                if self._socket:
                     self._socket.close()
                     self._socket = None
 
@@ -380,7 +380,7 @@ class UzblTabbed:
                         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)
@@ -391,11 +391,11 @@ class UzblTabbed:
                     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():
                         gobject.source_remove(self.timers[timer_call])
                         del self.timers[timer_call]
@@ -405,10 +405,10 @@ class UzblTabbed:
 
             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)
             self.parent.goto_tab(tabid)
@@ -416,7 +416,7 @@ class UzblTabbed:
 
         def probe(self):
             '''Probes the client for information about its self.'''
-            
+
             if self._connected:
                 self.send(self._probecmds)
                 self._lastprobe = time.time()
@@ -436,16 +436,16 @@ class UzblTabbed:
             self._socketout.append(msg)
             # Flush messages from queue if able.
             return self.flush()
-              
+
 
     def __init__(self):
         '''Create tablist, window and notebook.'''
-        
+
         self._fifos = {}
         self._timers = {}
         self._buffer = ""
-        
-        # Once a second is updated with the latest tabs' uris so that when the 
+
+        # Once a second is updated with the latest tabs' uris so that when the
         # window is killed the session is saved.
         self._tabsuris = []
         # And index of current page in self._tabsuris
@@ -453,13 +453,13 @@ class UzblTabbed:
 
         # Holds metadata on the uzbl childen open.
         self.tabs = {}
-        
+
         # Generates a unique id for uzbl socket filenames.
         self.next_pid = counter().next
-        
+
         # Create main window
         self.window = gtk.Window()
-        try: 
+        try:
             window_size = map(int, config['window_size'].split(','))
             self.window.set_default_size(*window_size)
 
@@ -468,7 +468,7 @@ class UzblTabbed:
 
         self.window.set_title("Uzbl Browser")
         self.window.set_border_width(0)
-        
+
         # Set main window icon
         icon_path = config['icon_path']
         if os.path.exists(icon_path):
@@ -478,11 +478,11 @@ class UzblTabbed:
             icon_path = '/usr/share/uzbl/examples/data/uzbl/uzbl.png'
             if os.path.exists(icon_path):
                 self.window.set_icon(gtk.gdk.pixbuf_new_from_file(icon_path))
-        
+
         # Attach main window event handlers
         self.window.connect("delete-event", self.quit)
-        
-        # Create tab list 
+
+        # Create tab list
         if config['show_tablist']:
             vbox = gtk.VBox()
             self.window.add(vbox)
@@ -501,13 +501,13 @@ class UzblTabbed:
             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, 
+        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']])
@@ -534,10 +534,10 @@ class UzblTabbed:
 
         else:
             self.window.add(self.notebook)
-        
+
         self.window.show()
         self.wid = self.notebook.window.xid
-        
+
         # Create the uzbl_tabbed fifo
         fifo_filename = 'uzbltabbed_%d' % os.getpid()
         self.fifo_socket = os.path.join(config['fifo_dir'], fifo_filename)
@@ -546,7 +546,7 @@ class UzblTabbed:
 
 
     def _create_fifo_socket(self, fifo_socket):
-        '''Create interprocess communication fifo socket.''' 
+        '''Create interprocess communication fifo socket.'''
 
         if os.path.exists(fifo_socket):
             if not os.access(fifo_socket, os.F_OK | os.R_OK | os.W_OK):
@@ -557,7 +557,7 @@ class UzblTabbed:
             if not os.path.exists(basedir):
                 rmkdir(basedir)
             os.mkfifo(self.fifo_socket)
-        
+
         print "Listening on %s" % self.fifo_socket
 
 
@@ -574,22 +574,22 @@ class UzblTabbed:
                 del watchers[watcherid]
 
             del self._fifos[fifo_socket]
-        
+
         # Re-open fifo and add listeners.
         fd = os.open(fifo_socket, os.O_RDONLY | os.O_NONBLOCK)
         watchers = {}
         self._fifos[fifo_socket] = (fd, watchers)
         watcher = lambda key, id: watchers.__setitem__(key, id)
-        
+
         # Watch for incoming data.
         gid = gobject.io_add_watch(fd, gobject.IO_IN, self.main_fifo_read)
         watcher('main-fifo-read', gid)
-        
+
         # Watch for fifo hangups.
         gid = gobject.io_add_watch(fd, gobject.IO_HUP, self.main_fifo_hangup)
         watcher('main-fifo-hangup', gid)
-        
-    
+
+
     def run(self):
         '''UzblTabbed main function that calls the gtk loop.'''
 
@@ -597,7 +597,7 @@ class UzblTabbed:
         #timer = "update-tablist"
         #timerid = gobject.timeout_add(500, self.update_tablist,timer)
         #self._timers[timer] = timerid
-        
+
         # Probe clients every second for window titles and location
         timer = "probe-clients"
         timerid = gobject.timeout_add(1000, self.probe_clients, timer)
@@ -608,7 +608,7 @@ class UzblTabbed:
 
     def probe_clients(self, timer_call):
         '''Probe all uzbl clients for up-to-date window titles and uri's.'''
-        
+
         sockd = {}
         uriinventory = []
         tabskeys = self.tabs.keys()
@@ -627,7 +627,7 @@ class UzblTabbed:
 
         sockets = sockd.keys()
         (reading, _, errors) = select.select(sockets, [], sockets, 0)
-        
+
         for sock in reading:
             uzbl = sockd[sock]
             uzbl._buffer = sock.recv(1024).replace('\n',' ')
@@ -648,7 +648,7 @@ class UzblTabbed:
 
     def main_fifo_hangup(self, fd, cb_condition):
         '''Handle main fifo socket hangups.'''
-        
+
         # Close fd, re-open fifo_socket and watch.
         self._setup_fifo_watcher(self.fifo_socket)
 
@@ -672,28 +672,28 @@ class UzblTabbed:
             except:
                 error("parse_command: invalid command %s" % ' '.join(cmd))
                 raise
-        
+
         return True
 
 
     def parse_command(self, cmd):
         '''Parse instructions from uzbl child processes.'''
-        
-        # Commands ( [] = optional, {} = required ) 
+
+        # Commands ( [] = optional, {} = required )
         # new [uri]
-        #   open new tab and head to optional uri. 
-        # close [tab-num] 
+        #   open new tab and head to optional uri.
+        # close [tab-num]
         #   close current tab or close via tab id.
         # next [n-tabs]
         #   open next tab or n tabs down. Supports negative indexing.
         # prev [n-tabs]
         #   open prev tab or n tabs down. Supports negative indexing.
         # goto {tab-n}
-        #   goto tab n.  
+        #   goto tab n.
         # first
         #   goto first tab.
         # last
-        #   goto last tab. 
+        #   goto last tab.
         # title {pid} {document-title}
         #   updates tablist title.
         # uri {pid} {document-location}
@@ -721,7 +721,7 @@ class UzblTabbed:
         elif cmd[0] == "next":
             if len(cmd) == 2:
                 self.next_tab(int(cmd[1]))
-                   
+
             else:
                 self.next_tab()
 
@@ -731,7 +731,7 @@ class UzblTabbed:
 
             else:
                 self.prev_tab()
-        
+
         elif cmd[0] == "goto":
             self.goto_tab(int(cmd[1]))
 
@@ -755,7 +755,7 @@ class UzblTabbed:
         else:
             error("parse_command: unknown command %r" % ' '.join(cmd))
 
-    
+
     def get_tab_by_pid(self, pid):
         '''Return uzbl instance by pid.'''
 
@@ -764,25 +764,25 @@ class UzblTabbed:
                 return self.tabs[tab]
 
         return False
-   
+
 
     def new_tab(self, uri='', switch=None):
         '''Add a new tab to the notebook and start a new instance of uzbl.
-        Use the switch option to negate config['switch_to_new_tabs'] option 
-        when you need to load multiple tabs at a time (I.e. like when 
+        Use the switch option to negate config['switch_to_new_tabs'] option
+        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()
-        
+
         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)
-        
+
         if switch is None:
             switch = config['switch_to_new_tabs']
 
@@ -796,26 +796,26 @@ class UzblTabbed:
         self.tabs[tab] = uzbl
         cmd = 'uzbl -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. 
+        # has been created.
         timerid = gobject.timeout_add(100, uzbl.flush, "flush-initial-config")
         uzbl.timers['flush-initial-config'] = timerid
-    
+
         self.update_tablist()
 
 
     def config_uzbl(self, uzbl):
-        '''Send bind commands for tab new/close/next/prev to a uzbl 
+        '''Send bind commands for tab new/close/next/prev to a uzbl
         instance.'''
 
         binds = []
         bind_format = 'bind %s = sh "echo \\\"%s\\\" > \\\"%s\\\""'
         bind = lambda key, action: binds.append(bind_format % (key, action, \
           self.fifo_socket))
-        
+
         # Keys are defined in the config section
-        # bind ( key , command back to fifo ) 
+        # 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')
@@ -826,38 +826,38 @@ class UzblTabbed:
         bind(config['bind_goto_first'], 'goto 0')
         bind(config['bind_goto_last'], 'goto -1')
 
-        # uzbl.send via socket or uzbl.write via fifo, I'll try send. 
+        # uzbl.send via socket or uzbl.write via fifo, I'll try send.
         uzbl.send("\n".join(binds))
 
 
     def goto_tab(self, index):
         '''Goto tab n (supports negative indexing).'''
-        
+
         tabs = list(self.notebook)
         if 0 <= index < len(tabs):
             self.notebook.set_current_page(index)
             self.update_tablist()
             return None
 
-        try: 
+        try:
             tab = tabs[index]
             # Update index because index might have previously been a
-            # negative index. 
+            # negative index.
             index = tabs.index(tab)
             self.notebook.set_current_page(index)
             self.update_tablist()
-        
+
         except IndexError:
             pass
 
 
     def next_tab(self, step=1):
         '''Switch to next tab or n tabs right.'''
-        
+
         if step < 1:
             error("next_tab: invalid step %r" % step)
             return None
-                
+
         ntabs = self.notebook.get_n_pages()
         tabn = (self.notebook.get_current_page() + step) % ntabs
         self.notebook.set_current_page(tabn)
@@ -866,7 +866,7 @@ class UzblTabbed:
 
     def prev_tab(self, step=1):
         '''Switch to prev tab or n tabs left.'''
-        
+
         if step < 1:
             error("prev_tab: invalid step %r" % step)
             return None
@@ -880,24 +880,24 @@ class UzblTabbed:
 
     def close_tab(self, tabn=None):
         '''Closes current tab. Supports negative indexing.'''
-        
-        if tabn is None: 
+
+        if tabn is None:
             tabn = self.notebook.get_current_page()
-        
+
         else:
-            try: 
+            try:
                 tab = list(self.notebook)[tabn]
-        
+
             except IndexError:
                 error("close_tab: invalid index %r" % tabn)
                 return None
 
         self.notebook.remove_page(tabn)
 
-    
+
     def tab_opened(self, notebook, tab, index):
         '''Called upon tab creation. Called by page-added signal.'''
-        
+
         if config['switch_to_new_tabs']:
             self.notebook.set_focus_child(tab)
 
@@ -908,15 +908,15 @@ class UzblTabbed:
 
 
     def tab_closed(self, notebook, tab, index):
-        '''Close the window if no tabs are left. Called by page-removed 
+        '''Close the window if no tabs are left. Called by page-removed
         signal.'''
-        
+
         if tab in self.tabs.keys():
             uzbl = self.tabs[tab]
             for timer in uzbl.timers.keys():
                 error("tab_closed: removing timer %r" % timer)
                 gobject.source_remove(uzbl.timers[timer])
-            
+
             if uzbl._socket:
                 uzbl._socket.close()
                 uzbl._socket = None
@@ -925,7 +925,7 @@ class UzblTabbed:
             uzbl._socketout = []
             uzbl._kill = True
             del self.tabs[tab]
-        
+
         if self.notebook.get_n_pages() == 0:
             self.quit()
 
@@ -936,7 +936,7 @@ class UzblTabbed:
 
     def tab_changed(self, notebook, page, index):
         '''Refresh tab list. Called by switch-page signal.'''
-        
+
         tab = self.notebook.get_nth_page(index)
         self.notebook.set_focus_child(tab)
         self.update_tablist(index)
@@ -945,7 +945,7 @@ class UzblTabbed:
 
     def update_tablist(self, curpage=None):
         '''Upate tablist status bar.'''
-    
+
         show_tablist = config['show_tablist']
         show_gtk_tabs = config['show_gtk_tabs']
         tab_titles = config['tab_titles']
@@ -968,17 +968,17 @@ class UzblTabbed:
                 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"
 
         for index, tab in enumerate(self.notebook):
             if tab not in tabs: continue
             uzbl = self.tabs[tab]
-            
+
             if index == curpage:
                 self.window.set_title(title_format % uzbl.title)
-            
+
             tabtitle = uzbl.title[:max_title_len]
             if show_ellipsis and len(tabtitle) != len(uzbl.title):
                 tabtitle = "%s\xe2\x80\xa6" % tabtitle[:-1] # Show Ellipsis
@@ -999,7 +999,7 @@ class UzblTabbed:
                       escape(tabtitle))
                 else:
                     pango += tab_format % (tabc, textc, index)
-        
+
         if show_tablist:
             self.tablist.set_markup(pango)
 
@@ -1008,7 +1008,7 @@ class UzblTabbed:
 
     def quit(self, *args):
         '''Cleanup the application and quit. Called by delete-event signal.'''
-        
+
         for fifo_socket in self._fifos.keys():
             fd, watchers = self._fifos[fifo_socket]
             os.close(fd)
@@ -1017,7 +1017,7 @@ class UzblTabbed:
                 del watchers[watcherid]
 
             del self._fifos[fifo_socket]
-        
+
         for timerid in self._timers.keys():
             gobject.source_remove(self._timers[timerid])
             del self._timers[timerid]
@@ -1032,29 +1032,29 @@ class UzblTabbed:
                 if not os.path.isfile(session_file):
                     dirname = os.path.dirname(session_file)
                     if not os.path.isdir(dirname):
-                        # Recursive mkdir not rmdir. 
+                        # Recursive mkdir not rmdir.
                         rmkdir(dirname)
-                
+
                 sessionstr = '\n'.join(self._tabsuris)
                 h = open(session_file, 'w')
                 h.write('current = %s\n%s' % (self._curpage, sessionstr))
                 h.close()
-                
+
             else:
                 # Notebook has no pages so delete session file if it exists.
                 if os.path.isfile(session_file):
                     os.remove(session_file)
 
-        gtk.main_quit() 
+        gtk.main_quit()
 
 
 if __name__ == "__main__":
-    
-    # Read from the uzbl config into the global config dictionary. 
+
+    # Read from the uzbl config into the global config dictionary.
     readconfig(uzbl_config, config)
-     
+
     uzbl = UzblTabbed()
-    
+
     if os.path.isfile(os.path.expandvars(config['session_file'])):
         h = open(os.path.expandvars(config['session_file']),'r')
         lines = [line.strip() for line in h.readlines()]
@@ -1071,8 +1071,8 @@ if __name__ == "__main__":
         for (index, url) in enumerate(urls):
             if current == index:
                 uzbl.new_tab(line, True)
-            
-            else:        
+
+            else:
                 uzbl.new_tab(line, False)
 
         if not len(urls):
@@ -1082,5 +1082,3 @@ if __name__ == "__main__":
         uzbl.new_tab()
 
     uzbl.run()
-
-