diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index 17376dc7f..ee5717550 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -650,6 +650,7 @@ class AbstractTab(QWidget): renderer_process_terminated = pyqtSignal(TerminationStatus, int) predicted_navigation = pyqtSignal(QUrl) audio_muted_changed = pyqtSignal(bool) + recently_audible_changed = pyqtSignal(bool) def __init__(self, *, win_id, mode_manager, private, parent=None): self.private = private @@ -932,3 +933,7 @@ class AbstractTab(QWidget): def is_muted(self): """Whether this tab is muted.""" raise NotImplementedError + + def is_recently_audible(self): + """Whether this tab has had audio playing recently.""" + raise NotImplementedError diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index a0339180b..0fccd6b73 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -1093,6 +1093,7 @@ class WebEngineTab(browsertab.AbstractTab): page.contentsSizeChanged.connect(self.contents_size_changed) page.navigation_request.connect(self._on_navigation_request) page.audioMutedChanged.connect(self.audio_muted_changed) + page.recentlyAudibleChanged.connect(self.recently_audible_changed) view.titleChanged.connect(self.title_changed) view.urlChanged.connect(self._on_url_changed) @@ -1125,3 +1126,7 @@ class WebEngineTab(browsertab.AbstractTab): def is_muted(self): page = self._widget.page() return page.isAudioMuted() + + def is_recently_audible(self): + page = self._widget.page() + return page.recentlyAudible() diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py index ae3a09463..d243c7e18 100644 --- a/qutebrowser/browser/webkit/webkittab.py +++ b/qutebrowser/browser/webkit/webkittab.py @@ -835,3 +835,7 @@ class WebKitTab(browsertab.AbstractTab): def is_muted(self): # Dummy value for things that read muted status return False + + def is_recently_audible(self): + # Dummy value for things that read audible status + return False diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index cdbaa328b..cfeeee07e 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -1344,7 +1344,7 @@ tabs.title.alignment: desc: Alignment of the text inside of tabs. tabs.title.format: - default: '{index}: {title}' + default: '{audio}{index}: {title}' type: name: FormatString fields: @@ -1359,7 +1359,7 @@ tabs.title.format: - private - current_url - protocol - - muted + - audio none_ok: true desc: | Format to use for the tab title. @@ -1377,7 +1377,7 @@ tabs.title.format: * `{private}`: Indicates when private mode is enabled. * `{current_url}`: URL of the current web page. * `{protocol}`: Protocol (http/https/...) of the current web page. - * `{muted}`: Icon if the tab is muted + * `{audio}`: Cookie for audio/mute status tabs.title.format_pinned: default: '{index}' @@ -1395,7 +1395,7 @@ tabs.title.format_pinned: - private - current_url - protocol - - muted + - audio none_ok: true desc: Format to use for the tab title for pinned tabs. The same placeholders like for `tabs.title.format` are defined. @@ -1563,7 +1563,7 @@ window.title_format: - private - current_url - protocol - - muted + - audio default: '{perc}{title}{title_sep}qutebrowser' desc: | Format to use for the window title. The same placeholders like for @@ -2366,6 +2366,7 @@ bindings.default: : follow-selected -t .: repeat-command : tab-pin + : tab-mute q: record-macro "@": run-macro tsh: config-cycle -p -t -u *://{url:host}/* content.javascript.enabled ;; reload diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py index cc290ba1e..c2ca7acd4 100644 --- a/qutebrowser/mainwindow/tabbedbrowser.py +++ b/qutebrowser/mainwindow/tabbedbrowser.py @@ -239,7 +239,9 @@ class TabbedBrowser(QWidget): tab.renderer_process_terminated.connect( functools.partial(self._on_renderer_process_terminated, tab)) tab.audio_muted_changed.connect( - functools.partial(self.on_mute_changed, tab)) + functools.partial(self.on_audio_changed, tab)) + tab.recently_audible_changed.connect( + functools.partial(self.on_audio_changed, tab)) tab.new_tab_requested.connect(self.tabopen) if not self.private: web_history = objreg.get('web-history') @@ -736,16 +738,16 @@ class TabbedBrowser(QWidget): self.widget.update_tab_title(idx, 'scroll_pos') @pyqtSlot() - def on_mute_changed(self, tab, muted): - """Update tab and window title when scroll position changed.""" + def on_audio_changed(self, tab, muted): + """Update audio cookie in tab when mute or recentlyAudible changed.""" try: idx = self._tab_index(tab) except TabDeletedError: # We can get signals for tabs we already deleted... return - self.widget.update_tab_title(idx, 'muted') + self.widget.update_tab_title(idx, 'audio') if idx == self.widget.currentIndex(): - self._update_window_title('muted') + self._update_window_title('audio') def _on_renderer_process_terminated(self, tab, status, code): """Show an error when a renderer process terminated.""" diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py index ace938592..c9f65c5a6 100644 --- a/qutebrowser/mainwindow/tabwidget.py +++ b/qutebrowser/mainwindow/tabwidget.py @@ -172,7 +172,8 @@ class TabWidget(QTabWidget): fields['perc_raw'] = tab.progress() fields['backend'] = objects.backend.name fields['private'] = ' [Private Mode] ' if tab.private else '' - fields['muted'] = '[M] ' if tab.is_muted() else '' + fields['audio'] = '[M] ' if tab.is_muted() else ( + '[A] ' if tab.is_recently_audible() else '') if tab.load_status() == usertypes.LoadStatus.loading: fields['perc'] = '[{}%] '.format(tab.progress())