Set an initial window size for background tabs

When we open a background tab, it gets a hardcoded size (800x600 or so) because
it doesn't get resized by the layout yet.

By resizing it to the size it'll actually have later, we make sure scrolling to
an anchor in an background tab works, and JS also gets the correct size for
background tabs.

Fixes #1190
Fixes #2495
See #1417
This commit is contained in:
Florian Bruhin 2017-06-11 17:45:18 +02:00
parent 2e5620cac1
commit 57fbfbd606
8 changed files with 87 additions and 3 deletions

View File

@ -134,6 +134,8 @@ Fixed
- Various other rare crashes should now be fixed.
- The settings documentation was truncated with v0.10.1 which should now be
fixed.
- Scrolling to an anchor in a background tab now works correctly, and javascript
gets the correct window size for background tabs.
v0.10.1
-------

View File

@ -23,7 +23,7 @@ import functools
import collections
from PyQt5.QtWidgets import QSizePolicy
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QTimer, QUrl
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QTimer, QUrl, QSize
from PyQt5.QtGui import QIcon
from qutebrowser.config import config
@ -426,12 +426,20 @@ class TabbedBrowser(tabwidget.TabWidget):
if url is not None:
tab.openurl(url)
if background is None:
background = config.get('tabs', 'background-tabs')
if background:
# Make sure the background tab has the correct initial size.
# With a foreground tab, it's going to be resized correctly by the
# layout anyways.
tab_size = QSize(self.width(),
self.height() - self.tabBar().height())
tab.resize(tab_size)
self.tab_index_changed.emit(self.currentIndex(), self.count())
else:
self.setCurrentWidget(tab)
tab.show()
self.new_tab.emit(tab, idx)
return tab

View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>window sizes</title>
<script>
function updateText(elem) {
var size = window.innerWidth + "/" + window.innerHeight;
document.getElementById(elem).textContent = size;
console.log(elem + " window size: " + size);
}
document.addEventListener("DOMContentLoaded", function() {
updateText("hidden");
console.log("loaded");
});
</script>
</head>
<body>
<p>visible: <span id="visible">unknown</span></p>
<p>hidden: <span id="hidden">unknown</span></p>
</body>
</html>

View File

@ -3,10 +3,24 @@
<head>
<meta charset="utf-8">
<title>Scrolling</title>
<script>
function checkAnchor() {
var old_position = window.scrollY;
document.getElementById("anchor").scrollIntoView();
var new_position = window.scrollY;
if (old_position != new_position) {
console.log("[FAIL] Old position " + old_position +
" != new position " + new_position);
} else {
console.log("[PASS] Positions equal: " + old_position);
}
}
</script>
</head>
<body>
<a href="/data/hello.txt" id="link">Just a link</a>
<button>blub</button>
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p>
<pre>
0
1
@ -78,7 +92,7 @@
67
68
69
70
<span id="anchor">70</span>
71
72
73

View File

@ -72,6 +72,7 @@ Feature: Javascript stuff
Scenario: Executing jseval when javascript is disabled
When I set content -> allow-javascript to false
And I run :jseval console.log('jseval executed')
And I set content -> allow-javascript to true
Then the javascript message "jseval executed" should be logged
## webelement issues (mostly with QtWebEngine)
@ -100,3 +101,18 @@ Feature: Javascript stuff
And I run :click-element id listitem
And I wait for "Sending fake click to *" in the log
Then no crash should happen
# We load the tab in the background, and the HTML sets the window size for
# when it's hidden.
# Then, "the window sizes should be the same" uses :jseval to set the size
# when it's shown, and compares the two.
# https://github.com/qutebrowser/qutebrowser/issues/1190
# https://github.com/qutebrowser/qutebrowser/issues/2495
Scenario: Checking visible/invisible window size
When I run :tab-only
And I set general -> log-javascript-console to info
And I open data/javascript/windowsize.html in a new background tab
And I wait for "[*/data/javascript/windowsize.html:*] loaded" in the log
And I run :tab-next
Then the window sizes should be the same

View File

@ -314,3 +314,12 @@ Feature: Scrolling
And I wait until the scroll position changed
And I run :scroll-page --bottom-navigate next 0 1
Then data/hello2.txt should be loaded
Scenario: Scrolling to anchor in background tab
When I set general -> log-javascript-console to info
And I open about:blank
And I run :tab-only
And I open data/scroll/simple.html#anchor in a new background tab
And I run :tab-next
And I run :jseval --world main checkAnchor()
Then "[*] [PASS] Positions equal: *" should be logged

View File

@ -19,3 +19,13 @@
import pytest_bdd as bdd
bdd.scenarios('javascript.feature')
@bdd.then("the window sizes should be the same")
def check_window_sizes(quteproc):
hidden = quteproc.wait_for_js('hidden window size: *')
quteproc.send_cmd(':jseval --world main updateText("visible")')
visible = quteproc.wait_for_js('visible window size: *')
hidden_size = hidden.message.split()[-1]
visible_size = visible.message.split()[-1]
assert hidden_size == visible_size

View File

@ -430,7 +430,8 @@ class QuteProc(testprocess.Process):
pattern="load status for <* tab_id=* url='*duckduckgo*'>: *",
value=msg.message)
is_log_error = msg.loglevel > logging.INFO
is_log_error = (msg.loglevel > logging.INFO and
not msg.message.startswith("Ignoring world ID"))
return is_log_error or is_js_error or is_ddg_load
def _maybe_skip(self):