More window support.

This commit is contained in:
Florian Bruhin 2014-10-06 17:58:40 +02:00
parent 2cd4642ece
commit 6324751af6
5 changed files with 86 additions and 43 deletions

View File

@ -28,7 +28,7 @@ It was inspired by other browsers/addons like dwb and Vimperator/Pentadactyl.
Commands to execute on startup.
*'URL'*::
URLs to open on startup.
URLs to open on startup (empty as a window separator).
=== optional arguments
*-h*, *--help*::

View File

@ -63,10 +63,19 @@ class CommandDispatcher:
def __repr__(self):
return utils.get_repr(self)
def _tabbed_browser(self):
"""Convienence method to get the right tabbed-browser."""
return objreg.get('tabbed-browser', scope='window',
window=self._win_id)
def _tabbed_browser(self, window=False):
"""Convienence method to get the right tabbed-browser.
Args:
window: If True, open a new window.
"""
if window:
# We have to import this here to avoid a circular import.
from qutebrowser.widgets import mainwindow
win_id = mainwindow.create_window(True)
else:
win_id = self._win_id
return objreg.get('tabbed-browser', scope='window', window=win_id)
def _count(self):
"""Convenience method to get the widget count."""
@ -104,11 +113,7 @@ class CommandDispatcher:
if sum(1 for e in (tab, background, window) if e) > 1:
raise cmdexc.CommandError("Only one of -t/-b/-w can be given!")
elif window:
# We have to import this here to avoid a circular import.
from qutebrowser.widgets import mainwindow
win_id = mainwindow.create_window(True)
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=win_id)
tabbed_browser = self._tabbed_browser(window=True)
tabbed_browser.tabopen(url)
elif tab:
tabbed_browser.tabopen(url, background=False, explicit=True)
@ -302,26 +307,29 @@ class CommandDispatcher:
diag.open(lambda: tab.print(diag.printer()))
@cmdutils.register(instance='command-dispatcher', scope='window')
def tab_clone(self, bg=False):
def tab_clone(self, bg=False, window=False):
"""Duplicate the current tab.
Args:
bg: Open in a background tab.
window: Open in a new window.
Return:
The new QWebView.
"""
if bg and window:
raise cmdexc.CommandError("Only one of -b/-w can be given!")
curtab = self._current_widget()
tabbed_browser = self._tabbed_browser()
tabbed_browser = self._tabbed_browser(window)
newtab = tabbed_browser.tabopen(background=bg, explicit=True)
history = qtutils.serialize(curtab.history())
qtutils.deserialize(history, newtab.history())
return newtab
def _back_forward(self, tab, bg, count, forward):
def _back_forward(self, tab, bg, window, count, forward):
"""Helper function for :back/:forward."""
if tab or bg:
widget = self.tab_clone(bg)
if tab or bg or window:
widget = self.tab_clone(bg, window)
else:
widget = self._current_widget()
for _ in range(count):
@ -331,34 +339,38 @@ class CommandDispatcher:
widget.go_back()
@cmdutils.register(instance='command-dispatcher', scope='window')
def back(self, tab=False, bg=False, count=1):
def back(self, tab=False, bg=False, window=False, count=1):
"""Go back in the history of the current tab.
Args:
tab: Go back in a new tab.
bg: Go back in a background tab.
window: Go back in a new window.
count: How many pages to go back.
"""
self._back_forward(tab, bg, count, forward=False)
self._back_forward(tab, bg, window, count, forward=False)
@cmdutils.register(instance='command-dispatcher', scope='window')
def forward(self, tab=False, bg=False, count=1):
def forward(self, tab=False, bg=False, window=False, count=1):
"""Go forward in the history of the current tab.
Args:
tab: Go forward in a new tab.
bg: Go back in a background tab.
bg: Go forward in a background tab.
window: Go forward in a new window.
count: How many pages to go forward.
"""
self._back_forward(tab, bg, count, forward=True)
self._back_forward(tab, bg, window, count, forward=True)
def _navigate_incdec(self, url, tab, incdec):
def _navigate_incdec(self, url, incdec, tab, background, window):
"""Helper method for :navigate when `where' is increment/decrement.
Args:
url: The current url.
tab: Whether to open the link in a new tab.
incdec: Either 'increment' or 'decrement'.
tab: Whether to open the link in a new tab.
background: Open the link in a new background tab.
window: Open the link in a new window.
"""
encoded = bytes(url.toEncoded()).decode('ascii')
# Get the last number in a string
@ -383,25 +395,27 @@ class CommandDispatcher:
raise ValueError("Invalid value {} for indec!".format(incdec))
urlstr = ''.join([pre, str(val), post]).encode('ascii')
new_url = QUrl.fromEncoded(urlstr)
self._open(new_url, tab, background=False, window=False)
self._open(new_url, tab, background, window)
def _navigate_up(self, url, tab):
def _navigate_up(self, url, tab, background, window):
"""Helper method for :navigate when `where' is up.
Args:
url: The current url.
tab: Whether to open the link in a new tab.
background: Open the link in a new background tab.
window: Open the link in a new window.
"""
path = url.path()
if not path or path == '/':
raise cmdexc.CommandError("Can't go up!")
new_path = posixpath.join(path, posixpath.pardir)
url.setPath(new_path)
self._open(url, tab, background=False, window=False)
self._open(url, tab, background, window)
@cmdutils.register(instance='command-dispatcher', scope='window')
def navigate(self, where: ('prev', 'next', 'up', 'increment', 'decrement'),
tab=False):
tab=False, bg=False, window=False):
"""Open typical prev/next links or navigate using the URL path.
This tries to automatically click on typical _Previous Page_ or
@ -419,7 +433,11 @@ class CommandDispatcher:
- `decrement`: Decrement the last number in the URL.
tab: Open in a new tab.
bg: Open in a background tab.
window: Open in a new window.
"""
if sum(1 for e in (tab, bg, window) if e) > 1:
raise cmdexc.CommandError("Only one of -t/-b/-w can be given!")
widget = self._current_widget()
frame = widget.page().currentFrame()
url = self._current_url()
@ -427,13 +445,15 @@ class CommandDispatcher:
raise cmdexc.CommandError("No frame focused!")
hintmanager = objreg.get('hintmanager', scope='tab')
if where == 'prev':
hintmanager.follow_prevnext(frame, url, prev=True, newtab=tab)
hintmanager.follow_prevnext(frame, url, prev=True, tab=tab,
background=background, window=window)
elif where == 'next':
hintmanager.follow_prevnext(frame, url, prev=False, newtab=tab)
hintmanager.follow_prevnext(frame, url, prev=False, tab=tab,
background=background, window=window)
elif where == 'up':
self._navigate_up(url, tab)
self._navigate_up(url, tab, background, window)
elif where in ('decrement', 'increment'):
self._navigate_incdec(url, tab, where)
self._navigate_incdec(url, where, tab, background, window)
else:
raise ValueError("Got called with invalid value {} for "
"`where'.".format(where))

