Merge 7060e7682c into 7e3df43463
This commit is contained in:
commit
02e61e5008
|
|
@ -127,6 +127,7 @@ class TabData:
|
|||
open_target: usertypes.ClickTarget = usertypes.ClickTarget.normal
|
||||
override_target: Optional[usertypes.ClickTarget] = None
|
||||
pinned: bool = False
|
||||
custom_title: Optional[str] = None
|
||||
fullscreen: bool = False
|
||||
netrc_used: bool = False
|
||||
input_mode: usertypes.KeyMode = usertypes.KeyMode.normal
|
||||
|
|
@ -1132,12 +1133,13 @@ class AbstractTab(QWidget):
|
|||
qtutils.ensure_valid(url)
|
||||
url_string = url.toDisplayString()
|
||||
log.webview.debug("Going to start loading: {}".format(url_string))
|
||||
self.title_changed.emit(url_string)
|
||||
if not self.title() and not self.data.custom_title:
|
||||
self.title_changed.emit(url_string)
|
||||
|
||||
@pyqtSlot(QUrl)
|
||||
def _on_url_changed(self, url: QUrl) -> None:
|
||||
"""Update title when URL has changed and no title is available."""
|
||||
if url.isValid() and not self.title():
|
||||
if url.isValid() and not self.title() and not self.data.custom_title:
|
||||
self.title_changed.emit(url.toDisplayString())
|
||||
self.url_changed.emit(url)
|
||||
|
||||
|
|
@ -1189,7 +1191,7 @@ class AbstractTab(QWidget):
|
|||
|
||||
self.load_finished.emit(ok)
|
||||
|
||||
if not self.title():
|
||||
if not self.title() and not self.data.custom_title:
|
||||
self.title_changed.emit(self.url().toDisplayString())
|
||||
|
||||
self.zoom.reapply()
|
||||
|
|
@ -1285,9 +1287,25 @@ class AbstractTab(QWidget):
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def title(self) -> str:
|
||||
def raw_title(self) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
def title(self) -> str:
|
||||
return self.data.custom_title or self.raw_title()
|
||||
|
||||
def set_title(self, title: str) -> None:
|
||||
"""Set a custom tab's title, or reset it if empty is passed.
|
||||
|
||||
Args:
|
||||
title: A custom tab's title
|
||||
"""
|
||||
if title:
|
||||
self.data.custom_title = title
|
||||
self.title_changed.emit(title)
|
||||
else:
|
||||
self.data.custom_title = None
|
||||
self.title_changed.emit(self.raw_title())
|
||||
|
||||
def icon(self) -> QIcon:
|
||||
raise NotImplementedError
|
||||
|
||||
|
|
|
|||
|
|
@ -258,6 +258,24 @@ class CommandDispatcher:
|
|||
|
||||
self._tabbed_browser.tab_close_prompt_if_pinned(tab, force, close)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window',
|
||||
name='tab-title')
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
@cmdutils.argument('title')
|
||||
def tab_title(self, count=None, title=None):
|
||||
"""Set/Unset the current/[count]th tab's title.
|
||||
|
||||
Set the text to empty to unset the tab's title.
|
||||
|
||||
Args:
|
||||
count: The tab index to set or unset tab's title, or None
|
||||
title: The tab title to renamed to, or empty to reset it
|
||||
"""
|
||||
tab = self._cntwidget(count)
|
||||
if tab is None:
|
||||
return
|
||||
tab.set_title(title or '')
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window',
|
||||
name='tab-pin')
|
||||
@cmdutils.argument('count', value=cmdutils.Value.count)
|
||||
|
|
@ -426,6 +444,7 @@ class CommandDispatcher:
|
|||
newtab.history.private_api.deserialize(history)
|
||||
newtab.zoom.set_factor(curtab.zoom.factor())
|
||||
|
||||
newtab.set_title(curtab.data.custom_title)
|
||||
newtab.set_pinned(curtab.data.pinned)
|
||||
return newtab
|
||||
|
||||
|
|
|
|||
|
|
@ -1406,7 +1406,7 @@ class WebEngineTab(browsertab.AbstractTab):
|
|||
def stop(self):
|
||||
self._widget.stop()
|
||||
|
||||
def title(self):
|
||||
def raw_title(self):
|
||||
return self._widget.title()
|
||||
|
||||
def renderer_process_pid(self) -> int:
|
||||
|
|
@ -1724,6 +1724,12 @@ class WebEngineTab(browsertab.AbstractTab):
|
|||
else:
|
||||
selection.selectNone()
|
||||
|
||||
def _on_title_changed(self, title):
|
||||
"""Handle title updates."""
|
||||
if self.data.custom_title:
|
||||
return
|
||||
self.title_changed.emit(title)
|
||||
|
||||
def _connect_signals(self):
|
||||
view = self._widget
|
||||
page = view.page()
|
||||
|
|
@ -1742,7 +1748,7 @@ class WebEngineTab(browsertab.AbstractTab):
|
|||
page.printRequested.connect(self._on_print_requested)
|
||||
page.selectClientCertificate.connect(self._on_select_client_certificate)
|
||||
|
||||
view.titleChanged.connect(self.title_changed)
|
||||
view.titleChanged.connect(self._on_title_changed)
|
||||
view.urlChanged.connect(self._on_url_changed)
|
||||
view.renderProcessTerminated.connect(
|
||||
self._on_render_process_terminated)
|
||||
|
|
|
|||
|
|
@ -927,7 +927,7 @@ class WebKitTab(browsertab.AbstractTab):
|
|||
def stop(self):
|
||||
self._widget.stop()
|
||||
|
||||
def title(self):
|
||||
def raw_title(self):
|
||||
return self._widget.title()
|
||||
|
||||
def renderer_process_pid(self) -> Optional[int]:
|
||||
|
|
@ -1017,6 +1017,12 @@ class WebKitTab(browsertab.AbstractTab):
|
|||
def _on_ssl_errors(self, reply):
|
||||
self._insecure_hosts.add(reply.url().host())
|
||||
|
||||
def _on_title_changed(self, title):
|
||||
"""Handle title updates."""
|
||||
if self.data.custom_title:
|
||||
return
|
||||
self.title_changed.emit(title)
|
||||
|
||||
def _connect_signals(self):
|
||||
view = self._widget
|
||||
page = view.page()
|
||||
|
|
@ -1031,7 +1037,7 @@ class WebKitTab(browsertab.AbstractTab):
|
|||
self._on_load_started)
|
||||
view.scroll_pos_changed.connect(self.scroller.perc_changed)
|
||||
view.titleChanged.connect( # type: ignore[attr-defined]
|
||||
self.title_changed)
|
||||
self._on_title_changed)
|
||||
view.urlChanged.connect( # type: ignore[attr-defined]
|
||||
self._on_url_changed)
|
||||
view.shutting_down.connect(self.shutting_down)
|
||||
|
|
|
|||
|
|
@ -3707,6 +3707,7 @@ bindings.default:
|
|||
K: tab-prev
|
||||
<Ctrl-PgUp>: tab-prev
|
||||
gC: tab-clone
|
||||
tt: cmd-set-text -s :tab-title
|
||||
r: reload
|
||||
<F5>: reload
|
||||
R: reload -f
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class _UndoEntry:
|
|||
history: bytes
|
||||
index: int
|
||||
pinned: bool
|
||||
title: Optional[str]
|
||||
created_at: datetime.datetime = dataclasses.field(
|
||||
default_factory=datetime.datetime.now)
|
||||
|
||||
|
|
@ -516,6 +517,7 @@ class TabbedBrowser(QWidget):
|
|||
entry = _UndoEntry(url=tab.url(),
|
||||
history=history_data,
|
||||
index=idx,
|
||||
title=tab.data.custom_title,
|
||||
pinned=tab.data.pinned)
|
||||
if new_undo or not self.undo_stack:
|
||||
self.undo_stack.append([entry])
|
||||
|
|
@ -563,6 +565,7 @@ class TabbedBrowser(QWidget):
|
|||
newtab = self.tabopen(background=False, idx=entry.index)
|
||||
|
||||
newtab.history.private_api.deserialize(entry.history)
|
||||
newtab.set_title(entry.title or '')
|
||||
newtab.set_pinned(entry.pinned)
|
||||
newtab.setFocus()
|
||||
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ class SessionManager(QObject):
|
|||
data['scroll-pos'] = {'x': pos.x(), 'y': pos.y()}
|
||||
|
||||
data['pinned'] = tab.data.pinned
|
||||
data['custom_title'] = tab.data.custom_title
|
||||
|
||||
return data
|
||||
|
||||
|
|
@ -412,6 +413,9 @@ class SessionManager(QObject):
|
|||
if 'pinned' in histentry:
|
||||
new_tab.data.pinned = histentry['pinned']
|
||||
|
||||
if 'custom_title' in histentry:
|
||||
new_tab.data.custom_title = histentry['custom_title']
|
||||
|
||||
if (config.val.session.lazy_restore and
|
||||
histentry.get('active', False) and
|
||||
not histentry['url'].startswith('qute://back')):
|
||||
|
|
@ -449,7 +453,10 @@ class SessionManager(QObject):
|
|||
last_visited=last_visited)
|
||||
entries.append(entry)
|
||||
if active:
|
||||
new_tab.title_changed.emit(histentry['title'])
|
||||
if new_tab.data.custom_title:
|
||||
new_tab.title_changed.emit(new_tab.data.custom_title)
|
||||
else:
|
||||
new_tab.title_changed.emit(histentry['title'])
|
||||
|
||||
try:
|
||||
new_tab.history.private_api.load_items(entries)
|
||||
|
|
@ -470,6 +477,8 @@ class SessionManager(QObject):
|
|||
tab_to_focus = i
|
||||
if new_tab.data.pinned:
|
||||
new_tab.set_pinned(True)
|
||||
if new_tab.data.custom_title:
|
||||
new_tab.set_title(new_tab.data.custom_title)
|
||||
if tab_to_focus is not None:
|
||||
tabbed_browser.widget.setCurrentIndex(tab_to_focus)
|
||||
|
||||
|
|
|
|||
|
|
@ -1925,6 +1925,136 @@ Feature: Tab management
|
|||
"""
|
||||
|
||||
|
||||
# :tab-title
|
||||
|
||||
Scenario: Set tab title
|
||||
When I open data/title.html
|
||||
And I open data/title.html in a new tab
|
||||
And I run :tab-title renamed
|
||||
Then the session should look like:
|
||||
"""
|
||||
windows:
|
||||
- tabs:
|
||||
- history:
|
||||
- url: about:blank
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title:
|
||||
- active: true
|
||||
history:
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title: renamed
|
||||
"""
|
||||
|
||||
Scenario: Set specific tab title using count
|
||||
When I open data/title.html
|
||||
And I open data/title.html in a new tab
|
||||
And I run :tab-title renamed with count 1
|
||||
Then the session should look like:
|
||||
"""
|
||||
windows:
|
||||
- tabs:
|
||||
- history:
|
||||
- url: about:blank
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title: renamed
|
||||
- active: true
|
||||
history:
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title:
|
||||
"""
|
||||
|
||||
Scenario: Set tab title with space
|
||||
When I open data/title.html
|
||||
And I open data/title.html in a new tab
|
||||
And I run :tab-title 'a new title'
|
||||
Then the session should look like:
|
||||
"""
|
||||
windows:
|
||||
- tabs:
|
||||
- history:
|
||||
- url: about:blank
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title:
|
||||
- active: true
|
||||
history:
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title: a new title
|
||||
"""
|
||||
|
||||
Scenario: Custom tab title when navigated
|
||||
When I open data/numbers/1.txt
|
||||
And I run :tab-title 'a new title'
|
||||
And I open data/title.html
|
||||
Then the session should look like:
|
||||
"""
|
||||
windows:
|
||||
- tabs:
|
||||
- active: true
|
||||
history:
|
||||
- url: about:blank
|
||||
- url: http://localhost:*/data/numbers/1.txt
|
||||
custom_title: a new title
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title: a new title
|
||||
"""
|
||||
|
||||
Scenario: Cloning a tab with a custom tab title
|
||||
When I open data/title.html
|
||||
And I open data/title.html in a new tab
|
||||
And I run :tab-title 'a new title'
|
||||
And I run :tab-clone
|
||||
And I wait until data/title.html is loaded
|
||||
Then the session should look like:
|
||||
"""
|
||||
windows:
|
||||
- tabs:
|
||||
- history:
|
||||
- url: about:blank
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title:
|
||||
- history:
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title: a new title
|
||||
- active: true
|
||||
history:
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title: a new title
|
||||
"""
|
||||
|
||||
Scenario: Undo a tab with a custom tab title
|
||||
When I open data/title.html
|
||||
And I open data/title.html in a new tab
|
||||
And I run :tab-title 'a new title'
|
||||
And I run :tab-close --force
|
||||
And I run :undo
|
||||
And I wait until data/title.html is loaded
|
||||
Then the session should look like:
|
||||
"""
|
||||
windows:
|
||||
- tabs:
|
||||
- history:
|
||||
- url: about:blank
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title:
|
||||
- active: true
|
||||
history:
|
||||
- url: http://localhost:*/data/title.html
|
||||
title: Test title
|
||||
custom_title: a new title
|
||||
"""
|
||||
|
||||
|
||||
Scenario: Focused webview after clicking link in bg
|
||||
When I open data/hints/link_input.html
|
||||
And I run :click-element id qute-input-existing
|
||||
|
|
|
|||
|
|
@ -1413,12 +1413,15 @@ def test_undo_completion(tabbed_browser_stubs, info):
|
|||
"""Test :undo completion."""
|
||||
entry1 = tabbedbrowser._UndoEntry(url=QUrl('https://example.org/'),
|
||||
history=None, index=None, pinned=None,
|
||||
title=None,
|
||||
created_at=datetime(2020, 1, 1))
|
||||
entry2 = tabbedbrowser._UndoEntry(url=QUrl('https://example.com/'),
|
||||
history=None, index=None, pinned=None,
|
||||
title=None,
|
||||
created_at=datetime(2020, 1, 2))
|
||||
entry3 = tabbedbrowser._UndoEntry(url=QUrl('https://example.net/'),
|
||||
history=None, index=None, pinned=None,
|
||||
title=None,
|
||||
created_at=datetime(2020, 1, 2))
|
||||
|
||||
# Most recently closed is at the end
|
||||
|
|
@ -1453,7 +1456,7 @@ def undo_completion_retains_sort_order(tabbed_browser_stubs, info):
|
|||
tabbedbrowser._UndoEntry(
|
||||
url=QUrl(f'https://example.org/{idx}'),
|
||||
history=None, index=None, pinned=None,
|
||||
created_at=created_dt,
|
||||
title=None, created_at=created_dt,
|
||||
)
|
||||
for idx in range(1, 11)
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in New Issue