diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index 22f1c7e51..67d2bee44 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -560,6 +560,7 @@ class AbstractTab(QWidget): self._mouse_event_filter = mouse.MouseEventFilter( self, widget_class=self.WIDGET_CLASS, parent=self) self.backend = None + self.pin = False # FIXME:qtwebengine Should this be public api via self.hints? # Also, should we get it out of objreg? diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 2c0e01b5f..3ee28493e 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -227,6 +227,14 @@ class CommandDispatcher: tab = self._cntwidget(count) if tab is None: return + + if tab.pin is True: + result = message.ask("Are you sure you want to close a pinned tab?", + mode=usertypes.PromptMode.yesno, default=False) + + if result is False or result is None: + return + tabbar = self._tabbed_browser.tabBar() selection_override = self._get_selection_override(left, right, opposite) @@ -238,6 +246,29 @@ class CommandDispatcher: self._tabbed_browser.close_tab(tab) tabbar.setSelectionBehaviorOnRemove(old_selection_behavior) + @cmdutils.register(instance='command-dispatcher', scope='window', name='pin') + @cmdutils.argument('index') + @cmdutils.argument('count', count=True) + def tab_pin(self, index=1, count=None): + tab = self._cntwidget(count) + if tab is None: + return + tab.pin = True + self.tab_move(int(index)) + + @cmdutils.register(instance='command-dispatcher', scope='window', name='unpin') + @cmdutils.argument('index') + @cmdutils.argument('count', count=True) + def tab_unpin(self, index=None, count=None): + tab = self._cntwidget(count) + if tab is None: + return + tab.pin = False + if index is not None: + self.tab_move(int(index)) + else: + self.tab_move(self._count()) + @cmdutils.register(instance='command-dispatcher', name='open', maxsplit=0, scope='window') @cmdutils.argument('url', completion=usertypes.Completion.url) @@ -281,6 +312,9 @@ class CommandDispatcher: else: # Explicit count with a tab that doesn't exist. return + elif curtab.pin is True: + message.info("Tab is pinned!") + else: curtab.openurl(cur_url) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index bad6fa51a..3219b5c9b 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -1652,6 +1652,8 @@ KEY_DATA = collections.OrderedDict([ ('follow-selected', RETURN_KEYS), ('follow-selected -t', ['', '']), ('repeat-command', ['.']), + ('pin', ['']), + ('unpin', ['']), ])), ('insert', collections.OrderedDict([ diff --git a/qutebrowser/misc/sessions.py b/qutebrowser/misc/sessions.py index c3a3a8e34..d7c844c77 100644 --- a/qutebrowser/misc/sessions.py +++ b/qutebrowser/misc/sessions.py @@ -205,6 +205,9 @@ class SessionManager(QObject): if 'scroll-pos' in user_data: pos = user_data['scroll-pos'] data['scroll-pos'] = {'x': pos.x(), 'y': pos.y()} + + data['pin'] = tab.pin + return data def _save_tab(self, tab, active): @@ -332,6 +335,9 @@ class SessionManager(QObject): pos = histentry['scroll-pos'] user_data['scroll-pos'] = QPoint(pos['x'], pos['y']) + if 'pin' in histentry: + new_tab.pin = histentry['pin'] + active = histentry.get('active', False) url = QUrl.fromEncoded(histentry['url'].encode('ascii')) if 'original-url' in histentry: