From 1919029858ef25b832790f06b269d334f3d75d76 Mon Sep 17 00:00:00 2001
From: Jay Kamat <jaygkamat@gmail.com>
Date: Mon, 18 Jun 2018 18:09:13 -0400
Subject: [PATCH 1/3] Add setting for controlling stacking of new tabs

---
 qutebrowser/config/configdata.yml       | 19 ++++++++++++--
 qutebrowser/mainwindow/tabbedbrowser.py |  5 +++-
 tests/end2end/features/tabs.feature     | 33 +++++++++++++++++++++++++
 3 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index 49e037538..e17f6afac 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -1348,12 +1348,27 @@ tabs.mousewheel_switching:
 tabs.new_position.related:
   default: next
   type: NewTabPosition
-  desc: Position of new tabs opened from another tab.
+  desc: >-
+    Position of new tabs opened from another tab.
+
+    See `tabs.new_position.stacking` for controlling stacking behavior.
 
 tabs.new_position.unrelated:
   default: last
   type: NewTabPosition
-  desc: "Position of new tabs which aren't opened from another tab."
+  desc: >-
+    Position of new tabs which are not opened from another tab.
+
+    See `tabs.new_position.stacking` for controlling stacking behavior.
+
+tabs.new_position.stacking:
+  default: true
+  type: Bool
+  desc: >-
+    Stack relative tabs on top of each other when opened consecutively.
+
+    Only applies `next` and `prev` values of `tabs.new_position.related` and
+    `tabs.new_position.unrelated`.
 
 tabs.padding:
   default:
diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py
index 2b74df72b..cc1be1c00 100644
--- a/qutebrowser/mainwindow/tabbedbrowser.py
+++ b/qutebrowser/mainwindow/tabbedbrowser.py
@@ -533,7 +533,10 @@ class TabbedBrowser(QWidget):
             # *before* the currently focused tab, indices will shift by
             # 1 automatically.
         elif pos == 'next':
-            idx = self._tab_insert_idx_right
+            if config.val.tabs.new_position.stacking:
+                idx = self._tab_insert_idx_right
+            else:
+                idx = self.widget.currentIndex() + 1
             self._tab_insert_idx_right += 1
         elif pos == 'first':
             idx = 0
diff --git a/tests/end2end/features/tabs.feature b/tests/end2end/features/tabs.feature
index 5f5ae5d29..7cc63ce52 100644
--- a/tests/end2end/features/tabs.feature
+++ b/tests/end2end/features/tabs.feature
@@ -894,6 +894,39 @@ Feature: Tab management
             - about:blank
             - data/hello.txt (active)
 
+    # stacking tabs
+    Scenario: stacking tabs opening tab with tabs.new_position.related next
+        When I set tabs.new_position.related to next
+        And I set tabs.new_position.stacking to true
+        And I set tabs.background to true
+        And I open about:blank
+        And I open data/navigate/index.html in a new tab
+        And I hint with args "all tab-bg" and follow a
+        And I hint with args "all tab-bg" and follow s
+        And I wait until data/navigate/prev.html is loaded
+        And I wait until data/navigate/next.html is loaded
+        Then the following tabs should be open:
+            - about:blank
+            - data/navigate/index.html (active)
+            - data/navigate/prev.html
+            - data/navigate/next.html
+
+    Scenario: no stacking tabs opening tab with tabs.new_position.related next
+        When I set tabs.new_position.related to next
+        And I set tabs.new_position.stacking to false
+        And I set tabs.background to true
+        And I open about:blank
+        And I open data/navigate/index.html in a new tab
+        And I hint with args "all tab-bg" and follow a
+        And I hint with args "all tab-bg" and follow s
+        And I wait until data/navigate/prev.html is loaded
+        And I wait until data/navigate/next.html is loaded
+        Then the following tabs should be open:
+            - about:blank
+            - data/navigate/index.html (active)
+            - data/navigate/next.html
+            - data/navigate/prev.html
+
     # :buffer
 
     Scenario: :buffer without args or count

From 0e7bbccd71a2a9d0fb18fba32e8389cd19d51aef Mon Sep 17 00:00:00 2001
From: Jay Kamat <jaygkamat@gmail.com>
Date: Tue, 19 Jun 2018 12:06:26 -0400
Subject: [PATCH 2/3] Fix stacking tabs setting with new_tab prev

---
 qutebrowser/mainwindow/tabbedbrowser.py | 17 +++++++------
 tests/end2end/features/tabs.feature     | 32 +++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py
index cc1be1c00..bc054900a 100644
--- a/qutebrowser/mainwindow/tabbedbrowser.py
+++ b/qutebrowser/mainwindow/tabbedbrowser.py
@@ -526,18 +526,21 @@ class TabbedBrowser(QWidget):
         else:
             pos = config.val.tabs.new_position.unrelated
         if pos == 'prev':
