From 7a297e2e3f1464c2711e4e0aecae530264a3bb92 Mon Sep 17 00:00:00 2001 From: Jay Kamat Date: Wed, 9 May 2018 18:28:05 -0700 Subject: [PATCH] Add support for muting tabs --- qutebrowser/browser/browsertab.py | 9 +++++++++ qutebrowser/browser/commands.py | 17 +++++++++++++++++ qutebrowser/browser/webengine/webenginetab.py | 9 +++++++++ qutebrowser/browser/webkit/webkittab.py | 7 +++++++ qutebrowser/config/configdata.yml | 4 ++++ qutebrowser/mainwindow/tabbedbrowser.py | 14 ++++++++++++++ qutebrowser/mainwindow/tabwidget.py | 1 + 7 files changed, 61 insertions(+) diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index 2a9662eef..17376dc7f 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -649,6 +649,7 @@ class AbstractTab(QWidget): fullscreen_requested = pyqtSignal(bool) renderer_process_terminated = pyqtSignal(TerminationStatus, int) predicted_navigation = pyqtSignal(QUrl) + audio_muted_changed = pyqtSignal(bool) def __init__(self, *, win_id, mode_manager, private, parent=None): self.private = private @@ -923,3 +924,11 @@ class AbstractTab(QWidget): def is_deleted(self): return sip.isdeleted(self._widget) + + def set_muted(self, muted: bool): + """Set this tab as muted or not.""" + raise NotImplementedError + + def is_muted(self): + """Whether this tab is muted.""" + raise NotImplementedError diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 60844029f..e4d75777b 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -2230,3 +2230,20 @@ class CommandDispatcher: window = self._tabbed_browser.widget.window() window.setWindowState(window.windowState() ^ Qt.WindowFullScreen) + + @cmdutils.register(instance='command-dispatcher', scope='window', + name='tab-mute') + @cmdutils.argument('count', count=True) + def tab_mute(self, count=None): + """Mute/Unmute the current/[count]th tab. + + Args: + count: The tab index to pin or unpin, or None + """ + tab = self._cntwidget(count) + if tab is None: + return + try: + tab.set_muted(not tab.is_muted()) + except browsertab.WebTabError as e: + raise cmdexc.CommandError(e) diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index fb04dc120..a0339180b 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -1092,6 +1092,7 @@ class WebEngineTab(browsertab.AbstractTab): page.fullScreenRequested.connect(self._on_fullscreen_requested) page.contentsSizeChanged.connect(self.contents_size_changed) page.navigation_request.connect(self._on_navigation_request) + page.audioMutedChanged.connect(self.audio_muted_changed) view.titleChanged.connect(self.title_changed) view.urlChanged.connect(self._on_url_changed) @@ -1116,3 +1117,11 @@ class WebEngineTab(browsertab.AbstractTab): def event_target(self): return self._widget.focusProxy() + + def set_muted(self, muted: bool): + page = self._widget.page() + page.setAudioMuted(muted) + + def is_muted(self): + page = self._widget.page() + return page.isAudioMuted() diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py index 9d5305f10..ae3a09463 100644 --- a/qutebrowser/browser/webkit/webkittab.py +++ b/qutebrowser/browser/webkit/webkittab.py @@ -828,3 +828,10 @@ class WebKitTab(browsertab.AbstractTab): def event_target(self): return self._widget + + def set_muted(self, muted: bool): + raise browsertab.WebTabError('Muting is not supported on QtWebKit!') + + def is_muted(self): + # Dummy value for things that read muted status + return False diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index 1784e4b7d..cdbaa328b 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -1359,6 +1359,7 @@ tabs.title.format: - private - current_url - protocol + - muted none_ok: true desc: | Format to use for the tab title. @@ -1376,6 +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 tabs.title.format_pinned: default: '{index}' @@ -1393,6 +1395,7 @@ tabs.title.format_pinned: - private - current_url - protocol + - muted none_ok: true desc: Format to use for the tab title for pinned tabs. The same placeholders like for `tabs.title.format` are defined. @@ -1560,6 +1563,7 @@ window.title_format: - private - current_url - protocol + - muted default: '{perc}{title}{title_sep}qutebrowser' desc: | Format to use for the window title. The same placeholders like for diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py index 2d674e280..cc290ba1e 100644 --- a/qutebrowser/mainwindow/tabbedbrowser.py +++ b/qutebrowser/mainwindow/tabbedbrowser.py @@ -238,6 +238,8 @@ class TabbedBrowser(QWidget): functools.partial(self.on_window_close_requested, tab)) 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)) tab.new_tab_requested.connect(self.tabopen) if not self.private: web_history = objreg.get('web-history') @@ -733,6 +735,18 @@ class TabbedBrowser(QWidget): self._update_window_title('scroll_pos') 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.""" + 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') + if idx == self.widget.currentIndex(): + self._update_window_title('muted') + def _on_renderer_process_terminated(self, tab, status, code): """Show an error when a renderer process terminated.""" if status == browsertab.TerminationStatus.normal: diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py index 6a6eac901..ace938592 100644 --- a/qutebrowser/mainwindow/tabwidget.py +++ b/qutebrowser/mainwindow/tabwidget.py @@ -172,6 +172,7 @@ 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 '' if tab.load_status() == usertypes.LoadStatus.loading: fields['perc'] = '[{}%] '.format(tab.progress())