Example #1
0
    def __init__(self,
                 bus=None,
                 uri=None,
                 profile='default',
                 width=1213,
                 height=628):
        """ Browser(bus=None, uri=None, profile='default', width=1213, 
        height=628) -> 
        Main browser window of size 'width'x'height' embed browser tab 'pid'
        and use dbus 'bus' to communicate with the external tabs.

        """

        super(Browser, self).__init__(uri=uri,
                                      profile=profile,
                                      width=width,
                                      height=height)

        # Connect the dbus receiver to allow opening new tabs from external
        # tabs.
        if bus:
            self._receiver = BrowserReceiver(bus, '/main_browser%s' % id(self))
            self._receiver.connect('get-socket-id', self._get_socket_id)

            # Connect dbus to bus.
            self._connect_dbus(bus)
            self._bus = bus

        # Should we use a proxy.
        self._no_proxy = True
        self._proxy = os.environ.get('http_proxy', '')
        os.environ['http_proxy'] = ''

        # This dictionary is used to keep track of which tabs have died
        # so it can restart connected tabs properly.
        self._died_dict = {}

        # A dictionary to match closed pids with their replacement pid.
        self._closed_pid_dict = {}

        # Add an extra keyboard shortcut to open alternative tabs
        keyval, modifier = gtk.accelerator_parse('<Control><Alt>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE,
                                   self._new_tab_key_pressed)
        keyval, modifier = gtk.accelerator_parse('<Control><Shift><Alt>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE,
                                   self._new_tab_key_pressed)
        keyval, modifier = gtk.accelerator_parse('<Control><Mod4>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE,
                                   self._new_tab_key_pressed)

        # Setup the python executable to use for external tabs.
        #self._pyexec = subprocess.Popen(['which', 'python2'],
        #stdout=subprocess.PIPE).communicate()[0].strip()
        self._pyexec = sys.executable

        if uri:
            # Open a tab if there was a uri given.
            self.do_open_tab(uri=uri)
Example #2
0
    def __init__(self, bus=None, uri=None, profile='default', width=1213, 
            height=628):
        """ Browser(bus=None, uri=None, profile='default', width=1213, 
        height=628) -> 
        Main browser window of size 'width'x'height' embed browser tab 'pid'
        and use dbus 'bus' to communicate with the external tabs.

        """

        super(Browser, self).__init__(uri=uri, profile=profile, width=width, 
                height=height)

        # Connect the dbus receiver to allow opening new tabs from external
        # tabs.
        if bus:
            self._receiver = BrowserReceiver(bus, '/main_browser%s' % id(self))
            self._receiver.connect('get-socket-id', self._get_socket_id)

            # Connect dbus to bus.
            self._connect_dbus(bus)
            self._bus = bus

        # Should we use a proxy.
        self._no_proxy = True
        self._proxy = os.environ.get('http_proxy', '')
        os.environ['http_proxy'] = ''

        # This dictionary is used to keep track of which tabs have died
        # so it can restart connected tabs properly.
        self._died_dict = {}

        # A dictionary to match closed pids with their replacement pid.
        self._closed_pid_dict = {}

        # Add an extra keyboard shortcut to open alternative tabs
        keyval, modifier = gtk.accelerator_parse('<Control><Alt>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE, 
                self._new_tab_key_pressed)
        keyval, modifier = gtk.accelerator_parse('<Control><Shift><Alt>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE, 
                self._new_tab_key_pressed)
        keyval, modifier = gtk.accelerator_parse('<Control><Mod4>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE, 
                self._new_tab_key_pressed)
        
        # Setup the python executable to use for external tabs.
        #self._pyexec = subprocess.Popen(['which', 'python2'], 
                #stdout=subprocess.PIPE).communicate()[0].strip()
        self._pyexec = sys.executable

        if uri:
            # Open a tab if there was a uri given.
            self.do_open_tab(uri=uri)
Example #3
0
class Browser(BrowserBase):
    """ Main browser handles starting and exiting and opening and closing
    tabs.  It also handles the downloads, debug terminal, and bookmarks.

    """

    # Make a global of the dbus interface name used to open new tabs
    INTERFACE = "com.browser.main%d"

    def __init__(self,
                 bus=None,
                 uri=None,
                 profile='default',
                 width=1213,
                 height=628):
        """ Browser(bus=None, uri=None, profile='default', width=1213, 
        height=628) -> 
        Main browser window of size 'width'x'height' embed browser tab 'pid'
        and use dbus 'bus' to communicate with the external tabs.

        """

        super(Browser, self).__init__(uri=uri,
                                      profile=profile,
                                      width=width,
                                      height=height)

        # Connect the dbus receiver to allow opening new tabs from external
        # tabs.
        if bus:
            self._receiver = BrowserReceiver(bus, '/main_browser%s' % id(self))
            self._receiver.connect('get-socket-id', self._get_socket_id)

            # Connect dbus to bus.
            self._connect_dbus(bus)
            self._bus = bus

        # Should we use a proxy.
        self._no_proxy = True
        self._proxy = os.environ.get('http_proxy', '')
        os.environ['http_proxy'] = ''

        # This dictionary is used to keep track of which tabs have died
        # so it can restart connected tabs properly.
        self._died_dict = {}

        # A dictionary to match closed pids with their replacement pid.
        self._closed_pid_dict = {}

        # Add an extra keyboard shortcut to open alternative tabs
        keyval, modifier = gtk.accelerator_parse('<Control><Alt>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE,
                                   self._new_tab_key_pressed)
        keyval, modifier = gtk.accelerator_parse('<Control><Shift><Alt>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE,
                                   self._new_tab_key_pressed)
        keyval, modifier = gtk.accelerator_parse('<Control><Mod4>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE,
                                   self._new_tab_key_pressed)

        # Setup the python executable to use for external tabs.
        #self._pyexec = subprocess.Popen(['which', 'python2'],
        #stdout=subprocess.PIPE).communicate()[0].strip()
        self._pyexec = sys.executable

        if uri:
            # Open a tab if there was a uri given.
            self.do_open_tab(uri=uri)

        #self._window.set_colormap(self._window.get_screen().get_rgba_colormap())

    def _connect_dbus(self, bus, disconnect=False):
        """ _connect_dbus(bus, disconnect=False) -> Connect the internal 
        dbus bus.  Internal dbus bus is used by external tabs to send debug 
        messages.

        """

        bus_receiver_dict = {
            'print_message_signal': self._receive_print_message,
        }

        for signal_name, handler_func in bus_receiver_dict.iteritems():
            if disconnect:
                bus.remove_signal_receiver(handler_func,
                                           dbus_interface=Browser.INTERFACE %
                                           os.getpid(),
                                           signal_name=signal_name,
                                           path='/bplug_sender%s' % id(self))
            else:
                bus.add_signal_receiver(handler_func,
                                        dbus_interface=Browser.INTERFACE %
                                        os.getpid(),
                                        signal_name=signal_name,
                                        path='/bplug_sender%s' % id(self))

    def _clean_died_dict(self, pid):
        """ _clean_died_dict(pid) -> Clean the dictionary of dead tabs of
        tab pid.  If a tab dies its old and new pids are stored in the 
        died_dict.  This function cleans already restarted tabs out of
        that dictionary.

        """

        if pid in self._died_dict.values():
            # The pid has died.
            for oldpid, newpid in self._died_dict.iteritems():
                if pid == newpid:
                    # When pid == newpid than oldpid should be removed
                    self._died_dict.pop(oldpid)
                    break

    def _receive_print_message(self, message, color, data_color):
        """ _receive_print_message(message, color, data_color) -> Log message
        to the debug console.  'color' is used to differentiate between a tabs
        message and the main windows message, and 'data_color' is for 
        different types of messages.

        """

        self.print_message(message, color, data_color)

    def _get_socket_id(self, receiver, pid):
        """ _get_socket_id(receiver, pid) -> Open a new tab for the external 
        tab with a pid of 'pid'.  This function returns the socket id of the 
        new tab's socket.
        
        """

        # Just send a normal tab.
        return self.do_open_tab(pid=pid, popup=True,
                                tab=BrowserSock()).get_socket_id()

    def _browser_plug_died(self, browsebox, oldpid):
        """ _browser_plug_died(browsebox, oldpid) -> When an external tab's
        browser dies this function is called to start a new one.  The old
        pid is associated with the new pid in the died_dict so any tabs that
        share the same pid can be restarted properly.

        """

        newpid = self._died_dict.get(oldpid, None)
        newpid = self.setup_plug(browsebox, pid=newpid, died=True)
        self._died_dict[oldpid] = newpid
        self._clean_died_dict(oldpid)

    def do_browser_closed(self, browsebox):
        """ do_browser_closed(browsebox) -> Clean up after a tab is closed.

        """

        if type(browsebox) == BrowserSock:
            self._clean_died_dict(browsebox.get_pid())
        else:
            self.print_message("main: tab closed", MSGCOLOR)

    def new_tab(self, uri=None, popup=False, history_str='', history_index=1):
        """ new_tab(uri=None, popup=False, history_str='', history_index=1) 
        -> Open a new internal tab.  Load uri in the new tab and if popup is 
        True and uri is empty open the tab in the foreground.  history_index 
        is the index in the history to load when the tab opens.  history_str 
        is a string containing the history to copy to the new tab.

        """

        browsebox = BrowserTab(popup=popup,
                               uri=uri,
                               history_str=history_str,
                               history_index=history_index,
                               profile=self._profile)

        self.do_new_tab(browsebox, uri, popup)

        self.print_message("main: tab added", MSGCOLOR)

        return browsebox

    def _start_plug(self):
        """ _start_plug() -> Start external browser to embed in a tab.
        Returns the pid of the new process.

        """

        tabcmd = [
            self._pyexec,
            '%s/browserplug.py' % self._path,
            '%s' % id(self)
        ]
        env_dict = os.environ
        if not self._no_proxy:
            env_dict['http_proxy'] = self._proxy
            self._no_proxy = True
        bplug = subprocess.Popen(tabcmd, env=env_dict)
        env_dict['http_proxy'] = ''

        return bplug.pid

    def setup_plug(self, browsebox, pid=None, died=False):
        """ setup_plug(browsebox, pid=None, died=False) -> Setup a plug to
        embed in a tab.  If the pid is set then the plug is started and it
        just needs to start a new browser instance to embed.  Otherwise start
        a new plug.

        """

        if not pid:
            pid = self._start_plug()
        elif not died:
            while True:
                try:
                    browsebox.setup_socket(pid)
                    break
                except:
                    pass
        browsebox.set_pid(pid)

        return pid

    def new_tab_plug(self,
                     uri=None,
                     pid=None,
                     popup=False,
                     history_str='',
                     history_index=1):
        """ new_tab_plug(uri=None, pid=None, popup=False, history_str='', 
        history_index=1) -> Start a new  external tab.  Open a shared tab if 
        pid is set. If set, load history item of index 'history_index' or uri 
        if set.  history_str is a string containing the history to copy to 
        the new tab.

        """

        browsebox = BrowserSock(popup=popup,
                                uri=uri,
                                history_str=history_str,
                                history_index=history_index,
                                profile=self._profile)

        # Connect extra signals.
        connection_dict = {
            'browser-plug-died': self._browser_plug_died,
        }
        for signal, callback in connection_dict.iteritems():
            browsebox.connect(signal, callback)

        self.do_new_tab(browsebox, uri, popup)
        self.setup_plug(browsebox, pid)

        self.print_message("main socket_id: %d" % browsebox.get_socket_id(),
                           MSGCOLOR)

        return browsebox

    def do_open_tab(self,
                    flags=0,
                    tab=None,
                    uri=None,
                    popup=False,
                    pid=None,
                    history_str='',
                    history_index=1,
                    button=None,
                    tab_type=None):
        """ do_open_tab(flags=0, tab=None, uri=None, popup=False, 
        pid=None, history_str='', history_index=1 tab_type=None) ->
        Open a new tab.  If flags indecates that alt was held than a tab
        of a different type than tab will be opened.  Load uri in the new tab
        or history item history_index.

        """

        if button == 2:
            # Get selected text (primary clipboard)
            clipboard = gtk.clipboard_get(selection='PRIMARY')
            clipboard_text = clipboard.wait_for_text()

            # Load selection
            if clipboard_text:
                # Load selected text in address entry
                uri = clipboard_text

        if not tab and not tab_type:
            tab = self._current_tab

        if not gtk.gdk.SHIFT_MASK & flags:
            # The new tab is only going to have back history.
            history_index = 1
        else:
            # If shift was held down, and 'history_str' is not set, than
            # copy the history of 'tab' into the new tab.
            if not history_str:
                if tab:
                    history_str = tab.do_get_history(history_index)
                else:
                    history_str = self._current_tab.do_get_history(
                        history_index)
            if hasattr(tab, 'get_pid'):
                pid = tab.get_pid()
            elif hasattr(self._current_tab, 'get_pid'):
                pid = self._current_tab.get_pid()

        if type(tab) == BrowserSock or tab_type == 'BrowserSock':
            if gtk.gdk.MOD1_MASK & flags:
                # Open an internal tab because the alt key was pressed
                new_tab = self.new_tab(uri=uri,
                                       popup=popup,
                                       history_str=history_str,
                                       history_index=history_index)
            else:
                if gtk.gdk.MOD4_MASK & flags:
                    self._no_proxy = False
                new_tab = self.new_tab_plug(uri=uri,
                                            pid=pid,
                                            popup=popup,
                                            history_str=history_str,
                                            history_index=history_index)
        else:
            if gtk.gdk.MOD1_MASK & flags or gtk.gdk.MOD4_MASK & flags:
                if gtk.gdk.MOD4_MASK & flags:
                    self._no_proxy = False
                # Open an external tab because the alt key was pressed
                new_tab = self.new_tab_plug(uri=uri,
                                            popup=popup,
                                            history_str=history_str,
                                            history_index=history_index)
            else:
                new_tab = self.new_tab(uri=uri,
                                       popup=popup,
                                       history_str=history_str,
                                       history_index=history_index)

        return new_tab

    def do_restore_tab(self, tab_dict, flags):
        """ do_restore_tab(tab_dict, flags) -> Restores a tab based on 
        'tab_dict'.  'flags' holds the key masks of the modifier keys that 
        were pressed.

        """

        info_list = tab_dict['info_list']
        if isinstance(info_list, dict):
            # New type
            tab_pid = info_list['pid']
            tab_state = info_list['state']
            hist_list = info_list['history']
        else:
            tab_pid, tab_state, hist_list = info_list

        history_str = json.dumps(hist_list)
        tab_index = int(tab_dict['index'])

        if tab_pid:
            pid = None
            tab_pid = int(tab_pid)
            new_pid = self._closed_pid_dict.get(tab_pid, None)
            for tab in self._browser_book.get_children():
                if hasattr(tab, 'get_pid'):
                    if tab.get_pid() == tab_pid:
                        pid = tab_pid
                        break
                    elif tab.get_pid() == new_pid:
                        pid = new_pid
                        break
            browsebox = self.do_open_tab(tab_type='BrowserSock',
                                         pid=pid,
                                         history_str=history_str,
                                         flags=flags)
            if hasattr(browsebox, 'get_pid'):
                self._closed_pid_dict[tab_pid] = browsebox.get_pid()
        else:
            browsebox = self.do_open_tab(tab_type='BrowserTab',
                                         flags=flags,
                                         history_str=history_str)

        self._browser_book.reorder_child(browsebox, tab_index)
        self._browser_book.set_tab_state(browsebox, tab_state)

    def do_exit(self):
        """ Disconnect dbus handlers.
        
        """

        self._connect_dbus(self._bus, disconnect=True)

    def do_create_window(self, browsebox=None, uri=None):
        """ Create a new window.

        """

        if browsebox:
            if browsebox.type == 'BrowserSock':
                return None

        return create_window(self._bus, uri=uri)