-            idx = self._tab_insert_idx_left
-            # On first sight, we'd think we have to decrement
-            # self._tab_insert_idx_left here, as we want the next tab to be
-            # *before* the one we just opened. However, since we opened a tab
-            # *before* the currently focused tab, indices will shift by
-            # 1 automatically.
+            if config.val.tabs.new_position.stacking:
+                idx = self._tab_insert_idx_left
+                # On first sight, we'd think we have to decrement
+                # self._tab_insert_idx_left here, as we want the next tab to be
+                # *before* the one we just opened. However, since we opened a tab
+                # *before* the currently focused tab, indices will shift by
+                # 1 automatically.
+            else:
+                idx = self.widget.currentIndex()
         elif pos == 'next':
             if config.val.tabs.new_position.stacking:
                 idx = self._tab_insert_idx_right
+                self._tab_insert_idx_right += 1
             else:
                 idx = self.widget.currentIndex() + 1
-            self._tab_insert_idx_right += 1
         elif pos == 'first':
             idx = 0
         elif pos == 'last':
diff --git a/tests/end2end/features/tabs.feature b/tests/end2end/features/tabs.feature
index 7cc63ce52..cb6fbd226 100644
--- a/tests/end2end/features/tabs.feature
+++ b/tests/end2end/features/tabs.feature
@@ -911,6 +911,22 @@ Feature: Tab management
             - data/navigate/prev.html
             - data/navigate/next.html
 
+    Scenario: stacking tabs opening tab with tabs.new_position.related prev
+        When I set tabs.new_position.related to prev
+        And I set tabs.new_position.stacking to true
+        And I set tabs.background to true
+        And I open about:blank
+        And I open data/navigate/index.html in a new tab
+        And I hint with args "all tab-bg" and follow a
+        And I hint with args "all tab-bg" and follow s
+        And I wait until data/navigate/prev.html is loaded
+        And I wait until data/navigate/next.html is loaded
+        Then the following tabs should be open:
+            - about:blank
+            - data/navigate/next.html
+            - data/navigate/prev.html
+            - data/navigate/index.html (active)
+
     Scenario: no stacking tabs opening tab with tabs.new_position.related next
         When I set tabs.new_position.related to next
         And I set tabs.new_position.stacking to false
@@ -927,6 +943,22 @@ Feature: Tab management
             - data/navigate/next.html
             - data/navigate/prev.html
 
+    Scenario: no stacking tabs opening tab with tabs.new_position.related prev
+        When I set tabs.new_position.related to prev
+        And I set tabs.new_position.stacking to false
+        And I set tabs.background to true
+        And I open about:blank
+        And I open data/navigate/index.html in a new tab
+        And I hint with args "all tab-bg" and follow a
+        And I hint with args "all tab-bg" and follow s
+        And I wait until data/navigate/prev.html is loaded
+        And I wait until data/navigate/next.html is loaded
+        Then the following tabs should be open:
+            - about:blank
+            - data/navigate/prev.html
+            - data/navigate/next.html
+            - data/navigate/index.html (active)
+
     # :buffer
 
     Scenario: :buffer without args or count

From 454c532668633d0e53ceab3ae3c4cc05654b3022 Mon Sep 17 00:00:00 2001
From: Jay Kamat <jaygkamat@gmail.com>
Date: Thu, 21 Jun 2018 18:58:48 -0400
Subject: [PATCH 3/3] Fix behavior when toggling stacking behavior in a single
 tab

---
 qutebrowser/config/configdata.yml       | 2 +-
 qutebrowser/mainwindow/tabbedbrowser.py | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml
index e17f6afac..d4cfcd020 100644
--- a/qutebrowser/config/configdata.yml
+++ b/qutebrowser/config/configdata.yml
@@ -1365,7 +1365,7 @@ tabs.new_position.stacking:
   default: true
   type: Bool
   desc: >-
-    Stack relative tabs on top of each other when opened consecutively.
+    Stack related tabs on top of each other when opened consecutively.
 
     Only applies `next` and `prev` values of `tabs.new_position.related` and
     `tabs.new_position.unrelated`.
diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py
index bc054900a..c0c303414 100644
--- a/qutebrowser/mainwindow/tabbedbrowser.py
+++ b/qutebrowser/mainwindow/tabbedbrowser.py
@@ -530,17 +530,17 @@ class TabbedBrowser(QWidget):
                 idx = self._tab_insert_idx_left
                 # On first sight, we'd think we have to decrement
                 # self._tab_insert_idx_left here, as we want the next tab to be
-                # *before* the one we just opened. However, since we opened a tab
-                # *before* the currently focused tab, indices will shift by
+                # *before* the one we just opened. However, since we opened a
+                # tab *before* the currently focused tab, indices will shift by
                 # 1 automatically.
             else:
                 idx = self.widget.currentIndex()
         elif pos == 'next':
             if config.val.tabs.new_position.stacking:
                 idx = self._tab_insert_idx_right
-                self._tab_insert_idx_right += 1
             else:
                 idx = self.widget.currentIndex() + 1
+            self._tab_insert_idx_right += 1
         elif pos == 'first':
             idx = 0
         elif pos == 'last':