View File

@ -37,7 +37,7 @@ from qutebrowser.utils import usertypes, log, qtutils, message, objreg
ElemTuple = collections.namedtuple('ElemTuple', ['elem', 'label'])
Target = usertypes.enum('Target', ['normal', 'tab', 'tab_bg', 'yank',
Target = usertypes.enum('Target', ['normal', 'tab', 'tab_bg', 'window', 'yank',
'yank_primary', 'fill', 'rapid', 'download',
'userscript', 'spawn'])
@ -58,7 +58,7 @@ class HintContext:
elems: A mapping from keystrings to (elem, label) namedtuples.
baseurl: The URL of the current page.
target: What to do with the opened links.
normal/tab/tab_bg: Get passed to BrowserTab.
normal/tab/tab_bg/window: Get passed to BrowserTab.
yank/yank_primary: Yank to clipboard/primary selection
fill: Fill commandline with link.
rapid: Rapid mode with background tabs
@ -127,6 +127,7 @@ class HintManager(QObject):
Target.normal: "Follow hint...",
Target.tab: "Follow hint in new tab...",
Target.tab_bg: "Follow hint in background tab...",
Target.window: "Follow hint in new window...",
Target.yank: "Yank hint to clipboard...",
Target.yank_primary: "Yank hint to primary selection...",
Target.fill: "Set hint in commandline...",
@ -500,14 +501,17 @@ class HintManager(QObject):
keyparser = keyparsers[usertypes.KeyMode.hint]
keyparser.update_bindings(strings)
def follow_prevnext(self, frame, baseurl, prev=False, newtab=False):
def follow_prevnext(self, frame, baseurl, prev=False, tab=False,
background=False, window=False):
"""Click a "previous"/"next" element on the page.
Args:
frame: The frame where the element is in.
baseurl: The base URL of the current tab.
prev: True to open a "previous" link, False to open a "next" link.
newtab: True to open in a new tab, False for the current tab.
tab: True to open in a new tab, False for the current tab.
background: True to open in a background tab.
window: True to open in a new window, False for the current one.
"""
elem = self._find_prevnext(frame, prev)
if elem is None:
@ -518,13 +522,21 @@ class HintManager(QObject):
raise cmdexc.CommandError("No {} links found!".format(
"prev" if prev else "forward"))
qtutils.ensure_valid(url)
if newtab:
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=self._win_id)
tabbed_browser.tabopen(url, background=False)
if window:
# We have to import this here to avoid a circular import.
from qutebrowser.widgets import mainwindow
win_id = mainwindow.create_window(True)
tab_id = 0
else:
webview = objreg.get('webview', scope='tab', window=self._win_id,
tab=self._tab_id)
win_id = self._win_id
tab_id = self._tab_id
if tab:
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=win_id)
tabbed_browser.tabopen(url, background=background)
else:
webview = objreg.get('webview', scope='tab', window=win_id,
tab=tab_id)
webview.openurl(url)
@cmdutils.register(instance='hintmanager', scope='tab', name='hint')
@ -544,6 +556,7 @@ class HintManager(QObject):
- `normal`: Open the link in the current tab.
- `tab`: Open the link in a new tab.
- `tab-bg`: Open the link in a new background tab.
- `window`: Open the link in a new window.
- `yank`: Yank the link to the clipboard.
- `yank-primary`: Yank the link to the primary selection.
- `fill`: Fill the commandline with the command given as
@ -650,6 +663,7 @@ class HintManager(QObject):
Target.normal: self._click,
Target.tab: self._click,
Target.tab_bg: self._click,
Target.window: self._click,
Target.rapid: self._click,
# _download needs a QWebElement to get the frame.
Target.download: self._download,

View File

@ -302,11 +302,20 @@ class BrowserPage(QWebPage):
return False
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=self._win_id)
if self.view().open_target == usertypes.ClickTarget.tab:
open_target = self.view().open_target
if open_target == usertypes.ClickTarget.tab:
tabbed_browser.tabopen(url, False)
return False
elif self.view().open_target == usertypes.ClickTarget.tab_bg:
elif open_target == usertypes.ClickTarget.tab_bg:
tabbed_browser.tabopen(url, True)
return False
elif open_target == usertypes.ClickTarget.window:
# We have to import this here to avoid a circular import.
from qutebrowser.widgets import mainwindow
win_id = mainwindow.create_window(True)
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=win_id)
tabbed_browser.openurl(url, False)
return False
else:
return True

View File

@ -228,7 +228,7 @@ PromptMode = enum('PromptMode', ['yesno', 'text', 'user_pwd', 'alert'])
# Where to open a clicked link.
ClickTarget = enum('ClickTarget', ['normal', 'tab', 'tab_bg'])
ClickTarget = enum('ClickTarget', ['normal', 'tab', 'tab_bg', 'window'])
# Key input modes