Example #4
0
class Browser(BrowserBase):
    """ Main browser handles starting and exiting and opening and closing
    tabs.  It also handles the downloads, debug terminal, and bookmarks.

    """

    # Make a global of the dbus interface name used to open new tabs
    INTERFACE = "com.browser.main%d"

    def __init__(self, bus=None, uri=None, profile='default', width=1213, 
            height=628):
        """ Browser(bus=None, uri=None, profile='default', width=1213, 
        height=628) -> 
        Main browser window of size 'width'x'height' embed browser tab 'pid'
        and use dbus 'bus' to communicate with the external tabs.

        """

        super(Browser, self).__init__(uri=uri, profile=profile, width=width, 
                height=height)

        # Connect the dbus receiver to allow opening new tabs from external
        # tabs.
        if bus:
            self._receiver = BrowserReceiver(bus, '/main_browser%s' % id(self))
            self._receiver.connect('get-socket-id', self._get_socket_id)

            # Connect dbus to bus.
            self._connect_dbus(bus)
            self._bus = bus

        # Should we use a proxy.
        self._no_proxy = True
        self._proxy = os.environ.get('http_proxy', '')
        os.environ['http_proxy'] = ''

        # This dictionary is used to keep track of which tabs have died
        # so it can restart connected tabs properly.
        self._died_dict = {}

        # A dictionary to match closed pids with their replacement pid.
        self._closed_pid_dict = {}

        # Add an extra keyboard shortcut to open alternative tabs
        keyval, modifier = gtk.accelerator_parse('<Control><Alt>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE, 
                self._new_tab_key_pressed)
        keyval, modifier = gtk.accelerator_parse('<Control><Shift><Alt>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE, 
                self._new_tab_key_pressed)
        keyval, modifier = gtk.accelerator_parse('<Control><Mod4>t')
        self._accels.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE, 
                self._new_tab_key_pressed)
        
        # Setup the python executable to use for external tabs.
        #self._pyexec = subprocess.Popen(['which', 'python2'], 
                #stdout=subprocess.PIPE).communicate()[0].strip()
        self._pyexec = sys.executable

        if uri:
            # Open a tab if there was a uri given.
            self.do_open_tab(uri=uri)

        #self._window.set_colormap(self._window.get_screen().get_rgba_colormap())
    
    def _connect_dbus(self, bus, disconnect=False):
        """ _connect_dbus(bus, disconnect=False) -> Connect the internal 
        dbus bus.  Internal dbus bus is used by external tabs to send debug 
        messages.

        """

        bus_receiver_dict = {
                'print_message_signal': self._receive_print_message,
                }

        for signal_name, handler_func in bus_receiver_dict.iteritems():
            if disconnect:
                bus.remove_signal_receiver(handler_func, 
                        dbus_interface=Browser.INTERFACE % os.getpid(), 
                        signal_name=signal_name,
                        path='/bplug_sender%s' % id(self))
            else:
                bus.add_signal_receiver(handler_func, 
                        dbus_interface=Browser.INTERFACE % os.getpid(), 
                        signal_name=signal_name,
                        path='/bplug_sender%s' % id(self))

    def _clean_died_dict(self, pid):
        """ _clean_died_dict(pid) -> Clean the dictionary of dead tabs of
        tab pid.  If a tab dies its old and new pids are stored in the 
        died_dict.  This function cleans already restarted tabs out of
        that dictionary.

        """

        if pid in self._died_dict.values():
            # The pid has died.
            for oldpid, newpid in self._died_dict.iteritems():
                if pid == newpid:
                    # When pid == newpid than oldpid should be removed
                    self._died_dict.pop(oldpid)
                    break

    def _receive_print_message(self, message, color, data_color):
        """ _receive_print_message(message, color, data_color) -> Log message
        to the debug console.  'color' is used to differentiate between a tabs
        message and the main windows message, and 'data_color' is for 
        different types of messages.

        """

        self.print_message(message, color, data_color)

    def _get_socket_id(self, receiver, pid):
        """ _get_socket_id(receiver, pid) -> Open a new tab for the external 
        tab with a pid of 'pid'.  This function returns the socket id of the 
        new tab's socket.
        
        """

        # Just send a normal tab.
        return self.do_open_tab(pid=pid, popup=True, 
                tab=BrowserSock()).get_socket_id()
            
    def _browser_plug_died(self, browsebox, oldpid):
        """ _browser_plug_died(browsebox, oldpid) -> When an external tab's
        browser dies this function is called to start a new one.  The old
        pid is associated with the new pid in the died_dict so any tabs that
        share the same pid can be restarted properly.

        """

        newpid = self._died_dict.get(oldpid, None)
        newpid = self.setup_plug(browsebox, pid=newpid, died=True)
        self._died_dict[oldpid] = newpid
        self._clean_died_dict(oldpid)

    def do_browser_closed(self, browsebox):
        """ do_browser_closed(browsebox) -> Clean up after a tab is closed.

        """

        if type(browsebox) == BrowserSock:
            self._clean_died_dict(browsebox.get_pid())
        else:
            self.print_message("main: tab closed", MSGCOLOR)

    def new_tab(self, uri=None, popup=False, history_str='', history_index=1):
        """ new_tab(uri=None, popup=False, history_str='', history_index=1) 
        -> Open a new internal tab.  Load uri in the new tab and if popup is 
        True and uri is empty open the tab in the foreground.  history_index 
        is the index in the history to load when the tab opens.  history_str 
        is a string containing the history to copy to the new tab.

        """

        browsebox = BrowserTab(popup=popup, uri=uri, 
                history_str=history_str, history_index=history_index,
                profile=self._profile)

        self.do_new_tab(browsebox, uri, popup)

        self.print_message("main: tab added", MSGCOLOR)

        return browsebox

    def _start_plug(self):
        """ _start_plug() -> Start external browser to embed in a tab.
        Returns the pid of the new process.

        """

        tabcmd = [self._pyexec, '%s/browserplug.py' % self._path, '%s' % id(self)]
        env_dict = os.environ
        if not self._no_proxy:
            env_dict['http_proxy'] = self._proxy
            self._no_proxy = True
        bplug = subprocess.Popen(tabcmd, env=env_dict)
        env_dict['http_proxy'] = ''

        return bplug.pid

    def setup_plug(self, browsebox, pid=None, died=False):
        """ setup_plug(browsebox, pid=None, died=False) -> Setup a plug to
        embed in a tab.  If the pid is set then the plug is started and it
        just needs to start a new browser instance to embed.  Otherwise start
        a new plug.

        """

        if not pid:
            pid = self._start_plug()
        elif not died:
            while True:
                try:
                    browsebox.setup_socket(pid)
                    break
                except:
                    pass
        browsebox.set_pid(pid)

        return pid

    def new_tab_plug(self, uri=None, pid=None, popup=False, history_str='', 
            history_index=1):
        """ new_tab_plug(uri=None, pid=None, popup=False, history_str='', 
        history_index=1) -> Start a new  external tab.  Open a shared tab if 
        pid is set. If set, load history item of index 'history_index' or uri 
        if set.  history_str is a string containing the history to copy to 
        the new tab.

        """

        browsebox = BrowserSock(popup=popup, uri=uri, 
                history_str=history_str, history_index=history_index,
                profile=self._profile)
        
        # Connect extra signals.
        connection_dict = {
                'browser-plug-died': self._browser_plug_died,
                }
        for signal, callback in connection_dict.iteritems():
            browsebox.connect(signal, callback)

        self.do_new_tab(browsebox, uri, popup)
        self.setup_plug(browsebox, pid)

        self.print_message("main socket_id: %d" % browsebox.get_socket_id(), 
                MSGCOLOR)

        return browsebox

    def do_open_tab(self, flags=0, tab=None, uri=None, popup=False, 
            pid=None, history_str='', history_index=1, button=None,
            tab_type=None):
        """ do_open_tab(flags=0, tab=None, uri=None, popup=False, 
        pid=None, history_str='', history_index=1 tab_type=None) ->
        Open a new tab.  If flags indecates that alt was held than a tab
        of a different type than tab will be opened.  Load uri in the new tab
        or history item history_index.

        """

        if button == 2:
            # Get selected text (primary clipboard)
            clipboard = gtk.clipboard_get(selection='PRIMARY')
            clipboard_text = clipboard.wait_for_text()

            # Load selection
            if clipboard_text:
                # Load selected text in address entry
                uri = clipboard_text

        if not tab and not tab_type:
            tab = self._current_tab

        if not gtk.gdk.SHIFT_MASK & flags:
            # The new tab is only going to have back history.
            history_index = 1
        else:
            # If shift was held down, and 'history_str' is not set, than 
            # copy the history of 'tab' into the new tab.
            if not history_str:
                if tab:
                    history_str = tab.do_get_history(history_index)
                else:
                    history_str = self._current_tab.do_get_history(history_index)
            if hasattr(tab, 'get_pid'):
                pid = tab.get_pid()
            elif hasattr(self._current_tab, 'get_pid'):
                pid = self._current_tab.get_pid()

        if type(tab) == BrowserSock or tab_type == 'BrowserSock':
            if gtk.gdk.MOD1_MASK & flags:
                # Open an internal tab because the alt key was pressed
                new_tab = self.new_tab(uri=uri, popup=popup, 
                        history_str=history_str, history_index=history_index) 
            else:
                if gtk.gdk.MOD4_MASK & flags:
                    self._no_proxy = False
                new_tab = self.new_tab_plug(uri=uri, pid=pid, popup=popup, 
                        history_str=history_str, history_index=history_index) 
        else:
            if gtk.gdk.MOD1_MASK & flags or gtk.gdk.MOD4_MASK & flags:
                if gtk.gdk.MOD4_MASK & flags:
                    self._no_proxy = False
                # Open an external tab because the alt key was pressed
                new_tab = self.new_tab_plug(uri=uri, popup=popup, 
                        history_str=history_str, history_index=history_index)
            else:
                new_tab = self.new_tab(uri=uri, popup=popup, 
                        history_str=history_str, history_index=history_index)

        return new_tab

    def do_restore_tab(self, tab_dict, flags):
        """ do_restore_tab(tab_dict, flags) -> Restores a tab based on 
        'tab_dict'.  'flags' holds the key masks of the modifier keys that 
        were pressed.

        """
        
        info_list = tab_dict['info_list']
        if isinstance(info_list, dict):
            # New type
            tab_pid = info_list['pid']
            tab_state = info_list['state']
            hist_list = info_list['history']
        else:
            tab_pid, tab_state, hist_list = info_list

        history_str = json.dumps(hist_list)
        tab_index = int(tab_dict['index'])

        if tab_pid:
            pid = None
            tab_pid = int(tab_pid)
            new_pid = self._closed_pid_dict.get(tab_pid, None)
            for tab in self._browser_book.get_children():
                if hasattr(tab, 'get_pid'):
                    if tab.get_pid() == tab_pid:
                        pid = tab_pid
                        break
                    elif tab.get_pid() == new_pid:
                        pid = new_pid
                        break
            browsebox = self.do_open_tab(tab_type='BrowserSock', pid=pid, 
                    history_str=history_str, flags=flags)
            if hasattr(browsebox, 'get_pid'):
                self._closed_pid_dict[tab_pid] = browsebox.get_pid()
        else:
            browsebox = self.do_open_tab(tab_type='BrowserTab', flags=flags, 
                    history_str=history_str)

        self._browser_book.reorder_child(browsebox, tab_index)
        self._browser_book.set_tab_state(browsebox, tab_state)

    def do_exit(self):
        """ Disconnect dbus handlers.
        
        """

        self._connect_dbus(self._bus, disconnect=True)

    def do_create_window(self, browsebox=None, uri=None):
        """ Create a new window.

        """

        if browsebox:
            if browsebox.type == 'BrowserSock':
                return None

        return create_window(self._bus, uri=uri)