Merge branch 'master' of https://github.com/djfinlay/qutebrowser into djfinlay-master
This commit is contained in:
commit
a83b86085a
@ -206,6 +206,7 @@ Contributors, sorted by the number of commits in descending order:
|
|||||||
* Jan Verbeek
|
* Jan Verbeek
|
||||||
* Fritz V155 Reichwald
|
* Fritz V155 Reichwald
|
||||||
* Franz Fellner
|
* Franz Fellner
|
||||||
|
* Daryl Finlay
|
||||||
* zwarag
|
* zwarag
|
||||||
* xd1le
|
* xd1le
|
||||||
* oniondreams
|
* oniondreams
|
||||||
|
@ -637,6 +637,7 @@ The format to use for the window title. The following placeholders are defined:
|
|||||||
* `{title_sep}`: The string ` - ` if a title is set, empty otherwise.
|
* `{title_sep}`: The string ` - ` if a title is set, empty otherwise.
|
||||||
* `{id}`: The internal window ID of this window.
|
* `{id}`: The internal window ID of this window.
|
||||||
* `{scroll_pos}`: The page scroll position.
|
* `{scroll_pos}`: The page scroll position.
|
||||||
|
* `{host}`: The host of the current web page.
|
||||||
|
|
||||||
Default: +pass:[{perc}{title}{title_sep}qutebrowser]+
|
Default: +pass:[{perc}{title}{title_sep}qutebrowser]+
|
||||||
|
|
||||||
@ -1153,6 +1154,7 @@ The format to use for the tab title. The following placeholders are defined:
|
|||||||
* `{index}`: The index of this tab.
|
* `{index}`: The index of this tab.
|
||||||
* `{id}`: The internal tab ID of this tab.
|
* `{id}`: The internal tab ID of this tab.
|
||||||
* `{scroll_pos}`: The page scroll position.
|
* `{scroll_pos}`: The page scroll position.
|
||||||
|
* `{host}`: The host of the current web page.
|
||||||
|
|
||||||
Default: +pass:[{index}: {title}]+
|
Default: +pass:[{index}: {title}]+
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ def data(readonly=False):
|
|||||||
('window-title-format',
|
('window-title-format',
|
||||||
SettingValue(typ.FormatString(fields=['perc', 'perc_raw', 'title',
|
SettingValue(typ.FormatString(fields=['perc', 'perc_raw', 'title',
|
||||||
'title_sep', 'id',
|
'title_sep', 'id',
|
||||||
'scroll_pos']),
|
'scroll_pos', 'host']),
|
||||||
'{perc}{title}{title_sep}qutebrowser'),
|
'{perc}{title}{title_sep}qutebrowser'),
|
||||||
"The format to use for the window title. The following "
|
"The format to use for the window title. The following "
|
||||||
"placeholders are defined:\n\n"
|
"placeholders are defined:\n\n"
|
||||||
@ -340,7 +340,8 @@ def data(readonly=False):
|
|||||||
"* `{title_sep}`: The string ` - ` if a title is set, empty "
|
"* `{title_sep}`: The string ` - ` if a title is set, empty "
|
||||||
"otherwise.\n"
|
"otherwise.\n"
|
||||||
"* `{id}`: The internal window ID of this window.\n"
|
"* `{id}`: The internal window ID of this window.\n"
|
||||||
"* `{scroll_pos}`: The page scroll position."),
|
"* `{scroll_pos}`: The page scroll position.\n"
|
||||||
|
"* `{host}`: The host of the current web page."),
|
||||||
|
|
||||||
('hide-mouse-cursor',
|
('hide-mouse-cursor',
|
||||||
SettingValue(typ.Bool(), 'false'),
|
SettingValue(typ.Bool(), 'false'),
|
||||||
@ -627,7 +628,7 @@ def data(readonly=False):
|
|||||||
('title-format',
|
('title-format',
|
||||||
SettingValue(typ.FormatString(
|
SettingValue(typ.FormatString(
|
||||||
fields=['perc', 'perc_raw', 'title', 'title_sep', 'index',
|
fields=['perc', 'perc_raw', 'title', 'title_sep', 'index',
|
||||||
'id', 'scroll_pos']), '{index}: {title}'),
|
'id', 'scroll_pos', 'host']), '{index}: {title}'),
|
||||||
"The format to use for the tab title. The following placeholders "
|
"The format to use for the tab title. The following placeholders "
|
||||||
"are defined:\n\n"
|
"are defined:\n\n"
|
||||||
"* `{perc}`: The percentage as a string like `[10%]`.\n"
|
"* `{perc}`: The percentage as a string like `[10%]`.\n"
|
||||||
@ -637,7 +638,8 @@ def data(readonly=False):
|
|||||||
"otherwise.\n"
|
"otherwise.\n"
|
||||||
"* `{index}`: The index of this tab.\n"
|
"* `{index}`: The index of this tab.\n"
|
||||||
"* `{id}`: The internal tab ID of this tab.\n"
|
"* `{id}`: The internal tab ID of this tab.\n"
|
||||||
"* `{scroll_pos}`: The page scroll position."),
|
"* `{scroll_pos}`: The page scroll position.\n"
|
||||||
|
"* `{host}`: The host of the current web page."),
|
||||||
|
|
||||||
('title-alignment',
|
('title-alignment',
|
||||||
SettingValue(typ.TextAlignment(), 'left'),
|
SettingValue(typ.TextAlignment(), 'left'),
|
||||||
|
@ -161,27 +161,9 @@ class TabbedBrowser(tabwidget.TabWidget):
|
|||||||
# (e.g. last tab removed)
|
# (e.g. last tab removed)
|
||||||
log.webview.debug("Not updating window title because index is -1")
|
log.webview.debug("Not updating window title because index is -1")
|
||||||
return
|
return
|
||||||
tabtitle = self.page_title(idx)
|
fields = self.get_tab_fields(idx)
|
||||||
widget = self.widget(idx)
|
|
||||||
|
|
||||||
fields = {}
|
|
||||||
if widget.load_status == webview.LoadStatus.loading:
|
|
||||||
fields['perc'] = '[{}%] '.format(widget.progress)
|
|
||||||
else:
|
|
||||||
fields['perc'] = ''
|
|
||||||
fields['perc_raw'] = widget.progress
|
|
||||||
fields['title'] = tabtitle
|
|
||||||
fields['title_sep'] = ' - ' if tabtitle else ''
|
|
||||||
fields['id'] = self._win_id
|
fields['id'] = self._win_id
|
||||||
y = widget.scroll_pos[1]
|
|
||||||
if y <= 0:
|
|
||||||
scroll_pos = 'top'
|
|
||||||
elif y >= 100:
|
|
||||||
scroll_pos = 'bot'
|
|
||||||
else:
|
|
||||||
scroll_pos = '{:2}%'.format(y)
|
|
||||||
|
|
||||||
fields['scroll_pos'] = scroll_pos
|
|
||||||
fmt = config.get('ui', 'window-title-format')
|
fmt = config.get('ui', 'window-title-format')
|
||||||
self.window().setWindowTitle(fmt.format(**fields))
|
self.window().setWindowTitle(fmt.format(**fields))
|
||||||
|
|
||||||
@ -231,14 +213,8 @@ class TabbedBrowser(tabwidget.TabWidget):
|
|||||||
Return:
|
Return:
|
||||||
The current URL as QUrl.
|
The current URL as QUrl.
|
||||||
"""
|
"""
|
||||||
widget = self.currentWidget()
|
idx = self.currentIndex()
|
||||||
if widget is None:
|
return super().tab_url(idx)
|
||||||
url = QUrl()
|
|
||||||
else:
|
|
||||||
url = widget.cur_url
|
|
||||||
# It's possible for url to be invalid, but the caller will handle that.
|
|
||||||
qtutils.ensure_valid(url)
|
|
||||||
return url
|
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
"""Try to shut down all tabs cleanly."""
|
"""Try to shut down all tabs cleanly."""
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
import collections
|
import collections
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QSize, QRect, QTimer
|
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QSize, QRect, QTimer, QUrl
|
||||||
from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle,
|
from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle,
|
||||||
QStyle, QStylePainter, QStyleOptionTab)
|
QStyle, QStylePainter, QStyleOptionTab)
|
||||||
from PyQt5.QtGui import QIcon, QPalette, QColor
|
from PyQt5.QtGui import QIcon, QPalette, QColor
|
||||||
@ -99,19 +99,34 @@ class TabWidget(QTabWidget):
|
|||||||
|
|
||||||
def update_tab_title(self, idx):
|
def update_tab_title(self, idx):
|
||||||
"""Update the tab text for the given tab."""
|
"""Update the tab text for the given tab."""
|
||||||
|
fields = self.get_tab_fields(idx)
|
||||||
|
fields['title'] = fields['title'].replace('&', '&&')
|
||||||
|
fields['index'] = idx + 1
|
||||||
|
|
||||||
|
fmt = config.get('tabs', 'title-format')
|
||||||
|
self.tabBar().setTabText(idx, fmt.format(**fields))
|
||||||
|
|
||||||
|
def get_tab_fields(self, idx):
|
||||||
|
"""Get the tab field data."""
|
||||||
widget = self.widget(idx)
|
widget = self.widget(idx)
|
||||||
page_title = self.page_title(idx).replace('&', '&&')
|
page_title = self.page_title(idx)
|
||||||
|
|
||||||
fields = {}
|
fields = {}
|
||||||
|
fields['id'] = widget.tab_id
|
||||||
|
fields['title'] = page_title
|
||||||
|
fields['title_sep'] = ' - ' if page_title else ''
|
||||||
|
fields['perc_raw'] = widget.progress
|
||||||
|
|
||||||
if widget.load_status == webview.LoadStatus.loading:
|
if widget.load_status == webview.LoadStatus.loading:
|
||||||
fields['perc'] = '[{}%] '.format(widget.progress)
|
fields['perc'] = '[{}%] '.format(widget.progress)
|
||||||
else:
|
else:
|
||||||
fields['perc'] = ''
|
fields['perc'] = ''
|
||||||
fields['perc_raw'] = widget.progress
|
|
||||||
fields['title'] = page_title
|
try:
|
||||||
fields['index'] = idx + 1
|
fields['host'] = self.tab_url(idx).host()
|
||||||
fields['id'] = widget.tab_id
|
except qtutils.QtValueError:
|
||||||
fields['title_sep'] = ' - ' if page_title else ''
|
fields['host'] = ''
|
||||||
|
|
||||||
y = widget.scroll_pos[1]
|
y = widget.scroll_pos[1]
|
||||||
if y <= 0:
|
if y <= 0:
|
||||||
scroll_pos = 'top'
|
scroll_pos = 'top'
|
||||||
@ -121,9 +136,7 @@ class TabWidget(QTabWidget):
|
|||||||
scroll_pos = '{:2}%'.format(y)
|
scroll_pos = '{:2}%'.format(y)
|
||||||
|
|
||||||
fields['scroll_pos'] = scroll_pos
|
fields['scroll_pos'] = scroll_pos
|
||||||
|
return fields
|
||||||
fmt = config.get('tabs', 'title-format')
|
|
||||||
self.tabBar().setTabText(idx, fmt.format(**fields))
|
|
||||||
|
|
||||||
@config.change_filter('tabs', 'title-format')
|
@config.change_filter('tabs', 'title-format')
|
||||||
def update_tab_titles(self):
|
def update_tab_titles(self):
|
||||||
@ -205,6 +218,21 @@ class TabWidget(QTabWidget):
|
|||||||
self.tabBar().on_change()
|
self.tabBar().on_change()
|
||||||
self.tab_index_changed.emit(index, self.count())
|
self.tab_index_changed.emit(index, self.count())
|
||||||
|
|
||||||
|
def tab_url(self, idx):
|
||||||
|
"""Get the URL of the tab at the given index.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
The tab URL as QUrl.
|
||||||
|
"""
|
||||||
|
widget = self.widget(idx)
|
||||||
|
if widget is None:
|
||||||
|
url = QUrl()
|
||||||
|
else:
|
||||||
|
url = widget.cur_url
|
||||||
|
# It's possible for url to be invalid, but the caller will handle that.
|
||||||
|
qtutils.ensure_valid(url)
|
||||||
|
return url
|
||||||
|
|
||||||
|
|
||||||
class TabBar(QTabBar):
|
class TabBar(QTabBar):
|
||||||
|
|
||||||
|
@ -134,10 +134,12 @@ class FakeQApplication:
|
|||||||
|
|
||||||
class FakeUrl:
|
class FakeUrl:
|
||||||
|
|
||||||
"""QUrl stub which provides .path()."""
|
"""QUrl stub which provides .path(), isValid() and host()."""
|
||||||
|
|
||||||
def __init__(self, path=None):
|
def __init__(self, path=None, valid=True, host=None):
|
||||||
self.path = mock.Mock(return_value=path)
|
self.path = mock.Mock(return_value=path)
|
||||||
|
self.isValid = mock.Mock(returl_value=valid)
|
||||||
|
self.host = mock.Mock(returl_value=host)
|
||||||
|
|
||||||
|
|
||||||
class FakeNetworkReply:
|
class FakeNetworkReply:
|
||||||
@ -222,6 +224,7 @@ class FakeWebView(QWidget):
|
|||||||
self.scroll_pos = (-1, -1)
|
self.scroll_pos = (-1, -1)
|
||||||
self.load_status = webview.LoadStatus.none
|
self.load_status = webview.LoadStatus.none
|
||||||
self.tab_id = 0
|
self.tab_id = 0
|
||||||
|
self.cur_url = FakeUrl()
|
||||||
|
|
||||||
|
|
||||||
class FakeSignal:
|
class FakeSignal:
|
||||||
|
Loading…
Reference in New Issue
Block a user