Compare commits

...

927 Commits

Author SHA1 Message Date
Florian Bruhin
e9e411311a Remove unused import 2017-10-09 10:08:45 +02:00
Florian Bruhin
33b71ee937 Use develop branch of PyInstaller
https://github.com/pyinstaller/pyinstaller/pull/2519 was merged.
Fixes #2880

(cherry picked from commit ba04822388)
2017-10-09 08:46:31 +02:00
Florian Bruhin
d166587f3d Release v0.11.1 2017-10-09 08:30:18 +02:00
Florian Bruhin
dd663df35f Update changelog from master 2017-10-09 08:30:03 +02:00
Florian Bruhin
9d292128d2 Remove test_upgrade_version
This is the last v0.11.x release
2017-10-09 08:24:56 +02:00
Florian Bruhin
f3eb5dbb66 Revert "Only emit perc_changed signal when the percentage actually changed"
This reverts commit 3eaad092b8.
This breaks various end2end test relying on getting log messages for scrolling.
2017-10-06 10:17:13 +02:00
Florian Bruhin
3eaad092b8 Only emit perc_changed signal when the percentage actually changed
QtWebEngine emits scrollPositionChanged a lot during smooth scrolling, and
there's no reason we need to update percentages when they didn't *actually*
change.

This reduces the updates with a single spacebar press from 6-7 to 2-3 on my
machine, which might not be enough though.

See #2233

(cherry picked from commit 1d50c2c39a)
2017-10-06 08:54:52 +02:00
Florian Bruhin
38bccd4fdd Remove unused import
(cherry picked from commit 629f6a6876)
2017-10-04 11:16:18 +02:00
Florian Bruhin
9a5668f7a0 Fix test_version after OpenGL removal 2017-10-04 09:32:33 +02:00
Florian Bruhin
48023e7b1d Use ctypes instead of PyOpenGL for QtWebEngine Nvidia workaround
Normally a dependency change like this wouldn't appear on a stable branch, but
it looks like multiple people have issues with importing PyOpenGL:

Traceback (most recent call last):
  ...
  File "/usr/lib/python3/dist-packages/qutebrowser/browser/webengine/webenginesettings.py", line 208, in init
    from OpenGL import GL  # pylint: disable=unused-variable
  File "/usr/lib/python3/dist-packages/OpenGL/GL/__init__.py", line 3, in <module>
    from OpenGL.GL.VERSION.GL_1_1 import *
  File "/usr/lib/python3/dist-packages/OpenGL/GL/VERSION/GL_1_1.py", line 10, in <module>
    from OpenGL import platform, constants, constant, arrays
  File "/usr/lib/python3/dist-packages/OpenGL/arrays/__init__.py", line 22, in <module>
    formathandler.FormatHandler.loadAll()
  File "/usr/lib/python3/dist-packages/OpenGL/arrays/formathandler.py", line 28, in loadAll
    cls.loadPlugin( entrypoint )
  File "/usr/lib/python3/dist-packages/OpenGL/arrays/formathandler.py", line 35, in loadPlugin
    plugin_class = entrypoint.load()
  File "/usr/lib/python3/dist-packages/OpenGL/plugins.py", line 14, in load
    return importByName( self.import_path )
  File "/usr/lib/python3/dist-packages/OpenGL/plugins.py", line 28, in importByName
    module = __import__( ".".join(moduleName), {}, {}, moduleName)
  File "/usr/lib/python3/dist-packages/OpenGL/arrays/vbo.py", line 430, in <module>
    def mapVBO( vbo, access=GL.GL_READ_WRITE ):
AttributeError: module 'OpenGL.GL' has no attribute 'GL_READ_WRITE'

Fixes #2821

(cherry picked from commit a942613d7f)
2017-10-04 06:54:08 +02:00
Florian Bruhin
74e1b1ec26 Make userscripts work on both Python 2 and 3
(cherry picked from commit dca962ca03)
2017-09-29 13:39:09 +02:00
Florian Bruhin
cfe7386f20 eslint: Turn off function-paren-newline 2017-09-10 12:50:25 +02:00
Jay Kamat
12b00dad44 Enforce a minimum size for non-pinned tabs
Closes #2826
2017-09-10 01:52:55 +02:00
Jay Kamat
ccf3cb6d7c Restructure minimum tab size behavior 2017-09-10 01:52:55 +02:00
Jay Kamat
fcd8be5b68 Test for saving a session with --only-active-window 2017-08-28 07:58:32 +02:00
cryzed
259d08ba29 :save-session --only-active-window implies --with-private for private windows 2017-08-28 07:58:32 +02:00
Florian Bruhin
9d65039b35 Ignore a new Geoclue error during tests 2017-08-08 22:01:36 +02:00
Florian Bruhin
e50b7b65a4 version.distribution(): Handle Funtoo 2017-08-08 21:29:07 +02:00
Florian Bruhin
1aefaaf7c7 Fix tests for QProcess changes 2017-07-23 22:11:01 +02:00
Florian Bruhin
4da89139d1 Disallow :spawn -u -d
(cherry picked from commit efe6719f4f354348e7db6f77dc22c319850de5d4)
2017-07-23 21:34:56 +02:00
Florian Bruhin
3f04c94047 Fix error message with :spawn -d
(cherry picked from commit c951b71307e666cb6a02c1c0e9f54131ac61266a)
2017-07-23 21:34:50 +02:00
Florian Bruhin
00f456fd7f Fix the "try again" button on error pages
Fixes #2810

(cherry picked from commit 5c367e7ab2)
2017-07-13 17:28:06 +02:00
Jay Kamat
00d5aa6b22 Refactor tab_close_prompt_if_pinned
Now it lives in tabbedbrowser.py as method instead of a static function

(cherry picked from commit 7dfca60893)
2017-07-13 11:03:28 +02:00
Jay Kamat
91c5eff2c9 Prompt when closing a pinned tab via the mouse
Closes #2761

(cherry picked from commit 4d1dbe11e8)
2017-07-13 11:03:22 +02:00
Florian Bruhin
0d704043ec Fix printing on macOS
Fixes #2798

(cherry picked from commit 53620ecce4)
2017-07-12 07:43:18 +02:00
Florian Bruhin
b11abb028b Remove unused import
(cherry picked from commit cfb169b5f0)
2017-07-09 12:40:30 +02:00
Florian Bruhin
474e904409 Move OpenGL workaround import
OpenGL.GL gets imported in earlyinit already anyways, so we can move everything
there.

(cherry picked from commit 9e7f2e470f)
2017-07-09 11:57:48 +02:00
Florian Bruhin
cc05cb1c67 Recommend QT_XCB_FORCE_SOFTWARE_OPENGL
This won't disable OpenGL for stuff started from qutebrowser.

See #2368.

(cherry picked from commit fcf5158258)
2017-07-08 17:37:44 +02:00
Florian Bruhin
e10ce420ab Improve earlyinit check for PyOpenGL
Importing OpenGL alone doesn't actually load libgl, it only checks that the
package is here. If libgl is missing, we'd later get an exception.

(cherry picked from commit b81474d2fd)
2017-07-08 17:34:41 +02:00
Florian Bruhin
5b5adc1a00 Fix :restart with private browsing mode
(cherry picked from commit 0de0bbfa71)
2017-07-08 10:46:57 +02:00
Florian Bruhin
63fa412882 Fix build_release.py 2017-07-07 15:18:14 +02:00
Florian Bruhin
47ad8f212e build_release: Fail GitHub uploads early 2017-07-07 14:28:44 +02:00
Florian Bruhin
7ac27fdd85 Add Gentoo instructions to backend warning 2017-07-06 00:40:58 +02:00
Florian Bruhin
d4baeb2ada Merge branch 'pr/2747' into v0.11.x 2017-07-05 22:15:23 +02:00
Florian Bruhin
0304040cbb Update docs 2017-07-05 22:14:01 +02:00
Florian Bruhin
a8120a23c4 Update comment for TabBarStyle 2017-07-05 22:13:24 +02:00
Florian Bruhin
eaecfe5882 build_release: Adjust Windows installer names 2017-07-04 22:27:17 +02:00
Florian Bruhin
725d4a44f0 build_release: Don't fail if hdiutil detach fails 2017-07-04 22:16:21 +02:00
Florian Bruhin
c424a745d8 build_release: Add comment about missing 3rdparty upgrade 2017-07-04 21:36:20 +02:00
Florian Bruhin
3cbe419cee Update Python version for Windows in release checklist 2017-07-04 21:36:20 +02:00
Florian Bruhin
8f03a36862 build_release: Use correct path when copying dirs 2017-07-04 21:31:53 +02:00
Florian Bruhin
7ecdd6c1c5 build_release: Print some more information about copied files 2017-07-04 21:04:08 +02:00
Florian Bruhin
d96403fe93 build_release: Clean up before doing stuff
So we can inspect the results later.
2017-07-04 21:03:55 +02:00
Florian Bruhin
2df9508e44 Add PyQt5 OpenGL module to PyInstaller hiddenimports 2017-07-04 21:03:34 +02:00
Florian Bruhin
defe140d98 build_release: Run tox with -vv 2017-07-04 19:56:54 +02:00
Florian Bruhin
28410b8533 Release v0.11.0 2017-07-04 18:02:34 +02:00
Florian Bruhin
378914b327 Ignore another new geoclue error during tests 2017-07-04 18:01:24 +02:00
Florian Bruhin
023bf82638 Update for PyQt 5.9.1 2017-07-04 17:31:09 +02:00
Florian Bruhin
45b1285402 Merge pull request #2765 from jgkamat/jay/tab-crashes
Refactor set_tab_pinned to take a tab widget.
2017-07-04 17:24:10 +02:00
Florian Bruhin
629038632c Add proxy support for QtWebEngine and Qt 5.7.1
This used to give us crashes in libproxy:
https://github.com/libproxy/libproxy/issues/45
https://bugreports.qt.io/browse/QTBUG-56852

However, trying again with Qt 5.7.1 on Debian and from PyPI, this doesn't happen
anymore, so it was probably something with how Archlinux handled things.

See #2082, #2775.
Reverts fd29528e4f
2017-07-03 10:29:28 +02:00
Florian Bruhin
3b53ec1cb6 Skip tests with permission changes if they didn't work
This e.g. wouldn't work inside of a Docker container otherwise.
2017-07-03 10:07:40 +02:00
Florian Bruhin
2f26490536 Remove FIXME 2017-07-02 14:03:38 +02:00
Florian Bruhin
69337ed264 Update tox default envlist 2017-07-02 13:07:13 +02:00
Jay Kamat
2fbadc46d2 Remove error when count is invalid to :tab-pin 2017-06-30 09:57:39 -07:00
Florian Bruhin
9cedaa60bc Check for PyQt5.QtQml in earlyinit 2017-06-30 14:56:02 +02:00
Florian Bruhin
e4a054d34e Stop marking QtWebEngine as experimental 2017-06-30 10:42:33 +02:00
Jay Kamat
596dee69d6 Clean up pin_tab
Also add a test case for :pin-tab with an invalid count
2017-06-29 20:04:02 -07:00
Florian Bruhin
0d5a33ef2a Update changelog 2017-06-29 23:21:10 +02:00
Florian Bruhin
d132b6ed71 Fix :scroll-page with --bottom-navigate on QtWebEngine
There were two issues here:

- The comparison was backwards, causing scroller.at_bottom() to always return
  true.
- When zoomed in, jsret['px']['y'] can be a float, which means we can be
  slightly off when checking the difference - math.ceil() fixes that.
2017-06-29 22:39:48 +02:00
Jay Kamat
302961a86a Refactor set_tab_pinned to take a tab widget.
See #2759
2017-06-28 22:22:33 -07:00
Florian Bruhin
f136f78802 Fix :undo documentation
See #2759
2017-06-28 22:41:08 +02:00
Florian Bruhin
a98a6ac0c8 travis: Write a sane sources.list
Also updates nodejs
2017-06-28 21:42:50 +02:00
Florian Bruhin
5ec94f96fd Allow a trailing % for :zoom 2017-06-26 21:51:35 +02:00
Florian Bruhin
92d5f6c41d Ignore _remove_tab for crashed deleted tabs 2017-06-26 20:50:17 +02:00
Florian Bruhin
24caaea54d Handle OSError in SessionManager.delete 2017-06-26 19:52:07 +02:00
Florian Bruhin
130be2aedc Handle OSError when trying to delete autosave session 2017-06-26 19:47:54 +02:00
Florian Bruhin
736dd77a6e Regenerate authors 2017-06-26 18:05:25 +02:00
Florian Bruhin
8a7610206e Merge branch 'master' of https://github.com/jupart/qutebrowser 2017-06-26 18:04:57 +02:00
pyup-bot
78c93e1225 Update pytest-rerunfailures from 2.1.0 to 2.2 2017-06-26 15:47:14 +02:00
pyup-bot
e8dac08a35 Update cheroot from 5.5.2 to 5.7.0 2017-06-26 15:47:13 +02:00
pyup-bot
6d1775fcd6 Update pylint from 1.7.1 to 1.7.2 2017-06-26 15:47:11 +02:00
Justin Partain
cb67a911fa Remove recommendation to use '-c' command line argument, which doesn't exist 2017-06-21 10:56:25 -04:00
Marius
df6b8b7ff5 Update tabwidget.py 2017-06-21 09:03:15 +02:00
Marius
f3a2b84033 remove space 2017-06-20 23:58:23 +02:00
Marius
dfedddf0bd Wrap scroll button workaround in try/except
for older pyqt5 versions (5.2.1)
2017-06-20 23:55:11 +02:00
Marius
6e166d139a Fix alignment of scroll buttons in tab bar 2017-06-20 21:18:13 +02:00
Florian Bruhin
cb5cd1a910 Remove old test_commands.py 2017-06-20 15:20:32 +02:00
Florian Bruhin
994e8c692f Merge different FakeTabbedBrowser objects 2017-06-20 15:19:53 +02:00
Florian Bruhin
096b0a7a37 Remove unused import 2017-06-20 15:03:42 +02:00
Florian Bruhin
750ef834dc Make PyOpenGL a required dependency
Looks like the "black screen" issue isn't the only thing going wrong, some
people even report segfaults since the vendor check was added.
2017-06-20 13:05:53 +02:00
Florian Bruhin
73940a64bb Update docs 2017-06-20 12:46:55 +02:00
Florian Bruhin
cf3c7266aa Make show_error keyword-only 2017-06-20 12:45:36 +02:00
Florian Bruhin
06d4a24bd1 Merge branch 'master' of https://github.com/iordanisg/qutebrowser 2017-06-20 12:45:21 +02:00
Florian Bruhin
3a7a3909d7 Merge remote-tracking branch 'origin/pyup-scheduled-update-06-19-2017' 2017-06-20 12:44:05 +02:00
Florian Bruhin
27c6aa00bd travis: Add group: edge 2017-06-19 18:15:35 +02:00
Iordanis Grigoriou
f0ff02fcb2 Avoid throwing exception when no last focused tab exists 2017-06-19 15:48:17 +02:00
pyup-bot
aa460a7abd Update hypothesis from 3.11.3 to 3.11.6 2017-06-19 15:46:21 +02:00
pyup-bot
0306c3e898 Update cheroot from 5.5.0 to 5.5.2 2017-06-19 15:46:19 +02:00
pyup-bot
61737f95a9 Update requests from 2.17.3 to 2.18.1 2017-06-19 15:46:18 +02:00
pyup-bot
5913f92b19 Update requests from 2.17.3 to 2.18.1 2017-06-19 15:46:16 +02:00
pyup-bot
86fffb5462 Update requests from 2.17.3 to 2.18.1 2017-06-19 15:46:15 +02:00
Florian Bruhin
3053ed01e4 backers: Add Bostan 2017-06-19 15:30:09 +02:00
Florian Bruhin
2adb57f263 travis: Remove the archlinux-ng docker env
Archlinux merged qt5-webkit-ng into qt5-webkit
2017-06-19 14:17:56 +02:00
Florian Bruhin
7062f9e060 Update qt5-webkit-ng docs for Archlinux 2017-06-19 13:44:41 +02:00
Florian Bruhin
df0bd23d79 Make pylint shut up about test_version 2017-06-19 13:42:19 +02:00
Florian Bruhin
40b949364e Fix qute://backend-warning issues
We now set a title correctly, and don't crash if we find a Debian/Ubuntu without
version.
2017-06-19 13:37:00 +02:00
Florian Bruhin
bef372e5f5 Clear search on page load
Fixes #2728
2017-06-19 10:27:27 +02:00
Florian Bruhin
4ae8e247d0 Show 'legacy QtWebKit' in version output 2017-06-19 10:24:33 +02:00
Florian Bruhin
8191a5465a Regenerate authors 2017-06-19 09:44:04 +02:00
Florian Bruhin
5bb63e67e0 Remove another stray # 2017-06-19 09:43:45 +02:00
Florian Bruhin
8494332c3a Merge branch 'fix-tabbar-padding' of https://github.com/kmarius/qutebrowser 2017-06-19 09:43:26 +02:00
Florian Bruhin
df6c4c6e73 Fix earlyinit.qt_version issues 2017-06-19 09:42:49 +02:00
Florian Bruhin
9b5227b987 Improve test_version output 2017-06-19 09:06:18 +02:00
Florian Bruhin
6c534bea6b Actually remove version import in earlyinit... 2017-06-19 08:59:26 +02:00
Florian Bruhin
fdba676933 Move version.qt_version() to earlyinit
Importing version in earlyinit is a bad idea, as it already pulls in a lot of
stuff we don't want.
2017-06-19 08:57:29 +02:00
Marius
de743732aa remove # inside comment 2017-06-19 08:29:23 +02:00
Marius
ebd442ea95 add needed parens and remove trailing whitespace 2017-06-18 23:07:38 +02:00
Marius
68f172558b fix line length 2017-06-18 22:44:06 +02:00
Marius
4b2bf12efa Fix padding of remaining tabbar space with pinned tabs 2017-06-18 21:49:04 +02:00
Florian Bruhin
a5db21abe9 Update FAQ, fixes #2732 2017-06-17 15:47:39 +02:00
Florian Bruhin
695a2656fe Rename webelem.js functions to match WebEngineElem
Fixes #2726
2017-06-16 23:14:17 +02:00
Florian Bruhin
9cc688ea2b Fix initial tab sizing with vertical tabbar 2017-06-16 23:00:16 +02:00
Iordanis Grigoriou
e14477375b Fix typo in test 2017-06-16 12:41:30 +02:00
Iordanis Grigoriou
f28d523225 Select the last focused tab when running ':tab-focus <current tab number>' 2017-06-16 12:28:56 +02:00
Florian Bruhin
b37d040d44 Add version check for 5.8 search segfault workaround 2017-06-14 10:57:32 +02:00
Florian Bruhin
2ffb10badf Merge pull request #2715 from qutebrowser/pyup-scheduled-update-06-12-2017
Scheduled weekly dependency update for week 24
2017-06-14 10:44:11 +02:00
Florian Bruhin
54154e2434 Mark :stop test as flaky
Looks like the requests sometimes aren't updated, but I have no idea why.
2017-06-12 18:15:05 +02:00
Florian Bruhin
38d54cb112 Stabilize history tests
Get current URL right away in :view-source, and wait until source is shown in
the test.
2017-06-12 18:13:17 +02:00
pyup-bot
c9979d18db Update pytest from 3.1.1 to 3.1.2 2017-06-12 15:45:19 +02:00
pyup-bot
a2878a382c Update hypothesis from 3.11.1 to 3.11.3 2017-06-12 15:45:17 +02:00
pyup-bot
1deb6e53d0 Update chardet from 3.0.3 to 3.0.4 2017-06-12 15:45:16 +02:00
pyup-bot
227fd47f2f Update chardet from 3.0.3 to 3.0.4 2017-06-12 15:45:15 +02:00
pyup-bot
62d56237bd Update chardet from 3.0.3 to 3.0.4 2017-06-12 15:45:13 +02:00
Florian Bruhin
b687ede25c Adjust eslintrc for eslint 4.0 2017-06-12 09:23:20 +02:00
Florian Bruhin
57fbfbd606 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
2017-06-11 17:48:01 +02:00
Florian Bruhin
2e5620cac1 Try a different way of fixing userscript crashes 2017-06-11 14:44:19 +02:00
Florian Bruhin
a49adc6298 Revert "Work around userscript crash issue"
This reverts commit 73ff2afb3f.

Doesn't seem to help, at least for pkill9...
2017-06-11 14:41:58 +02:00
Florian Bruhin
73ff2afb3f Work around userscript crash issue 2017-06-11 13:17:40 +02:00
Florian Bruhin
89218c9d31 Improve error handling in version.opengl_vendor()
Not being able to get versionFunctions is now handled, and the cleanup is done
in a finally: block.
2017-06-09 23:14:34 +02:00
Florian Bruhin
9c851293ac pyinstaller: Add PyQt5.QtOpenGL to hiddenimports 2017-06-09 21:50:52 +02:00
Florian Bruhin
ad260366ef Remove ":messages without messages" test
We can never know for sure there aren't any messages - for example, on Travis we get a message about XDG_RUNTIME_DIR being unset on Qt 5.9.
2017-06-09 11:04:21 +02:00
Florian Bruhin
9f9061f146 Update docs 2017-06-09 11:04:04 +02:00
Florian Bruhin
b874432c69 Remove private browsing notes for QtWebKit-NG 2017-06-09 10:31:21 +02:00
Florian Bruhin
250da212cd Adjust tests for new QtWebKit-NG 2017-06-09 10:28:41 +02:00
Florian Bruhin
d2c289b6a6 Adjust changelog 2017-06-08 14:18:40 +02:00
Florian Bruhin
6361a5bab2 Merge branch 'private_tag_tab_title' of https://github.com/craftyguy/qutebrowser 2017-06-08 14:17:43 +02:00
Florian Bruhin
56f1dfb9eb Merge remote-tracking branch 'origin/pyup-update-isort-4.2.14-to-4.2.15' 2017-06-08 14:17:25 +02:00
Florian Bruhin
ddf4521305 Fix :messages tests 2017-06-08 14:16:30 +02:00
Florian Bruhin
c8d4ef13de Adjust default :messages level 2017-06-08 12:35:21 +02:00
Florian Bruhin
63f6409fdb Remove stray StatusBar._option 2017-06-08 12:29:07 +02:00
Clayton Craft
daa12ed435 Add private mode title format for tabs too
This continues the spirit of my previous PR and allows formatting tab
titles to designate when private mode is enabled. I didn't even realize
that tab title-format was a separate thing from window-title-format
(yes, it's in the name.. silly craftyguy), until now.
2017-06-07 08:17:03 -07:00
Florian Bruhin
7e09b7a707 manifest: Exclude all hidden files 2017-06-07 12:25:15 +02:00
Florian Bruhin
1123129dc4 Slow down pyup requirement updates 2017-06-07 11:19:17 +02:00
pyup-bot
b7cb852c1a Update isort from 4.2.14 to 4.2.15 2017-06-07 09:50:12 +02:00
pyup-bot
dbea815c3a Update isort from 4.2.14 to 4.2.15 2017-06-07 09:50:11 +02:00
Florian Bruhin
09baa08948 Remove colon from error page 2017-06-06 22:15:19 +02:00
Florian Bruhin
dd4fb87db6 Update docs 2017-06-06 18:25:42 +02:00
Florian Bruhin
8990513c1b Merge commit '49b8737f7979fc878ba25aed94cc3e57f481ae3a' into craftyguy/private_tab_title 2017-06-06 18:23:51 +02:00
Florian Bruhin
8df0b063be Get rid of utils.unused because it's unused 2017-06-06 17:04:21 +02:00
Clayton Craft
49b8737f79 Implement changing of tab title when privacy mode is enabled 2017-06-06 08:00:19 -07:00
Florian Bruhin
a5af98b063 Add a few tests for qutebrowser.is_ignored_chromium_message 2017-06-06 16:26:01 +02:00
Florian Bruhin
cb03fb7d80 Make process/thread ID optional for Chromium messages
Looks like at least on Travis they're not always there.
2017-06-06 16:18:53 +02:00
Florian Bruhin
dd490f85d8 Update docs 2017-06-06 16:18:15 +02:00
Florian Bruhin
6d175fbb4b Get rid of configtypes.WebKitBytes 2017-06-06 16:17:44 +02:00
Florian Bruhin
f9b046d766 Get proper settings object in WebEngineElement._click_js 2017-06-06 16:15:25 +02:00
Florian Bruhin
a7413d7b4a Remove stale getter 2017-06-06 15:59:42 +02:00
Florian Bruhin
1b0a125cf3 websettings: Improve errors when setting settings=... 2017-06-06 15:59:42 +02:00
Florian Bruhin
b1a0bc13f2 webkitsettings: Use self._get_settings in CookiePolicy._set 2017-06-06 15:59:42 +02:00
Florian Bruhin
30fe3ed328 Remove old websetting comments 2017-06-06 15:46:54 +02:00
Florian Bruhin
e17494c972 Cleanup 2017-06-06 15:25:21 +02:00
Florian Bruhin
9c9a5914b3 Changelog fixup 2017-06-06 14:50:57 +02:00
Florian Bruhin
0ca59f2184 Rename storage -> offline-web-application-storage to -cache 2017-06-06 14:50:57 +02:00
Florian Bruhin
c696723650 Merge storage -> offline-storage-database into local-storage setting
Looks like it's the same with QtWebEngine too - setting LocalStorageEnabled also
toggles WebSQL there.
2017-06-06 14:50:57 +02:00
Florian Bruhin
626d299a0d Add webenginesettings.DefaultProfileSetter.__repr__ 2017-06-06 14:50:57 +02:00
Florian Bruhin
93d21c376d Regenerate docs 2017-06-06 14:50:57 +02:00
Florian Bruhin
2a32e26846 Get rid of various rarely customized settings
All those were customized by some <5 people in the past few years of crash
reports.

Closes #1751.
See #2639.
2017-06-06 14:50:57 +02:00
Florian Bruhin
1785b72393 Refactor websettings default handling
With per-domain settings, having a getter for a setting gets really complicated,
as there isn't one true value for a setting.

The only reason we needed those getters is to save away the default values for
some settings where we were unsure what the defaults are.

- For font setters, we can get the defaults from QFont, like QtWeb{Kit,Engine}
  do.
- For font sizes, we hardcode the defaults QtWeb{Kit,Engine} hardcodes too.
- For maximum-page-in-cache, we hardcode 0, just like QtWebKit.
- For default-encoding, we hardcode iso-8559-1, like QtWeb{Kit,Engine}
- For offline-storage-default-quota, we hardcode 5MB, like QtWebKit
- For offline-web-application-cache-quota, we hardcode MAXINT as default value,
  but we still keep the empty value in the config. It means "no quota"
  internally in QtWebKit, but it's a too confusing value to have in the config.
- For object-cache-capacities it's a bit more complicated (the defaults are
  calculated based on disk space), but let's just get rid of the setting
  altogether in the next commit (see #1751).

Closes #2639.
2017-06-06 14:50:57 +02:00
Florian Bruhin
2f5756e63b Merge commit '0501cc626c27a369c2e311c71c2ce2c5cc3f9442' into pyup-bot/pyup-update-isort-4.2.13-to-4.2.14 2017-06-06 10:19:00 +02:00
Florian Bruhin
998f93dfd3 tests: Properly parse Chromium logging messages
Closes #2519
2017-06-06 10:01:45 +02:00
pyup-bot
0501cc626c Update isort from 4.2.13 to 4.2.14 2017-06-06 09:20:10 +02:00
pyup-bot
d57f96da87 Update isort from 4.2.13 to 4.2.14 2017-06-06 09:20:09 +02:00
Florian Bruhin
f280129e7c Merge commit 'ccdba004272ef40dfa1668a21329876253877155' into pyup-bot/pyup-update-astroid-1.5.2-to-1.5.3 2017-06-06 07:59:15 +02:00
Florian Bruhin
46d11655d8 Merge commit '6a17ee66adee0da5b88c0246c833cf7023bee9cc' into pyup-bot/pyup-update-py-1.4.33-to-1.4.34 2017-06-06 07:59:11 +02:00
Florian Bruhin
b746fe666c Remove colorama from test requirements
Otherwise it collides with the colorama in qutebrowser's own requirements.
2017-06-06 07:56:30 +02:00
Florian Bruhin
d4f58533c0 Add error messages for QtWebEngine downloads
Fixes #2164
2017-06-06 06:29:52 +02:00
Florian Bruhin
0e85342f57 Update changelog 2017-06-05 23:50:24 +02:00
Florian Bruhin
73249d8abe Adjust ignored Chromium messages for Qt 5.9 debug builds 2017-06-05 21:57:53 +02:00
Florian Bruhin
eea3396cdc Add hunter to test requirements 2017-06-05 20:18:36 +02:00
Florian Bruhin
27ea9a6954 Fix test_debug_trace 2017-06-05 20:17:39 +02:00
Florian Bruhin
a45de9cef2 Remove request tracking from NetworkManager
This breaks things (with "ValueError: list.remove(x): x not in list") on
PyQt 5.9 (probably due to the destroyed object tracking it introduces?).

This was originally added in 0abb5cf738 to fix
some segfaults on exit, but things look much better with recent Qt versions.
2017-06-05 18:19:29 +02:00
Florian Bruhin
211f9cfc8c Add SB to backers 2017-06-05 13:04:37 +02:00
Florian Bruhin
4d64bcc852 Make version.opengl_vendor() work with an existing context
This makes it possible to use it in :debug-console
2017-06-04 23:05:23 +02:00
Florian Bruhin
a858611bb9 Don't make errors in version.opengl_vendor() fatal
Fixes #2694
2017-06-04 22:55:39 +02:00
pyup-bot
6a17ee66ad Update py from 1.4.33 to 1.4.34 2017-06-04 18:49:11 +02:00
pyup-bot
c15f7e8e72 Update py from 1.4.33 to 1.4.34 2017-06-04 18:49:09 +02:00
Florian Bruhin
71117f6dea Adjust debian deps in INSTALL 2017-06-04 15:12:11 +02:00
Florian Bruhin
70b3231dd1 Add some more stuff to the FAQ 2017-06-04 15:11:08 +02:00
pyup-bot
ccdba00427 Update astroid from 1.5.2 to 1.5.3 2017-06-03 16:33:05 +02:00
Florian Bruhin
c0705e735f Merge commit '9841f75f915a27a7bb81e917db08b615624cd1b6' into pyup-bot/pyup-update-isort-4.2.9-to-4.2.13 2017-06-02 21:54:51 +02:00
Florian Bruhin
722c117d54 Better handling of OpenSSL 1.1
Fixes #2690
2017-06-02 21:52:53 +02:00
pyup-bot
9841f75f91 Update isort from 4.2.9 to 4.2.13 2017-06-02 18:50:05 +02:00
pyup-bot
5f0f1cb7da Update isort from 4.2.9 to 4.2.13 2017-06-02 18:50:03 +02:00
Florian Bruhin
a90429fe6e Update needed dependencies
Fixes #2683
2017-06-01 19:30:32 +02:00
Florian Bruhin
1615c0aa1a Merge commit '4c9c9bdf989d18ffdd0c80e84fdde0ee9601d448' into pyup-bot/pyup-update-isort-4.2.5-to-4.2.9 2017-06-01 19:14:43 +02:00
pyup-bot
4c9c9bdf98 Update isort from 4.2.5 to 4.2.9 2017-06-01 18:04:04 +02:00
pyup-bot
002cfedaef Update isort from 4.2.5 to 4.2.9 2017-06-01 18:04:03 +02:00
Florian Bruhin
e15b7a4fde Recompile requirements
This reintroduces packages which have been masked before (as they were pip
dependencies).
2017-06-01 16:42:12 +02:00
Florian Bruhin
3523c2e78b Merge commit 'a9d739ec04898563d3d7cb790a621fb97fe0f23d' into pyup-bot/pyup-update-pytest-3.1.0-to-3.1.1 2017-06-01 16:24:34 +02:00
Florian Bruhin
0f9eb2ac54 Merge commit 'bf97bc9d3e97e608734e4ebc0d071c71ab1ab013' into pyup-bot/pyup-update-parse-1.8.0-to-1.8.2 2017-06-01 16:23:12 +02:00
Florian Bruhin
0945179f74 Merge commit '71cca7c154816678f955b242438417a2d8026198' into pyup-bot/pyup-update-setuptools-35.0.2-to-36.0.1 2017-06-01 16:22:58 +02:00
Florian Bruhin
f49bbcbb9f Sort names in recompile_requirements again
This got lost with the previous revert
2017-06-01 16:21:48 +02:00
Florian Bruhin
a7143d5649 Revert "Update recompile_requirements for newer pips"
This reverts commit 8afc215c3d.

Since setuptools 36, it now vendors its dependencies again, as the vendoring has
lead to various issues.
2017-06-01 16:16:04 +02:00
pyup-bot
71cca7c154 Update setuptools from 35.0.2 to 36.0.1 2017-06-01 15:37:03 +02:00
Florian Bruhin
a690d242a4 Update webengine dependency message 2017-06-01 14:03:46 +02:00
Florian Bruhin
c4d2b60f4d Initial backers file update 2017-06-01 13:54:48 +02:00
pyup-bot
bf97bc9d3e Update parse from 1.8.0 to 1.8.2 2017-06-01 02:30:03 +02:00
pyup-bot
a9d739ec04 Update pytest from 3.1.0 to 3.1.1 2017-05-31 19:37:05 +02:00
Florian Bruhin
587861d899 Check for OpenGL ES later
It looks like we still got False on AppVeyor with "versionFunctions: Not
supported on OpenGL ES". Hopefully this helps.
2017-05-31 11:44:34 +02:00
Florian Bruhin
eac284d880 Skip test_opengl_vendor without QtOpenGL
The test fails on Ubuntu Xenial because QtOpenGL is not installed.
This isn't a problem with real-life usage though, as we only call it with
QtWebEngine, and that ensures that QtOpenGL is available.
2017-05-31 10:29:46 +02:00
Florian Bruhin
4cec9adce6 Fix lint 2017-05-31 09:44:17 +02:00
Florian Bruhin
28f7444d9e Update changelog 2017-05-31 07:14:19 +02:00
Florian Bruhin
912cea6e7d Improve version.opengl_vendor()
On Windows with OpenGL ES we can't use versionFunctions, so we just return None
early.

Also, this fixes some lint and adds a smoke test.
2017-05-30 19:23:27 +02:00
Florian Bruhin
b8a32c577f Merge branch 'nouveau' 2017-05-30 17:36:58 +02:00
Florian Bruhin
62b44c5338 Fix lint 2017-05-30 17:07:31 +02:00
Florian Bruhin
eb9a0c01ba Set backend-warning-shown in test_invocations 2017-05-30 16:49:39 +02:00
Florian Bruhin
67755e6f6c Add error message for QtWebEngine and Nouveau
See #2368
2017-05-30 16:47:39 +02:00
Florian Bruhin
048aec1aa6 Revert "Reorganize earlyinit checks"
This reverts commit 6f3f9ede01a6b30b105d5110a48cfea592e8db52.
2017-05-30 15:53:29 +02:00
Florian Bruhin
d0461eece3 Reorganize earlyinit checks
We first do all checks we can without knowing the backend, before getting that.
This is because we need to do some more stuff in get_backend now.
2017-05-30 15:53:29 +02:00
Florian Bruhin
bec8299b2e Update install instructions
Closes #2440
2017-05-30 15:34:46 +02:00
Florian Bruhin
58de271fc1 Regenerate authors 2017-05-30 10:40:33 +02:00
Florian Bruhin
65329c97c7 Merge branch 'pyup-bot/pyup-update-requests-2.16.5-to-2.17.3' 2017-05-30 10:39:50 +02:00
Florian Bruhin
f656cda248 Merge commit '798cae51d4971a74fa5a7de4815b32d9871caad5' 2017-05-30 10:39:20 +02:00
Florian Bruhin
8167c55e61 Merge commit 'ee99b25bf6eb203726a796f53fa60036f5caeb24' into pyup-bot/pyup-update-requests-2.16.5-to-2.17.3 2017-05-30 10:37:11 +02:00
Florian Bruhin
1c6fd6f725 Add a backend warning when using QtWebKit 2017-05-30 08:42:37 +02:00
Florian Bruhin
4cb82af11e Add QUTE_FAKE_OS_RELEASE envvar 2017-05-30 07:37:10 +02:00
pyup-bot
ee99b25bf6 Update requests from 2.16.5 to 2.17.3 2017-05-30 01:20:03 +02:00
pyup-bot
009acc1600 Update requests from 2.16.5 to 2.17.3 2017-05-30 01:20:02 +02:00
pyup-bot
863e1f1d84 Update requests from 2.16.5 to 2.17.3 2017-05-30 01:20:00 +02:00
Philipp Hansch
798cae51d4 Fix pylint issue 2017-05-29 23:15:22 +02:00
Philipp Hansch
ad8cf371b8 Style table of contents properly for qute theme 2017-05-29 21:50:06 +02:00
Philipp Hansch
932b2814b0 Hide false header element from the TOC 2017-05-29 21:50:04 +02:00
Philipp Hansch
abd3333b9f Add TOC to installation instructions
This adds a Table of Contents to the installation instructions to
improve the navigation within the document.

I decided to use the command line to configure the TOC because there
were problems with using just using an attribute entry in the document
header.
Specifically the insertion of the `header.asciidoc` into the resulting
HTML file prevented the attribute entry approach from working.

The TOC can now be inserted into any doc file using

    toc::[]
2017-05-29 21:14:01 +02:00
Florian Bruhin
ef504e5b25 Allow None for WebKitElement.value
This fixes an exception when trying to run :open-editor with a comment field
with QtWebKit:

    16:37:51 DEBUG    webelem    webelem:is_editable:238 Checking if element is editable: <qutebrowser.browser.webkit.webkitelem.WebKitElement html='<div id="writer9997095275-writer" class="writer selectable no-lub put-art-here ui-droppable empty" style="min-height: 146px; width: 1169px;" contenteditable="true"></div>'>
    16:37:51 ERROR    misc       crashsignal:exception_hook:205 Uncaught exception
    Traceback (most recent call last):
      File "/home/florian/proj/qutebrowser/git/qutebrowser/app.py", line 882, in eventFilter
        return handler(event)
      File "/home/florian/proj/qutebrowser/git/qutebrowser/app.py", line 842, in _handle_key_event
        return man.eventFilter(event)
      File "/home/florian/proj/qutebrowser/git/qutebrowser/keyinput/modeman.py", line 337, in eventFilter
        return self._eventFilter_keypress(event)
      File "/home/florian/proj/qutebrowser/git/qutebrowser/keyinput/modeman.py", line 168, in _eventFilter_keypress
        handled = parser.handle(event)
      File "/home/florian/proj/qutebrowser/git/qutebrowser/keyinput/basekeyparser.py", line 307, in handle
        handled = self._handle_special_key(e)
      File "/home/florian/proj/qutebrowser/git/qutebrowser/keyinput/basekeyparser.py", line 136, in _handle_special_key
        self.execute(cmdstr, self.Type.special, count)
      File "/home/florian/proj/qutebrowser/git/qutebrowser/keyinput/keyparser.py", line 44, in execute
        self._commandrunner.run(cmdstr, count)
      File "/home/florian/proj/qutebrowser/git/qutebrowser/commands/runners.py", line 275, in run
        result.cmd.run(self._win_id, args, count=count)
      File "/home/florian/proj/qutebrowser/git/qutebrowser/commands/command.py", line 525, in run
        self.handler(*posargs, **kwargs)
      File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/commands.py", line 1600, in open_editor
        tab.elements.find_focused(self._open_editor_cb)
      File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/webkit/webkittab.py", line 589, in find_focused
        callback(webkitelem.WebKitElement(elem, tab=self._tab))
      File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/commands.py", line 1580, in _open_editor_cb
        text = elem.value()
      File "/home/florian/proj/qutebrowser/git/qutebrowser/browser/webkit/webkitelem.py", line 116, in value
        assert isinstance(val, (int, float, str)), val
    AssertionError: None
2017-05-29 16:56:36 +02:00
Florian Bruhin
7186dcb98f Send crash reports to private pastebin
Fixes #481
2017-05-29 09:20:10 +02:00
Florian Bruhin
b32223acc7 Only inherit private mode when window is set
Otherwise, everything calling _open in a private window (like :quickmark-load)
will open a new window.
2017-05-29 06:37:28 +02:00
pyup-bot
615b027fad Update hypothesis from 3.11.0 to 3.11.1 2017-05-28 16:24:59 +02:00
Florian Bruhin
4f6474dc69 Add new requests requirements 2017-05-28 11:30:28 +02:00
Florian Bruhin
f273939521 Merge commit '9e3847863868e780b5a87975254959731c9ac2fb' into pyup-bot/pyup-update-requests-2.14.2-to-2.16.5 2017-05-28 11:25:12 +02:00
Florian Bruhin
8bd6974042 Open a window with an empty session
With general -> save-session on and only private windows open, we can easily get
a session file with "windows: []" in it. If we loaded such a file, we got no
windows at all when qutebrowser started.

Fixes #2664
2017-05-28 11:15:51 +02:00
Florian Bruhin
beb731c04c Move signal connections around 2017-05-28 10:54:16 +02:00
Florian Bruhin
06e754a632 Track HTML fullscreen per-tab
We now automatically get out of fullscreen when switching away from a
fullscreened tab. This also means we can't get into a situation where we can't
leave fullscreen anymore.

Fixes #2379.
2017-05-28 10:51:14 +02:00
pyup-bot
9e38478638 Update requests from 2.14.2 to 2.16.5 2017-05-28 09:52:02 +02:00
pyup-bot
3014a5207a Update requests from 2.14.2 to 2.16.5 2017-05-28 09:52:00 +02:00
pyup-bot
0106036e9e Update requests from 2.14.2 to 2.16.5 2017-05-28 09:51:59 +02:00
Florian Bruhin
a18ebd52a9 Rename TabWidget methods 2017-05-26 18:39:35 +02:00
Florian Bruhin
75409966a7 pyinstaller: Exclude tkinter 2017-05-24 21:53:53 +02:00
Florian Bruhin
54a4a087d4 nsis: Use solid lzma compressor
File sizes, 32 bit:
- default: 64 MB
- lzma: 50 MB
- lzma solid: 47 MB

64 bit:
- default: 75 MB
- lzma: 58 MB
- lzma solid: 55 MB

Between lzma and lzma solid, installation speed doesn't seem to vary much, so
let's go for the smallest.
2017-05-24 21:31:18 +02:00
Florian Bruhin
464eb29704 Set PATH in build_release.py when calling tox
On Windows, we need to have the proper Python folder in PATH when using PyQt5,
so it can load python3.dll properly.
2017-05-24 20:52:57 +02:00
Florian Bruhin
1adcf28e31 build_release: Adjust Windows Python paths 2017-05-24 13:30:11 +02:00
Florian Bruhin
ee320ade21 Regenerate authors 2017-05-24 08:40:20 +02:00
Florian Bruhin
b06599b2c9 Merge branch 'pyup-bot/pyup-update-hypothesis-3.10.0-to-3.11.0' 2017-05-24 08:39:09 +02:00
Florian Bruhin
52f077a780 Merge commit 'baa46aa7c1e54c5007ec35daf015225e425d0acd' 2017-05-24 08:39:09 +02:00
Florian Bruhin
49d7c44e6d Merge commit 'baa46aa7c1e54c5007ec35daf015225e425d0acd' into pyup-bot/pyup-update-hypothesis-3.10.0-to-3.11.0 2017-05-24 08:38:52 +02:00
Florian Bruhin
4e48f878ba build_release: Call tox with -v 2017-05-24 08:37:06 +02:00
Florian Bruhin
b811b9e380 Run update_3rdparty correctly from build_release 2017-05-24 08:37:06 +02:00
Florian Bruhin
e012b738f7 Add qutebrowser.nsi to MANIFEST.in 2017-05-24 08:37:06 +02:00
Florian Bruhin
59760b58d9 Add windows installers to build_release 2017-05-24 08:37:06 +02:00
Florian Bruhin
b6b78ba5eb Fix up NSIS paths 2017-05-24 08:37:06 +02:00
Florian Bruhin
86a61ba59a Remove nsis subfolder 2017-05-24 08:37:06 +02:00
Florian Bruhin
95d56bfc85 nsis: Use proper folders 2017-05-24 08:37:06 +02:00
Florian Bruhin
4879b48afe Merge nsis files into one 2017-05-24 08:37:06 +02:00
Link
bbd33d24a3 Initial nsis install script 2017-05-24 08:37:06 +02:00
pyup-bot
baa46aa7c1 Update hypothesis from 3.10.0 to 3.11.0 2017-05-24 02:24:52 +02:00
Florian Bruhin
681ce601e3 Add tor to FAQ 2017-05-23 22:23:15 +02:00
Florian Bruhin
e96f085f8d Merge commit '38ca583084e89de0da35cb1b626d21b051ea2c70' 2017-05-23 17:43:01 +02:00
Florian Bruhin
ffb4bb5f7c Improve chrome:// URL docs 2017-05-23 17:28:42 +02:00
Florian Bruhin
bc8e176a70 Update authors 2017-05-23 17:22:20 +02:00
Florian Bruhin
8b7cdb5d15 Merge commit 'a1e1e90ec916bcff0bf4fd5500fe80408f860f8b' 2017-05-23 17:22:08 +02:00
Florian Bruhin
70a28ed810 Update authors 2017-05-23 17:19:10 +02:00
Florian Bruhin
af1e1d9239 Merge commit 'c814ced7b35968cfdeb6284cc79168bfffed7c85' 2017-05-23 17:18:55 +02:00
Florian Bruhin
0f3a17ae88 Fix raw string prefix 2017-05-23 10:09:06 +02:00
Florian Bruhin
ea2fbc427a tests: Use match= for pytest.raises 2017-05-23 09:36:00 +02:00
Florian Bruhin
af7923de4d tests: Use pytest.param 2017-05-23 08:08:46 +02:00
Florian Bruhin
18a761369b requirements: Update pytest-warnings
It's been integrated to pytest core with 3.1
2017-05-23 06:14:32 +02:00
Florian Bruhin
7da6b55767 Merge commit 'aab90f015bbb4d5f406ce37e58b8b557284bb3c2' into pyup-bot/pyup-update-pytest-3.0.7-to-3.1.0 2017-05-23 06:13:08 +02:00
pyup-bot
aab90f015b Update pytest from 3.0.7 to 3.1.0 2017-05-23 05:18:50 +02:00
pyup-bot
a83c18f2c9 Update hypothesis from 3.9.1 to 3.10.0 2017-05-22 17:54:50 +02:00
pyup-bot
10e5aa9e2a Update hypothesis from 3.9.0 to 3.9.1 2017-05-22 11:09:50 +02:00
Florian Bruhin
4684ce8f0c Update changelog 2017-05-22 08:22:08 +02:00
Florian Bruhin
c32c01ffc0 Merge commit '419793c0b9ff4f293babea7623dcaf4787bbaa35' 2017-05-22 07:55:44 +02:00
Jay Kamat
419793c0b9 Misc cleanup and documentation update 2017-05-21 22:42:51 -07:00
Jay Kamat
00f001729b Fix undo with pinned tabs
Add tests for undo with a pinned tab
Add tests for clone with a pinned tab
2017-05-21 21:03:33 -07:00
Jay Kamat
2a961c3951 Clean up pinned status to a centralized location
- Add support for :tab-clone with pinned tabs

Now tabbed_browser.set_tab_pinned can be called independently.
2017-05-21 19:49:10 -07:00
pyup-bot
a26011c62d Update pytest-warnings from 0.2.0 to 0.3.0 2017-05-21 17:13:48 +02:00
Florian Bruhin
64e7e027d8 Merge commit '4096defd134c44449bcc1c62b39e58f2fb0c25d1' into pyup-bot/pyup-update-hypothesis-3.8.5-to-3.9.0 2017-05-21 16:20:57 +02:00
Florian Bruhin
28c651067d Remove crowdfunding notes 2017-05-20 23:30:36 +02:00
Florian Bruhin
aa8e6c8d17 Add parsed distribution to version info
Fixes #2369
2017-05-20 23:26:00 +02:00
Florian Bruhin
fe145b66c1 Add a version.distribution()
See #2369
2017-05-20 23:26:00 +02:00
pyup-bot
4096defd13 Update hypothesis from 3.8.5 to 3.9.0 2017-05-19 17:54:45 +02:00
Florian Bruhin
964b06bf7e Fix shadowed import 2017-05-19 09:26:48 +02:00
Florian Bruhin
802eb51891 Update docs 2017-05-19 08:59:34 +02:00
Florian Bruhin
f66c1a0e44 Merge commit '3d9729839d6d9b5ee5d38afdf6ddf410dfca2027' into abbradar/pac-fix 2017-05-19 08:36:39 +02:00
Florian Bruhin
c4fb2bc609 Fix URL/renderer crash tests with Qt 5.9
The behavior in Qt changed there (in a good way), so we need to adjust the tests
accordingly.

Fixes #2514
2017-05-19 08:10:17 +02:00
Nikolay Amiantov
3d9729839d Fix crash on PAC evaluation error 2017-05-18 16:54:49 +03:00
Florian Bruhin
f67cf17055 Hopefully fix pylint on AppVeyor... 2017-05-17 22:47:17 +02:00
Florian Bruhin
edd10aac56 pylint: Add more stuff to known-standard-library 2017-05-17 22:14:17 +02:00
Florian Bruhin
499f5df2a9 ci: Use Python 3.6 everywhere 2017-05-17 21:40:24 +02:00
Florian Bruhin
f90df52c6a Update changelog 2017-05-17 21:32:59 +02:00
Florian Bruhin
e3f5e8ca9a Disable local storage test for now
It also seems to run unstable on Windows (AppVeyor), so we probably need to wait
for qutewm to run it.
2017-05-17 20:38:30 +02:00
Florian Bruhin
00a7a0cee6 Reorganize pylint config
This removes various stuff we don't need anymoe, and also re-enables and fixes
the import order check.
2017-05-17 20:20:12 +02:00
Florian Bruhin
12520bf4ba Install PyQt from PyPI for pylint
This means we can be sure to have QtWebEngine available and won't have QtWebKit.
2017-05-17 19:08:59 +02:00
Florian Bruhin
608ac89f06 Fix lint 2017-05-17 14:32:13 +02:00
Florian Bruhin
6473d64e40 Merge commit '20e8ce687f04b9cae702a5446b32a5ae3e0351c5' into pyup-bot/pyup-update-hypothesis-3.8.3-to-3.8.5 2017-05-17 13:50:07 +02:00
Florian Bruhin
a4ddc9706a tox: Also use $PYTHON for pylint 2017-05-17 13:48:31 +02:00
Florian Bruhin
dd15b4b953 Fix local storage test
Looks like it needs a window manager to run properly...
2017-05-17 13:38:21 +02:00
Florian Bruhin
c5957bc9d0 Exclude pdfjs from build packages for now
It only makes things bigger, and currently pdfjs doesn't work on QtWebEngine
anyways.
2017-05-17 11:42:58 +02:00
Florian Bruhin
9898d80625 Remove legacy cx_Freeze code
This also removes frozen tests for now. They should be readded at some point...
2017-05-17 11:31:14 +02:00
Florian Bruhin
e955540f71 build_release: More fixes 2017-05-17 11:10:36 +02:00
Florian Bruhin
47bf261994 build_release: Different PyInstaller workaround 2017-05-17 11:10:32 +02:00
Florian Bruhin
71b5d83e19 build_release: Various fixes 2017-05-17 11:10:20 +02:00
Florian Bruhin
dc947bf9a9 build_release: Python version adjustments 2017-05-17 11:09:22 +02:00
Florian Bruhin
49a328727e build_release: Add Windows patching for PyInstaller 2017-05-17 11:09:22 +02:00
Florian Bruhin
9816de9e8d build_release: Initial changes for PyInstaller 2017-05-17 11:06:06 +02:00
Florian Bruhin
70e2963432 build_release: Adjust repo name 2017-05-17 11:05:27 +02:00
Florian Bruhin
68bb0f557f Switch to xoviat pyinstaller branch 2017-05-17 11:05:27 +02:00
pyup-bot
20e8ce687f Update hypothesis from 3.8.3 to 3.8.5 2017-05-17 10:54:42 +02:00
Florian Bruhin
e0ff2d98fe Test for private browsing differently
In a48ea597d0 we fixed settings in private
QtWebEngine windows.

However, this means we also enable local storage for private windows, which was
disabled in QtWebEngine by default:

4ef5831a39 (diff-44ac7d27348388501944f6a8e2e67d8dR207)

It should be safe to enable it, as we get the same behavior as in Chromium, i.e.
a working local storage which entirely lives in RAM.

This also makes those tests work on QtWebKit-NG, presumably because private
browsing for cookies is implemented there.

It also adds a test to at least check whether local storage is isolated from
non-private tabs. I tried writing a test which ensures nothing lands on the hard
disk, but due to QTBUG-52121 this might not happen at all:

https://bugreports.qt.io/browse/QTBUG-52121
2017-05-17 09:42:28 +02:00
Florian Bruhin
a48ea597d0 Set websettings on each profile's setting object
Turns out QWebEngineSettings.globalSettings() only sets things on the default
profile. We now get everything from the default profile settings, but set it on
both the default and the private profile.

Fixes #2638

(cherry picked from commit b11a4388cd10b6ff2fd917fca689ebdc50d581ae)
2017-05-17 06:31:51 +02:00
Jay Kamat
5e3c68530a Regenerate documentation 2017-05-16 21:03:33 -07:00
Jay Kamat
1142a19de9 Add (pinned) keyword to 'following tabs open' tests 2017-05-16 20:16:43 -07:00
Florian Bruhin
00083ad825 Merge commit '7b204c4ec7931ba8da5f685b29352413ec25f194' into pyup-bot/pyup-update-flask-0.12.1-to-0.12.2 2017-05-16 16:51:50 +02:00
Florian Bruhin
8428d72005 Merge commit 'c2ca8e48f58fcf6fe6758f8e206d95bacddb8c58' into pyup-bot/pyup-update-werkzeug-0.12.1-to-0.12.2 2017-05-16 16:50:31 +02:00
Florian Bruhin
407537dbe6 tests: Wait until window is closed after :close
If we don't wait here, we might end up running the subsequent commands (like
:command-history-prev) on the old window while it's still closing, causing an
exception at least on AppVeyor:

    Traceback (most recent call last):
      File "C:\projects\qutebrowser\qutebrowser\app.py", line 110, in <lambda>
        target_arg=target_arg))
      File "C:\projects\qutebrowser\qutebrowser\app.py", line 265, in process_pos_args
        win_id = mainwindow.get_window(via_ipc, force_tab=True)
      File "C:\projects\qutebrowser\qutebrowser\mainwindow\mainwindow.py", line 89, in get_window
        window.setWindowState(window.windowState() & ~Qt.WindowMinimized)
    RuntimeError: wrapped C/C++ object of type MainWindow has been deleted
2017-05-16 15:46:20 +02:00
Florian Bruhin
9408babef5 Also remove test for removed assertion 2017-05-16 12:56:25 +02:00
Florian Bruhin
766a1ebb6d Remove wrong private browsing assertion
This tried to assert that we never create a DiskCache object when private
browsing is turned on. However, when initializing, we still create a global
DiskCache, so this will hit when qutebrowser is started with private browsing
turned on via the config.

We could just not create the DiskCache at all when started in private browsing
mode, however we might still need it later when opening a non-private window.
2017-05-16 11:33:52 +02:00
Florian Bruhin
27aa40428e Also make DownloadManager NAM private if private browsing is on
There's only one global DownloadManager with its own NAM (for downloads not
associated with a page). We can't really decide whether that should be private
or not, so as a best-effort approximation we simply make it private if private
browsing was turned on when starting qutebrowser.
2017-05-16 11:32:35 +02:00
pyup-bot
c2ca8e48f5 Update werkzeug from 0.12.1 to 0.12.2 2017-05-16 09:12:19 +02:00
pyup-bot
7b204c4ec7 Update flask from 0.12.1 to 0.12.2 2017-05-16 09:12:15 +02:00
Florian Bruhin
89dc8185b9 Fix lint 2017-05-16 09:08:59 +02:00
Florian Bruhin
1fcce6d87c Change how error page retries work
A simple reload won't work when e.g. the renderer process crashed, so let's try
this instead.

Also, searchFor seemed to be unused.
2017-05-16 07:51:37 +02:00
Florian Bruhin
a4021e8e7a Show error page for renderer process crashes on 5.9
Fixes #2291
2017-05-16 07:50:26 +02:00
Florian Bruhin
bdf56e63dd Fix long line 2017-05-16 07:31:02 +02:00
Florian Bruhin
37b3ed0ca9 Update changelog 2017-05-16 07:14:03 +02:00
Florian Bruhin
d0dd1644af Set user agent correctly on QtWebEngine 2017-05-16 06:46:45 +02:00
Florian Bruhin
086139110d Merge branch 'new-private-browsing' 2017-05-16 06:32:15 +02:00
Florian Bruhin
adb924a758 Use -p for :save-session --with-private 2017-05-16 06:28:21 +02:00
Florian Bruhin
658abf7b2b Fix coverage on old Qt versions 2017-05-15 13:39:49 +02:00
Florian Bruhin
51163f5e12 Recompile requirements 2017-05-15 11:35:34 +02:00
Florian Bruhin
991b3123d7 check_coverage: Add qutebrowser/ to filter list
For coverage 4.4 we removed qutebrowser/ from filenames, so we need to re-add it
here so the filter still works correctly.
2017-05-15 11:32:41 +02:00
Florian Bruhin
e13a5c0f17 Use a list for stylesheet flags
If we simply use sorted() on a dict, we define insert before private-command,
which means the statusbar isn't going to be green when in insert mode while
private browsing.
2017-05-15 11:07:43 +02:00
Florian Bruhin
3cdcc34d1d Update private-browsing option description 2017-05-15 11:07:43 +02:00
Florian Bruhin
c4307c9f03 Fix lint 2017-05-15 11:07:43 +02:00
Florian Bruhin
3f8b9fb1a5 tests: Improve matching of exceptions to show verbose output
In some situations we can get a TypeError without a stack
2017-05-15 11:07:43 +02:00
Florian Bruhin
f6fc2666ce Generate stylesheet for statusbar 2017-05-15 11:07:43 +02:00
Florian Bruhin
73ca884d24 Add a setting for private command mode color
This also refactors how color properties are handled in StatusBar.
2017-05-15 11:07:43 +02:00
Florian Bruhin
3c3f695af4 Fix things pointed out in reviews 2017-05-15 11:07:43 +02:00
Florian Bruhin
6ee382ef30 Sort windows when saving sessions
This should help with flaky tests when the window order changes
2017-05-15 11:02:29 +02:00
Florian Bruhin
510b437916 Update docs 2017-05-15 11:02:29 +02:00
Florian Bruhin
8993667479 Remove unused imports 2017-05-15 11:02:29 +02:00
Florian Bruhin
c3ac3ccdee Add tests for new private browsing 2017-05-15 11:02:29 +02:00
Florian Bruhin
eda95d7926 Simplify window/private distinction in commands.py 2017-05-15 11:02:29 +02:00
Florian Bruhin
cde36f34b0 Remove QtWebKit-NG warnings
The next release will support private browsing, and we can't easily check the
version somehow.
2017-05-15 11:02:29 +02:00
Florian Bruhin
9805b43c85 Handle private browsing in sessions 2017-05-15 11:02:29 +02:00
Florian Bruhin
f907b6b6b0 Have an isolated command history for private windows 2017-05-15 11:02:26 +02:00
Florian Bruhin
157a0af908 Hopefully fix failing history test on old Qt 2017-05-15 10:29:13 +02:00
Florian Bruhin
56144d6c3d Merge commit '7688f263986f97073d5bd253a506b4d3bbac1759' into pyup-bot/pyup-update-coverage-4.4-to-4.4.1 2017-05-15 09:22:07 +02:00
Florian Bruhin
dd675c4e8d Set title for :view-source pages 2017-05-15 09:16:24 +02:00
Florian Bruhin
5b1d35bef9 Don't add data: URLs to history 2017-05-15 09:04:16 +02:00
Florian Bruhin
920dde4a68 Don't set an URL for :view-source tabs
Otherwise the page URL gets added to the history again with QtWebKit.
2017-05-15 09:03:45 +02:00
pyup-bot
7688f26398 Update coverage from 4.4 to 4.4.1 2017-05-15 08:48:42 +02:00
pyup-bot
b3a509f856 Update coverage from 4.4 to 4.4.1 2017-05-15 08:48:40 +02:00
Florian Bruhin
f2d3d78b12 Update changelog 2017-05-15 08:22:04 +02:00
Jay Kamat
17169812be Misc cleanup and fixes 2017-05-14 00:21:51 -07:00
Florian Bruhin
5174ce6a83 Update authors 2017-05-13 15:55:43 +02:00
Matthias Lisin
c814ced7b3 Add Android UA 2017-05-13 15:05:54 +02:00
Anton Grensjö
47f391d38b Set explicit=False for :navigate --tab
Related to #2624
2017-05-13 04:16:49 +02:00
Jay Kamat
b526c9a2a9 Try to fix a pylint error 2017-05-12 18:38:06 -07:00
Jay Kamat
a5eb3e27f8 Fix some bugs in session saving test case 2017-05-12 17:48:38 -07:00
Jay Kamat
068e47e22c Fix a few style issues 2017-05-12 16:56:07 -07:00
Jay Kamat
1572be83be Add documentation for pinning 2017-05-12 13:28:53 -07:00
Florian Bruhin
273749cce8 Don't set explicit=True for :tab-clone/:view-source
Fixes #2624
2017-05-12 22:27:24 +02:00
Jay Kamat
2ae1bfc033 Keep pinned tabs in place rather than moving them. 2017-05-12 13:09:22 -07:00
Jay Kamat
3e3f4b4164 Add :tab-only tests for --force 2017-05-12 11:06:17 -07:00
Jay Kamat
66dfb1b1c9 Fix a bug with titles not being refreshed when pinning tabs 2017-05-12 09:53:25 -07:00
Florian Bruhin
65952ca290 Fix webkitelem tests 2017-05-12 13:57:33 +02:00
Florian Bruhin
17fdda6a5e Check for href attribute in WebElement.is_link
Fixes #2619
2017-05-12 12:59:25 +02:00
Florian Bruhin
9ab4549b9b requirements: Filter flake8-pep3101 1.1 2017-05-12 10:32:06 +02:00
Florian Bruhin
bd75507c90 Merge commit 'e238f32e7b40f6da9aa893150cd35368814fc403' into pyup-bot/pyup-update-flake8-deprecated-1.1-to-1.2 2017-05-12 10:30:09 +02:00
Florian Bruhin
0e72f2166d Merge commit 'dfc44f05c57885e7c6890318dbfb7204f4e07618' into pyup-bot/pyup-update-pytest-cov-2.5.0-to-2.5.1 2017-05-12 10:30:07 +02:00
Florian Bruhin
9e2aa65c02 Remove webelem.Group.prevnext
Apart from checking for buttons with an href attribute (which made no sense at
all and should never return any element) this was identical to
webelem.Group.links.
2017-05-12 09:41:12 +02:00
Florian Bruhin
203a5dff74 Get rid of webelem.FILTERS
There's actually no good reason to filter javascript links as we might want to
click them (or copy their URL) just like any other link - this fixes #2404.

With that being gone, we don't need FILTERS at all anymore, as we can check for
existence of the href attribute in the CSS selector instead.
2017-05-12 09:41:12 +02:00
pyup-bot
dfc44f05c5 Update pytest-cov from 2.5.0 to 2.5.1 2017-05-12 00:59:40 +02:00
pyup-bot
e238f32e7b Update flake8-deprecated from 1.1 to 1.2 2017-05-12 00:59:36 +02:00
Jay Kamat
21455cf0e7 Clean up pinned tab alert logic
should be a lot more reusable now
2017-05-11 15:37:52 -07:00
Jay Kamat
4c28487fd0 Warn user if pinned tab is closed via tab-only 2017-05-11 14:30:45 -07:00
Jay Kamat
cb654225fd Add a test case for loading/saving pinned tabs in sessions 2017-05-11 14:05:25 -07:00
Jay Kamat
3317834b36 Fix a bug where pinned tabs were occasionally miscounted
Example case: :tab-only. This should cover other cases, but currently those
cases (such as :tab-only) do NOT have a warning message when popping up.
2017-05-11 13:28:26 -07:00
Jay Kamat
725bafea54 Merge branch 'master' into jay/pintab 2017-05-10 23:51:33 -07:00
pyup-bot
d50a08d159 Update requests from 2.14.1 to 2.14.2 2017-05-10 19:08:32 +02:00
pyup-bot
140eb13677 Update requests from 2.14.1 to 2.14.2 2017-05-10 19:08:31 +02:00
pyup-bot
b2abf7a3aa Update requests from 2.14.1 to 2.14.2 2017-05-10 19:08:29 +02:00
Florian Bruhin
c6e31391de Fix most tests/lint 2017-05-10 09:19:24 +02:00
Florian Bruhin
f4d3f97cb7 Implement private browsing for QtWebEngine 2017-05-10 09:17:54 +02:00
Florian Bruhin
1c50377c0a Initial work on new private browsing 2017-05-10 07:00:21 +02:00
Florian Bruhin
1d4c9d3b3f Merge commit '661c0f7b7c74c23db0a8ed2dfa111a711c5f8771' into pyup-bot/pyup-update-pytest-cov-2.4.0-to-2.5.0 2017-05-10 06:52:20 +02:00
Florian Bruhin
5e76810659 Merge commit '1973e61424efb124f453ce0894d1c8b3e5ea99c3' into pyup-bot/pyup-update-hypothesis-3.8.2-to-3.8.3 2017-05-10 06:52:18 +02:00
pyup-bot
661c0f7b7c Update pytest-cov from 2.4.0 to 2.5.0 2017-05-10 00:08:34 +02:00
pyup-bot
1973e61424 Update hypothesis from 3.8.2 to 3.8.3 2017-05-10 00:08:30 +02:00
pyup-bot
3bd7e33c4a Update requests from 2.13.0 to 2.14.1 2017-05-09 22:16:27 +02:00
pyup-bot
a0a9c9d32e Update requests from 2.13.0 to 2.14.1 2017-05-09 22:16:25 +02:00
pyup-bot
56d42b6c82 Update requests from 2.13.0 to 2.14.1 2017-05-09 22:16:24 +02:00
Florian Bruhin
b91d4ee9c2 Clean up :debug-webaction 2017-05-09 22:02:30 +02:00
Florian Bruhin
822623f2ed Finally update copyrights... 2017-05-09 21:37:03 +02:00
Florian Bruhin
905032924a Remove search_displayed initialization in subclasses
We set this in BrowserTab anyways, and the value in WebKitTab was wrong.
2017-05-09 17:58:28 +02:00
Florian Bruhin
4b5e528d05 Add AbstractTab.key_press 2017-05-09 17:56:07 +02:00
Florian Bruhin
76fa126133 Simplify debug string 2017-05-09 17:55:51 +02:00
Florian Bruhin
e3eda28d88 Update docstrings 2017-05-09 17:52:13 +02:00
Florian Bruhin
5f2fb2c4fc Update docs 2017-05-09 17:48:40 +02:00
Jay Kamat
e10d636ca0 Fix a few small issues
- Remove an unused warnings
- Reverse if statement arguments to simplify logic
2017-05-09 08:08:05 -07:00
Jay Kamat
a3d41c0467 Refactor search method of AbstractBrowserTab into a field 2017-05-09 00:24:13 -07:00
Jay Kamat
02f79c2990 Add tests for manual selection 2017-05-09 00:11:25 -07:00
Jay Kamat
d1aac9e9e9 Add docstrings to key_press methods 2017-05-08 23:43:21 -07:00
Jay Kamat
5bdd291d28 Refactor key_press into _repeated_key_press
Also split off generic key pressing ability from WebKitScroller to WebKitTab
2017-05-08 23:11:50 -07:00
Jay Kamat
63cffaf558 Refactor _key_press from WebEngineScroller to WebEngineTab 2017-05-08 22:49:14 -07:00
Jay Kamat
5ba81e3611 Add tests for follow_selected 2017-05-08 22:32:53 -07:00
Jay Kamat
c9953b9f0d Add support for follow_selected via fake-clicks 2017-05-08 22:31:29 -07:00
Jay Kamat
e07a1045a8 Add is_link method to webelem 2017-05-08 22:00:11 -07:00
Florian Bruhin
6c3f29d570 Merge commit '2b0fc0f52efccd0004b2cd8f90f930852947f403' into pyup-bot/pyup-update-coverage-4.3.4-to-4.4 2017-05-09 06:23:05 +02:00
Florian Bruhin
27bed81353 Merge commit '7a3651426f0152c6b23ed4f83bab0eab2e763d91' into pyup-bot/pyup-update-beautifulsoup4-4.5.3-to-4.6.0 2017-05-09 06:23:03 +02:00
Florian Bruhin
af18b208bb Merge commit '00c48427bcee63921705f85251d71795dab980bd' into pyup-bot/pyup-update-lazy-object-proxy-1.3.0-to-1.3.1 2017-05-09 06:23:00 +02:00
Florian Bruhin
9db92de2d5 Add a no cover pragma for certificate error hashing 2017-05-09 06:15:21 +02:00
Florian Bruhin
8052249b1b Make check_coverage.py work with coverage 4.4
With coverage 4.4, the source name (qutebrowser/) is not added to the filename
anymore. To adjust for that, we remove qutebrowser/ from all paths, and also
make sure to remove it from what coverage returns (in case someone is running an
older version).
2017-05-09 06:13:35 +02:00
pyup-bot
2b0fc0f52e Update coverage from 4.3.4 to 4.4 2017-05-08 07:26:27 +02:00
pyup-bot
ee2a6ae6f0 Update coverage from 4.3.4 to 4.4 2017-05-08 07:26:25 +02:00
pyup-bot
7a3651426f Update beautifulsoup4 from 4.5.3 to 4.6.0 2017-05-07 16:42:20 +02:00
pyup-bot
00c48427bc Update lazy-object-proxy from 1.3.0 to 1.3.1 2017-05-05 15:51:20 +02:00
pyup-bot
2beba920e7 Update lazy-object-proxy from 1.3.0 to 1.3.1 2017-05-05 15:51:18 +02:00
pyup-bot
88545dec4d Update lazy-object-proxy from 1.2.2 to 1.3.0 2017-05-04 08:36:26 +02:00
pyup-bot
caa3be2277 Update lazy-object-proxy from 1.2.2 to 1.3.0 2017-05-04 08:36:25 +02:00
Florian Bruhin
789aebd742 Merge commit '120379dd217d8daaa6b48cb21c8cb3de7679bbec' into rcorre/benchmark_history 2017-05-03 23:15:36 +02:00
Florian Bruhin
eab7c79cf7 Merge commit '3b0bb6a831791c22a77f25aa2f3223c24e6ba628' into pyup-bot/pyup-update-cheroot-5.4.0-to-5.5.0 2017-05-03 23:15:26 +02:00
Florian Bruhin
90b0af97ce Improve serialization crash check
It now works correctly with view-source URLs and is disabled on Qt 5.9.

Fixes #2289
See #2458
2017-05-03 23:15:17 +02:00
Florian Bruhin
ea2d5e97e2 Disable serialization crash check on Qt 5.9 2017-05-03 21:31:09 +02:00
Florian Bruhin
ebf3d208f6 Adjust Qt 5.8.1 check
There's never going to be a 5.8.1
2017-05-03 21:25:00 +02:00
Florian Bruhin
a320aa5ef7 Disable renderer process crash workaround on Qt 5.9 2017-05-03 21:24:25 +02:00
Florian Bruhin
2a4af0666b Regenerate authors 2017-05-03 18:36:48 +02:00
Ryan Roden-Corrent
120379dd21 Benchmark url completion.
This benchmark simulates what I expect to be the most common use-case for url
completion: opening completion and entering several letters.
2017-05-03 07:43:02 -04:00
Florian Bruhin
a77cb44723 Block all request methods in host blocker 2017-05-03 08:42:37 +02:00
pyup-bot
3b0bb6a831 Update cheroot from 5.4.0 to 5.5.0 2017-05-02 11:43:35 +02:00
Florian Bruhin
7c6981e512 Remove unused imports 2017-05-02 10:41:51 +02:00
Florian Bruhin
d5c5d09b18 Hopefully stabilize test_version
When using QuteProcess here, we fight with it over who can read the output.
Just use a raw QProcess instead.
2017-05-02 09:12:06 +02:00
Florian Bruhin
7b4ab901e9 tests: Fix Chromium message matching 2017-05-02 08:24:57 +02:00
Florian Bruhin
d8e134c5f0 Merge commit '64a4e33caa539b751acfc7e0eb76c871e8ab423d' into pyup-bot/pyup-update-flake8-tuple-0.2.12-to-0.2.13 2017-05-02 08:22:43 +02:00
Florian Bruhin
55db8719f2 Merge commit '6ae6df9d74b9d94f56489b5d6a4586995aeda340' into stevepeak/patch-1 2017-05-02 08:22:37 +02:00
Florian Bruhin
2fb59958a6 Merge commit 'fe02267de2f9bc164cb265c357770d8f56c68554' into pyup-bot/pyup-update-pytest-bdd-2.18.1-to-2.18.2 2017-05-02 08:22:32 +02:00
Florian Bruhin
64e144f3eb Make text selectable in prompts 2017-05-01 13:52:46 +02:00
pyup-bot
fe02267de2 Update pytest-bdd from 2.18.1 to 2.18.2 2017-05-01 12:43:14 +02:00
Steve Peak
6ae6df9d74 Update codecov.yml 2017-04-30 14:55:35 -04:00
pyup-bot
64a4e33caa Update flake8-tuple from 0.2.12 to 0.2.13 2017-04-30 12:29:12 +02:00
Florian Bruhin
6e0d138d23 flake8 requirements: Pin flake8-docstrings to < 1.1.0
Closes #2593
2017-04-29 13:45:14 +02:00
Florian Bruhin
5bbd16c92a Fix qWebKitVersion issues 2017-04-28 22:59:24 +02:00
Florian Bruhin
bffdea6719 Read qWebKitVersion in qtutils.is_webkit_ng.
This means we need to try and import qWebKitVersion in qtutils, but better there
than at every place which calls it.
2017-04-28 21:36:02 +02:00
Florian Bruhin
8101fe99a8 Fix starting with Python 2
Fixes #2567
2017-04-28 20:51:38 +02:00
Florian Bruhin
a5b1c293a4 Ignore comment position with eslint 2017-04-28 20:29:20 +02:00
Florian Bruhin
0a3e20f5ab Merge commit '26b4d13c6faf6217bb116e15c01eec37c10dd976' into pyup-bot/pyup-update-setuptools-35.0.1-to-35.0.2 2017-04-28 19:44:59 +02:00
Florian Bruhin
9f942cb9a8 Merge commit '11383169d83f1ff14d2df40e6963221e46ab29d1' into pyup-bot/pyup-update-codecov-2.0.8-to-2.0.9 2017-04-28 19:44:57 +02:00
Florian Bruhin
421aa0d319 Also try harder to get text content 2017-04-28 19:11:02 +02:00
Florian Bruhin
76ec465f67 Allow to set cookies-store at runtime with Qt 5.9
Fixes #2588
2017-04-28 17:40:43 +02:00
Florian Bruhin
c8090b5388 Don't wait for click message in webelem tests
Looks like we get this sometimes:

----> Waiting for 'Clicked non-editable element!' in the log
14:02:14.976 DEBUG    webview    webkittab:find_at_pos:618 Hit test result element is null!
14:02:14.976 DEBUG    mouse      mouse:_mousepress_insertmode_cb:149 Got None element, scheduling check on mouse release
14:02:14.977 DEBUG    mouse      webview:mousePressEvent:299 Normal click, setting normal target
14:02:14.978 DEBUG    mouse      mouse:mouserelease_insertmode_cb:173 Element vanished!
2017-04-28 17:29:19 +02:00
pyup-bot
11383169d8 Update codecov from 2.0.8 to 2.0.9 2017-04-28 17:27:11 +02:00
Florian Bruhin
5ed870e0c6 Fix lint 2017-04-28 16:29:44 +02:00
Florian Bruhin
20da495376 Add missing file 2017-04-28 15:22:29 +02:00
Florian Bruhin
a2c8e093f4 Move webelement checks to javascript.feature 2017-04-28 15:16:36 +02:00
Florian Bruhin
6458c692cb Improve JS value type checks 2017-04-28 15:15:32 +02:00
Florian Bruhin
571f0c4486 Loosen JS value type check 2017-04-28 14:57:14 +02:00
Florian Bruhin
0c653c4703 Handle elem.className in webelem.js 2017-04-28 14:48:30 +02:00
Florian Bruhin
513f83d446 Try harder to get tag name from element
This could happen for any of the attributes, but for tagName this actually
happens in the wild... Since elem.tagName is equal to elem.nodeName we just try
to use this.

Fixes #2569
2017-04-28 14:48:30 +02:00
Florian Bruhin
06e317ac53 Do type checks on values we get from JS 2017-04-28 14:48:30 +02:00
Florian Bruhin
4f92fe6895 Add an assert for tag_name we get from JS
This should help tracking down #2569 once we get another report about it.
2017-04-28 10:33:57 +02:00
pyup-bot
26b4d13c6f Update setuptools from 35.0.1 to 35.0.2 2017-04-27 22:07:03 +02:00
Florian Bruhin
7b283cd58e Merge branch 'haasn/favicon-scale' 2017-04-27 21:15:09 +02:00
Florian Bruhin
d8bfa6d6b7 Merge commit '6549fd84ce461d3098c13818219df4e4bfd6b444' 2017-04-27 21:15:09 +02:00
Florian Bruhin
f9055dc1e4 Update changelog 2017-04-27 21:14:28 +02:00
Florian Bruhin
5823af0b7b Merge commit '6549fd84ce461d3098c13818219df4e4bfd6b444' into haasn/favicon-scale 2017-04-27 21:13:17 +02:00
Florian Bruhin
0efbd085b0 Merge commit 'c12347189fca26261af7dcdce121e51c170b521d' into pyup-bot/pyup-update-colorama-0.3.8-to-0.3.9 2017-04-27 21:12:21 +02:00
Florian Bruhin
44e6b9ac54 Merge commit '0e14117fdad0442520c4e1fe64231b447306cbc7' into pyup-bot/pyup-update-codecov-2.0.7-to-2.0.8 2017-04-27 21:12:18 +02:00
Florian Bruhin
d62ebdb926 Make most of search BDD tests work with QtWebEngine 2017-04-27 21:02:26 +02:00
Florian Bruhin
4cd977cab6 Fix zero handling in qflags_key 2017-04-27 20:14:51 +02:00
pyup-bot
0e14117fda Update codecov from 2.0.7 to 2.0.8 2017-04-27 18:27:03 +02:00
pyup-bot
c12347189f Update colorama from 0.3.8 to 0.3.9 2017-04-27 09:42:00 +02:00
Niklas Haas
6549fd84ce Add tabs->favicon-scale setting
This allows users to change the size of the favicon independently from
the size of the font/tab, in order to adjust the balance between
favicons and text. The drawing code is also adjusted to place the icon
relative to the text center, rather than the text top.

Works as expected even for values of 0.0 (which is equivalent to hiding
the favicon completely).

Closes #2549.
2017-04-27 08:53:51 +02:00
Florian Bruhin
046401c489 Clean up search.feature 2017-04-27 08:20:55 +02:00
pyup-bot
38099c45bd Update hypothesis from 3.8.1 to 3.8.2 2017-04-26 21:48:21 +02:00
Florian Bruhin
b094f2d513 Merge branch 'pyup-bot/pyup-update-vulture-0.13-to-0.14' 2017-04-26 21:30:56 +02:00
Florian Bruhin
5e7e159ac7 Merge commit '9ef17d434ddc85c6cda4d08f00fef15b7904add1' 2017-04-26 21:30:56 +02:00
Florian Bruhin
9f8937fd80 Merge commit '9ef17d434ddc85c6cda4d08f00fef15b7904add1' into pyup-bot/pyup-update-vulture-0.13-to-0.14 2017-04-26 21:30:16 +02:00
pyup-bot
e252862f51 Update hypothesis from 3.8.0 to 3.8.1 2017-04-26 15:15:11 +02:00
pyup-bot
9ef17d434d Update vulture from 0.13 to 0.14 2017-04-26 10:32:43 +02:00
pyup-bot
b1d88b47c1 Update vulture from 0.13 to 0.14 2017-04-26 10:32:42 +02:00
Florian Bruhin
27057622ba Update authors 2017-04-26 08:56:41 +02:00
Florian Bruhin
4f444b870e Merge branch 'imransobir/hostname-in-history' 2017-04-26 08:54:39 +02:00
Florian Bruhin
95b866e4f4 Merge commit 'fe7d21dfbe0b9dabcb66eaa61c20a5d16c9e175c' 2017-04-26 08:54:39 +02:00
Florian Bruhin
abb82ce922 Merge branch 'pyup-bot/pyup-update-codecov-2.0.5-to-2.0.7' 2017-04-26 07:23:09 +02:00
Florian Bruhin
4bee5deacc Merge commit 'ab61fc57a98abcbfe6ac50622e9cbff25ad0325c' 2017-04-26 07:23:09 +02:00
Florian Bruhin
cbfb155a05 Merge commit 'ab61fc57a98abcbfe6ac50622e9cbff25ad0325c' into pyup-bot/pyup-update-codecov-2.0.5-to-2.0.7 2017-04-26 07:22:46 +02:00
Florian Bruhin
6a35797a2c Mention C++/JS in CONTRIBUTING 2017-04-25 22:57:39 +02:00
Florian Bruhin
70d7a56b11 Also set Fusion style for downloads and completion
This makes those UI elements look the same on different platforms/OS styles,
with the small drawback of overriding the context menu style.

This most likely fixes #80 (though I couldn't reproduce that on Windows 10).
2017-04-25 22:20:37 +02:00
Florian Bruhin
66eb330a0a Always base tabbar on Fusion style.
Fixes crashes with qt5ct.
Fixes #2477.
Fixes #1554.
2017-04-25 21:44:15 +02:00
Florian Bruhin
ca0e04fd0d Mention :open in issue template
See #2574
2017-04-25 18:41:00 +02:00
Florian Bruhin
1015badb8b Disable animation for completion view 2017-04-25 09:18:31 +02:00
Florian Bruhin
c3e6222296 Close the current tab when the tabbar itself is clicked 2017-04-25 06:59:51 +02:00
Florian Bruhin
3125b69d19 Fix no-cover pragma 2017-04-25 06:43:31 +02:00
pyup-bot
ab61fc57a9 Update codecov from 2.0.5 to 2.0.7 2017-04-25 00:34:15 +02:00
Florian Bruhin
111944fb65 Revert "Raise exception when a stylesheet is unparsable."
This reverts commit 0400945ac4.

See #2571
2017-04-24 23:16:10 +02:00
Imran Sobir
fe7d21dfbe Show hostname in non-javascript history page. 2017-04-24 15:30:01 +05:00
Florian Bruhin
11c026bf4c Reenable QtWebKit cache with Qt 5.9.
This was fixed here:
https://codereview.qt-project.org/#/c/190818/

See #2427
2017-04-24 12:27:00 +02:00
Florian Bruhin
1539301d64 Fix test coverage for statusbar.url 2017-04-24 08:41:29 +02:00
Florian Bruhin
bf4e343887 Merge commit '18082526f48afcef3fc574e1536ef282aa0cf5bd' into imransobir/hostname-in-history 2017-04-24 08:06:13 +02:00
Florian Bruhin
2120429960 Regenerate authors 2017-04-24 08:01:44 +02:00
Imran Sobir
18082526f4 Show hostname in history page. 2017-04-24 10:59:11 +05:00
Marcel Schilling
930b0f0818 typo fix (in comment) 2017-04-24 07:56:44 +02:00
Florian Bruhin
52f31ed15c Rename urlutils.safe_display_url to safe_display_string 2017-04-24 07:49:12 +02:00
Florian Bruhin
b632fe3285 Fix invalid URL handling in statusbar 2017-04-24 07:47:58 +02:00
Florian Bruhin
38294c1ca6 Merge commit '02cccb3673e7880fb1c507ca0f3e12e3ed954d6e' into pyup-bot/pyup-update-colorama-0.3.7-to-0.3.8 2017-04-24 07:15:56 +02:00
Florian Bruhin
a71b2e482e Merge commit '4220cfc34e85c10fc810a779a37eb1f3871e2ff4' into pyup-bot/pyup-update-hypothesis-3.7.3-to-3.8.0 2017-04-24 07:13:40 +02:00
Florian Bruhin
195d0ea207 Show Punycode URL for IDN pages in addition to decoded one
This helps when Unicode homographs are used for phishing purposes.
Fixes #2547
2017-04-24 06:58:41 +02:00
Florian Bruhin
beb661cdc7 Add xos4 Terminus to default monospace fonts 2017-04-23 23:11:12 +02:00
Florian Bruhin
a1de313aa3 Add qapp to test_proxy_from_url_pac 2017-04-23 23:10:29 +02:00
pyup-bot
4220cfc34e Update hypothesis from 3.7.3 to 3.8.0 2017-04-23 16:45:10 +02:00
pyup-bot
02cccb3673 Update colorama from 0.3.7 to 0.3.8 2017-04-23 11:48:10 +02:00
pyup-bot
616a764b6d Update hypothesis from 3.7.0 to 3.7.3 2017-04-21 20:00:01 +02:00
Florian Bruhin
1ebe0f2ce8 Regenerate docs 2017-04-20 04:40:03 +02:00
Florian Bruhin
c485b67fc0 Merge commit '6151b43c47f1ed0b8a6f0118037ba8bb93447f42' into rcorre/fix-qutescheme-bench 2017-04-20 04:39:45 +02:00
Florian Bruhin
0b118f4fd8 Blacklist pydocstyle >= 2.0.0
Closes #2539
2017-04-20 04:35:10 +02:00
pyup-bot
0c96a32366 Update setuptools from 35.0.0 to 35.0.1 2017-04-19 01:52:32 +02:00
Florian Bruhin
b82aada50b Fix highlights in crowdfunding note 2017-04-18 16:38:36 +02:00
Florian Bruhin
59a01b860f Add crowdfunding note to README/website 2017-04-18 16:36:14 +02:00
Ryan Roden-Corrent
6151b43c47 Fix qute_history benchmark.
This benchmark was running very quickly due to an improper setup.
The current history implementation expects that a newly inserted entry must
be more recent than any existing entries and sorts according to this
assumption.

The benchmark test inserts increasingly older entries, breaking this invariant.
When run in the benchmark, the qute://history/data implementation would
see an entry older than the oldest time in the time window and would
immediately return with a single "next" entry.

This patch inserts data in an order that mantains history's invariant and adds
a sanity-check at the end of the test. It does not check for the exact length
as not all entries will be within the time window. The length will be some
values <= 100000, the check just ensures that there is at least something more
than a "next" entry.

Before:
---------------------------------------------- benchmark: 1 tests ----------------------------------------------
Name (time in us)                  Min      Max    Mean  StdDev  Median     IQR  Outliers(*)  Rounds  Iterations
----------------------------------------------------------------------------------------------------------------
test_qute_history_benchmark     9.3050  21.9250  9.6143  0.2454  9.5880  0.1070      230;360    9930           1
----------------------------------------------------------------------------------------------------------------

After:
-------------------------------------------------- benchmark: 1 tests -------------------------------------------------
Name (time in ms)                    Min       Max      Mean  StdDev    Median     IQR  Outliers(*)  Rounds  Iterations
-----------------------------------------------------------------------------------------------------------------------
test_qute_history_benchmark     220.7040  223.1900  221.7536  1.1070  221.1939  1.8803          1;0       5           1
-----------------------------------------------------------------------------------------------------------------------
2017-04-17 12:15:49 -04:00
Florian Bruhin
db8b6d3e68 Add test for QNetworkReply.abort 2017-04-17 16:02:57 +02:00
Florian Bruhin
d60fc90ffd Merge commit '6fb48a5514f2f5dd6759ccfae0ea66ec8ad8297a' into pyup-bot/pyup-update-astroid-1.5.1-to-1.5.2 2017-04-17 16:01:36 +02:00
pyup-bot
00e4bf7640 Update pylint from 1.7.0 to 1.7.1 2017-04-17 15:20:23 +02:00
pyup-bot
6fb48a5514 Update astroid from 1.5.1 to 1.5.2 2017-04-17 14:00:24 +02:00
Florian Bruhin
ad9e82b91e Adjust bookmark tests 2017-04-16 21:13:01 +02:00
Florian Bruhin
9d2734ff62 Make sure host is valid for qute:// redirects 2017-04-16 13:15:15 +02:00
Florian Bruhin
c82bd83715 Implement RedirectNetworkReply.abort 2017-04-16 13:14:19 +02:00
Florian Bruhin
6deb079c2a Merge commit 'dd24039d64e72d4a79cda9ee3b7d0d0b19f146a4' into danieljakots/master 2017-04-16 13:09:09 +02:00
Florian Bruhin
d1d858b630 Merge commit '9050aac71e433dc82d087d47eb31f1f4e764d809' into pyup-bot/pyup-update-setuptools-34.4.1-to-35.0.0 2017-04-16 13:09:03 +02:00
Florian Bruhin
2d45257dcc Remove exclamation mark for bookmark messages 2017-04-16 13:08:15 +02:00
Florian Bruhin
842c2d297e Allow to set message clear timer to 0
Fixes #2527
2017-04-16 13:07:33 +02:00
pyup-bot
9050aac71e Update setuptools from 34.4.1 to 35.0.0 2017-04-15 17:37:14 +02:00
Daniel Jakots
dd24039d64 OpenBSD 6.1 is now released. Also prefer the package than the port. 2017-04-14 12:37:41 -04:00
Florian Bruhin
7c4e4a5818 Adjust flake8 config
Since we now ignore this on a per-file level for pylint, we need to do the
same for flake8 too.
2017-04-13 21:12:58 +02:00
Florian Bruhin
1d0f187fab Adjustments for new pylint version 2017-04-13 18:22:16 +02:00
Florian Bruhin
90e9850ad9 Merge commit '4511d042a1b0dc2ec3174716da8696dd6a87202c' into pyup-bot/pyup-update-astroid-1.4.9-to-1.5.1 2017-04-13 17:34:22 +02:00
pyup-bot
10b1c954b2 Update pylint from 1.6.5 to 1.7.0 2017-04-13 17:30:12 +02:00
pyup-bot
4511d042a1 Update astroid from 1.4.9 to 1.5.1 2017-04-13 17:30:03 +02:00
Florian Bruhin
4a480e6f5f Ignore Chromium NETLINK message 2017-04-12 13:24:10 +02:00
Florian Bruhin
fdaff02a58 Update docs 2017-04-12 12:43:38 +02:00
Fritz Reichwald
68c655bd9c Add period at end of docstring to make flake happy 2017-04-12 10:21:03 +02:00
Fritz Reichwald
b00c1dc906 Add docstring 2017-04-12 09:23:29 +02:00
Fritz Reichwald
ff767dd965 Add neccessary metadata to py script 2017-04-12 08:47:39 +02:00
Fritz Reichwald
c38dc95c23 Add posix to stdin test beacause the py script fails on windows 2017-04-12 07:59:40 +02:00
Fritz Reichwald
b784ddeddd Also test stdin close for detached start 2017-04-12 07:40:11 +02:00
Fritz Reichwald
590a9b4f78 Indent with spaces and minor changes 2017-04-12 07:32:40 +02:00
Fritz Reichwald
3d549bf607 Remove closeWriteChannel from detached start 2017-04-12 07:32:12 +02:00
Fritz Reichwald
424d0aec5a change test_stdinclose.py to stdinclose.py 2017-04-12 07:31:24 +02:00
Fritz Reichwald
bc7f8018c0 Close stdin after starting QProcess Fixes 2491 2017-04-12 06:56:38 +02:00
Fritz Reichwald
75f8d2a1d1 Test if stdin gets closed when starting QProcess 2017-04-12 06:54:39 +02:00
Florian Bruhin
c47da15bb1 Remove nargs=1 for --debug-flag
Otherwisse we get [['foo'], ['bar']] from argparse...
2017-04-11 21:26:23 +02:00
Florian Bruhin
20b17f3fb1 Improve --debug-flag error message 2017-04-11 21:21:07 +02:00
Florian Bruhin
13c5150e58 Update docs 2017-04-11 21:21:07 +02:00
Florian Bruhin
b966034250 Merge commit 'f31aead992e829cb15c4fbedbf816a23d2a916a7' into jswz72/master 2017-04-11 21:17:49 +02:00
pyup-bot
a4c3aaaf1d Update setuptools from 34.4.0 to 34.4.1 2017-04-10 18:34:47 +02:00
Florian Bruhin
b1e3add02e Update screenshots 2017-04-10 08:47:43 +02:00
Jacob Sword
f31aead992 Add default to --debug-flag 2017-04-09 23:34:33 -04:00
Jacob Sword
dcf8f29a67 Remove old --pdb-postmortem and --debug-exit flags 2017-04-09 10:43:40 -05:00
Jacob Sword
c0ac1bd79a Add 'dest' for '--debug-flag' 2017-04-09 10:34:51 -05:00
Florian Bruhin
fc37223d1b Regenerate docs properly for qute:help test 2017-04-09 11:36:13 +02:00
Jacob Sword
37d91cd17b Merge branch 'master' of https://github.com/jswz72/qutebrowser 2017-04-08 19:05:22 -04:00
Jacob Sword
7588cdb185 fixed formatting issues 2017-04-08 19:04:25 -04:00
Jacob Sword
6ccb420230 Fix syntax error in debug-exit 2017-04-08 18:42:26 -04:00
Florian Bruhin
778832a813 Set path when redirecting qute:* URLs
Fixes #2513
2017-04-08 23:04:10 +02:00
Jacob Sword
45dff6c0c8 update usage of debug-flag arguments 2017-04-08 16:54:08 -04:00
Florian Bruhin
28e6158a04 Stabilize some tests with Qt 5.9 QtWebEngine 2017-04-08 20:38:23 +02:00
Florian Bruhin
232f091bfe Merge branch 'pyup-bot/pyup-update-setuptools-34.3.3-to-34.4.0' 2017-04-08 20:24:03 +02:00
Florian Bruhin
ee31922c46 Merge commit '043039d673e9435d80034a80dcfe389f26d2dd06' into pyup-bot/pyup-update-setuptools-34.3.3-to-34.4.0 2017-04-08 20:15:13 +02:00
Florian Bruhin
6051f93c02 Avoid checking for scroll position in macro tests
This makes them simpler and more stable.
2017-04-08 19:54:30 +02:00
Florian Bruhin
e23318fe91 Mark failing test as flaky on QtWebEngine
It consistently fails on Qt 5.9 now while waiting the page to be scrolled to
0/20, but I can't figure out why that is happening.

See #2514, #2410
2017-04-08 19:29:46 +02:00
Florian Bruhin
a081d4184d tests: Adjust percent-encoding tests for Qt 5.9 changes
See #2514
2017-04-08 19:25:55 +02:00
Florian Bruhin
c23e4b1c5f tests: Allow @qt<... marker for BDD tests 2017-04-08 19:20:53 +02:00
pyup-bot
043039d673 Update setuptools from 34.3.3 to 34.4.0 2017-04-08 05:19:34 +02:00
Jacob Sword
dadbf7657f Merge remote-tracking branch 'upstream/master' 2017-04-07 21:21:01 -04:00
Jacob Sword
3b87e7c297 Add --debug-exit argument and validity check 2017-04-07 21:12:42 -04:00
Florian Bruhin
0068d87382 Merge commit '8878f867a7c8565801bc0187796e6638bfe02c85' into pyup-bot/pyup-update-tox-2.6.0-to-2.7.0 2017-04-06 21:44:32 +02:00
Florian Bruhin
fd9b86a340 Remove unused imports 2017-04-06 21:40:26 +02:00
Florian Bruhin
871504d91b Fix undefined names 2017-04-06 21:37:23 +02:00
pyup-bot
8878f867a7 Update tox from 2.6.0 to 2.7.0 2017-04-06 21:19:49 +02:00
Florian Bruhin
4ec5700cbf Redirect qute:foo to qute://foo
Before, we just returned the same data for both, but then we'll run into
same-origin restrictions as qute:history and qute:history/data are not the same
host.
2017-04-06 21:18:58 +02:00
Florian Bruhin
3cc9f9f073 Don't use from-import 2017-04-06 20:36:54 +02:00
Florian Bruhin
6d4948f9d0 Update authors 2017-04-06 20:35:32 +02:00
Florian Bruhin
760dca475e Merge commit 'be254be13a61171d4109224450db9e67d1076080' into imransobir/fix-webkit-history 2017-04-06 20:34:49 +02:00
Florian Bruhin
6f952c83af Update docs 2017-04-06 07:16:18 +02:00
Florian Bruhin
d9d0fbb6ae Merge commit 'e7755f5d9f8a5e995b83a239c05016cf1d58abba' 2017-04-06 07:10:22 +02:00
Martin Tournoij
e7755f5d9f Add :debug-log-filter none
This allows us to clear any filters. Useful for users, and needed for
the tests.
2017-04-04 20:51:14 +01:00
Martin Tournoij
857565c384 Mention that qutebrowser@ also gets the mails from qutebrowser-announce@ 2017-04-04 19:58:51 +01:00
Martin Tournoij
200e439a30 Fix crash of :debug-log-filter when --filter wasn't given
There was no `LogFilter`. The fix is to always initialize a
`LogFilter()` with `None`. as the "filter".

Fixes #2303.
2017-04-04 17:45:23 +01:00
Florian Bruhin
6c8ca30766 Update docs 2017-04-04 18:26:04 +02:00
Imran Sobir
be254be13a Use new history page on webkit-ng. 2017-04-04 19:21:25 +05:00
Martin Tournoij
c5427a0127 Fix display of errors while reading the key config file
Also catch `cmdexc.CommandError` on startup to show these errors in the
alert dialog on startup.

Fixes #1340
2017-04-04 09:50:12 +01:00
Florian Bruhin
0de3b5460e Only disable the cache on Qt 5.7.1
I ended up bisecting it, and https://codereview.qt-project.org/#/c/153977/
causes this, which is not in 5.7.0.
2017-04-04 08:24:50 +02:00
Florian Bruhin
2eb365b146 Also disable cache on Qt 5.7 2017-04-03 20:22:54 +02:00
Florian Bruhin
b6642e66fa Fix cache tests on Qt 5.8 2017-04-03 19:41:37 +02:00
Florian Bruhin
1b0ea19ca4 Disable QtNetwork cache on Qt 5.8
See #2427
2017-04-03 17:49:13 +02:00
pyup-bot
8f82113748 Update jinja2 from 2.9.5 to 2.9.6 2017-04-03 16:32:48 +02:00
Florian Bruhin
cb4c64eec9 Remove null argument for QtValueError 2017-04-03 10:18:56 +02:00
Florian Bruhin
2c3fcda18e Remove qtutils.ensure_not_null
It's not used anymore.
2017-04-03 09:32:13 +02:00
Florian Bruhin
3b1b325711 Fix logging 2017-04-03 09:04:28 +02:00
Florian Bruhin
a11356bb99 Don't require working icon to start 2017-04-03 08:32:39 +02:00
Florian Bruhin
9dc5e978ac Update docs 2017-04-03 06:55:54 +02:00
Florian Bruhin
35181ff84e Merge commit '4004d5adf09e6d22dae5d781a02c5fc2bbd26724' into Carpetsmoker/unwritable-keyconf 2017-04-03 06:55:01 +02:00
Martin Tournoij
4004d5adf0 Don't crash when trying to write an unwritable keyconf.
Also change the logic in _load_default a wee bit so that it won't try to
write the keys.conf on startup.

Fixes #1235
2017-04-03 01:48:39 +01:00
Florian Bruhin
30655e29fc Regenerate authors 2017-04-02 22:58:22 +02:00
Florian Bruhin
55b0f16383 Merge commit 'cdb3605b03911e0cffce7cc7a07bb5b120d195ce' into Penaz91/master 2017-04-02 22:57:47 +02:00
Florian Bruhin
e3fc23fa30 Update authors 2017-04-02 19:24:06 +02:00
Florian Bruhin
2108846948 Merge commit '1a337f6a77cf9e284abcf14813b6c70241e0045c' into Carpetsmoker/document-spell 2017-04-02 19:23:52 +02:00
Florian Bruhin
ad6ed83782 Update changelog 2017-04-02 19:17:13 +02:00
Florian Bruhin
248ff09624 Merge commit '5efca155948bc467e4fb7b19dafd98d47e33745b' into Carpetsmoker/config-comments 2017-04-02 19:14:00 +02:00
Florian Bruhin
48094fb33d Update authors 2017-04-02 18:47:16 +02:00
Florian Bruhin
b20267b57d Merge commit '7f13c9a3c31aa719144ca3afcad7af305dd2f6ed' into Carpetsmoker/relax-cmdline 2017-04-02 18:47:00 +02:00
Florian Bruhin
338307ac24 Add #noqa for Quitter._shutdown 2017-04-02 18:35:10 +02:00
Florian Bruhin
f595c2a7fb Update changelog 2017-04-02 18:34:39 +02:00
Florian Bruhin
e2cf02c705 Merge commit '79a22f1f4751741cabd5f5a19ee4bcdb6b6dfce8' into Carpetsmoker/unknown-setting-c 2017-04-02 18:34:12 +02:00
Florian Bruhin
f2ddf608a8 Update authors 2017-04-02 18:33:55 +02:00
Florian Bruhin
bf1834e132 Merge commit '522e105aaf4c326d27e087222c0ba76680d1bed3' into pyup-bot/pyup-update-flask-0.12-to-0.12.1 2017-04-02 18:11:34 +02:00
Florian Bruhin
2238a888dc Fix changelog 2017-04-02 15:20:44 +02:00
Penaz
cdb3605b03 Update INSTALL.asciidoc 2017-04-02 10:36:11 +02:00
Penaz
1f2e04c466 Update INSTALL.asciidoc
Updated Install.asciidoc to include Live Install on Gentoo
2017-04-01 23:32:42 +02:00
Martin Tournoij
79a22f1f47 Allow pressing ^C when there's an unknown setting
All of it is just converting `objreg.get('xxx')` to `objreg.get('xxx',
None)` and adding a `if xxx is not None` check.

Fixes #1170
2017-04-01 21:14:35 +01:00
Martin Tournoij
1a337f6a77 Document how to do spell checking in the FAQ 2017-03-31 18:51:04 +01:00
pyup-bot
522e105aaf Update flask from 0.12 to 0.12.1 2017-03-31 19:49:32 +02:00
Martin Tournoij
7f13c9a3c3 Relax commandline parsing a bit
Problem 1: Entering a command of `:::save` gives an error.
Problem 2: Entering a command of `:save\n` gives an error.

Both scenarios may seem a bit silly at first, but I encountered both by
copy/pasting a command:

1. Enter `:` in qutebrowser.
2. Copy a full line from a terminal starting with `:`.
3. You will now have both of the above problems.

Solution: Trim all whitespace and `:` of a command. This is also what
Vim does, by the way.
2017-03-31 17:14:11 +01:00
Florian Bruhin
9cd2c9aa6d Merge branch 'Carpetsmoker/feature-modeline' 2017-03-31 17:47:34 +02:00
Florian Bruhin
05059b4a5e Merge commit '8af5cfb4ac9e6d928cfeb0522fa729ba616df70a' 2017-03-31 17:47:34 +02:00
Florian Bruhin
80a5613b80 Merge commit '8af5cfb4ac9e6d928cfeb0522fa729ba616df70a' into Carpetsmoker/feature-modeline 2017-03-31 17:47:02 +02:00
Martin Tournoij
8af5cfb4ac Add a modeline to all the *.feature files
This really tripped me up yesterday, My "Vim default" is to use tabs.

This (where `!···` is a tab) does not work as you'll hope it works:

    Scenario: Retrying a failed download when the directory didn't exist (issue 2445)
        When I download http://localhost:(port)/data/downloads/download.bin to <path>
        And I wait for the error "Download error: No such file or directory: *"
        And I make the directory <mkdir>
        And I run :download-retry
!···!···And I wait until the download is finished
        Then the downloaded file <expected> should exist

        Examples:
        | path                 | mkdir   | expected             |
        | asd/zxc/             | asd/zxc | asd/zxc/download.bin |

Unfortunately, pytest-bdd uses the "Python 2 behaviour" of "expand all
tabs to 8 spaces", and doesn't give any errors on strange/inconsistent
whitespace. It can cause very confusing errors.
2017-03-31 16:16:31 +01:00
Florian Bruhin
189c1721af Don't wait for download.bin in windows downloads 2017-03-31 14:46:29 +02:00
Florian Bruhin
fd276dabc7 appveyor_install: Don't install old PyQt if unneeded 2017-03-31 13:05:35 +02:00
Florian Bruhin
c28c428051 appveyor: Add Python36 to PATH
Otherwise the PyQt in the virtualenv won't be able to find python3.dll.
2017-03-31 13:05:35 +02:00
Florian Bruhin
a6041834f8 Try adding a PyPI testenv on AppVeyor 2017-03-31 13:05:34 +02:00
Florian Bruhin
6c3abadb32 Stabilize :repeat-command test 2017-03-31 13:05:34 +02:00
Florian Bruhin
004eb742f6 Stabilize test_guiprocess 2017-03-31 13:05:34 +02:00
Florian Bruhin
43155b0cc8 Stabilize history.replaceState tests 2017-03-31 13:05:34 +02:00
Florian Bruhin
eb202d761c Stabilize dumping bookmarks test
For some reason, with QtWebEngine on Windows, sometimes the :debug-dump-page
callback does not get called if we try to dump the same page again...
2017-03-31 13:05:34 +02:00
Florian Bruhin
1eda2b0ea4 Fallback to clipboard when primary selection is unsupported 2017-03-31 13:05:34 +02:00
Florian Bruhin
64feb62fb1 Paste clipboard when using shift-insert in prompts 2017-03-31 13:05:34 +02:00
Florian Bruhin
7dba877354 tests: Update "Unable to set geometry" ignore 2017-03-31 13:05:34 +02:00
Florian Bruhin
2884277dbd Fix Shift-Insert without it being supported 2017-03-31 13:05:34 +02:00
Florian Bruhin
dc405ec3a8 Skip QtWebEngine SSL tests on Windows 2017-03-31 13:05:34 +02:00
Florian Bruhin
a4619d07db tests: Wait until about:blank is loaded 2017-03-31 13:03:40 +02:00
Florian Bruhin
bf66bb221f Ignore getrlimit error during tests 2017-03-31 13:03:40 +02:00
Florian Bruhin
708b46d6c0 Fix text with empty primary selection 2017-03-31 13:03:40 +02:00
Florian Bruhin
4d49d9da09 Skip renderer process crash test on Windows 2017-03-31 13:03:40 +02:00
Florian Bruhin
c551c62c27 Stabilize JS tests 2017-03-31 13:03:40 +02:00
Florian Bruhin
dc0a782839 Run python in hints tests 2017-03-31 13:03:40 +02:00
Florian Bruhin
2c4e549d80 Close temporary download file for QtWebEngine
Otherwise, Chromium won't be able to write on it on Windows - and we only
need the name anyways.
2017-03-31 13:03:18 +02:00
Florian Bruhin
edb197b028 Make waiting for download prompt more robust 2017-03-31 13:03:18 +02:00
Florian Bruhin
e28eabe5eb Add marker for #2478 2017-03-31 13:03:17 +02:00
Florian Bruhin
5a16133685 Fix prompt with SSL error test 2017-03-31 13:03:17 +02:00
Florian Bruhin
a3a885f053 Ignore bogus Qt warning during tests 2017-03-31 13:03:17 +02:00
Florian Bruhin
a55d1b1ee8 Save old socket for IPC
At least on Windows with Qt 5.8, we get readyRead notifications *after*
disconnect...
2017-03-31 13:03:17 +02:00
Florian Bruhin
57223b78f3 Merge commit '03704ecb4b3b603379f7caf297ae568f0902f90a' 2017-03-31 12:06:07 +02:00
Florian Bruhin
390006281f Merge commit '3c8e2a630a374fb571d70ed8c5a9f0c7faefd64a' into pyup-bot/pyup-update-pyqt5-5.8.1.1-to-5.8.2 2017-03-31 12:04:17 +02:00
Florian Bruhin
150676404e Merge commit '47c7feea551e8a6822d5da522187cca417ca3223' into pyup-bot/pyup-update-pytest-mock-1.5.0-to-1.6.0 2017-03-31 12:04:15 +02:00
Florian Bruhin
134155480e tox: Update PyQt5 to 5.8.2 2017-03-31 10:10:55 +02:00
Florian Bruhin
3b351d9066 Run more invocation tests with QtWebEngine 2017-03-31 06:18:43 +02:00
pyup-bot
47c7feea55 Update pytest-mock from 1.5.0 to 1.6.0 2017-03-31 01:25:27 +02:00
Florian Bruhin
eb31f679f4 Allow unknown args in testbrowser 2017-03-30 21:50:19 +02:00
Martin Tournoij
5efca15594 Put option comments right above the option value
Problem: I like to edit `~/.config/qutebrowser/qutebrowser.conf`
manually with Vim. This works great, except that the current format is a
bit of a pain to deal with:

	[section-name]
	# section description
	#
	# [ Description of all the options]

	actual options

So if I want to know the description or what the default value is, I
need to scroll up and back down.

Solution: change the order of the comments to:

	# section description
	[section-name]

	# Option description
	option = value

	# Option description two
	optiontwo = value

	# Hello, world!
	[section-two]
	...

Which is much more convenient (and also what almost any other program
does).

(This patch changes much less code than it looks in the diff; I just
de-looped and moved `_str_option_desc` below `_str_items` as that makes
more sense since it gets called by `_str_items`).
2017-03-30 18:45:28 +01:00
pyup-bot
3c8e2a630a Update pyqt5 from 5.8.1.1 to 5.8.2 2017-03-30 13:39:30 +02:00
pyup-bot
03704ecb4b Update sip from 4.19.1 to 4.19.2 2017-03-30 12:39:24 +02:00
Florian Bruhin
6939f81de7 Merge commit '563a5431e35831cb0a8c418835c54d0264d92c78' into Kingdread/windows-drive-cwd 2017-03-30 10:48:39 +02:00
Florian Bruhin
2377235c14 Merge commit 'caf0a87e16cf930f67ce9fc64ea94e17cae6269d' into amosbird/master 2017-03-30 10:48:32 +02:00
Florian Bruhin
20c414a62c Update changelog 2017-03-30 10:44:11 +02:00
Florian Bruhin
203b2d30cc Update changelog 2017-03-30 10:42:43 +02:00
Florian Bruhin
6a144ef7bd Merge branch 'Kingdread/windows-drive-cwd' 2017-03-30 10:41:58 +02:00
Daniel Schadt
563a5431e3 fixup! use message.error instead of a tooltip 2017-03-29 18:32:07 +02:00
Daniel Schadt
186eab8eb1 use message.error instead of a tooltip 2017-03-29 17:07:53 +02:00
Daniel Schadt
99f7bfa712 show messages on top of the prompt
Otherwise, errors are hidden behind the prompt, which makes it hard to
use them in the filename prompt.
2017-03-29 16:44:29 +02:00
Imran Sobir
3aaebe83fb Remove noscript message from history.html. 2017-03-29 14:22:58 +05:00
Amos Bird
caf0a87e16 Fix #2476, recognize SOCKS5, SOCKS4 in proxy. 2017-03-29 14:22:37 +08:00
Florian Bruhin
93a12797aa Fix quteprocess tests with Python 3.6 on Windows
Values smaller than 86400 would result in a negative unsupported timestamp and
thus throw ValueError in Python 3.6
2017-03-28 20:53:11 +02:00
Florian Bruhin
5d9cd98c0f tox: Add a mkvenv-win-pypi env 2017-03-28 20:42:23 +02:00
Florian Bruhin
fe81f153cf tests: Ignore "Unable to locate theme engine" messages 2017-03-28 20:41:23 +02:00
Imran Sobir
4a4c7b96d1 Add nojs history page. 2017-03-28 18:34:47 +05:00
Florian Bruhin
607710eeae Update changelog
[ci skip]
2017-03-27 08:02:43 +02:00
Florian Bruhin
bcb4649235 Fix crash when window_ids change during init 2017-03-27 08:00:19 +02:00
Florian Bruhin
b98d34b29c Handle None-tab in get_tab_fields
I can't reproduce this but I got a crash report about it.
2017-03-27 07:57:43 +02:00
Florian Bruhin
bcee6d295c Handle None-widget in tabbedbrowser.widgets()
I can't reproduce this, but got a crash report about it.
2017-03-27 07:52:33 +02:00
Florian Bruhin
5a4d11be68 Fix lint 2017-03-27 07:16:10 +02:00
Florian Bruhin
a8bc531eee Add a test for :open with -s 2017-03-27 07:09:55 +02:00
Florian Bruhin
43090d146b Update docs 2017-03-27 07:09:48 +02:00
Florian Bruhin
f6906512dc Merge commit 'df93e30ec20dd1b2b4fe163bdb5a69c232fb8c71' into Al-Caveman/master 2017-03-27 07:00:53 +02:00
Florian Bruhin
37d22a7cfd Merge commit '9dccd00ebb2483fd0bb6c6447f57c76a4b40d335' into Kingdread/windows-drive-cwd 2017-03-26 22:14:47 +02:00
pyup-bot
b3660cf3f4 Update setuptools from 34.3.2 to 34.3.3 2017-03-26 18:21:23 +02:00
Florian Bruhin
39b09f7822 Improve messageview hide code 2017-03-26 15:03:44 +02:00
Florian Bruhin
59094b71a9 Update docs 2017-03-26 15:03:44 +02:00
Florian Bruhin
2181e1ddc4 Merge commit '13677d3563dbd01ae188a2b1a79c7dd840a5dc5e' into pkill-nine/upstream-master-close_message_on_click 2017-03-26 14:59:08 +02:00
pkill9
13677d3563 Add mouse back button to click test. 2017-03-25 21:16:51 +00:00
pkill9
5e1c530d71 Add docstring to MessageView.mousePressEvent 2017-03-25 21:03:21 +00:00
pkill9
bf2493c1c4 Add test. 2017-03-25 20:06:58 +00:00
pkill9
67034273f7 Move criteria into a list and add middle mouse button. 2017-03-25 15:58:37 +00:00
caveman
df93e30ec2 fixes #2468 2017-03-25 11:44:36 +04:00
Daniel Schadt
9dccd00ebb fix unused import 2017-03-24 14:49:30 +01:00
Daniel Schadt
a011034ff7 fix tests 2017-03-24 13:21:09 +01:00
Daniel Schadt
df83f7aa99 also add path transformations to :download 2017-03-24 12:30:29 +01:00
Daniel Schadt
07b3a7db7c add integration tests for reserved filenames 2017-03-24 11:57:05 +01:00
Daniel Schadt
bc4430e5d9 prevent reserved filenames on Windows
Fixes #82

Prevents filenames like COM1, ...
2017-03-24 11:36:19 +01:00
Daniel Schadt
9d905ebb5c disallow filenames like E:filename
Per-drive working directories are not really supported.
2017-03-24 11:04:20 +01:00
Florian Bruhin
52b448e368 pylint: Ignore no-else-return
This will be added in the next pylint release, and it seems we can already add
it without getting an error.
2017-03-23 20:51:37 +01:00
Florian Bruhin
38beba98b9 pylint-master requirements: Add github3.py 2017-03-23 20:32:58 +01:00
Daniel Schadt
3da21a32d2 treat E: and E:\ the same when downloading
Fixes #2305
2017-03-23 18:16:15 +01:00
Florian Bruhin
a7d6cc6509 Update docs 2017-03-23 06:17:48 +01:00
Ryan Roden-Corrent
a68f997d95 Make keyhint delay configurable.
ui.keyhint-delay controls the time from starting a keychain to showing the
keyhint dialog. Resolves #2462.
2017-03-22 21:50:26 -04:00
Florian Bruhin
0c7d012420 Update changelog 2017-03-22 22:54:33 +01:00
Florian Bruhin
042ffeca91 Merge commit '631936361405d812f353b4108246c883cdf48100' into Kingdread/issue-2304 2017-03-22 22:50:28 +01:00
Daniel Schadt
6319363614 add a test for downloading a 500 inline attachment 2017-03-22 13:38:03 +01:00
Florian Bruhin
4d65abfcc6 Check if widget is deleted in _on_webkit_icon_changed 2017-03-22 06:32:09 +01:00
Daniel Schadt
ebc70f66e5 Check for None-reply in _do_die
Fixes #2304

In some cases, the finished handler fired before the error handler, e.g.
when downloading a 500 error page that is sent as attachment:

    HTTP/1.1 500 Internal Server Error
    Content-Type: application/octet-stream
    Content-Disposition: inline; filename="attachment.jpg"

here we downloaded 0 bytes, fired the finished handler and after that
fired the error handler because of the 500 - but the finished handler
had already set our reply to None (and displayed the error message).
2017-03-21 18:54:21 +01:00
Florian Bruhin
f8e043214a Update WORKAROUND comments 2017-03-21 10:29:31 +01:00
Florian Bruhin
081abde9cd Fix indent 2017-03-20 22:06:05 +01:00
Florian Bruhin
3fbb9a14e0 Fix continuing a search after clearing it
Fixes #2438
2017-03-20 21:34:33 +01:00
Florian Bruhin
41268f994d Merge branch 'pyup-bot/pyup-update-hypothesis-3.6.1-to-3.7.0' 2017-03-20 17:58:34 +01:00
Florian Bruhin
78ae6a7a5f Merge commit 'cd91da32c4a1680cb201e58e40dfb3744628eca8' 2017-03-20 17:58:34 +01:00
Florian Bruhin
13878647b2 Merge commit 'cd91da32c4a1680cb201e58e40dfb3744628eca8' into pyup-bot/pyup-update-hypothesis-3.6.1-to-3.7.0 2017-03-20 16:48:41 +01:00
Florian Bruhin
c996245012 Fix line length 2017-03-20 16:48:21 +01:00
Florian Bruhin
c48339fe06 Update changelog 2017-03-20 16:47:36 +01:00
pyup-bot
cd91da32c4 Update hypothesis from 3.6.1 to 3.7.0 2017-03-20 16:04:22 +01:00
Florian Bruhin
98f17a03bb Prevent page without history from being serialized
Fixes #2458
2017-03-20 11:50:04 +01:00
Florian Bruhin
4b6b9c2d21 Add missing file 2017-03-20 11:28:01 +01:00
Florian Bruhin
ed4cd816d4 Update docs 2017-03-20 09:45:27 +01:00
Florian Bruhin
6888ac04e1 Fix handling of failed downloads with QtWebEngine 2017-03-20 09:44:07 +01:00
Florian Bruhin
3e2ba32240 Fix retrying downloads with QtWebEngine
Fixes #2298
2017-03-20 09:35:53 +01:00
Florian Bruhin
1581db2d59 Update changelog 2017-03-20 09:16:26 +01:00
Florian Bruhin
1179ee7a93 Merge branch 'imransobir/newhistory' 2017-03-20 09:11:58 +01:00
Florian Bruhin
7652b6ae03 Merge commit '724e6b29c38a55f722f17997379f1ebe190fa6db' 2017-03-20 09:11:47 +01:00
pyup-bot
26f5fb8eb4 Update cheroot from 5.3.0 to 5.4.0 2017-03-19 17:19:46 +01:00
thuck
20d058741e Merge branch 'pintab' of https://github.com/thuck/qutebrowser into pintab 2017-03-19 14:43:36 +01:00
thuck
650b1de3b6 Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2017-03-19 14:26:48 +01:00
thuck
02bf0401ab Last pinned to pinned_count 2017-03-19 14:05:21 +01:00
thuck
2eb07fc9cc Fix line size 2017-03-19 14:03:24 +01:00
MikeinRealLife
a1e1e90ec9 Issue #2292
Added a list of chrome urls that work.  A couple of with (?) next to
them did nothing and didn't hang or kill the browser, so I removed them.
They only work in OSX, not windows (opened separate issue for this).
2017-03-18 20:05:21 -07:00
Florian Bruhin
1254f4d132 Add -bb when running tests
Fixes #1989
2017-03-18 21:08:07 +01:00
Florian Bruhin
069f908a61 Get rid of run_pytest.py
Fixes #2452
2017-03-18 21:03:52 +01:00
Florian Bruhin
7c94b06be1 Merge commit '724e6b29c38a55f722f17997379f1ebe190fa6db' into imransobir/newhistory 2017-03-18 18:31:45 +01:00
pyup-bot
dc50c6ac3d Update py from 1.4.32 to 1.4.33 2017-03-17 04:29:28 +01:00
pyup-bot
4b4c28fc6a Update py from 1.4.32 to 1.4.33 2017-03-17 04:29:26 +01:00
Florian Bruhin
99c7301fb4 Update IPC atime once all 3h
See #996
2017-03-16 09:24:49 +01:00
Imran Sobir
724e6b29c3 Make session interval configurable. 2017-03-16 12:11:16 +05:00
Imran Sobir
fb97c6dffc Send history item atime in milliseconds. 2017-03-16 12:03:40 +05:00
Florian Bruhin
befb1afb2c Fix vulture 2017-03-16 07:50:23 +01:00
Florian Bruhin
d33e590ce5 Fix lint 2017-03-15 22:15:52 +01:00
Florian Bruhin
a70012b32e Merge commit '5f17887a255494e1872c33c96f0596d6701e35fc' into pyup-bot/pyup-update-werkzeug-0.12-to-0.12.1 2017-03-15 20:01:02 +01:00
Florian Bruhin
85fff35eef Merge branch 'gl-workaround' 2017-03-15 19:52:33 +01:00
Florian Bruhin
0877092cea Add workaround for black screen with QtWebEngine
Fixes #2441
2017-03-15 19:52:21 +01:00
pyup-bot
5f17887a25 Update werkzeug from 0.12 to 0.12.1 2017-03-15 19:00:29 +01:00
Florian Bruhin
54eddc4658 Merge commit '578fac1331ea5d733088379b28edc760964147b1' into pyup-bot/pyup-update-pytest-3.0.6-to-3.0.7 2017-03-15 08:24:17 +01:00
pyup-bot
d19979aa4a Update wrapt from 1.10.8 to 1.10.10 2017-03-15 01:48:48 +01:00
pyup-bot
c40844dc09 Update wrapt from 1.10.8 to 1.10.10 2017-03-15 01:48:47 +01:00
pyup-bot
578fac1331 Update pytest from 3.0.6 to 3.0.7 2017-03-15 01:18:51 +01:00
Florian Bruhin
608a16c8b7 Regen docs 2017-03-14 17:32:02 +01:00
Florian Bruhin
84d2e9adc6 Improve documentation around scrolling
Fixes #2447
2017-03-14 16:58:33 +01:00
Florian Bruhin
3a88b70eca Fix PyQt5 version in tox.ini 2017-03-13 09:11:22 +01:00
Florian Bruhin
f50485420a Merge commit 'b5d5f323bb85cfe6824bab97a6e29efe5204616f' into pyup-bot/pyup-update-werkzeug-0.11.15-to-0.12 2017-03-13 07:47:58 +01:00
Florian Bruhin
db4ca46ec1 Merge commit '4d9d4490f59401d790139b4e5cf45dc2b9096eee' into pyup-bot/pyup-update-setuptools-34.3.1-to-34.3.2 2017-03-13 07:47:56 +01:00
Florian Bruhin
b35be46b8d Merge commit '4b5af2296d07c7c9f0e6197d7167509ecc35c4f4' into pyup-bot/pyup-update-cheroot-5.2.0-to-5.3.0 2017-03-13 07:47:53 +01:00
Florian Bruhin
68247a1ef0 Fix PyQt5 requirements
See https://www.riverbankcomputing.com/pipermail/pyqt/2017-March/038964.html
2017-03-13 07:39:21 +01:00
Florian Bruhin
8d9030ec47 Use debug log for on_timeout message 2017-03-13 07:01:21 +01:00
Florian Bruhin
ecec836111 Fix adblock UTF-8 test on Windows 2017-03-13 07:01:13 +01:00
Florian Bruhin
7d9686f917 Don't keep temporary files around in asciidoc2html
Fixes #2431
2017-03-13 06:56:29 +01:00
pyup-bot
4b5af2296d Update cheroot from 5.2.0 to 5.3.0 2017-03-12 18:54:35 +01:00
pkill9
b1771a13c9 Removed setting. 2017-03-12 16:48:57 +00:00
pkill9
87c4c143bf Clear notification messages in a window when they're clicked. 2017-03-11 20:45:12 +00:00
pyup-bot
4d9d4490f5 Update setuptools from 34.3.1 to 34.3.2 2017-03-11 15:59:29 +01:00
pyup-bot
b5d5f323bb Update werkzeug from 0.11.15 to 0.12 2017-03-10 13:22:25 +01:00
Imran Sobir
ccbf8572c3 Check for null when receiving history. 2017-03-09 22:16:46 +05:00
Imran Sobir
a1bec12b2e Ensure qute:javascript throws QuteSchemeOSError on 404. 2017-03-09 22:07:55 +05:00
Imran Sobir
50bca33618 Use OSError instead of IOError. 2017-03-09 21:47:12 +05:00
Imran Sobir
19b7f779ef Fix ambiguity in history table ID. 2017-03-09 21:41:57 +05:00
Imran Sobir
3fbeecbec2 Hide 'Show more' when Javascript is disabled. 2017-03-09 21:35:22 +05:00
Florian Bruhin
0b5838f9fd Fix BDD version check operators 2017-03-08 20:56:30 +01:00
Florian Bruhin
685393c289 Update docs 2017-03-08 19:23:01 +01:00
Florian Bruhin
eb2888a957 Merge commit 'd3b16bbd075f9e8c8656a402975d776088c2dab8' into pkill-nine/upstream-master-close_messages 2017-03-08 19:19:30 +01:00
Florian Bruhin
4278cd5e3e Remove unused operator imports 2017-03-08 19:10:29 +01:00
Florian Bruhin
3925fa2872 Use separate requirements file for PyQt 2017-03-08 19:09:34 +01:00
pkill9
d3b16bbd07 Add command to clear messages - cleaner 2017-03-08 10:49:15 +00:00
Florian Bruhin
7d7f5350c5 Add test for utils.get_clipboard with empty clipboard 2017-03-08 09:33:36 +01:00
Florian Bruhin
7ba01e6764 Get rid of utils.actute_warning
Only Ubuntu Trusty still uses Qt < 5.3, and the issue seems to be fixed there by
now.
2017-03-08 09:25:46 +01:00
Florian Bruhin
f86f9cd92a Refactor qtutils.version_check API
Fixes #2423
2017-03-08 08:41:18 +01:00
Florian Bruhin
ac0409c60d Don't install requirements-pip.txt
It causes stuff to blow up when something in there got upgraded, and we ask pip
to downgrade one of its dependencies.

We still keep the file around so we get notified about updates.
2017-03-08 07:42:08 +01:00
Florian Bruhin
dfb4374ae1 Release v0.10.1 2017-03-08 06:26:22 +01:00
Florian Bruhin
6052d36ef0 Merge commit '2304fd81b5440e55d2686f7cb33c10bb8eaa9e92' into pyup-bot/pyup-update-markupsafe-0.23-to-1.0 2017-03-08 05:11:08 +01:00
Florian Bruhin
4110355167 Merge commit '9512206f97bc51bb2884c38a86b93a72e556428d' into pyup-bot/pyup-update-pyqt5-5.8-to-5.8.1 2017-03-08 05:11:00 +01:00
Florian Bruhin
589ea70626 Update changelog for v0.10.1
(cherry picked from commit 361e4e93ed)
2017-03-08 05:09:53 +01:00
Florian Bruhin
6bdf8495aa pylint: Disable too-many-boolean-expressions 2017-03-08 05:06:35 +01:00
Florian Bruhin
7c9d004bbc Fix compiled version check
Fixes #2412
2017-03-07 22:05:17 +01:00
Florian Bruhin
4c3c86081f Refactor adblock parsing 2017-03-07 21:46:04 +01:00
Florian Bruhin
3258ef7e3f Merge commit 'c50e652cc70dcf1f86dd440b82c2b3f3c8fd5663' into pyup-bot/pyup-update-appdirs-1.4.2-to-1.4.3 2017-03-07 20:37:36 +01:00
Florian Bruhin
ace4006179 Stringify py.path.local in adblock tests 2017-03-07 20:36:50 +01:00
Florian Bruhin
c45019f0a0 Handle invalid UTF8 data in hostblock lists
Fixes #2301
2017-03-07 20:25:13 +01:00
pyup-bot
2304fd81b5 Update markupsafe from 0.23 to 1.0 2017-03-07 17:20:17 +01:00
pyup-bot
9512206f97 Update pyqt5 from 5.8 to 5.8.1 2017-03-07 12:10:15 +01:00
pyup-bot
c50e652cc7 Update appdirs from 1.4.2 to 1.4.3 2017-03-07 09:00:55 +01:00
Florian Bruhin
3cc4f69125 Merge commit '7ef71750e769f9402991f72b1d0e78c0efacf14a' into pyup-bot/pyup-update-flake8-tidy-imports-1.0.5-to-1.0.6 2017-03-07 06:51:34 +01:00
Florian Bruhin
d42dff67f2 Reorder initialization
marcos.init() really belongs into _init_modules, and we need to do _process_args
after everything has been initialized.

Fixes #2408.
2017-03-07 06:46:35 +01:00
pyup-bot
7ef71750e7 Update flake8-tidy-imports from 1.0.5 to 1.0.6 2017-03-07 06:16:53 +01:00
Florian Bruhin
35a58b27af Merge pull request #2406 from qutebrowser/pyup-update-vulture-0.12-to-0.13
Update vulture to 0.13
2017-03-06 16:12:04 +01:00
pyup-bot
694a1247a1 Update vulture from 0.12 to 0.13 2017-03-06 13:30:50 +01:00
pyup-bot
990ee1826e Update vulture from 0.12 to 0.13 2017-03-06 13:30:49 +01:00
Florian Bruhin
3870e9f6b4 Merge pull request #2405 from qutebrowser/pyup-update-pyparsing-2.1.10-to-2.2.0
Update pyparsing to 2.2.0
2017-03-06 06:31:19 +01:00
Florian Bruhin
5fb6d26465 Stabilize some tests 2017-03-06 06:28:26 +01:00
pyup-bot
a19ebfb6d0 Update pyparsing from 2.1.10 to 2.2.0 2017-03-06 03:58:50 +01:00
Florian Bruhin
b117d981a5 Install debug packages on Ubuntu 2017-03-05 20:28:27 +01:00
Florian Bruhin
23a26bf08b Improve travis backtrace script 2017-03-05 20:28:27 +01:00
Florian Bruhin
8fb640f1ff Debug segfaults on travis
Fixes #2097
2017-03-05 20:28:27 +01:00
pkill9
74be2fa4b9 Add command to close all messages. 2017-03-05 14:55:28 +00:00
Florian Bruhin
271cb3be3d Merge branch 'Kingdread-fast-open-download' 2017-03-05 15:51:35 +01:00
Florian Bruhin
27edc89d88 Update changelog 2017-03-05 15:51:14 +01:00
Florian Bruhin
ec42d2fd2a Merge branch 'fast-open-download' of https://github.com/Kingdread/qutebrowser into Kingdread-fast-open-download 2017-03-05 15:50:38 +01:00
Florian Bruhin
0e56cff702 Merge branch 'TomRiddle01-hide_adblock_message' 2017-03-05 15:19:09 +01:00
Florian Bruhin
6fbaa16366 Update authors 2017-03-05 15:18:59 +01:00
Florian Bruhin
a585015d9d Merge branch 'hide_adblock_message' of https://github.com/TomRiddle01/qutebrowser into TomRiddle01-hide_adblock_message 2017-03-05 15:18:43 +01:00
Florian Bruhin
a1c7d179e3 Only call QApplication::sync() with QtWebEngine 2017-03-05 15:16:14 +01:00
Florian Bruhin
fa89fff668 Stabilize session tests 2017-03-05 15:15:12 +01:00
Florian Bruhin
199a2ffe27 Remove unneeded deleted attribute for FakeSocket 2017-03-05 15:15:12 +01:00
Florian Bruhin
efe18b056a Merge pull request #2401 from qutebrowser/pyup-update-cssutils-1.0.1-to-1.0.2
Update cssutils to 1.0.2
2017-03-05 11:03:21 +01:00
Florian Bruhin
c422897abb Make sure to process history after the rest of init is done
Otherwise, with 5ccafd62d4 the history starts
processing before the webview opened, and opening it is delayed until the whole
history is read.

Instead, call _process_args directly (I'm not even sure why it was using a 0ms
QTimer...) and schedule _init_late_modules after everything is really done.
2017-03-04 18:24:44 +01:00
Florian Bruhin
5ccafd62d4 Fix initial keyboard focus with QtWebEngine
Fixes #2321.
2017-03-04 18:11:34 +01:00
Florian Bruhin
e81edc8224 ipc: Delay deleting of QLocalSocket on disconnect
Fixes #2396.

See https://bugreports.qt.io/browse/QTBUG-59297 and
https://github.com/qutebrowser/qutebrowser/issues/2321#issuecomment-284024213
2017-03-04 18:11:34 +01:00
pyup-bot
52518f6abe Update cssutils from 1.0.1 to 1.0.2 2017-03-04 17:50:46 +01:00
Yannis Rohloff
7984643365 flake8 fails fixed 2017-03-04 17:16:52 +01:00
Yannis Rohloff
5d5652a24b always read the host file 2017-03-04 17:08:53 +01:00
Yannis Rohloff
6219b37c39 adblock: Don't show message if host-blocking-enabled is true
Fixes #2364
2017-03-04 16:39:44 +01:00
Imran Sobir
0092b18c44 Fix qute:javascript on Windows. 2017-03-04 19:37:48 +05:00
Daniel Schadt
90f12a1d5a return fast from DownloadItem.open_file
Fixes #2296

By using a singleshot timer, we return fast from DownloadItem.open_file,
which in turn closes the prompt fast, which in turn doesn't allow a
second Ctrl-x to be registered, which in turn doesn't want to set the
filename twice.
2017-03-04 11:30:41 +01:00
Florian Bruhin
550514c20b Merge pull request #2393 from qutebrowser/pyup-update-setuptools-34.3.0-to-34.3.1
Update setuptools to 34.3.1
2017-03-03 07:31:41 +01:00
pyup-bot
0eeb3a51d3 Update setuptools from 34.3.0 to 34.3.1 2017-03-03 01:50:32 +01:00
Florian Bruhin
a5af039bf4 Merge pull request #2391 from qutebrowser/pyup-update-cheroot-5.1.0-to-5.2.0
Update cheroot to 5.2.0
2017-03-02 22:49:32 +01:00
Florian Bruhin
0186a9bde5 Fix lint 2017-03-02 21:10:31 +01:00
pyup-bot
88a04556ea Update cheroot from 5.1.0 to 5.2.0 2017-03-02 20:45:31 +01:00
Florian Bruhin
75bc400e74 Add Chromium version to version output
This also restructures things a bit to show the backend version together with
the backend.

Fixes #2380
2017-03-02 20:22:17 +01:00
Imran Sobir
907d94591d Make a now fixture to hold time of test. 2017-03-02 23:55:59 +05:00
Imran Sobir
96e81f595f Fix a case where 'next' is not correctly returned. 2017-03-02 23:14:00 +05:00
Florian Bruhin
56ab02f54d Set tab as parent for print dialogs
Fixes #2366
2017-03-02 18:44:07 +01:00
Imran Sobir
895620b536 Don't assume 'next' appears last. 2017-03-02 22:40:24 +05:00
Florian Bruhin
ea653e6fe4 Merge pull request #2388 from qutebrowser/pyup-initial-update
Initial Update
2017-03-02 10:16:49 +01:00
Florian Bruhin
65a701a180 Stabilize existing text test 2017-03-02 08:38:07 +01:00
Florian Bruhin
d6f47bd3fb Fix lint 2017-03-02 08:29:43 +01:00
Florian Bruhin
d4124c5c2a Ignore pyup-bot for author list 2017-03-01 23:55:19 +01:00
pyup-bot
22650785aa Update parse from 1.6.6 to 1.8.0 2017-03-01 23:52:42 +01:00
Florian Bruhin
81a36ffd7d Strip QtWebEngine download suffixes properly
Fixes #2386
2017-03-01 23:43:04 +01:00
Florian Bruhin
88904864c9 Skip failing tests on Qt < 5.8 2017-03-01 20:24:34 +01:00
Florian Bruhin
f4490fb90c Fix WebKitElement._move_text_cursor with old PyQt 2017-03-01 20:19:40 +01:00
Florian Bruhin
1f12b4c1c1 Relax validation of QssColor values
Fixes #2370
2017-03-01 18:11:53 +01:00
Florian Bruhin
65f407e926 Remove webelem.style_property()
It's not used anymore, and not possible to support with QtWebEngine without a
massive performance hit when serializing elements.
2017-03-01 17:54:27 +01:00
Florian Bruhin
b4af966167 Make stubbed methods fail tests again
Only some caret browsing stuff and a few webelement methods are stubbed out now.
Make them fail tests so we notice when we use a stub.
2017-03-01 17:43:33 +01:00
Florian Bruhin
03f1e0913d Add _js_call to WebEngineElement 2017-03-01 17:34:21 +01:00
Florian Bruhin
bc0a9cd94d Move cursor to end with input elements on QtWebEngine 2017-03-01 17:30:48 +01:00
Florian Bruhin
1e1ba34b60 Fix selecting text fields with QtWebKit
Using focus() in JS there means that existing text in the field gets selected.
Move the cursor to the end after focusing it to prevent that.

Fixes #2359
2017-03-01 17:13:02 +01:00
Florian Bruhin
f9697f1ebe Update changelog 2017-03-01 14:26:38 +01:00
Florian Bruhin
deb59fc66e Don't strip info when loading PAC from a file 2017-03-01 14:19:23 +01:00
Florian Bruhin
9bb5c9fdab Remove UserInfo and path/query for PAC URLs 2017-03-01 14:19:13 +01:00
Florian Bruhin
5d0c9440f6 Fix monkeypatch 2017-03-01 12:12:40 +01:00
Florian Bruhin
ca4f249c30 Use three-argument form of monkeypatch.*attr 2017-03-01 11:33:41 +01:00
Florian Bruhin
1e42fd1319 Fix lint 2017-03-01 11:12:28 +01:00
Florian Bruhin
642afb0aff Merge branch 'wasamasa-ZZ-and-ZQ' 2017-02-28 21:23:18 +01:00
Florian Bruhin
0bd167cf96 Update authors 2017-02-28 21:23:10 +01:00
Florian Bruhin
61e7d5883f Merge branch 'ZZ-and-ZQ' of https://github.com/wasamasa/qutebrowser into wasamasa-ZZ-and-ZQ 2017-02-28 21:22:55 +01:00
Imran Sobir
cb6c6b814e Fix pylint errors. 2017-02-28 20:11:51 +05:00
Imran Sobir
9e6b0240f6 Put javascript in module, fix lint errors 2017-02-28 19:23:31 +05:00
Imran Sobir
3e45f739fc Show message when Javascript is turned off. 2017-02-28 19:22:10 +05:00
Imran Sobir
e8db008671 Move qute:history javascript to own file. 2017-02-27 22:44:13 +05:00
Imran Sobir
3b3846c9dc Add qute:javascript to serve JS files. 2017-02-27 22:37:24 +05:00
Imran Sobir
783769d302 Load new history items from next item's time. 2017-02-27 21:44:23 +05:00
Imran Sobir
c4416c8ac0 Prevent crash with invalid start_time param. 2017-02-27 21:41:35 +05:00
Imran Sobir
c223f6c69d Style/misc fixes. 2017-02-27 21:39:51 +05:00
Imran Sobir
76bf8c0049 Convert history to list before converting to JSON. 2017-02-26 19:58:14 +05:00
Imran Sobir
845f21b275 New qute:history page. 2017-02-26 17:07:30 +05:00
Vasilij Schneidermann
ce433bd139 Add ZZ and ZQ keys to (save and) quit the session 2017-02-25 23:10:18 +01:00
Daniel Karbach
38ca583084 new default keybinds 2016-11-28 10:57:16 +01:00
thuck
a254097558 Using log instead of prompt functions for test 2016-11-24 00:05:17 +01:00
thuck
8d4b55bb80 Fix comments and change self.pinned to self.pinned_count 2016-11-23 22:18:55 +01:00
thuck
e9c79e9be3 Fix for comments on configdata 2016-11-23 08:18:10 +01:00
thuck
05d3631750 Test for accidental url opened in a pinned tab 2016-11-23 08:10:13 +01:00
thuck
9dff4299e8 flake8 fixes 2016-11-23 08:10:13 +01:00
thuck
be980a7268 Including tests for pinned tab prompt
Duplicate function for "I wait for a prompt"
2016-11-23 08:10:13 +01:00
thuck
9547938f79 Fix initial tests 2016-11-23 08:10:13 +01:00
thuck
92e1181680 Included --force option for tab-close
This makes possible to close pinned tabs without
any confirmation.
2016-11-23 08:10:13 +01:00
thuck
b920de764f Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2016-11-23 08:10:11 +01:00
thuck
982e4f46e0 Test for accidental url opened in a pinned tab 2016-11-22 07:24:02 +01:00
thuck
175744761b flake8 fixes 2016-11-22 06:57:00 +01:00
thuck
69c82f8563 Including tests for pinned tab prompt
Duplicate function for "I wait for a prompt"
2016-11-21 20:56:34 +01:00
thuck
41adafdec4 Fix initial tests 2016-11-21 20:56:34 +01:00
thuck
e514b0d58e Included --force option for tab-close
This makes possible to close pinned tabs without
any confirmation.
2016-11-21 20:56:34 +01:00
thuck
bcb0010fcb Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2016-11-21 20:56:31 +01:00
thuck
e2a6f97c07 Initial tests 2016-11-16 07:48:12 +01:00
thuck
abe3c19646 Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2016-11-14 19:01:49 +01:00
thuck
6053078637 Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2016-11-13 14:16:05 +01:00
thuck
84c41c964b First test for tab-pin 2016-11-13 09:40:07 +01:00
thuck
a8ccfe050d Remove unecessary empty line 2016-11-13 08:56:43 +01:00
thuck
785c03c15c Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2016-11-13 08:56:19 +01:00
thuck
9eb0a85bae Some fixes for pyflake, pylint and remove useless function 2016-11-11 17:10:46 +01:00
thuck
25b69fe76a Configuration for the size of a pinned tab 2016-11-11 13:57:01 +01:00
thuck
19cc721eb1 Changed behavior on location of tab being pinned
Now when a tab is pinned it goes to the end of all pinned tabs.
Before it went to the index 1.
2016-11-11 12:05:04 +01:00
thuck
00f2b4df96 Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2016-11-11 11:07:30 +01:00
thuck
23628cdfbf Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2016-11-10 20:20:52 +01:00
thuck
9f70fa3ec8 Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2016-11-10 00:28:31 +01:00
thuck
9beb097c53 Corrected some unecessary spaces 2016-11-09 23:52:56 +01:00
thuck
d7f5f61f03 Implemented counter for total number of tabs
With this counter we can better control the space on the tabbar.
2016-11-09 23:50:41 +01:00
thuck
6f8aaccc2b Attach pin information to tabwidget
Simple access to pin information on tab widget.
Some change for the fmt_pin to not use fields as cheap trick
2016-11-08 21:12:20 +01:00
thuck
d8b5ca295e Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2016-11-08 19:53:46 +01:00
thuck
17b7b5c663 Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2016-11-08 08:13:15 +01:00
thuck
931b008f89 Update title when title-format-pinned is modified 2016-11-08 08:12:40 +01:00
thuck
4f0034911a title-format-pinned initial work
Created configuration configdata.
Load and use template defined on configdata.

TODO: ability to conserve information between restart
TODO: ability to update title on configuration change
2016-11-08 07:56:13 +01:00
thuck
b24ac0ae78 More small fixes
Removed unsed variables.
Removed some empty lines.
Inncluded docstring.
2016-11-08 04:45:07 +01:00
thuck
f9b1d998d4 Last configuration as pin changed to pinned 2016-11-07 22:32:42 +01:00
thuck
f10284b04a Initial work on message.confirm_async
Creation of _tab_close and usage of partial.
2016-11-07 22:28:05 +01:00
thuck
49b2a19925 Merge branch 'master' of https://github.com/The-Compiler/qutebrowser into pintab 2016-11-07 21:25:36 +01:00
thuck
ec50d39578 Some fixes for the pylint 2016-11-07 21:25:05 +01:00
thuck
4ed046d5e7 Everything is pinned instead of pin, and one if corrected 2016-11-07 21:12:34 +01:00
thuck
20eae4d671 Modifed exception structure 2016-11-07 08:11:47 +01:00
thuck
f8dffb4e5c Some modifications from initial feedback
Moved pin information from BrowserTab to TabData.
Changed attribute from pin to pinned.
Changed "ifs" to implicit check boolen value.
Removed blancked line on before else statement.
2016-11-07 08:02:25 +01:00
thuck
29d1c0d68b Small fix for situations where we cannot find the tab for the index
Need to investigate better why and when this is excatly happening
2016-11-06 23:27:06 +01:00
thuck
d7a1a542b6 Change shortcut to tab-pin 2016-11-06 23:25:36 +01:00
thuck
d592651c50 Change command from pin/unpin to tab-pin 2016-11-06 23:24:24 +01:00
thuck
6d7a6db130 Proper title and size for pinned tab
As I'm using self.count() without taking in consideration the number of
pinned tabs the end result is a lot of empty space.
2016-11-06 19:04:32 +01:00
thuck
22133beb72 Fix small bug because result was not declared 2016-11-06 18:24:33 +01:00
thuck
6f610e9c44 Initial development to support pin tabs #926
Done so far:
Two new commands pin/unpin, both accept a index to help the organization
(maybe this should be more a flag and not exactly two commands)
Crtl+p to pin, Crtl+O to unpin (not sure which should a good default
shortcut)
If user tries to close a pinned tab it's asked to confirm
If user tries to open a URL in a pinned tab it receives a message with a
information that the tab is pinned and ignore the openurl command
Preserve the pinned information across restart if session is activated

Missing:
Visual indication of the tab being pinned
Tab appearance being distinct over other tabs
Make pinned tabs to be the firsts on the tab bar

This is not ready, but it would be good to get some feedback earlier
2016-11-06 15:52:23 +01:00
426 changed files with 7053 additions and 4517 deletions

View File

@@ -5,13 +5,15 @@ cache:
build: off
environment:
PYTHONUNBUFFERED: 1
PYTHON: C:\Python36\python.exe
matrix:
- TESTENV: py34
- TESTENV: unittests-frozen
- TESTENV: py36-pyqt58
- TESTENV: pylint
install:
- C:\Python27\python -u scripts\dev\ci\appveyor_install.py
- '%PYTHON% -m pip install -U pip'
- '%PYTHON% -m pip install -r misc\requirements\requirements-tox.txt'
- 'set PATH=%PATH%;C:\Python36'
test_script:
- C:\Python34\Scripts\tox -e %TESTENV%
- '%PYTHON% -m tox -e %TESTENV%'

View File

@@ -35,9 +35,9 @@ max-complexity = 12
putty-auto-ignore = True
putty-ignore =
/# pylint: disable=invalid-name/ : +N801,N806
/# pylint: disable=wildcard-import/ : +F403
/# pragma: no mccabe/ : +C901
tests/*/test_*.py : +D100,D101,D401
tests/conftest.py : +F403
tests/unit/browser/webkit/test_history.py : +N806
tests/helpers/fixtures.py : +N806
tests/unit/browser/webkit/http/test_content_disposition.py : +D400

View File

@@ -1,2 +1,2 @@
<!-- If this is a bug report, please remember to mention your version info from
the `qute:version` page or `qutebrowser --version` -->
`:open qute:version` or `qutebrowser --version` -->

View File

@@ -30,15 +30,12 @@ disable=no-self-use,
broad-except,
bare-except,
eval-used,
exec-used,
file-ignored,
wrong-import-order,
ungrouped-imports,
redefined-variable-type,
suppressed-message,
too-many-return-statements,
duplicate-code,
wrong-import-position
wrong-import-position,
no-else-return
[BASIC]
function-rgx=[a-z_][a-z0-9_]{2,50}$
@@ -52,12 +49,9 @@ no-docstring-rgx=(^_|^main$)
[FORMAT]
max-line-length=79
ignore-long-lines=(<?https?://|^# Copyright 201\d|# (pylint|flake8): disable=)
ignore-long-lines=(<?https?://|^# Copyright 201\d)
expected-line-ending-format=LF
[SIMILARITIES]
min-similarity-lines=8
[VARIABLES]
dummy-variables-rgx=_.*
@@ -68,12 +62,10 @@ max-args=10
valid-metaclass-classmethod-first-arg=cls
[TYPECHECK]
# WORKAROUND for https://github.com/PyCQA/astroid/pull/357
ignored-modules=pytest
# MsgType added as WORKAROUND for
# https://bitbucket.org/logilab/pylint/issues/690/
# UnsetObject because pylint infers any objreg.get(...) as UnsetObject.
ignored-classes=qutebrowser.utils.objreg.UnsetObject,
qutebrowser.browser.webkit.webelem.WebElementWrapper,
scripts.dev.check_coverage.MsgType,
qutebrowser.browser.downloads.UnsupportedAttribute
ignored-modules=PyQt5,PyQt5.QtWebKit
[IMPORTS]
# WORKAROUND
# For some reason, pylint doesn't know about some Python 3 modules on
# AppVeyor...
known-standard-library=faulthandler,http,enum,tokenize,posixpath,importlib,types

1
.pyup.yml Normal file
View File

@@ -0,0 +1 @@
schedule: "every week"

View File

@@ -1,6 +1,7 @@
sudo: required
dist: trusty
language: generic
group: edge
matrix:
include:
@@ -15,9 +16,6 @@ matrix:
- os: linux
env: DOCKER=archlinux-webengine QUTE_BDD_WEBENGINE=true
services: docker
- os: linux
env: DOCKER=archlinux-ng
services: docker
- os: linux
env: DOCKER=ubuntu-xenial
services: docker
@@ -25,14 +23,18 @@ matrix:
language: python
python: 3.6
env: TESTENV=py36-pyqt571
- os: linux
language: python
python: 3.6
env: TESTENV=py36-pyqt58
- os: linux
language: python
python: 3.5
env: TESTENV=py35-pyqt58
env: TESTENV=py35-pyqt59
- os: linux
language: python
python: 3.6
env: TESTENV=py36-pyqt58
env: TESTENV=py36-pyqt59
- os: osx
env: TESTENV=py36 OSX=elcapitan
osx_image: xcode7.3
@@ -41,7 +43,9 @@ matrix:
# env: TESTENV=py35 OSX=yosemite
# osx_image: xcode6.4
- os: linux
env: TESTENV=pylint
env: TESTENV=pylint PYTHON=python3.6
language: python
python: 3.6
- os: linux
env: TESTENV=flake8
- os: linux
@@ -73,6 +77,7 @@ before_install:
install:
- bash scripts/dev/ci/travis_install.sh
- ulimit -c unlimited
script:
- bash scripts/dev/ci/travis_run.sh
@@ -80,6 +85,9 @@ script:
after_success:
- '[[ $TESTENV == *-cov ]] && codecov -e TESTENV -X gcov'
after_failure:
- bash scripts/dev/ci/travis_backtrace.sh
notifications:
webhooks:
- https://buildtimetrend.herokuapp.com/travis

View File

@@ -14,6 +14,167 @@ This project adheres to http://semver.org/[Semantic Versioning].
// `Fixed` for any bug fixes.
// `Security` to invite users to upgrade in case of vulnerabilities.
v0.11.1
-------
Fixes
~~~~~
- Fixed empty space being shown after tabs in the tabbar in some cases.
- Fixed `:restart` in private browsing mode.
- Fixed printing on macOS.
- Closing a pinned tab via mouse now also prompts for confirmation.
- The "try again" button on error pages works correctly again.
- :spawn -u -d is now disallowed.
- :spawn -d shows error messages correctly now.
v0.11.0
-------
New dependencies
~~~~~~~~~~~~~~~~
- New dependency on `PyQt5.QtOpenGL` if QtWebEngine is used. QtWebEngine depends
on QtOpenGL already, but on distributions packaging split PyQt5 wrappers, the
wrappers for QtOpenGL are now required.
- New dependency on `PyOpenGL` if QtWebEngine is used.
Added
~~~~~
- Private browsing is now implemented for QtWebEngine, *and changed its
behavior*: The `general -> private-browsing` setting now only applies to newly
opened windows, and you can use the `-p` flag to `:open` to open a private
window.
- New "pinned tabs" feature, with a new `:tab-pin` command (bound
to `<Ctrl-p>` by default).
- (QtWebEngine) Implemented `:follow-selected`.
- New `:clear-messages` command to clear shown messages.
- New `ui -> keyhint-delay` setting to configure the delay until
the keyhint overlay pops up.
- New `-s` option for `:open` to force a HTTPS scheme.
- `:debug-log-filter` now accepts `none` as an argument to clear any log
filters.
- New `--debug-flag` argument which replaces `--debug-exit` and
`--pdb-postmortem`.
- New `tabs -> favicon-scale` option to scale up/down favicons.
- `colors -> statusbar.bg/fg.private` and `.command.private` to
customize statusbar colors for private windows.
- New `{private}` field displaying `[Private Mode]` for
`ui -> window-title-format` and `tabs -> title-format`.
- (QtWebEngine) Proxy support with Qt 5.7.1 (already was supported for 5.8 and
newer)
Changed
~~~~~~~
- To prevent elaborate phishing attacks, the Punycode version (`xn--*`) is now
shown in addition to the decoded version for international domain names
(IDN).
- Starting with legacy QtWebKit now shows a warning message.
*With the next release, support for it will be removed.*
- The Windows releases are redone from scratch, which means:
- They now use the new QtWebEngine backend
- The bundled Qt is updated from 5.5 to 5.9
- The bundled Python is updated from 3.4 to 3.6
- They are now generated with PyInstaller instead of cx_Freeze
- The installer is now generated using NSIS instead of being a MSI
- Improved `qute://history` page (with lazy loading)
- Crash reports are not public anymore.
- Paths like `C:` are now treated as absolute paths on Windows for downloads,
and invalid paths are handled properly.
- Comments in the config file are now placed before the individual options
instead of being before sections.
- Messages are now hidden when clicked.
- stdin is now closed immediately for processes spawned from qutebrowser.
- When `ui -> message-timeout` is set to 0, messages are now never cleared.
- Middle/right-clicking the blank parts of the tab bar (when vertical) now
closes the current tab.
- The adblocker now also blocks non-GET requests (e.g. POST).
- `javascript:` links can now be hinted.
- `:view-source`, `:tab-clone` and `:navigate --tab` now don't open the tab as
"explicit" anymore, i.e. (with the default settings) open it next to the
active tab.
- `qute:*` pages now use `qute://*` instead (e.g. `qute://version` instead of
`qute:version`), but the old versions are automatically redirected.
- Texts in prompts are now selectable.
- The default level for `:messages` is now `info`, not `error`
- Trying to focus the currently focused tab with `:tab-focus` now focuses the
last viewed tab.
- (QtWebEngine) With Qt 5.9, `content -> cookies-store` can now be set without
a restart.
- (QtWebEngine) With Qt 5.9, better error messages are now shown for failed
downloads.
- (QtWebEngine) The underlying Chromium version is now shown in the version
info.
- (QtWebKit) Renderer process crashes now show an error page on Qt 5.9 or newer.
- (QtWebKit) storage -> offline-web-application-storage` got renamed to `...-cache`
- (QtWebKit) PAC now supports SOCKS5 as type.
Fixed
~~~~~
- The macOS .dmg is now built against Qt 5.9 which fixes various
important issues (such as not being able to type dead keys).
- Fixed crash with `:download` on PyQt 5.9.
- Cloning a page without history doesn't crash anymore.
- When a download results in a HTTP error, it now shows the error correctly
instead of crashing.
- Pressing ctrl-c while a config error is shown works as intended now.
- When the key config isn't writable, we now show an error instead of crashing.
- Fixed crash when unbinding an unbound key in the key config.
- Fixed crash when using `:debug-log-filter` when `--filter` wasn't given on startup.
- Fixed crash with some invalid setting values.
- Continuing a search after clearing it now works correctly.
- The tabbar and completion should now be more consistently and correctly
styled with various system styles.
- Applying styiles in `qt5ct` now shouldn't crash anymore.
- The validation for colors in stylesheets is now less strict,
allowing for all valid Qt values.
- `data:` URLs now aren't added to the history anymore.
- Accidentally starting with Python 2 now shows a proper error message again.
- For some people, running some userscripts crashed - this should now be 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.
- (QtWebEngine) Added a workaround for a black screen with some setups
- (QtWebEngine) Starting with Nouveau graphics now shows an error message
instead of crashing in Qt.
- (QtWebEngine) Retrying downloads now shows an error instead of crashing.
- (QtWebEngine) Cloning a view-source tab now doesn't crash anymore.
- (QtWebEngine) `window.navigator.userAgent` is now set correctly when
customizing the user agent.
- (QtWebEngine) HTML fullscreen is now tracked for each tab separately, which
means it's not possible anymore to accidentally get stuck in fullscreen state
by closing a tab with a fullscreen video.
- (QtWebEngine) `:scroll-page` with `--bottom-navigate` now works correctly.
- (QtWebKit) The HTTP cache is disabled on Qt 5.7.1 and 5.8 now as it leads to
frequent crashes due to a Qt bug.
- (QtWebKit) Fixed Crash when a PAC file returns an invalid value.
v0.10.1
-------
Changed
~~~~~~~
- `--qt-arg` and `--qt-flag` can now also be used to pass arguments to Chromium when using QtWebEngine.
Fixed
~~~~~
- URLs are now redacted properly (username/password, and path/query for HTTPS) when using Proxy Autoconfig with QtWebKit
- Crash when updating adblock lists with invalid UTF8-chars in them
- Fixed the web inspector with QtWebEngine
- Version checks when starting qutebrowser now also take the Qt version PyQt was compiled against into account
- Hinting a input now doesn't select existing text anymore with QtWebKit
- The cursor now moves to the end when input elements are selected with QtWebEngine
- Download suffixes like (1) are now correctly stripped with QtWebEngine
- Crash when trying to print a tab which was closed in the meantime
- Crash when trying to open a file twice on Windows
v0.10.0
-------
@@ -36,7 +197,7 @@ Added
- Open tabs are now auto-saved on each successful load and restored in case of a crash
- `:jseval` now has a `--file` flag so you can pass a javascript file
- `:session-save` now has a `--only-active-window` flag to only save the active window
- OS X builds are back, and built with QtWebEngine
- macOS builds are back, and built with QtWebEngine
Changed
~~~~~~~
@@ -52,6 +213,18 @@ Changed
- `network -> proxy` can also be set to `pac+file://...` now to
use a local proxy autoconfig file (on QtWebKit)
Removed
~~~~~~~
- (QtWebKit) Various rarely customized settings were removed:
- `ui -> css-media-type` (defaults to desktop)
- `general -> site-specific-quirks` (now always turned on)
- `storage -> offline-storage-default-quota` (defaults to 5MB)
- `storage -> offline-web-application-cache-quota` (defaults to no quota)
- `storage -> object-cache-capacities` (default depends on disk space)
- `content -> css-regions` (now always turned off)
- `storage -> offline-storage-database` (merged into `storage -> local-storage`)
Fixed
~~~~~
@@ -326,7 +499,7 @@ Fixed
- Fix crash when pressing enter without a command
- Adjust error message to point out QtWebEngine is unsupported with the OS
X .app currently.
- Hide Harfbuzz warning with the OS X .app
- Hide Harfbuzz warning with the macOS .app
v0.8.0
------
@@ -689,7 +862,7 @@ Fixed
- Fixed scrolling to the very left/right with `:scroll-perc`.
- Using an external editor should now work correctly with some funny chars
(U+2028/U+2029/BOM).
- Movements in caret mode now should work correctly on OS X and Windows.
- Movements in caret mode now should work correctly on macOS and Windows.
- Fixed upgrade from earlier config versions.
- Fixed crash when killing a running userscript.
- Fixed characters being passed through when shifted with
@@ -764,7 +937,7 @@ Changed
- The completion widget doesn't show a border anymore.
- The tabbar doesn't display ugly arrows anymore if there isn't enough space
for all tabs.
- Some insignificant Qt warnings which were printed on OS X are now hidden.
- Some insignificant Qt warnings which were printed on macOS are now hidden.
- Better support for Qt 5.5 and Python 3.5.
Fixed
@@ -875,7 +1048,7 @@ Fixed
- Fixed AssertionError when closing many windows quickly.
- Various fixes for deprecated key bindings and auto-migrations.
- Workaround for qutebrowser not starting when there are NUL-bytes in the history (because of a currently unknown bug).
- Fixed handling of keybindings containing Ctrl/Meta on OS X.
- Fixed handling of keybindings containing Ctrl/Meta on macOS.
- Fixed crash when downloading a URL without filename (e.g. magnet links) via "Save as...".
- Fixed exception when starting qutebrowser with `:set` as argument.
- Fixed horrible completion performance when the `shrink` option was set.
@@ -973,7 +1146,7 @@ Changed
- Add a `:search` command in addition to `/foo` so it's more visible and can be used from scripts.
- Various improvements to documentation, logging, and the crash reporter.
- Expand `~` to the users home directory with `:run-userscript`.
- Improve the userscript runner on Linux/OS X by using `QSocketNotifier`.
- Improve the userscript runner on Linux/macOS by using `QSocketNotifier`.
- Add luakit-like `gt`/`gT` keybindings to cycle through tabs.
- Show default value for config values in the completion.
- Clone tab icon, tab text and zoom level when cloning tabs.
@@ -993,7 +1166,7 @@ Changed
* `init_venv.py` and `run_checks.py` have been replaced by http://tox.readthedocs.org/[tox]. Install tox and run `tox -e mkvenv` instead.
* The tests now use http://pytest.org/[pytest]
* Many new tests added
* Mac Mini buildbot to run the tests on OS X.
* Mac Mini buildbot to run the tests on macOS.
* Coverage recording via http://nedbatchelder.com/code/coverage/[coverage.py].
* New `--pdb-postmortem argument` to drop into the pdb debugger on exceptions.
* Use https://github.com/ionelmc/python-hunter[hunter] for line tracing instead of a selfmade solution.
@@ -1129,7 +1302,7 @@ Fixed
* Fix rare exception when a key is pressed shortly after opening a window
* Fix exception with certain invalid URLs like `http:foo:0`
* Work around Qt bug which renders checkboxes on OS X unusable
* Work around Qt bug which renders checkboxes on macOS unusable
* Fix exception when a local files can't be read in `:adblock-update`
* Hide 2 more Qt warnings.
* Add `!important` to hint CSS so websites don't override the hint look
@@ -1165,7 +1338,7 @@ Changes
* Set zoom to default instead of 100% with `:zoom`/`=`.
* Adjust page zoom if default zoom changed.
* Force tabs to be focused on `:undo`.
* Replace manual installation instructions on OS X with homebrew/macports.
* Replace manual installation instructions on macOS with homebrew/macports.
* Allow min-/maximizing of print preview on Windows.
* Various documentation improvements.
* Various other small improvements and cleanups.

View File

@@ -42,6 +42,12 @@ be easy to solve]
* https://github.com/qutebrowser/qutebrowser/labels/not%20code[Issues which
require little/no coding]
If you prefer C++ or Javascript to Python, see the relevant issues which involve
work in those languages:
* https://github.com/qutebrowser/qutebrowser/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3Ac%2B%2B[C++] (mostly work on Qt, the library behind qutebrowser)
* https://github.com/qutebrowser/qutebrowser/issues?q=is%3Aopen+is%3Aissue+label%3Ajavascript[JavaScript]
There are also some things to do if you don't want to write code:
* Help the community, e.g., on the mailinglist and the IRC channel.
@@ -214,7 +220,7 @@ Documentation of used Python libraries:
* http://pygments.org/docs/[pygments]
* http://fdik.org/pyPEG/index.html[pyPEG2]
* http://pythonhosted.org/setuptools/[setuptools]
* http://cx-freeze.readthedocs.org/en/latest/overview.html[cx_Freeze]
* http://www.pyinstaller.org/[PyInstaller]
* https://pypi.python.org/pypi/colorama[colorama]
Related RFCs and standards:
@@ -546,6 +552,28 @@ Rebuilding the website
If you want to rebuild the website, run `./scripts/asciidoc2html.py --website <outputdir>`.
Chrome URLs
~~~~~~~~~~~
With the QtWebEngine backend, qutebrowser supports several chrome:// urls which
can be useful for debugging:
- chrome://appcache-internals/
- chrome://blob-internals/
- chrome://gpu/
- chrome://histograms/
- chrome://indexeddb-internals/
- chrome://media-internals/
- chrome://network-errors/
- chrome://serviceworker-internals/
- chrome://webrtc-internals/
- chrome://crash/ (crashes the current renderer process!)
- chrome://kill/ (kills the current renderer process!)
- chrome://gpucrash/ (crashes qutebrowser!)
- chrome://gpuhang/ (hangs qutebrowser!)
- chrome://gpuclean/ (crashes the current renderer process!)
- chrome://ppapiflashcrash/
- chrome://ppapiflashhang/
Style conventions
-----------------
@@ -654,8 +682,9 @@ qutebrowser release
* Add newest config to `tests/unit/config/old_configs` and update `test_upgrade_version`
- `python -m qutebrowser --basedir conf :quit`
- `sed '/^#/d' conf/config/qutebrowser.conf > tests/unit/config/old_configs/qutebrowser-v0.x.y.conf`
- `sed '/^#/d' conf/config/qutebrowser.conf > tests/unit/config/old_configs/qutebrowser-v0.$x.$y.conf`
- `rm -r conf`
- git add
- commit
* Adjust `__version_info__` in `qutebrowser/__init__.py`.
* Update changelog (remove *(unreleased)*)
@@ -670,7 +699,7 @@ qutebrowser release
as closed.
* Linux: Run `python3 scripts/dev/build_release.py --upload v0.$x.$y`
* Windows: Run `C:\Python34_x32\python scripts\dev\build_release.py --asciidoc C:\Python27\python C:\asciidoc-8.6.9\asciidoc.py --upload v0.X.Y` (replace X/Y by hand)
* Windows: Run `C:\Python36-32\python scripts\dev\build_release.py --asciidoc C:\Python27\python C:\asciidoc-8.6.9\asciidoc.py --upload v0.X.Y` (replace X/Y by hand)
* OS X: Run `python3 scripts/dev/build_release.py --upload v0.X.Y` (replace X/Y by hand)
* On server: Run `python3 scripts/dev/download_release.py v0.X.Y` (replace X/Y by hand)
* Update `qutebrowser-git` PKGBUILD if dependencies/install changed

View File

@@ -72,8 +72,8 @@ Is there an adblocker?::
http://www.reddit.com/r/programming/comments/25j41u/adblock_pluss_effect_on_firefoxs_memory_usage/chhpomw[big
impact] on browsing speed and
https://blog.mozilla.org/nnethercote/2014/05/14/adblock-pluss-effect-on-firefoxs-memory-usage/[RAM
usage], so implementing it properly might take some time and won't be done
for v0.1 if at all.
usage], so implementing support for AdBlockPlus-like lists is currently not
a priority.
How do I play Youtube videos with mpv?::
You can easily add a key binding to play youtube videos inside a real video
@@ -124,6 +124,53 @@ When using quickmark, you can give them all names, like
`:open foodrecipes`, you will see a list of all the food recipe sites,
without having to remember the exact website title or address.
How do I use spell checking?::
Qutebrowser's support for spell checking is somewhat limited at the moment
(see https://github.com/qutebrowser/qutebrowser/issues/700[#700]), but it
can be done.
+
For QtWebKit:
. Install https://github.com/QupZilla/qtwebkit-plugins[qtwebkit-plugins].
. Note: with QtWebKit reloaded you may experience some issues. See
https://github.com/QupZilla/qtwebkit-plugins/issues/10[#10].
. The dictionary to use is taken from the `DICTIONARY` environment variable.
The default is `en_US`. For example to use Dutch spell check set `DICTIONARY`
to `nl_NL`; you can't use multiple dictionaries or change them at runtime at
the moment.
(also see the README file for `qtwebkit-plugins`).
. Remember to install the hunspell dictionaries if you don't have them already
(most distros should have packages for this).
+
For QtWebEngine:
. Not yet supported unfortunately :-( +
Adding it shouldn't be too hard though, since QtWebEngine 5.8 added an API for
this (see
https://github.com/qutebrowser/qutebrowser/issues/700#issuecomment-290780706[this
comment for a basic example]), so what are you waiting for and why aren't you
hacking qutebrowser yet?
How do I use Tor with qutebrowser?::
Start tor on your machine, and do `:set network proxy socks://localhost:9050/`
in qutebrowser. Note this won't give you the same amount of fingerprinting
protection that the Tor Browser does, but it's useful to be able to access
`.onion` sites.
Why does J move to the next (right) tab, and K to the previous (left) one?::
One reason is because https://bitbucket.org/portix/dwb[dwb] did it that way,
and qutebrowser's keybindings are designed to be compatible with dwb's.
The rationale behind it is that J is "down" in vim, and K is "up", which
corresponds nicely to "next"/"previous". It also makes much more sense with
vertical tabs (e.g. `:set tabs position left`).
What's the difference between insert and passthrough mode?::
They are quite similar, but insert mode has some bindings (like `Ctrl-e` to
open an editor) while passthrough mode only has escape bound. It might also
be useful to rebind escape to something else in passthrough mode only, to be
able to send an escape keypress to the website.
== Troubleshooting
Configuration not saved after modifying config.::

View File

@@ -1,6 +1,8 @@
Installing qutebrowser
======================
toc::[]
On Debian / Ubuntu
------------------
@@ -15,6 +17,10 @@ still relatively easy!
You can use packages that are built for every release or build it yourself from git.
On Ubuntu 16.04 and 16.10 it's recommended to <<tox,install qutebrowser via tox>>
instead in order to be able to use the new QtWebEngine backend. Newer versions
have a QtWebEngine package in the repositories.
Using the packages
~~~~~~~~~~~~~~~~~~
@@ -24,6 +30,12 @@ Install the dependencies via apt-get:
# apt-get install python3-lxml python-tox python3-pyqt5 python3-pyqt5.qtwebkit python3-pyqt5.qtquick python3-sip python3-jinja2 python3-pygments python3-yaml
----
On Debian Stretch or Ubuntu 17.04 or later, it's also recommended to use the
newer QtWebEngine backend.
To do so, install `python3-pyqt5.qtwebengine` and `python3-pyqt5.qtopengl`, then
start qutebrowser with `--backend webengine`.
Get the qutebrowser package from the
https://github.com/qutebrowser/qutebrowser/releases[release page] and download
the https://qutebrowser.org/python3-pypeg2_2.15.2-1_all.deb[PyPEG2 package].
@@ -40,43 +52,14 @@ Build it from git
Install the dependencies via apt-get:
[NOTE]
==========================
On Debian, it's recommended to install the Qt packages from the
https://wiki.debian.org/DebianExperimental[experimental] repository as those
are a much newer version of Qt which is more stable.
Add the following line to your `/etc/apt/sources.list`:
----
deb http://ftp.debian.org/debian experimental main
----
Then install the packages like this:
----
# apt-get update
# apt-get install -t experimental python3-pyqt5 python3-pyqt5.qtwebkit python3-pyqt5.qtquick python3-sip python3-dev
# apt-get install python-tox
----
It's also recommended to pin those packages to receive updates by creating a
file `/etc/apt/preferences.d/qutebrowser` with the following contents:
----
Package: python3-pyqt5* libqt5*
Pin: release a=experimental
Pin-Priority: 800
----
==========================
For distributions other than Debian or if you prefer to not use the
experimental repo:
----
# apt-get install python3-pyqt5 python3-pyqt5.qtwebkit python3-pyqt5.qtquick python-tox python3-sip python3-dev
----
On Debian Stretch or Ubuntu 17.04 or later, it's also recommended to install
`python3-pyqt5.qtwebengine` and start qutebrowser with `--backend webengine` in
order to use the new backend.
To generate the documentation for the `:help` command, when using the git
repository (rather than a release):
@@ -102,6 +85,9 @@ qutebrowser is available in the official repositories for Fedora 22 and newer.
# dnf install qutebrowser
----
It's also recommended to install `qt5-qtwebengine` and start with `--backend
webengine` to use the new backend.
On Archlinux
------------
@@ -111,6 +97,10 @@ qutebrowser is available in the official [community] repository.
# pacman -S qutebrowser
----
Archlinux packages an updated `qt5-webkit` package by default. If you want to
use the QtWebEngine backend instead, install `qt5-webengine` and start with
`--backend webengine`.
There is also a -git version available in the AUR:
https://aur.archlinux.org/packages/qutebrowser-git/[qutebrowser-git].
@@ -135,16 +125,50 @@ If video or sound don't seem to work, try installing the gstreamer plugins:
On Gentoo
---------
qutebrowser is available in the main repository and can be installed with:
A version of qutebrowser is available in the main repository and can be installed with:
----
# emerge -av qutebrowser
----
However it is suggested to install the Live version (-9999) to take advantage
of the newest features introduced.
First of all you need to edit your package.accept_keywords file to accept the live
version:
----
# nano /etc/portage/package.accept_keywords
----
And add the following line to it:
=www-client/qutebrowser-9999 **
Save the file and then install qutebrowser via
----
# emerge -av qutebrowser
----
Or rebuild your system if you already installed it.
To update to the last Live version, remember to do
----
# emerge -uDNav @live-rebuild @world
----
To include qutebrowser among the updates.
Make sure you have `python3_4` in your `PYTHON_TARGETS`
(`/etc/portage/make.conf`) and rebuild your system (`emerge -uDNav @world`) if
necessary.
It's also recommended to install QtWebKit-NG via
https://gist.github.com/annulen/309569fb61e5d64a703c055c1e726f71[this ebuild],
or install Qt >= 5.7.1 with QtWebEngine in order to use an up-to-date backend.
If video or sound don't seem to work, try installing the gstreamer plugins:
----
@@ -162,6 +186,10 @@ with:
# xbps-install qutebrowser
----
It's currently recommended to install `python3-PyQt5-webengine` and
`python3-PyQt5-opengl`, then start with `--backend webengine` to use the new
backend.
On NixOS
--------
@@ -172,6 +200,9 @@ it with:
$ nix-env -i qutebrowser
----
It's recommended to install `qt5.qtwebengine` and start with
`--backend webengine` to use the new backend.
On openSUSE
-----------
@@ -192,19 +223,19 @@ On OpenBSD
qutebrowser is in http://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/www/qutebrowser/[OpenBSD ports].
Manual install:
Install the package:
----
# pkg_add qutebrowser
----
Or alternatively, use the ports system :
----
# cd /usr/ports/www/qutebrowser
# make install
----
Or alternatively if you're using `-current` (or OpenBSD 6.1 once it's been released):
----
# pkg_add qutebrowser
----
On Windows
----------
@@ -213,7 +244,7 @@ There are different ways to install qutebrowser on Windows:
Prebuilt binaries
~~~~~~~~~~~~~~~~~
Prebuilt standalone packages and MSI installers
Prebuilt standalone packages and installers
https://github.com/qutebrowser/qutebrowser/releases[are built] for every
release.
@@ -314,17 +345,23 @@ Then run tox inside the qutebrowser repository to set up a
https://docs.python.org/3/library/venv.html[virtual environment]:
----
$ tox -e mkvenv
$ tox -e mkvenv-pypi
----
On Windows, run tox with the 'mkvenv-win' option, however make sure that ONLY Python3 is in your PATH before running tox.
If your distribution uses OpenSSL 1.1 (like Debian Stretch or Archlinux), you'll
need to set `LD_LIBRARY_PATH` to the OpenSSL 1.0 directory
(`export LD_LIBRARY_PATH=/usr/lib/openssl-1.0` on Archlinux) before starting
qutebrowser.
----
$ tox -e mkvenv-win
----
Alternatively, you can use `tox -e mkvenv` (without `-pypi`) to symlink your
local Qt install instead of installing PyQt in the virtualenv. However, unless
you have QtWebKit-NG or QtWebEngine available, qutebrowser will use the legacy
QtWebKit backend.
This installs all needed Python dependencies in a `.venv` subfolder. The
system-wide Qt5/PyQt5 installations are symlinked into the virtual environment.
On Windows, run `tox -e 'mkvenv-win' instead, however make sure that ONLY
Python3 is in your PATH before running tox.
This installs all needed Python dependencies in a `.venv` subfolder.
You can then create a simple wrapper script to start qutebrowser somewhere in
your `$PATH` (e.g. `/usr/local/bin/qutebrowser` or `~/bin/qutebrowser`):
@@ -334,14 +371,6 @@ your `$PATH` (e.g. `/usr/local/bin/qutebrowser` or `~/bin/qutebrowser`):
~/path/to/qutebrowser/.venv/bin/python3 -m qutebrowser "$@"
----
If you are developing on qutebrowser, you may want to redirect it to a local
config:
----
#!/bin/bash
~/path/to/qutebrowser/.venv/bin/python3 -m qutebrowser -c .qutebrowser-local "$@"
----
Updating
~~~~~~~~
@@ -352,5 +381,5 @@ virtualenv. Thus it's recommended to run the following command to recreate the
virtualenv:
----
$ tox -r -e mkvenv
$ tox -r -e mkvenv-pypi
----

View File

@@ -30,20 +30,15 @@ prune tests
prune qutebrowser/3rdparty
prune misc/requirements
prune misc/docker
exclude .editorconfig
exclude pytest.ini
exclude qutebrowser.rcc
exclude .coveragerc
exclude .pylintrc
exclude qutebrowser/javascript/.eslintrc.yaml
exclude qutebrowser/javascript/.eslintignore
exclude doc/help
exclude .appveyor.yml
exclude .travis.yml
exclude .*
exclude codecov.yml
exclude .pydocstylerc
exclude misc/appveyor_install.py
exclude misc/qutebrowser.spec
exclude .flake8
exclude misc/qutebrowser.nsi
global-exclude __pycache__ *.pyc *.pyo

View File

@@ -71,7 +71,8 @@ https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser[mailinglist] at
mailto:qutebrowser@lists.qutebrowser.org[].
There's also a https://lists.schokokeks.org/mailman/listinfo.cgi/qutebrowser-announce[announce-only mailinglist]
at mailto:qutebrowser-announce@lists.qutebrowser.org[].
at mailto:qutebrowser-announce@lists.qutebrowser.org[] (the announcements also
get sent to the general qutebrowser@ list).
Contributions / Bugs
--------------------
@@ -97,11 +98,11 @@ Requirements
The following software and libraries are required to run qutebrowser:
* http://www.python.org/[Python] 3.4 or newer
* http://qt.io/[Qt] 5.2.0 or newer (5.5.1 recommended)
* http://www.python.org/[Python] 3.4 or newer (3.5 recommended)
* http://qt.io/[Qt] 5.2.0 or newer (5.9 recommended)
* QtWebKit (old or link:https://github.com/annulen/webkit/wiki[reloaded]/NG) or QtWebEngine
* http://www.riverbankcomputing.com/software/pyqt/intro[PyQt] 5.2.0 or newer
(5.5.1 recommended) for Python 3
(5.9 recommended) for Python 3
* https://pypi.python.org/pypi/setuptools/[pkg_resources/setuptools]
* http://fdik.org/pyPEG/[pyPEG2]
* http://jinja.pocoo.org/[jinja2]
@@ -152,44 +153,49 @@ Contributors, sorted by the number of commits in descending order:
* Lamar Pavel
* Marshall Lochbaum
* Bruno Oliveira
* thuck
* Martin Tournoij
* Imran Sobir
* Alexander Cogneau
* Felix Van der Jeugt
* Daniel Karbach
* Martin Tournoij
* Kevin Velghe
* Raphael Pierzina
* Joel Torstensson
* Patric Schmitz
* Tarcisio Fedrizzi
* Jay Kamat
* Claude
* Philipp Hansch
* Fritz Reichwald
* Corentin Julé
* meles5
* Philipp Hansch
* Imran Sobir
* Panagiotis Ktistakis
* Artur Shaik
* Nathan Isom
* Thorsten Wißmann
* Austin Anderson
* Fritz Reichwald
* Jimmy
* Niklas Haas
* Maciej Wołczyk
* Spreadyy
* Clayton Craft
* sandrosc
* Alexey "Averrin" Nabrodov
* pkill9
* nanjekyejoannah
* avk
* ZDarian
* Milan Svoboda
* John ShaggyTwoDope Jenkins
* Clayton Craft
* Peter Vilim
* Jacob Sword
* knaggita
* Oliver Caldwell
* Nikolay Amiantov
* Marius
* Julian Weigt
* Tomasz Kramkowski
* Sebastian Frysztak
* Nikolay Amiantov
* Julie Engel
* Jonas Schürmann
* error800
@@ -211,35 +217,38 @@ Contributors, sorted by the number of commits in descending order:
* Michał Góral
* Michael Ilsaas
* Martin Zimmermann
* Link
* Jussi Timperi
* Cosmin Popescu
* Brian Jackson
* thuck
* sbinix
* rsteube
* neeasade
* jnphilipp
* Yannis Rohloff
* Tobias Patzl
* Stefan Tatschner
* Samuel Loury
* Peter Michely
* Panashe M. Fundira
* Lucas Hoffmann
* Link
* Larry Hynes
* Kirill A. Shutemov
* Johannes Altmanninger
* Jeremy Kaplan
* Ismail
* Iordanis Grigoriou
* Edgar Hipp
* Daryl Finlay
* pkill9
* arza
* adam
* Samir Benmendil
* Regina Hug
* Penaz
* Matthias Lisin
* Mathias Fussenegger
* Marcelo Santos
* Marcel Schilling
* Joel Bradshaw
* Jean-Louis Fuchs
* Franz Fellner
@@ -252,26 +261,28 @@ Contributors, sorted by the number of commits in descending order:
* haxwithaxe
* evan
* dylan araps
* caveman
* addictedtoflames
* Xitian9
* Vasilij Schneidermann
* Tomas Orsava
* Tom Janson
* Tobias Werth
* Tim Harder
* Thiago Barroso Perrotta
* Steve Peak
* Sorokin Alexei
* Simon Désaulniers
* Rok Mandeljc
* Noah Huesser
* Moez Bouhlel
* Matthias Lisin
* Marcel Schilling
* MikeinRealLife
* Lazlow Carmichael
* Kevin Wang
* Ján Kobezda
* Justin Partain
* Johannes Martinsson
* Jean-Christophe Petkovich
* Jay Kamat
* Helen Sherwood-Taylor
* HalosGhost
* Gregor Pohl
@@ -279,9 +290,12 @@ Contributors, sorted by the number of commits in descending order:
* Dietrich Daroch
* Derek Sivers
* Daniel Lu
* Daniel Jakots
* Arseniy Seroka
* Anton Grensjö
* Andy Balaam
* Andreas Fischer
* Amos Bird
* Akselmo
// QUTE_AUTHORS_END

View File

@@ -1,9 +1,7 @@
status:
project:
enabled: no
patch:
enabled: no
changes:
enabled: no
coverage:
status:
project: off
patch: off
changes: off
comment: off

View File

@@ -1,13 +1,135 @@
Crowdfunding backers
====================
2017
----
Mid-2017, qutebrowser had its
https://www.kickstarter.com/projects/the-compiler/qutebrowser-v10-with-per-domain-settings[second crowdfunding]
with the goal of implementing the new config system and releasing v1.0.
Thanks a lot to the following people who contributed to it:
Gold sponsors
~~~~~~~~~~~~~
TODO
Silver sponsors
~~~~~~~~~~~~~~~
TODO
Other sponsors
~~~~~~~~~~~~~~
TODO: people with t-shirts or higher pledge levels
- 7scan
- Alex Suykov
- Alexey Zhikhartsev
- Allan Nordhøy
- Anirudh Sanjeev
- Anssi Puustinen
- Benedikt Steindorf
- Bernardo Kuri
- Blaise Duszynski
- Bostan
- Bruno Oliveira
- Colin Jacobs
- Daniel Andersson
- Danilo
- David Beley
- David Hollings
- David Parrish
- Derin Yarsuvat
- Dmytro Kostiuchenko
- Frederik Thorøe
- G4v4g4i
- Gyula Teleki
- H
- Hosaka
- Iordanis Grigoriou
- Isaac Sandaljian
- Jakub Podeszwik
- Jamie Anderson
- Jasper Woudenberg
- Jens Højgaard
- Johannes
- John Baber-Lucero
- Jonas Schürmann
- Kenichiro Ito
- Kenny Low
- Lars Ivar Igesund
- Lucas Aride Moulin
- Ludovic Chabant
- Lukas Gierth
- Marulkan
- Matthew Chun-Lum
- Matthew Cronen
- Matthew Quigley
- Michael Schönwälder
- Mika Kutila
- Mitchell Stokes
- Nathan Howell
- Nathan Schlehlein
- Noël Zindel
- Obri
- Patrik Peng
- Peter DiMarco
- Peter Rice
- Philipp Middendorf
- Pkill9
- Prescott
- Robotichead
- Roshless
- Ryan Ellis
- Ryan P Deslandes
- Sam Doshi
- Sam Stone
- Sean Herman
- Sebastian Frysztak
- Shelby Cruver
- SirCmpwn
- Soham Pal
- Stewart Webb
- Sven Reinecke
- Tom Bass
- Tomas Slusny
- Tomasz Kramkowski
- Tommy Thomas
- Vasilij Schneidermann
- Vlaaaaaaad
- beanieuptop
- demure
- evenorbert
- fishss
- gsnewmark
- guillermohs9
- hubcaps
- lobachevsky
- neodarz
- nihlaeth
- notbenh
- patrick suwanvithaya
- pyratebeard
- randm_dave
- sabreman
- toml
- vimja
- wiz
- 43 Anonymous
2016
----
Mid-2016, qutebrowser did run a http://igg.me/at/qutebrowser[crowdfunding] for
QtWebEngine support in qutebrowser.
Thanks a lot to the following people who contributed to it:
Gold sponsors
-------------
~~~~~~~~~~~~~
- Chris Salzberg
- Clayton Craft
@@ -16,7 +138,7 @@ Gold sponsors
- 1 Anonymous
Day sponsors
------------
~~~~~~~~~~~~
- Agent 42
- Iggy Jackson
@@ -28,7 +150,7 @@ Day sponsors
- 4 Anonymous
Other sponsors
--------------
~~~~~~~~~~~~~~
- AP M
- Alessandro Balzano

View File

@@ -82,9 +82,10 @@ It is possible to run or bind multiple commands by separating them with `;;`.
|<<tab-move,tab-move>>|Move the current tab according to the argument and [count].
|<<tab-next,tab-next>>|Switch to the next tab, or switch [count] tabs forward.
|<<tab-only,tab-only>>|Close all tabs except for the current one.
|<<tab-pin,tab-pin>>|Pin/Unpin the current/[count]th tab.
|<<tab-prev,tab-prev>>|Switch to the previous tab, or switch [count] tabs back.
|<<unbind,unbind>>|Unbind a keychain.
|<<undo,undo>>|Re-open a closed tab (optionally skipping [count] closed tabs).
|<<undo,undo>>|Re-open a closed tab.
|<<view-source,view-source>>|Show the source of the current page in a new tab.
|<<window-only,window-only>>|Close all windows except for the current one.
|<<wq,wq>>|Save open pages and quit.
@@ -544,7 +545,8 @@ For `increment` and `decrement`, the number to change the URL by. For `up`, the
[[open]]
=== open
Syntax: +:open [*--implicit*] [*--bg*] [*--tab*] [*--window*] ['url']+
Syntax: +:open [*--implicit*] [*--bg*] [*--tab*] [*--window*] [*--secure*] [*--private*]
['url']+
Open a URL in the current/[count]th tab.
@@ -559,6 +561,8 @@ If the URL contains newlines, each line gets opened in its own tab.
* +*-b*+, +*--bg*+: Open in a new background tab.
* +*-t*+, +*--tab*+: Open in a new tab.
* +*-w*+, +*--window*+: Open in a new window.
* +*-s*+, +*--secure*+: Force HTTPS.
* +*-p*+, +*--private*+: Open a new window in private browsing mode.
==== count
The tab index to open the URL in.
@@ -742,6 +746,7 @@ Load a session.
[[session-save]]
=== session-save
Syntax: +:session-save [*--current*] [*--quiet*] [*--force*] [*--only-active-window*]
[*--with-private*]
['name']+
Save a session.
@@ -755,6 +760,7 @@ Save a session.
* +*-q*+, +*--quiet*+: Don't show confirmation message.
* +*-f*+, +*--force*+: Force saving internal sessions (starting with an underline).
* +*-o*+, +*--only-active-window*+: Saves only tabs of the currently active window.
* +*-p*+, +*--with-private*+: Include private windows.
[[set]]
=== set
@@ -830,7 +836,7 @@ Duplicate the current tab.
[[tab-close]]
=== tab-close
Syntax: +:tab-close [*--prev*] [*--next*] [*--opposite*]+
Syntax: +:tab-close [*--prev*] [*--next*] [*--opposite*] [*--force*]+
Close the current/[count]th tab.
@@ -839,6 +845,7 @@ Close the current/[count]th tab.
* +*-n*+, +*--next*+: Force selecting the tab after the current tab.
* +*-o*+, +*--opposite*+: Force selecting the tab in the opposite direction of what's configured in 'tabs->select-on-remove'.
* +*-f*+, +*--force*+: Avoid confirmation for pinned tabs.
==== count
The tab index to close
@@ -891,13 +898,23 @@ How many tabs to switch forward.
[[tab-only]]
=== tab-only
Syntax: +:tab-only [*--prev*] [*--next*]+
Syntax: +:tab-only [*--prev*] [*--next*] [*--force*]+
Close all tabs except for the current one.
==== optional arguments
* +*-p*+, +*--prev*+: Keep tabs before the current.
* +*-n*+, +*--next*+: Keep tabs after the current.
* +*-f*+, +*--force*+: Avoid confirmation for pinned tabs.
[[tab-pin]]
=== tab-pin
Pin/Unpin the current/[count]th tab.
Pinning a tab shrinks it to tabs->pinned-width size. Attempting to close a pinned tab will cause a confirmation, unless --force is passed.
==== count
The tab index to pin or unpin
[[tab-prev]]
=== tab-prev
@@ -919,7 +936,7 @@ Unbind a keychain.
[[undo]]
=== undo
Re-open a closed tab (optionally skipping [count] closed tabs).
Re-open a closed tab.
[[view-source]]
=== view-source
@@ -995,6 +1012,7 @@ How many steps to zoom out.
|==============
|Command|Description
|<<clear-keychain,clear-keychain>>|Clear the currently entered key chain.
|<<clear-messages,clear-messages>>|Clear all message notifications.
|<<click-element,click-element>>|Click the element matching the given filter.
|<<command-accept,command-accept>>|Execute the command currently in the commandline.
|<<command-history-next,command-history-next>>|Go forward in the commandline history.
@@ -1059,6 +1077,10 @@ How many steps to zoom out.
=== clear-keychain
Clear the currently entered key chain.
[[clear-messages]]
=== clear-messages
Clear all message notifications.
[[click-element]]
=== click-element
Syntax: +:click-element [*--target* 'target'] [*--force-event*] 'filter' 'value'+
@@ -1433,6 +1455,8 @@ Syntax: +:scroll 'direction'+
Scroll the current tab in the given direction.
Note you can use `:run-with-count` to have a keybinding with a bigger scroll increment.
==== positional arguments
* +'direction'+: In which direction to scroll (up/down/left/right/top/bottom).
@@ -1591,7 +1615,8 @@ Syntax: +:debug-log-filter 'filters'+
Change the log filter for console logging.
==== positional arguments
* +'filters'+: A comma separated list of logger names.
* +'filters'+: A comma separated list of logger names. Can also be "none" to clear any existing filters.
[[debug-log-level]]
=== debug-log-level
@@ -1646,7 +1671,7 @@ Syntax: +:debug-webaction 'action'+
Execute a webaction.
See http://doc.qt.io/qt-5/qwebpage.html#WebAction-enum for the available actions.
Available actions: http://doc.qt.io/archives/qt-5.5/qwebpage.html#WebAction-enum (WebKit) http://doc.qt.io/qt-5/qwebenginepage.html#WebAction-enum (WebEngine)
==== positional arguments
* +'action'+: The action to execute, e.g. MoveToNextChar.

View File

@@ -18,11 +18,10 @@
|<<general-auto-save-interval,auto-save-interval>>|How often (in milliseconds) to auto-save config/cookies/etc.
|<<general-editor,editor>>|The editor (and arguments) to use for the `open-editor` command.
|<<general-editor-encoding,editor-encoding>>|Encoding to use for editor.
|<<general-private-browsing,private-browsing>>|Do not record visited pages in the history or store web page icons.
|<<general-private-browsing,private-browsing>>|Open new windows in private browsing mode which does not record visited pages.
|<<general-developer-extras,developer-extras>>|Enable extra tools for Web developers.
|<<general-print-element-backgrounds,print-element-backgrounds>>|Whether the background color and images are also drawn when the page is printed.
|<<general-xss-auditing,xss-auditing>>|Whether load requests should be monitored for cross-site scripting attempts.
|<<general-site-specific-quirks,site-specific-quirks>>|Enable QtWebKit workarounds for broken sites.
|<<general-default-encoding,default-encoding>>|Default encoding to use for websites.
|<<general-new-instance-open-target,new-instance-open-target>>|How to open links in an existing instance if a new one is launched.
|<<general-new-instance-open-target.window,new-instance-open-target.window>>|Which window to choose when opening links as new tabs.
@@ -36,6 +35,7 @@
[options="header",width="75%",cols="25%,75%"]
|==============
|Setting|Description
|<<ui-history-session-interval,history-session-interval>>|The maximum time in minutes between two history items for them to be considered being from the same session. Use -1 to disable separation.
|<<ui-zoom-levels,zoom-levels>>|The available zoom levels, separated by commas.
|<<ui-default-zoom,default-zoom>>|The default zoom level.
|<<ui-downloads-position,downloads-position>>|Where to show the downloaded files.
@@ -47,8 +47,7 @@
|<<ui-frame-flattening,frame-flattening>>|Whether to expand each subframe to its contents.
|<<ui-user-stylesheet,user-stylesheet>>|User stylesheet to use (absolute filename or filename relative to the config directory). Will expand environment variables.
|<<ui-hide-scrollbar,hide-scrollbar>>|Hide the main scrollbar.
|<<ui-css-media-type,css-media-type>>|Set the CSS media type.
|<<ui-smooth-scrolling,smooth-scrolling>>|Whether to enable smooth scrolling for webpages.
|<<ui-smooth-scrolling,smooth-scrolling>>|Whether to enable smooth scrolling for web pages. Note smooth scrolling does not work with the :scroll-px command.
|<<ui-remove-finished-downloads,remove-finished-downloads>>|Number of milliseconds to wait before removing finished downloads. Will not be removed if value is -1.
|<<ui-hide-statusbar,hide-statusbar>>|Whether to hide the statusbar unless a message is shown.
|<<ui-statusbar-padding,statusbar-padding>>|Padding for statusbar (top, bottom, left, right).
@@ -56,6 +55,7 @@
|<<ui-modal-js-dialog,modal-js-dialog>>|Use standard JavaScript modal dialog for alert() and confirm()
|<<ui-hide-wayland-decoration,hide-wayland-decoration>>|Hide the window decoration when using wayland (requires restart)
|<<ui-keyhint-blacklist,keyhint-blacklist>>|Keychains that shouldn't be shown in the keyhint dialog
|<<ui-keyhint-delay,keyhint-delay>>|Time from pressing a key to seeing the keyhint dialog (ms)
|<<ui-prompt-radius,prompt-radius>>|The rounding radius for the edges of prompts.
|<<ui-prompt-filebrowser,prompt-filebrowser>>|Show a filebrowser in upload/download prompts.
|==============
@@ -124,10 +124,13 @@
|<<tabs-close-mouse-button,close-mouse-button>>|On which mouse button to close tabs.
|<<tabs-position,position>>|The position of the tab bar.
|<<tabs-show-favicons,show-favicons>>|Whether to show favicons in the tab bar.
|<<tabs-favicon-scale,favicon-scale>>|Scale for favicons in the tab bar. The tab size is unchanged, so big favicons also require extra `tabs->padding`.
|<<tabs-width,width>>|The width of the tab bar if it's vertical, in px or as percentage of the window.
|<<tabs-pinned-width,pinned-width>>|The width for pinned tabs with a horizontal tabbar, in px.
|<<tabs-indicator-width,indicator-width>>|Width of the progress indicator (0 to disable).
|<<tabs-tabs-are-windows,tabs-are-windows>>|Whether to open windows instead of tabs.
|<<tabs-title-format,title-format>>|The format to use for the tab title. The following placeholders are defined:
|<<tabs-title-format-pinned,title-format-pinned>>|The format to use for the tab title for pinned tabs. The same placeholders like for title-format are defined.
|<<tabs-title-alignment,title-alignment>>|Alignment of the text inside of tabs
|<<tabs-mousewheel-tab-switching,mousewheel-tab-switching>>|Switch between tabs using the mouse wheel.
|<<tabs-padding,padding>>|Padding for tabs (top, bottom, left, right).
@@ -142,12 +145,8 @@
|<<storage-prompt-download-directory,prompt-download-directory>>|Whether to prompt the user for the download location.
|<<storage-remember-download-directory,remember-download-directory>>|Whether to remember the last used download directory.
|<<storage-maximum-pages-in-cache,maximum-pages-in-cache>>|The maximum number of pages to hold in the global memory page cache.
|<<storage-object-cache-capacities,object-cache-capacities>>|The capacities for the global memory cache for dead objects such as stylesheets or scripts. Syntax: cacheMinDeadCapacity, cacheMaxDead, totalCapacity.
|<<storage-offline-storage-default-quota,offline-storage-default-quota>>|Default quota for new offline storage databases.
|<<storage-offline-web-application-cache-quota,offline-web-application-cache-quota>>|Quota for the offline web application cache.
|<<storage-offline-storage-database,offline-storage-database>>|Whether support for the HTML 5 offline storage feature is enabled.
|<<storage-offline-web-application-storage,offline-web-application-storage>>|Whether support for the HTML 5 web application cache feature is enabled.
|<<storage-local-storage,local-storage>>|Whether support for the HTML 5 local storage feature is enabled.
|<<storage-offline-web-application-cache,offline-web-application-cache>>|Whether support for the HTML 5 web application cache feature is enabled.
|<<storage-local-storage,local-storage>>|Whether support for HTML 5 local storage and Web SQL is enabled.
|<<storage-cache-size,cache-size>>|Size of the HTTP network cache. Empty to use the default value.
|==============
@@ -159,7 +158,6 @@
|<<content-allow-javascript,allow-javascript>>|Enables or disables the running of JavaScript programs.
|<<content-allow-plugins,allow-plugins>>|Enables or disables plugins in Web pages.
|<<content-webgl,webgl>>|Enables or disables WebGL.
|<<content-css-regions,css-regions>>|Enable or disable support for CSS regions.
|<<content-hyperlink-auditing,hyperlink-auditing>>|Enable or disable hyperlink auditing (<a ping>).
|<<content-geolocation,geolocation>>|Allow websites to request geolocations.
|<<content-notifications,notifications>>|Allow websites to show notifications.
@@ -172,7 +170,7 @@
|<<content-local-content-can-access-remote-urls,local-content-can-access-remote-urls>>|Whether locally loaded documents are allowed to access remote urls.
|<<content-local-content-can-access-file-urls,local-content-can-access-file-urls>>|Whether locally loaded documents are allowed to access other local urls.
|<<content-cookies-accept,cookies-accept>>|Control which cookies to accept.
|<<content-cookies-store,cookies-store>>|Whether to store cookies. Note this option needs a restart with QtWebEngine.
|<<content-cookies-store,cookies-store>>|Whether to store cookies. Note this option needs a restart with QtWebEngine on Qt < 5.9.
|<<content-host-block-lists,host-block-lists>>|List of URLs of lists which contain hosts to block.
|<<content-host-blocking-enabled,host-blocking-enabled>>|Whether host blocking is enabled.
|<<content-host-blocking-whitelist,host-blocking-whitelist>>|List of domains that should always be loaded, despite being ad-blocked.
@@ -218,10 +216,14 @@
|<<colors-completion.scrollbar.bg,completion.scrollbar.bg>>|Color of the scrollbar in completion view
|<<colors-statusbar.fg,statusbar.fg>>|Foreground color of the statusbar.
|<<colors-statusbar.bg,statusbar.bg>>|Background color of the statusbar.
|<<colors-statusbar.fg.private,statusbar.fg.private>>|Foreground color of the statusbar in private browsing mode.
|<<colors-statusbar.bg.private,statusbar.bg.private>>|Background color of the statusbar in private browsing mode.
|<<colors-statusbar.fg.insert,statusbar.fg.insert>>|Foreground color of the statusbar in insert mode.
|<<colors-statusbar.bg.insert,statusbar.bg.insert>>|Background color of the statusbar in insert mode.
|<<colors-statusbar.fg.command,statusbar.fg.command>>|Foreground color of the statusbar in command mode.
|<<colors-statusbar.bg.command,statusbar.bg.command>>|Background color of the statusbar in command mode.
|<<colors-statusbar.fg.command.private,statusbar.fg.command.private>>|Foreground color of the statusbar in private browsing + command mode.
|<<colors-statusbar.bg.command.private,statusbar.bg.command.private>>|Background color of the statusbar in private browsing + command mode.
|<<colors-statusbar.fg.caret,statusbar.fg.caret>>|Foreground color of the statusbar in caret mode.
|<<colors-statusbar.bg.caret,statusbar.bg.caret>>|Background color of the statusbar in caret mode.
|<<colors-statusbar.fg.caret-selection,statusbar.fg.caret-selection>>|Foreground color of the statusbar in caret mode with a selection
@@ -392,7 +394,7 @@ Default: +pass:[utf-8]+
[[general-private-browsing]]
=== private-browsing
Do not record visited pages in the history or store web page icons.
Open new windows in private browsing mode which does not record visited pages.
Valid values:
@@ -401,8 +403,6 @@ Valid values:
Default: +pass:[false]+
This setting is only available with the QtWebKit backend.
[[general-developer-extras]]
=== developer-extras
Enable extra tools for Web developers.
@@ -443,26 +443,13 @@ Valid values:
Default: +pass:[false]+
[[general-site-specific-quirks]]
=== site-specific-quirks
Enable QtWebKit workarounds for broken sites.
Valid values:
* +true+
* +false+
Default: +pass:[true]+
This setting is only available with the QtWebKit backend.
[[general-default-encoding]]
=== default-encoding
Default encoding to use for websites.
The encoding must be a string describing an encoding such as _utf-8_, _iso-8859-1_, etc. If left empty a default value will be used.
The encoding must be a string describing an encoding such as _utf-8_, _iso-8859-1_, etc.
Default: empty
Default: +pass:[iso-8859-1]+
[[general-new-instance-open-target]]
=== new-instance-open-target
@@ -536,6 +523,12 @@ Default: +pass:[path,query]+
== ui
General options related to the user interface.
[[ui-history-session-interval]]
=== history-session-interval
The maximum time in minutes between two history items for them to be considered being from the same session. Use -1 to disable separation.
Default: +pass:[30]+
[[ui-zoom-levels]]
=== zoom-levels
The available zoom levels, separated by commas.
@@ -573,6 +566,7 @@ Default: +pass:[bottom]+
[[ui-message-timeout]]
=== message-timeout
Time (in ms) to show messages in the statusbar for.
Set to 0 to never clear messages.
Default: +pass:[2000]+
@@ -645,17 +639,9 @@ Valid values:
Default: +pass:[true]+
[[ui-css-media-type]]
=== css-media-type
Set the CSS media type.
Default: empty
This setting is only available with the QtWebKit backend.
[[ui-smooth-scrolling]]
=== smooth-scrolling
Whether to enable smooth scrolling for webpages.
Whether to enable smooth scrolling for web pages. Note smooth scrolling does not work with the :scroll-px command.
Valid values:
@@ -699,6 +685,8 @@ The format to use for the window title. The following placeholders are defined:
* `{scroll_pos}`: The page scroll position.
* `{host}`: The host of the current web page.
* `{backend}`: Either 'webkit' or 'webengine'
* `{private}` : Indicates when private mode is enabled.
Default: +pass:[{perc}{title}{title_sep}qutebrowser]+
@@ -732,6 +720,12 @@ Globs are supported, so ';*' will blacklist all keychainsstarting with ';'. Use
Default: empty
[[ui-keyhint-delay]]
=== keyhint-delay
Time from pressing a key to seeing the keyhint dialog (ms)
Default: +pass:[500]+
[[ui-prompt-radius]]
=== prompt-radius
The rounding radius for the edges of prompts.
@@ -795,8 +789,6 @@ The proxy to use.
In addition to the listed values, you can use a `socks://...` or `http://...` URL.
This setting only works with Qt 5.8 or newer when using the QtWebEngine backend.
Valid values:
* +system+: Use the system wide proxy.
@@ -1191,12 +1183,24 @@ Valid values:
Default: +pass:[true]+
[[tabs-favicon-scale]]
=== favicon-scale
Scale for favicons in the tab bar. The tab size is unchanged, so big favicons also require extra `tabs->padding`.
Default: +pass:[1.0]+
[[tabs-width]]
=== width
The width of the tab bar if it's vertical, in px or as percentage of the window.
Default: +pass:[20%]+
[[tabs-pinned-width]]
=== pinned-width
The width for pinned tabs with a horizontal tabbar, in px.
Default: +pass:[43]+
[[tabs-indicator-width]]
=== indicator-width
Width of the progress indicator (0 to disable).
@@ -1227,9 +1231,17 @@ The format to use for the tab title. The following placeholders are defined:
* `{scroll_pos}`: The page scroll position.
* `{host}`: The host of the current web page.
* `{backend}`: Either 'webkit' or 'webengine'
* `{private}` : Indicates when private mode is enabled.
Default: +pass:[{index}: {title}]+
[[tabs-title-format-pinned]]
=== title-format-pinned
The format to use for the tab title for pinned tabs. The same placeholders like for title-format are defined.
Default: +pass:[{index}]+
[[tabs-title-alignment]]
=== title-alignment
Alignment of the text inside of tabs
@@ -1305,55 +1317,12 @@ The Page Cache allows for a nicer user experience when navigating forth or back
For more information about the feature, please refer to: http://webkit.org/blog/427/webkit-page-cache-i-the-basics/
Default: empty
Default: +pass:[0]+
This setting is only available with the QtWebKit backend.
[[storage-object-cache-capacities]]
=== object-cache-capacities
The capacities for the global memory cache for dead objects such as stylesheets or scripts. Syntax: cacheMinDeadCapacity, cacheMaxDead, totalCapacity.
The _cacheMinDeadCapacity_ specifies the minimum number of bytes that dead objects should consume when the cache is under pressure.
_cacheMaxDead_ is the maximum number of bytes that dead objects should consume when the cache is *not* under pressure.
_totalCapacity_ specifies the maximum number of bytes that the cache should consume *overall*.
Default: empty
This setting is only available with the QtWebKit backend.
[[storage-offline-storage-default-quota]]
=== offline-storage-default-quota
Default quota for new offline storage databases.
Default: empty
This setting is only available with the QtWebKit backend.
[[storage-offline-web-application-cache-quota]]
=== offline-web-application-cache-quota
Quota for the offline web application cache.
Default: empty
This setting is only available with the QtWebKit backend.
[[storage-offline-storage-database]]
=== offline-storage-database
Whether support for the HTML 5 offline storage feature is enabled.
Valid values:
* +true+
* +false+
Default: +pass:[true]+
This setting is only available with the QtWebKit backend.
[[storage-offline-web-application-storage]]
=== offline-web-application-storage
[[storage-offline-web-application-cache]]
=== offline-web-application-cache
Whether support for the HTML 5 web application cache feature is enabled.
An application cache acts like an HTTP cache in some sense. For documents that use the application cache via JavaScript, the loader engine will first ask the application cache for the contents, before hitting the network.
@@ -1371,7 +1340,7 @@ This setting is only available with the QtWebKit backend.
[[storage-local-storage]]
=== local-storage
Whether support for the HTML 5 local storage feature is enabled.
Whether support for HTML 5 local storage and Web SQL is enabled.
Valid values:
@@ -1435,19 +1404,6 @@ Valid values:
Default: +pass:[true]+
[[content-css-regions]]
=== css-regions
Enable or disable support for CSS regions.
Valid values:
* +true+
* +false+
Default: +pass:[true]+
This setting is only available with the QtWebKit backend.
[[content-hyperlink-auditing]]
=== hyperlink-auditing
Enable or disable hyperlink auditing (<a ping>).
@@ -1594,7 +1550,7 @@ This setting is only available with the QtWebKit backend.
[[content-cookies-store]]
=== cookies-store
Whether to store cookies. Note this option needs a restart with QtWebEngine.
Whether to store cookies. Note this option needs a restart with QtWebEngine on Qt < 5.9.
Valid values:
@@ -1884,6 +1840,18 @@ Background color of the statusbar.
Default: +pass:[black]+
[[colors-statusbar.fg.private]]
=== statusbar.fg.private
Foreground color of the statusbar in private browsing mode.
Default: +pass:[${statusbar.fg}]+
[[colors-statusbar.bg.private]]
=== statusbar.bg.private
Background color of the statusbar in private browsing mode.
Default: +pass:[#666666]+
[[colors-statusbar.fg.insert]]
=== statusbar.fg.insert
Foreground color of the statusbar in insert mode.
@@ -1908,6 +1876,18 @@ Background color of the statusbar in command mode.
Default: +pass:[${statusbar.bg}]+
[[colors-statusbar.fg.command.private]]
=== statusbar.fg.command.private
Foreground color of the statusbar in private browsing + command mode.
Default: +pass:[${statusbar.fg.private}]+
[[colors-statusbar.bg.command.private]]
=== statusbar.bg.command.private
Background color of the statusbar in private browsing + command mode.
Default: +pass:[${statusbar.bg.private}]+
[[colors-statusbar.fg.caret]]
=== statusbar.fg.caret
Foreground color of the statusbar in caret mode.
@@ -2252,7 +2232,7 @@ Fonts used for the UI, with optional style/weight/size.
=== _monospace
Default monospace fonts.
Default: +pass:[Terminus, Monospace, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Bitstream Vera Sans Mono&quot;, &quot;Andale Mono&quot;, &quot;Courier New&quot;, Courier, &quot;Liberation Mono&quot;, monospace, Fixed, Consolas, Terminal]+
Default: +pass:[xos4 Terminus, Terminus, Monospace, &quot;DejaVu Sans Mono&quot;, Monaco, &quot;Bitstream Vera Sans Mono&quot;, &quot;Andale Mono&quot;, &quot;Courier New&quot;, Courier, &quot;Liberation Mono&quot;, monospace, Fixed, Consolas, Terminal]+
[[fonts-completion]]
=== completion
@@ -2336,25 +2316,25 @@ Default: empty
=== web-size-minimum
The hard minimum font size.
Default: empty
Default: +pass:[0]+
[[fonts-web-size-minimum-logical]]
=== web-size-minimum-logical
The minimum logical font size that is applied when zooming out.
Default: empty
Default: +pass:[6]+
[[fonts-web-size-default]]
=== web-size-default
The default font size for regular text.
Default: empty
Default: +pass:[16]+
[[fonts-web-size-default-fixed]]
=== web-size-default-fixed
The default font size for fixed-pitch text.
Default: empty
Default: +pass:[13]+
[[fonts-keyhint]]
=== keyhint

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

@@ -57,7 +57,7 @@ show it.
How URLs should be opened if there is already a qutebrowser instance running.
*--backend* '{webkit,webengine}'::
Which backend to use (webengine backend is EXPERIMENTAL!).
Which backend to use.
*--enable-webengine-inspector*::
Enable the web inspector for QtWebEngine. Note that this is a SECURITY RISK and you should not visit untrusted websites with the inspector turned on. See https://bugreports.qt.io/browse/QTBUG-50725 for more details.
@@ -93,12 +93,6 @@ show it.
*--nowindow*::
Don't show the main window.
*--debug-exit*::
Turn on debugging of late exit.
*--pdb-postmortem*::
Drop into pdb on exceptions.
*--temp-basedir*::
Use a temporary basedir.
@@ -110,6 +104,9 @@ show it.
*--qt-flag* 'QT_FLAG'::
Pass an argument to Qt as flag.
*--debug-flag* 'DEBUG_FLAGS'::
Pass name of debugging feature to be turned on.
// QUTE_OPTIONS_END
== FILES

77
misc/qutebrowser.nsi Normal file
View File

@@ -0,0 +1,77 @@
Name "qutebrowser"
Unicode true
RequestExecutionLevel admin
SetCompressor /solid lzma
!ifdef X64
OutFile "..\dist\qutebrowser-${VERSION}-amd64.exe"
InstallDir "$ProgramFiles64\qutebrowser"
!else
OutFile "..\dist\qutebrowser-${VERSION}-win32.exe"
InstallDir "$ProgramFiles\qutebrowser"
!endif
;Default installation folder
!include "MUI2.nsh"
;!include "MultiUser.nsh"
!define MUI_ABORTWARNING
;!define MULTIUSER_MUI
;!define MULTIUSER_INSTALLMODE_COMMANDLINE
!define MUI_ICON "../icons/qutebrowser.ico"
!define MUI_UNICON "../icons/qutebrowser.ico"
!insertmacro MUI_PAGE_LICENSE "..\COPYING"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"
; depends on admin status
;SetShellVarContext current
Section "Install"
; Uninstall old versions
ExecWait 'MsiExec.exe /quiet /qn /norestart /X{633F41F9-FE9B-42D1-9CC4-718CBD01EE11}'
ExecWait 'MsiExec.exe /quiet /qn /norestart /X{9331D947-AC86-4542-A755-A833429C6E69}'
SetOutPath "$INSTDIR"
!ifdef X64
file /r "..\dist\qutebrowser-${VERSION}-x64\*.*"
!else
file /r "..\dist\qutebrowser-${VERSION}-x86\*.*"
!endif
SetShellVarContext all
CreateShortCut "$SMPROGRAMS\qutebrowser.lnk" "$INSTDIR\qutebrowser.exe"
;Create uninstaller
WriteUninstaller "$INSTDIR\uninst.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qutebrowser" "DisplayName" "qutebrowser"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qutebrowser" "UninstallString" '"$INSTDIR\uninst.exe"'
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qutebrowser" "QuietUninstallString" '"$INSTDIR\uninst.exe" /S'
SectionEnd
;--------------------------------
;Uninstaller Section
Section "Uninstall"
SetShellVarContext all
Delete "$SMPROGRAMS\qutebrowser.lnk"
RMDir /r "$INSTDIR\*.*"
RMDir "$INSTDIR"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qutebrowser"
SectionEnd

View File

@@ -18,10 +18,10 @@ def get_data_files():
('../qutebrowser/git-commit-id', '')
]
if os.path.exists(os.path.join('qutebrowser', '3rdparty', 'pdfjs')):
data_files.append(('../qutebrowser/3rdparty/pdfjs', '3rdparty/pdfjs'))
else:
print("Warning: excluding pdfjs as it's not present!")
# if os.path.exists(os.path.join('qutebrowser', '3rdparty', 'pdfjs')):
# data_files.append(('../qutebrowser/3rdparty/pdfjs', '3rdparty/pdfjs'))
# else:
# print("Warning: excluding pdfjs as it's not present!")
return data_files
@@ -41,10 +41,10 @@ a = Analysis(['../qutebrowser/__main__.py'],
pathex=['misc'],
binaries=None,
datas=get_data_files(),
hiddenimports=[],
hiddenimports=['PyQt5.QtOpenGL', 'PyQt5._QOpenGLFunctions_2_0'],
hookspath=[],
runtime_hooks=[],
excludes=[],
excludes=['tkinter'],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)

View File

@@ -1,5 +1,9 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
codecov==2.0.5
coverage==4.3.4
requests==2.13.0
certifi==2017.4.17
chardet==3.0.4
codecov==2.0.9
coverage==4.4.1
idna==2.5
requests==2.18.1
urllib3==1.21.1

View File

@@ -1,5 +0,0 @@
cx-Freeze < 5.0.0
# We'll probably switch to PyInstaller soon, and 5.x doesn't install without a
# compiler?
#@ filter: cx-Freeze < 5.0.0

View File

@@ -3,18 +3,21 @@
flake8==2.6.2 # rq.filter: < 3.0.0
flake8-copyright==0.2.0
flake8-debugger==1.4.0 # rq.filter: != 2.0.0
flake8-deprecated==1.1
flake8-docstrings==1.0.3
flake8-deprecated==1.2
flake8-docstrings==1.0.3 # rq.filter: < 1.1.0
flake8-future-import==0.4.3
flake8-mock==0.3
flake8-pep3101==1.0
flake8-pep3101==1.0 # rq.filter: < 1.1
flake8-polyfill==1.0.1
flake8-putty==0.4.0
flake8-string-format==0.2.3
flake8-tidy-imports==1.0.5
flake8-tuple==0.2.12
flake8-tidy-imports==1.0.6
flake8-tuple==0.2.13
mccabe==0.6.1
packaging==16.8
pep8-naming==0.4.1
pycodestyle==2.3.1
pydocstyle==1.1.1
pydocstyle==1.1.1 # rq.filter: < 2.0.0
pyflakes==1.5.0
pyparsing==2.2.0
six==1.10.0

View File

@@ -2,16 +2,16 @@ flake8<3.0.0
flake8-copyright
flake8-debugger!=2.0.0
flake8-deprecated
flake8-docstrings
flake8-docstrings<1.1.0
flake8-future-import
flake8-mock
flake8-pep3101
flake8-pep3101<1.1
flake8-putty
flake8-string-format
flake8-tidy-imports
flake8-tuple
pep8-naming
pydocstyle
pydocstyle<2.0.0
pyflakes
# Pinned to 2.0.0 otherwise
@@ -21,6 +21,9 @@ mccabe==0.6.1
# Waiting until flake8-putty updated
#@ filter: flake8 < 3.0.0
#@ filter: pydocstyle < 2.0.0
#@ filter: flake8-docstrings < 1.1.0
#@ filter: flake8-pep3101 < 1.1
# https://github.com/JBKahn/flake8-debugger/issues/5
#@ filter: flake8-debugger != 2.0.0

View File

@@ -1,8 +1,8 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
appdirs==1.4.2
appdirs==1.4.3
packaging==16.8
pyparsing==2.1.10
setuptools==34.3.0
pyparsing==2.2.0
setuptools==36.0.1
six==1.10.0
wheel==0.29.0

View File

@@ -1,5 +1,3 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-e git+https://github.com/pyinstaller/pyinstaller.git@develop#egg=PyInstaller
PyQt5==5.8
sip==4.19.1

View File

@@ -1,5 +1,4 @@
-e git+https://github.com/pyinstaller/pyinstaller.git@develop#egg=PyInstaller
PyQt5
# remove @commit-id for scm installs
#@ replace: @.*# @develop#
#@ replace: @.*# @develop#

View File

@@ -1,11 +1,18 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
-e git+https://github.com/PyCQA/astroid.git#egg=astroid
editdistance==0.3.1
isort==4.2.5
lazy-object-proxy==1.2.2
certifi==2017.4.17
chardet==3.0.4
github3.py==0.9.6
idna==2.5
isort==4.2.15
lazy-object-proxy==1.3.1
mccabe==0.6.1
-e git+https://github.com/PyCQA/pylint.git#egg=pylint
./scripts/dev/pylint_checkers
requests==2.13.0
wrapt==1.10.8
requests==2.18.1
six==1.10.0
uritemplate==3.0.0
uritemplate.py==3.0.2
urllib3==1.21.1
wrapt==1.10.10

View File

@@ -2,6 +2,7 @@
-e git+https://github.com/PyCQA/pylint.git#egg=pylint
./scripts/dev/pylint_checkers
requests
github3.py
# remove @commit-id for scm installs
#@ replace: @.*# #

View File

@@ -1,13 +1,18 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
astroid==1.4.9
astroid==1.5.3
certifi==2017.4.17
chardet==3.0.4
github3.py==0.9.6
isort==4.2.5
lazy-object-proxy==1.2.2
idna==2.5
isort==4.2.15
lazy-object-proxy==1.3.1
mccabe==0.6.1
pylint==1.6.5
pylint==1.7.2
./scripts/dev/pylint_checkers
requests==2.13.0
requests==2.18.1
six==1.10.0
uritemplate==3.0.0
uritemplate.py==3.0.2
wrapt==1.10.8
urllib3==1.21.1
wrapt==1.10.10

View File

@@ -1,3 +1,4 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
cx-Freeze==4.3.4 # rq.filter: < 5.0.0
PyQt5==5.9
sip==4.19.3

View File

@@ -0,0 +1 @@
PyQt5

View File

@@ -27,7 +27,6 @@ git+https://github.com/pytest-dev/pytest-qt.git
git+https://github.com/pytest-dev/pytest-repeat.git
git+https://github.com/pytest-dev/pytest-rerunfailures.git
git+https://github.com/abusalimov/pytest-travis-fold.git
git+https://github.com/fschulze/pytest-warnings.git
git+https://github.com/The-Compiler/pytest-xvfb.git
hg+https://bitbucket.org/gutworth/six
hg+https://bitbucket.org/jendrikseipp/vulture

View File

@@ -1,36 +1,39 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
beautifulsoup4==4.5.3
cheroot==5.1.0
beautifulsoup4==4.6.0
cheroot==5.7.0
click==6.7
coverage==4.3.4
# colorama==0.3.9
coverage==4.4.1
decorator==4.0.11
EasyProcess==0.2.3
Flask==0.12
fields==5.0.0
Flask==0.12.2
glob2==0.5
httpbin==0.5.0
hypothesis==3.6.1
hunter==1.4.1
hypothesis==3.11.6
itsdangerous==0.24
# Jinja2==2.9.5
# Jinja2==2.9.6
Mako==1.0.6
# MarkupSafe==0.23
parse==1.6.6
# MarkupSafe==1.0
parse==1.8.2
parse-type==0.3.4
py==1.4.32
pytest==3.0.6
pytest-bdd==2.18.1
py==1.4.34
pytest==3.1.2
pytest-bdd==2.18.2
pytest-benchmark==3.0.0
pytest-catchlog==1.2.2
pytest-cov==2.4.0
pytest-cov==2.5.1
pytest-faulthandler==1.3.1
pytest-instafail==0.3.0
pytest-mock==1.5.0
pytest-mock==1.6.0
pytest-qt==2.1.0
pytest-repeat==0.4.1
pytest-rerunfailures==2.1.0
pytest-rerunfailures==2.2
pytest-travis-fold==1.2.0
pytest-warnings==0.2.0
pytest-xvfb==1.0.0
PyVirtualDisplay==0.2.1
vulture==0.12
Werkzeug==0.11.15
six==1.10.0
vulture==0.14
Werkzeug==0.12.2

View File

@@ -2,6 +2,7 @@ beautifulsoup4
cheroot
coverage
Flask
hunter
httpbin
hypothesis
pytest
@@ -16,8 +17,7 @@ pytest-qt
pytest-repeat
pytest-rerunfailures
pytest-travis-fold
pytest-warnings
pytest-xvfb
vulture
#@ ignore: Jinja2, MarkupSafe
#@ ignore: Jinja2, MarkupSafe, colorama

View File

@@ -1,6 +1,6 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
pluggy==0.4.0
py==1.4.32
tox==2.6.0
py==1.4.34
tox==2.7.0
virtualenv==15.1.0

View File

@@ -1,3 +1,3 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
vulture==0.12
vulture==0.14

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env bash
# Copyright 2015 Zach-Button <zachrey.button@gmail.com>
# Copyright 2015-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
# Copyright 2015 jnphilipp <me@jnphilipp.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -9,7 +9,7 @@ directly ask me via IRC (nickname thorsten\`) in #qutebrowser on freenode.
$blink!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$reset
WARNING: the passwords are stored in qutebrowser's
debug log reachable via the url qute:log
debug log reachable via the url qute://log
$blink!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$reset
Usage: run as a userscript form qutebrowser, e.g.:

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env bash
# Copyright 2015 Zach-Button <zachrey.button@gmail.com>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python
#
# Executes python-readability on current page and opens the summary as new tab.
#

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python
#
# Adds DuckDuckGo bang as searchengine.
#
@@ -8,14 +8,21 @@
# Example:
# :spawn --userscript ripbang amazon maps
#
import os, re, requests, sys, urllib
from __future__ import print_function
import os, re, requests, sys
try:
from urllib.parse import unquote
except ImportError:
from urllib import unquote
for argument in sys.argv[1:]:
bang = '!' + argument
r = requests.get('https://duckduckgo.com/',
params={'q': bang + ' SEARCHTEXT'})
searchengine = urllib.unquote(re.search("url=[^']+", r.text).group(0))
searchengine = unquote(re.search("url=[^']+", r.text).group(0))
searchengine = searchengine.replace('url=', '')
searchengine = searchengine.replace('/l/?kh=-1&uddg=', '')
searchengine = searchengine.replace('SEARCHTEXT', '{}')
@@ -24,4 +31,4 @@ for argument in sys.argv[1:]:
with open(os.environ['QUTE_FIFO'], 'w') as fifo:
fifo.write('set searchengines %s %s' % (bang, searchengine))
else:
print '%s %s' % (bang, searchengine)
print('%s %s' % (bang, searchengine))

View File

@@ -24,11 +24,12 @@ markers =
js_prompt: Tests needing to display a javascript prompt
this: Used to mark tests during development
no_invalid_lines: Don't fail on unparseable lines in end2end tests
issue2478: Tests which are broken on Windows with QtWebEngine, https://github.com/qutebrowser/qutebrowser/issues/2478
qt_log_level_fail = WARNING
qt_log_ignore =
^SpellCheck: .*
^SetProcessDpiAwareness failed: .*
^QWindowsWindow::setGeometryDp: Unable to set geometry .*
^QWindowsWindow::setGeometry(Dp)?: Unable to set geometry .*
^QProcess: Destroyed while process .* is still running\.
^"Method "GetAll" with signature "s" on interface "org\.freedesktop\.DBus\.Properties" doesn't exist
^"Method \\"GetAll\\" with signature \\"s\\" on interface \\"org\.freedesktop\.DBus\.Properties\\" doesn't exist\\n"
@@ -44,6 +45,8 @@ qt_log_ignore =
^QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to .*
^QGeoclueMaster error creating GeoclueMasterClient\.
^Geoclue error: Process org\.freedesktop\.Geoclue\.Master exited with status 127
^QDBusConnection: name 'org.freedesktop.Geoclue.Master' had owner '' but we thought it was ':1.1'
^Failed to create Geoclue client interface. Geoclue error: org\.freedesktop\.DBus\.Error\.Disconnected
^QObject::connect: Cannot connect \(null\)::stateChanged\(QNetworkSession::State\) to QNetworkReplyHttpImpl::_q_networkSessionStateChanged\(QNetworkSession::State\)
^QXcbClipboard: Cannot transfer data, no data available
^load glyph failed
@@ -51,4 +54,6 @@ qt_log_ignore =
^Image of format '' blocked because it is not considered safe. If you are sure it is safe to do so, you can white-list the format by setting the environment variable QTWEBKIT_IMAGEFORMAT_WHITELIST=
^QPainter::end: Painter ended with \d+ saved states
^QSslSocket: cannot resolve SSLv[23]_(client|server)_method
^QQuickWidget::invalidateRenderControl could not make context current
^libpng warning: iCCP: known incorrect sRGB profile
xfail_strict = true

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -22,11 +22,11 @@
import os.path
__author__ = "Florian Bruhin"
__copyright__ = "Copyright 2014-2016 Florian Bruhin (The Compiler)"
__copyright__ = "Copyright 2014-2017 Florian Bruhin (The Compiler)"
__license__ = "GPL"
__maintainer__ = __author__
__email__ = "mail@qutebrowser.org"
__version_info__ = (0, 10, 0)
__version_info__ = (0, 11, 1)
__version__ = '.'.join(str(e) for e in __version_info__)
__description__ = "A keyboard-driven, vim-like browser based on PyQt5."

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -53,7 +53,7 @@ from qutebrowser.browser.webkit.network import networkmanager
from qutebrowser.keyinput import macros
from qutebrowser.mainwindow import mainwindow, prompt
from qutebrowser.misc import (readline, ipc, savemanager, sessions,
crashsignal, earlyinit)
crashsignal, earlyinit, objects)
from qutebrowser.misc import utilcmds # pylint: disable=unused-import
from qutebrowser.utils import (log, version, message, utils, qtutils, urlutils,
objreg, usertypes, standarddir, error, debug)
@@ -133,18 +133,14 @@ def init(args, crash_handler):
log.init.debug("Starting init...")
qApp.setQuitOnLastWindowClosed(False)
_init_icon()
utils.actute_warning()
try:
_init_modules(args, crash_handler)
except (OSError, UnicodeDecodeError) as e:
except (OSError, UnicodeDecodeError, browsertab.WebTabError) as e:
error.handle_fatal_exc(e, args, "Error while initializing!",
pre_text="Error while initializing")
sys.exit(usertypes.Exit.err_init)
QTimer.singleShot(0, functools.partial(_process_args, args))
QTimer.singleShot(10, functools.partial(_init_late_modules, args))
log.init.debug("Initializing eventfilter...")
event_filter = EventFilter(qApp)
qApp.installEventFilter(event_filter)
@@ -155,11 +151,13 @@ def init(args, crash_handler):
config_obj.style_changed.connect(style.get_stylesheet.cache_clear)
qApp.focusChanged.connect(on_focus_changed)
_process_args(args)
QDesktopServices.setUrlHandler('http', open_desktopservices_url)
QDesktopServices.setUrlHandler('https', open_desktopservices_url)
QDesktopServices.setUrlHandler('qute', open_desktopservices_url)
macros.init()
QTimer.singleShot(10, functools.partial(_init_late_modules, args))
log.init.debug("Init done!")
crash_handler.raise_crashdlg()
@@ -172,12 +170,15 @@ def _init_icon():
for size in [16, 24, 32, 48, 64, 96, 128, 256, 512]:
filename = ':/icons/qutebrowser-{}x{}.png'.format(size, size)
pixmap = QPixmap(filename)
qtutils.ensure_not_null(pixmap)
fallback_icon.addPixmap(pixmap)
qtutils.ensure_not_null(fallback_icon)
if pixmap.isNull():
log.init.warning("Failed to load {}".format(filename))
else:
fallback_icon.addPixmap(pixmap)
icon = QIcon.fromTheme('qutebrowser', fallback_icon)
qtutils.ensure_not_null(icon)
qApp.setWindowIcon(icon)
if icon.isNull():
log.init.warning("Failed to load icon")
else:
qApp.setWindowIcon(icon)
def _process_args(args):
@@ -194,14 +195,14 @@ def _process_args(args):
session_manager = objreg.get('session-manager')
if not session_manager.did_load:
log.init.debug("Initializing main window...")
window = mainwindow.MainWindow()
window = mainwindow.MainWindow(private=None)
if not args.nowindow:
window.show()
qApp.setActiveWindow(window)
process_pos_args(args.command)
_open_startpage()
_open_quickstart(args)
_open_special_pages(args)
delta = datetime.datetime.now() - earlyinit.START_TIME
log.init.debug("Init finished after {}s".format(delta.total_seconds()))
@@ -303,7 +304,7 @@ def _open_startpage(win_id=None):
window_ids = [win_id]
else:
window_ids = objreg.window_registry
for cur_win_id in window_ids:
for cur_win_id in list(window_ids): # Copying as the dict could change
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=cur_win_id)
if tabbed_browser.count() == 0:
@@ -318,23 +319,40 @@ def _open_startpage(win_id=None):
tabbed_browser.tabopen(url)
def _open_quickstart(args):
"""Open quickstart if it's the first start.
def _open_special_pages(args):
"""Open special notification pages which are only shown once.
Currently this is:
- Quickstart page if it's the first start.
- Legacy QtWebKit warning if needed.
Args:
args: The argparse namespace.
"""
if args.basedir is not None:
# With --basedir given, don't open quickstart.
# With --basedir given, don't open anything.
return
state_config = objreg.get('state-config')
try:
quickstart_done = state_config['general']['quickstart-done'] == '1'
except KeyError:
quickstart_done = False
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window='last-focused')
# Legacy QtWebKit warning
needs_warning = (objects.backend == usertypes.Backend.QtWebKit and
not qtutils.is_qtwebkit_ng())
warning_shown = state_config['general'].get('backend-warning-shown') == '1'
if not warning_shown and needs_warning:
tabbed_browser.tabopen(QUrl('qute://backend-warning'),
background=False)
state_config['general']['backend-warning-shown'] = '1'
# Quickstart page
quickstart_done = state_config['general'].get('quickstart-done') == '1'
if not quickstart_done:
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window='last-focused')
tabbed_browser.tabopen(
QUrl('https://www.qutebrowser.org/quickstart.html'))
state_config['general']['quickstart-done'] = '1'
@@ -342,8 +360,9 @@ def _open_quickstart(args):
def _save_version():
"""Save the current version to the state config."""
state_config = objreg.get('state-config')
state_config['general']['version'] = qutebrowser.__version__
state_config = objreg.get('state-config', None)
if state_config is not None:
state_config['general']['version'] = qutebrowser.__version__
def on_focus_changed(_old, new):
@@ -391,10 +410,8 @@ def _init_modules(args, crash_handler):
log.init.debug("Initializing network...")
networkmanager.init()
if qtutils.version_check('5.8'):
# Otherwise we can only initialize it for QtWebKit because of crashes
log.init.debug("Initializing proxy...")
proxy.init()
log.init.debug("Initializing proxy...")
proxy.init()
log.init.debug("Initializing readline-bridge...")
readline_bridge = readline.ReadlineBridge()
@@ -448,6 +465,7 @@ def _init_modules(args, crash_handler):
os.environ['QT_WAYLAND_DISABLE_WINDOWDECORATION'] = '1'
else:
os.environ.pop('QT_WAYLAND_DISABLE_WINDOWDECORATION', None)
macros.init()
# Init backend-specific stuff
browsertab.init()
@@ -616,7 +634,7 @@ class Quitter:
# Save the session if one is given.
if session is not None:
session_manager = objreg.get('session-manager')
session_manager.save(session)
session_manager.save(session, with_private=True)
# Open a new process and immediately shutdown the existing one
try:
args, cwd = self._get_restart_args(pages, session)
@@ -648,14 +666,14 @@ class Quitter:
self._shutting_down = True
log.destroy.debug("Shutting down with status {}, session {}...".format(
status, session))
session_manager = objreg.get('session-manager')
if session is not None:
session_manager.save(session, last_window=last_window,
load_next_time=True)
elif config.get('general', 'save-session'):
session_manager.save(sessions.default, last_window=last_window,
load_next_time=True)
session_manager = objreg.get('session-manager', None)
if session_manager is not None:
if session is not None:
session_manager.save(session, last_window=last_window,
load_next_time=True)
elif config.get('general', 'save-session'):
session_manager.save(sessions.default, last_window=last_window,
load_next_time=True)
if prompt.prompt_queue.shutdown():
# If shutdown was called while we were asking a question, we're in
@@ -672,7 +690,7 @@ class Quitter:
# event loop, so we can shut down immediately.
self._shutdown(status, restart=restart)
def _shutdown(self, status, restart):
def _shutdown(self, status, restart): # noqa
"""Second stage of shutdown."""
log.destroy.debug("Stage 2 of shutting down...")
if qApp is None:
@@ -681,7 +699,9 @@ class Quitter:
# Remove eventfilter
try:
log.destroy.debug("Removing eventfilter...")
qApp.removeEventFilter(objreg.get('event-filter'))
event_filter = objreg.get('event-filter', None)
if event_filter is not None:
qApp.removeEventFilter(event_filter)
except AttributeError:
pass
# Close all windows
@@ -723,7 +743,9 @@ class Quitter:
# Now we can hopefully quit without segfaults
log.destroy.debug("Deferring QApplication::exit...")
objreg.get('signal-handler').deactivate()
objreg.get('session-manager').delete_autosave()
session_manager = objreg.get('session-manager', None)
if session_manager is not None:
session_manager.delete_autosave()
# We use a singleshot timer to exit here to minimize the likelihood of
# segfaults.
QTimer.singleShot(0, functools.partial(qApp.exit, status))
@@ -785,7 +807,7 @@ class Application(QApplication):
def exit(self, status):
"""Extend QApplication::exit to log the event."""
log.destroy.debug("Now calling QApplication::exit.")
if self._args.debug_exit:
if 'debug-exit' in self._args.debug_flags:
if hunter is None:
print("Not logging late shutdown because hunter could not be "
"imported!", file=sys.stderr)

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -58,7 +58,7 @@ def get_fileobj(byte_io):
byte_io = zf.open(filename, mode='r')
else:
byte_io.seek(0) # rewind what zipfile.is_zipfile did
return io.TextIOWrapper(byte_io, encoding='utf-8')
return byte_io
def is_whitelisted_host(host):
@@ -147,7 +147,7 @@ class HostBlocker:
with open(filename, 'r', encoding='utf-8') as f:
for line in f:
target.add(line.strip())
except OSError:
except (OSError, UnicodeDecodeError):
log.misc.exception("Failed to read host blocklist!")
return True
@@ -165,7 +165,8 @@ class HostBlocker:
if not found:
args = objreg.get('args')
if (config.get('content', 'host-block-lists') is not None and
args.basedir is None):
args.basedir is None and
config.get('content', 'host-blocking-enabled')):
message.info("Run :adblock-update to get adblock lists.")
@cmdutils.register(instance='host-blocker')
@@ -205,6 +206,54 @@ class HostBlocker:
download.finished.connect(
functools.partial(self.on_download_finished, download))
def _parse_line(self, line):
"""Parse a line from a host file.
Args:
line: The bytes object to parse.
Returns:
True if parsing succeeded, False otherwise.
"""
if line.startswith(b'#'):
# Ignoring comments early so we don't have to care about
# encoding errors in them.
return True
try:
line = line.decode('utf-8')
except UnicodeDecodeError:
log.misc.error("Failed to decode: {!r}".format(line))
return False
# Remove comments
try:
hash_idx = line.index('#')
line = line[:hash_idx]
except ValueError:
pass
line = line.strip()
# Skip empty lines
if not line:
return True
parts = line.split()
if len(parts) == 1:
# "one host per line" format
host = parts[0]
elif len(parts) == 2:
# /etc/hosts format
host = parts[1]
else:
log.misc.error("Failed to parse: {!r}".format(line))
return False
if host not in self.WHITELISTED:
self._blocked_hosts.add(host)
return True
def _merge_file(self, byte_io):
"""Read and merge host files.
@@ -218,35 +267,18 @@ class HostBlocker:
line_count = 0
try:
f = get_fileobj(byte_io)
except (OSError, UnicodeDecodeError, zipfile.BadZipFile,
zipfile.LargeZipFile, LookupError) as e:
except (OSError, zipfile.BadZipFile, zipfile.LargeZipFile,
LookupError) as e:
message.error("adblock: Error while reading {}: {} - {}".format(
byte_io.name, e.__class__.__name__, e))
return
for line in f:
line_count += 1
# Remove comments
try:
hash_idx = line.index('#')
line = line[:hash_idx]
except ValueError:
pass
line = line.strip()
# Skip empty lines
if not line:
continue
parts = line.split()
if len(parts) == 1:
# "one host per line" format
host = parts[0]
elif len(parts) == 2:
# /etc/hosts format
host = parts[1]
else:
ok = self._parse_line(line)
if not ok:
error_count += 1
continue
if host not in self.WHITELISTED:
self._blocked_hosts.add(host)
log.misc.debug("{}: read {} lines".format(byte_io.name, line_count))
if error_count > 0:
message.error("adblock: {} read errors for {}".format(

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -21,7 +21,7 @@
import itertools
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, QObject, QSizeF
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, QObject, QSizeF, Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QWidget, QApplication
@@ -35,11 +35,12 @@ from qutebrowser.browser import mouse, hints
tab_id_gen = itertools.count(0)
def create(win_id, parent=None):
def create(win_id, private, parent=None):
"""Get a QtWebKit/QtWebEngine tab object.
Args:
win_id: The window ID where the tab will be shown.
private: Whether the tab is a private/off the record tab.
parent: The Qt parent to set.
"""
# Importing modules here so we don't depend on QtWebEngine without the
@@ -51,7 +52,8 @@ def create(win_id, parent=None):
else:
from qutebrowser.browser.webkit import webkittab
tab_class = webkittab.WebKitTab
return tab_class(win_id=win_id, mode_manager=mode_manager, parent=parent)
return tab_class(win_id=win_id, mode_manager=mode_manager, private=private,
parent=parent)
def init():
@@ -94,6 +96,8 @@ class TabData:
viewing_source: Set if we're currently showing a source view.
override_target: Override for open_target for fake clicks (like hints).
Only used for QtWebKit.
pinned: Flag to pin the tab.
fullscreen: Whether the tab has a video shown fullscreen currently.
"""
def __init__(self):
@@ -101,11 +105,21 @@ class TabData:
self.viewing_source = False
self.inspector = None
self.override_target = None
self.pinned = False
self.fullscreen = False
class AbstractAction:
"""Attribute of AbstractTab for Qt WebActions."""
"""Attribute of AbstractTab for Qt WebActions.
Class attributes (overridden by subclasses):
action_class: The class actions are defined on (QWeb{Engine,}Page)
action_base: The type of the actions (QWeb{Engine,}Page.WebAction)
"""
action_class = None
action_base = None
def __init__(self):
self._widget = None
@@ -118,6 +132,13 @@ class AbstractAction:
"""Save the current page."""
raise NotImplementedError
def run_string(self, name):
"""Run a webaction based on its name."""
member = getattr(self.action_class, name, None)
if not isinstance(member, self.action_base):
raise WebTabError("{} is not a valid web action!".format(name))
self._widget.triggerPageAction(member)
class AbstractPrinting:
@@ -155,6 +176,8 @@ class AbstractSearch(QObject):
Attributes:
text: The last thing this view was searched for.
search_displayed: Whether we're currently displaying search results in
this view.
_flags: The flags of the last search (needs to be set by subclasses).
_widget: The underlying WebView widget.
"""
@@ -163,6 +186,7 @@ class AbstractSearch(QObject):
super().__init__(parent)
self._widget = None
self.text = None
self.search_displayed = False
def search(self, text, *, ignore_case=False, reverse=False,
result_cb=None):
@@ -524,6 +548,7 @@ class AbstractTab(QWidget):
Attributes:
history: The AbstractHistory for the current tab.
registry: The ObjectRegistry associated with this tab.
private: Whether private browsing is turned on for this tab.
_load_status: loading status of this page
Accessible via load_status() method.
@@ -563,7 +588,8 @@ class AbstractTab(QWidget):
fullscreen_requested = pyqtSignal(bool)
renderer_process_terminated = pyqtSignal(TerminationStatus, int)
def __init__(self, win_id, mode_manager, parent=None):
def __init__(self, *, win_id, mode_manager, private, parent=None):
self.private = private
self.win_id = win_id
self.tab_id = next(tab_id_gen)
super().__init__(parent)
@@ -740,6 +766,10 @@ class AbstractTab(QWidget):
def clear_ssl_errors(self):
raise NotImplementedError
def key_press(self, key, modifier=Qt.NoModifier):
"""Send a fake key event to this tab."""
raise NotImplementedError
def dump_async(self, callback, *, plain=False):
"""Dump the current page to a file ascync.
@@ -771,7 +801,7 @@ class AbstractTab(QWidget):
def icon(self):
raise NotImplementedError
def set_html(self, html, base_url):
def set_html(self, html, base_url=QUrl()):
raise NotImplementedError
def networkaccessmanager(self):

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -20,22 +20,15 @@
"""Command dispatcher for TabbedBrowser."""
import os
import sys
import os.path
import shlex
import functools
from PyQt5.QtWidgets import QApplication, QTabBar
from PyQt5.QtWidgets import QApplication, QTabBar, QDialog
from PyQt5.QtCore import Qt, QUrl, QEvent, QUrlQuery
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtPrintSupport import QPrintDialog, QPrintPreviewDialog
try:
from PyQt5.QtWebKitWidgets import QWebPage
except ImportError:
QWebPage = None
try:
from PyQt5.QtWebEngineWidgets import QWebEnginePage
except ImportError:
QWebEnginePage = None
import pygments
import pygments.lexers
import pygments.formatters
@@ -75,10 +68,10 @@ class CommandDispatcher:
def __repr__(self):
return utils.get_repr(self)
def _new_tabbed_browser(self):
def _new_tabbed_browser(self, private):
"""Get a tabbed-browser from a new window."""
from qutebrowser.mainwindow import mainwindow
new_window = mainwindow.MainWindow()
new_window = mainwindow.MainWindow(private=private)
new_window.show()
return new_window.tabbed_browser
@@ -118,7 +111,7 @@ class CommandDispatcher:
return widget
def _open(self, url, tab=False, background=False, window=False,
explicit=True):
explicit=True, private=None):
"""Helper function to open a page.
Args:
@@ -126,12 +119,17 @@ class CommandDispatcher:
tab: Whether to open in a new tab.
background: Whether to open in the background.
window: Whether to open in a new window
private: If opening a new window, open it in private browsing mode.
If not given, inherit the current window's mode.
"""
urlutils.raise_cmdexc_if_invalid(url)
tabbed_browser = self._tabbed_browser
cmdutils.check_exclusive((tab, background, window), 'tbw')
if window:
tabbed_browser = self._new_tabbed_browser()
cmdutils.check_exclusive((tab, background, window, private), 'tbwp')
if window and private is None:
private = self._tabbed_browser.private
if window or private:
tabbed_browser = self._new_tabbed_browser(private)
tabbed_browser.tabopen(url)
elif tab:
tabbed_browser.tabopen(url, background=False, explicit=explicit)
@@ -160,12 +158,14 @@ class CommandDispatcher:
else:
return None
def _tab_focus_last(self):
def _tab_focus_last(self, *, show_error=True):
"""Select the tab which was last focused."""
try:
tab = objreg.get('last-focused-tab', scope='window',
window=self._win_id)
except KeyError:
if not show_error:
return
raise cmdexc.CommandError("No last focused tab!")
idx = self._tabbed_browser.indexOf(tab)
if idx == -1:
@@ -205,24 +205,21 @@ class CommandDispatcher:
"{!r}!".format(conf_selection))
return None
@cmdutils.register(instance='command-dispatcher', scope='window')
@cmdutils.argument('count', count=True)
def tab_close(self, prev=False, next_=False, opposite=False, count=None):
"""Close the current/[count]th tab.
def _tab_close(self, tab, prev=False, next_=False, opposite=False):
"""Helper function for tab_close be able to handle message.async.
Args:
tab: Tab object to select be closed.
prev: Force selecting the tab before the current tab.
next_: Force selecting the tab after the current tab.
opposite: Force selecting the tab in the opposite direction of
what's configured in 'tabs->select-on-remove'.
count: The tab index to close, or None
"""
tab = self._cntwidget(count)
if tab is None:
return
tabbar = self._tabbed_browser.tabBar()
selection_override = self._get_selection_override(prev, next_,
opposite)
if selection_override is None:
self._tabbed_browser.close_tab(tab)
else:
@@ -231,12 +228,55 @@ class CommandDispatcher:
self._tabbed_browser.close_tab(tab)
tabbar.setSelectionBehaviorOnRemove(old_selection_behavior)
@cmdutils.register(instance='command-dispatcher', scope='window')
@cmdutils.argument('count', count=True)
def tab_close(self, prev=False, next_=False, opposite=False,
force=False, count=None):
"""Close the current/[count]th tab.
Args:
prev: Force selecting the tab before the current tab.
next_: Force selecting the tab after the current tab.
opposite: Force selecting the tab in the opposite direction of
what's configured in 'tabs->select-on-remove'.
force: Avoid confirmation for pinned tabs.
count: The tab index to close, or None
"""
tab = self._cntwidget(count)
if tab is None:
return
close = functools.partial(self._tab_close, tab, prev,
next_, opposite)
self._tabbed_browser.tab_close_prompt_if_pinned(tab, force, close)
@cmdutils.register(instance='command-dispatcher', scope='window',
name='tab-pin')
@cmdutils.argument('count', count=True)
def tab_pin(self, count=None):
"""Pin/Unpin the current/[count]th tab.
Pinning a tab shrinks it to tabs->pinned-width size.
Attempting to close a pinned tab will cause a confirmation,
unless --force is passed.
Args:
count: The tab index to pin or unpin, or None
"""
tab = self._cntwidget(count)
if tab is None:
return
to_pin = not tab.data.pinned
self._tabbed_browser.set_tab_pinned(tab, to_pin)
@cmdutils.register(instance='command-dispatcher', name='open',
maxsplit=0, scope='window')
@cmdutils.argument('url', completion=usertypes.Completion.url)
@cmdutils.argument('count', count=True)
def openurl(self, url=None, implicit=False,
bg=False, tab=False, window=False, count=None):
bg=False, tab=False, window=False, count=None, secure=False,
private=False):
"""Open a URL in the current/[count]th tab.
If the URL contains newlines, each line gets opened in its own tab.
@@ -249,6 +289,8 @@ class CommandDispatcher:
implicit: If opening a new tab, treat the tab as implicit (like
clicking on a link).
count: The tab index to open the URL in, or None.
secure: Force HTTPS.
private: Open a new window in private browsing mode.
"""
if url is None:
urls = [config.get('general', 'default-page')]
@@ -256,11 +298,15 @@ class CommandDispatcher:
urls = self._parse_url_input(url)
for i, cur_url in enumerate(urls):
if secure:
cur_url.setScheme('https')
if not window and i > 0:
tab = False
bg = True
if tab or bg or window:
self._open(cur_url, tab, bg, window, not implicit)
if tab or bg or window or private:
self._open(cur_url, tab, bg, window, explicit=not implicit,
private=private)
else:
curtab = self._cntwidget(count)
if curtab is None:
@@ -271,6 +317,8 @@ class CommandDispatcher:
else:
# Explicit count with a tab that doesn't exist.
return
elif curtab.data.pinned:
message.info("Tab is pinned!")
else:
curtab.openurl(cur_url)
@@ -350,7 +398,7 @@ class CommandDispatcher:
message.error("Printing failed!")
tab.printing.check_preview_support()
diag = QPrintPreviewDialog()
diag = QPrintPreviewDialog(tab)
diag.setAttribute(Qt.WA_DeleteOnClose)
diag.setWindowFlags(diag.windowFlags() | Qt.WindowMaximizeButtonHint |
Qt.WindowMinimizeButtonHint)
@@ -376,9 +424,18 @@ class CommandDispatcher:
message.error("Printing failed!")
diag.deleteLater()
diag = QPrintDialog()
diag.open(lambda: tab.printing.to_printer(diag.printer(),
print_callback))
def do_print():
"""Called when the dialog was closed."""
tab.printing.to_printer(diag.printer(), print_callback)
diag = QPrintDialog(tab)
if sys.platform == 'darwin':
# For some reason we get a segfault when using open() on macOS
ret = diag.exec_()
if ret == QDialog.Accepted:
do_print()
else:
diag.open(do_print)
@cmdutils.register(instance='command-dispatcher', name='print',
scope='window')
@@ -435,10 +492,11 @@ class CommandDispatcher:
# The new tab could be in a new tabbed_browser (e.g. because of
# tabs-are-windows being set)
if window:
new_tabbed_browser = self._new_tabbed_browser()
new_tabbed_browser = self._new_tabbed_browser(
private=self._tabbed_browser.private)
else:
new_tabbed_browser = self._tabbed_browser
newtab = new_tabbed_browser.tabopen(background=bg, explicit=True)
newtab = new_tabbed_browser.tabopen(background=bg)
new_tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=newtab.win_id)
idx = new_tabbed_browser.indexOf(newtab)
@@ -452,6 +510,7 @@ class CommandDispatcher:
newtab.data.keep_icon = True
newtab.history.deserialize(history)
newtab.zoom.set_factor(curtab.zoom.factor())
new_tabbed_browser.set_tab_pinned(newtab, curtab.data.pinned)
return newtab
@cmdutils.register(instance='command-dispatcher', scope='window')
@@ -565,7 +624,7 @@ class CommandDispatcher:
tab=tab, background=bg, window=window)
elif where in ['up', 'increment', 'decrement']:
new_url = handlers[where](url, count)
self._open(new_url, tab, bg, window)
self._open(new_url, tab, bg, window, explicit=False)
else: # pragma: no cover
raise ValueError("Got called with invalid value {} for "
"`where'.".format(where))
@@ -595,6 +654,9 @@ class CommandDispatcher:
def scroll(self, direction: typing.Union[str, int], count=1):
"""Scroll the current tab in the given direction.
Note you can use `:run-with-count` to have a keybinding with a bigger
scroll increment.
Args:
direction: In which direction to scroll
(up/down/left/right/top/bottom).
@@ -628,7 +690,7 @@ class CommandDispatcher:
scope='window')
@cmdutils.argument('count', count=True)
@cmdutils.argument('horizontal', flag='x')
def scroll_perc(self, perc: float=None, horizontal=False, count=None):
def scroll_perc(self, perc: float = None, horizontal=False, count=None):
"""Scroll to a specific percentage of the page.
The percentage can be given either as argument or as count.
@@ -664,7 +726,7 @@ class CommandDispatcher:
@cmdutils.argument('bottom_navigate', metavar='ACTION',
choices=('next', 'increment'))
def scroll_page(self, x: float, y: float, *,
top_navigate: str=None, bottom_navigate: str=None,
top_navigate: str = None, bottom_navigate: str = None,
count=1):
"""Scroll the frame page-wise.
@@ -801,7 +863,7 @@ class CommandDispatcher:
@cmdutils.register(instance='command-dispatcher', scope='window')
@cmdutils.argument('count', count=True)
def zoom(self, zoom: int=None, count=None):
def zoom(self, zoom=None, count=None):
"""Set the zoom level for the current tab.
The zoom can be given as argument or as [count]. If neither is
@@ -812,6 +874,13 @@ class CommandDispatcher:
zoom: The zoom percentage to set.
count: The zoom percentage to set.
"""
if zoom is not None:
try:
zoom = int(zoom.rstrip('%'))
except ValueError:
raise cmdexc.CommandError("zoom: Invalid int value {}"
.format(zoom))
level = count if count is not None else zoom
if level is None:
level = config.get('ui', 'default-zoom')
@@ -824,27 +893,42 @@ class CommandDispatcher:
message.info("Zoom level: {}%".format(level), replace=True)
@cmdutils.register(instance='command-dispatcher', scope='window')
def tab_only(self, prev=False, next_=False):
def tab_only(self, prev=False, next_=False, force=False):
"""Close all tabs except for the current one.
Args:
prev: Keep tabs before the current.
next_: Keep tabs after the current.
force: Avoid confirmation for pinned tabs.
"""
cmdutils.check_exclusive((prev, next_), 'pn')
cur_idx = self._tabbed_browser.currentIndex()
assert cur_idx != -1
def _to_close(i):
"""Helper method to check if a tab should be closed or not."""
return not (i == cur_idx or
(prev and i < cur_idx) or
(next_ and i > cur_idx))
# Check to see if we are closing any pinned tabs
if not force:
for i, tab in enumerate(self._tabbed_browser.widgets()):
if _to_close(i) and tab.data.pinned:
self._tabbed_browser.tab_close_prompt_if_pinned(
tab,
force,
lambda: self.tab_only(
prev=prev, next_=next_, force=True))
return
for i, tab in enumerate(self._tabbed_browser.widgets()):
if (i == cur_idx or (prev and i < cur_idx) or
(next_ and i > cur_idx)):
continue
else:
if _to_close(i):
self._tabbed_browser.close_tab(tab)
@cmdutils.register(instance='command-dispatcher', scope='window')
def undo(self):
"""Re-open a closed tab (optionally skipping [count] closed tabs)."""
"""Re-open a closed tab."""
try:
self._tabbed_browser.undo()
except IndexError:
@@ -997,12 +1081,15 @@ class CommandDispatcher:
last tab.
count: The tab index to focus, starting with 1.
"""
index = count if count is not None else index
if index == 'last':
self._tab_focus_last()
return
index = count if count is not None else index
if index is None:
elif index == self._current_index() + 1:
self._tab_focus_last(show_error=False)
return
elif index is None:
self.tab_next()
return
@@ -1076,6 +1163,7 @@ class CommandDispatcher:
detach: Whether the command should be detached from qutebrowser.
cmdline: The commandline to execute.
"""
cmdutils.check_exclusive((userscript, detach), 'ud')
try:
cmd, *args = shlex.split(cmdline)
except ValueError as e:
@@ -1227,7 +1315,7 @@ class CommandDispatcher:
except urlmarks.Error as e:
raise cmdexc.CommandError(str(e))
else:
msg = "Bookmarked {}!" if was_added else "Removed bookmark {}!"
msg = "Bookmarked {}" if was_added else "Removed bookmark {}"
message.info(msg.format(url.toDisplayString()))
@cmdutils.register(instance='command-dispatcher', scope='window',
@@ -1331,6 +1419,9 @@ class CommandDispatcher:
scope='window', window=self._win_id)
target = None
if dest is not None:
dest = downloads.transform_path(dest)
if dest is None:
raise cmdexc.CommandError("Invalid target filename")
target = downloads.FileDownloadTarget(dest)
tab = self._current_widget()
@@ -1368,19 +1459,22 @@ class CommandDispatcher:
if tab.data.viewing_source:
raise cmdexc.CommandError("Already viewing source!")
try:
current_url = self._current_url()
except cmdexc.CommandError as e:
message.error(str(e))
return
def show_source_cb(source):
"""Show source as soon as it's ready."""
lexer = pygments.lexers.HtmlLexer()
formatter = pygments.formatters.HtmlFormatter(full=True,
linenos='table')
formatter = pygments.formatters.HtmlFormatter(
full=True, linenos='table',
title='Source for {}'.format(current_url.toDisplayString()))
highlighted = pygments.highlight(source, lexer, formatter)
try:
current_url = self._current_url()
except cmdexc.CommandError as e:
message.error(str(e))
return
new_tab = self._tabbed_browser.tabopen(explicit=True)
new_tab.set_html(highlighted, current_url)
new_tab = self._tabbed_browser.tabopen()
new_tab.set_html(highlighted)
new_tab.data.viewing_source = True
tab.dump_async(show_source_cb)
@@ -1463,7 +1557,7 @@ class CommandDispatcher:
self._open(url, tab, bg, window)
@cmdutils.register(instance='command-dispatcher', scope='window')
def messages(self, level='error', plain=False, tab=False, bg=False,
def messages(self, level='info', plain=False, tab=False, bg=False,
window=False):
"""Show a log of past messages.
@@ -1496,6 +1590,7 @@ class CommandDispatcher:
if text is None:
message.error("Could not get text from the focused element.")
return
assert isinstance(text, str), text
ed = editor.ExternalEditor(self._tabbed_browser)
ed.editing_finished.connect(functools.partial(
@@ -1533,10 +1628,7 @@ class CommandDispatcher:
backend=usertypes.Backend.QtWebKit)
def paste_primary(self):
"""Paste the primary selection at cursor position."""
try:
self.insert_text(utils.get_clipboard(selection=True))
except utils.SelectionUnsupportedError:
self.insert_text(utils.get_clipboard())
self.insert_text(utils.get_clipboard(selection=True, fallback=True))
@cmdutils.register(instance='command-dispatcher', maxsplit=0,
scope='window')
@@ -1647,21 +1739,22 @@ class CommandDispatcher:
tab = self._current_widget()
tab.search.clear()
if not text:
return
options = {
'ignore_case': config.get('general', 'ignore-case'),
'reverse': reverse,
}
self._tabbed_browser.search_text = text
self._tabbed_browser.search_options = dict(options)
if text:
cb = functools.partial(self._search_cb, tab=tab,
old_scroll_pos=tab.scroller.pos_px(),
options=options, text=text, prev=False)
else:
cb = None
cb = functools.partial(self._search_cb, tab=tab,
old_scroll_pos=tab.scroller.pos_px(),
options=options, text=text, prev=False)
options['result_cb'] = cb
tab.search.search(text, **options)
@cmdutils.register(instance='command-dispatcher', hide=True,
@@ -1897,33 +1990,20 @@ class CommandDispatcher:
def debug_webaction(self, action, count=1):
"""Execute a webaction.
See http://doc.qt.io/qt-5/qwebpage.html#WebAction-enum for the
available actions.
Available actions:
http://doc.qt.io/archives/qt-5.5/qwebpage.html#WebAction-enum (WebKit)
http://doc.qt.io/qt-5/qwebenginepage.html#WebAction-enum (WebEngine)
Args:
action: The action to execute, e.g. MoveToNextChar.
count: How many times to repeat the action.
"""
tab = self._current_widget()
if tab.backend == usertypes.Backend.QtWebKit:
assert QWebPage is not None
member = getattr(QWebPage, action, None)
base = QWebPage.WebAction
elif tab.backend == usertypes.Backend.QtWebEngine:
assert QWebEnginePage is not None
member = getattr(QWebEnginePage, action, None)
base = QWebEnginePage.WebAction
if not isinstance(member, base):
raise cmdexc.CommandError("{} is not a valid web action!".format(
action))
for _ in range(count):
# This whole command is backend-specific anyways, so it makes no
# sense to introduce some API for this.
# pylint: disable=protected-access
tab._widget.triggerPageAction(member)
try:
tab.action.run_string(action)
except browsertab.WebTabError as e:
raise cmdexc.CommandError(str(e))
@cmdutils.register(instance='command-dispatcher', scope='window',
maxsplit=0, no_cmd_split=True)

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -19,11 +19,13 @@
"""Shared QtWebKit/QtWebEngine code for downloads."""
import re
import sys
import html
import os.path
import collections
import functools
import pathlib
import tempfile
import sip
@@ -161,6 +163,25 @@ def get_filename_question(*, suggested_filename, url, parent=None):
return q
def transform_path(path):
r"""Do platform-specific transformations, like changing E: to E:\.
Returns None if the path is invalid on the current platform.
"""
if sys.platform != "win32":
return path
path = utils.expand_windows_drive(path)
# Drive dependent working directories are not supported, e.g.
# E:filename is invalid
if re.match(r'[A-Z]:[^\\]', path, re.IGNORECASE):
return None
# Paths like COM1, ...
# See https://github.com/qutebrowser/qutebrowser/issues/82
if pathlib.Path(path).is_reserved():
return None
return path
class NoFilenameError(Exception):
"""Raised when we can't find out a filename in DownloadTarget."""
@@ -507,6 +528,14 @@ class AbstractDownloadItem(QObject):
"""Retry a failed download."""
raise NotImplementedError
@pyqtSlot()
def try_retry(self):
"""Try to retry a download and show an error if it's unsupported."""
try:
self.retry()
except UnsupportedOperationError as e:
message.error(str(e))
def _get_open_filename(self):
"""Get the filename to open a download.
@@ -529,7 +558,11 @@ class AbstractDownloadItem(QObject):
if filename is None: # pragma: no cover
log.downloads.error("No filename to open the download!")
return
utils.open_file(filename, cmdline)
# By using a singleshot timer, we ensure that we return fast. This
# is important on systems where process creation takes long, as
# otherwise the prompt might hang around and cause bugs
# (see issue #2296)
QTimer.singleShot(0, lambda: utils.open_file(filename, cmdline))
def _ensure_can_set_filename(self, filename):
"""Make sure we can still set a filename."""
@@ -919,7 +952,7 @@ class DownloadModel(QAbstractListModel):
@cmdutils.register(instance='download-model', scope='window', maxsplit=0)
@cmdutils.argument('count', count=True)
def download_open(self, cmdline: str=None, count=0):
def download_open(self, cmdline: str = None, count=0):
"""Open the last/[count]th download.
If no specific command is given, this will use the system's default
@@ -964,7 +997,7 @@ class DownloadModel(QAbstractListModel):
raise cmdexc.CommandError("No failed downloads!")
else:
download = to_retry[0]
download.retry()
download.try_retry()
def can_clear(self):
"""Check if there are finished downloads to clear."""

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -23,7 +23,7 @@ import functools
import sip
from PyQt5.QtCore import pyqtSlot, QSize, Qt, QTimer
from PyQt5.QtWidgets import QListView, QSizePolicy, QMenu
from PyQt5.QtWidgets import QListView, QSizePolicy, QMenu, QStyleFactory
from qutebrowser.browser import downloads
from qutebrowser.config import style
@@ -75,6 +75,7 @@ class DownloadView(QListView):
def __init__(self, win_id, parent=None):
super().__init__(parent)
self.setStyle(QStyleFactory.create('Fusion'))
style.set_register_stylesheet(self)
self.setResizeMode(QListView.Adjust)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
@@ -134,7 +135,7 @@ class DownloadView(QListView):
if item.successful:
actions.append(("Open", item.open_file))
else:
actions.append(("Retry", item.retry))
actions.append(("Retry", item.try_retry))
actions.append(("Remove", item.remove))
else:
actions.append(("Cancel", item.cancel))

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -579,12 +579,10 @@ class HintManager(QObject):
if elems is None:
message.error("There was an error while getting hint elements")
return
filterfunc = webelem.FILTERS.get(self._context.group, lambda e: True)
elems = [e for e in elems if filterfunc(e)]
if not elems:
message.error("No elements found.")
return
strings = self._hint_strings(elems)
log.hints.debug("hints: {}".format(', '.join(strings)))

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -27,7 +27,6 @@ from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, QObject
from qutebrowser.commands import cmdutils
from qutebrowser.utils import (utils, objreg, standarddir, log, qtutils,
usertypes, message)
from qutebrowser.config import config
from qutebrowser.misc import lineparser, objects
@@ -257,6 +256,12 @@ class WebHistory(QObject):
@pyqtSlot(QUrl, QUrl, str)
def add_from_tab(self, url, requested_url, title):
"""Add a new history entry as slot, called from a BrowserTab."""
if url.scheme() == 'data' or requested_url.scheme() == 'data':
return
if url.isEmpty():
# things set via setHtml
return
no_formatting = QUrl.UrlFormattingOption(0)
if (requested_url.isValid() and
not requested_url.matches(url, no_formatting)):
@@ -274,9 +279,9 @@ class WebHistory(QObject):
(hidden in completion)
atime: Override the atime used to add the entry
"""
if config.get('general', 'private-browsing'):
return
if not url.isValid():
if not url.isValid(): # pragma: no cover
# the no cover pragma is a WORKAROUND for this not being covered in
# old Qt versions.
log.misc.warning("Ignoring invalid URL being added to history")
return

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -79,8 +79,7 @@ def _find_prevnext(prev, elems):
return e
# Then check for regular links/buttons.
filterfunc = webelem.FILTERS[webelem.Group.prevnext]
elems = [e for e in elems if e.tag_name() != 'link' and filterfunc(e)]
elems = [e for e in elems if e.tag_name() != 'link']
option = 'prev-regexes' if prev else 'next-regexes'
if not elems:
return None
@@ -128,20 +127,21 @@ def prevnext(*, browsertab, win_id, baseurl, prev=False,
return
qtutils.ensure_valid(url)
cur_tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=win_id)
if window:
from qutebrowser.mainwindow import mainwindow
new_window = mainwindow.MainWindow()
new_window = mainwindow.MainWindow(
private=cur_tabbed_browser.private)
new_window.show()
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=new_window.win_id)
tabbed_browser.tabopen(url, background=False)
elif tab:
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=win_id)
tabbed_browser.tabopen(url, background=background)
cur_tabbed_browser.tabopen(url, background=background)
else:
browsertab.openurl(url)
selector = ', '.join([webelem.SELECTORS[webelem.Group.links],
webelem.SELECTORS[webelem.Group.prevnext]])
browsertab.elements.find_css(selector, _prevnext_cb)
browsertab.elements.find_css(webelem.SELECTORS[webelem.Group.links],
_prevnext_cb)

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -22,7 +22,7 @@
import sys
import functools
from PyQt5.QtCore import (QObject, pyqtSignal, pyqtSlot)
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, QUrl
from PyQt5.QtNetwork import (QNetworkProxy, QNetworkRequest, QHostInfo,
QNetworkReply, QNetworkAccessManager,
QHostAddress)
@@ -155,7 +155,7 @@ class PACResolver:
raise ParseProxyError("Invalid number of parameters for PROXY")
host, port = PACResolver._parse_proxy_host(config[1])
return QNetworkProxy(QNetworkProxy.HttpProxy, host, port)
elif config[0] == "SOCKS":
elif config[0] in ["SOCKS", "SOCKS5"]:
if len(config) != 2:
raise ParseProxyError("Invalid number of parameters for SOCKS")
host, port = PACResolver._parse_proxy_host(config[1])
@@ -199,16 +199,24 @@ class PACResolver:
err = "Cannot resolve FindProxyForURL function, got '{}' instead"
raise EvalProxyError(err.format(self._resolver.toString()))
def resolve(self, query):
def resolve(self, query, from_file=False):
"""Resolve a proxy via PAC.
Args:
query: QNetworkProxyQuery.
from_file: Whether the proxy info is coming from a file.
Return:
A list of QNetworkProxy objects in order of preference.
"""
result = self._resolver.call([query.url().toString(),
if from_file:
string_flags = QUrl.PrettyDecoded
else:
string_flags = QUrl.RemoveUserInfo
if query.url().scheme() == 'https':
string_flags |= QUrl.RemovePath | QUrl.RemoveQuery
result = self._resolver.call([query.url().toString(string_flags),
query.peerHostName()])
result_str = result.toString()
if not result.isString():
@@ -236,6 +244,7 @@ class PACFetcher(QObject):
assert url.scheme().startswith(pac_prefix)
url.setScheme(url.scheme()[len(pac_prefix):])
self._pac_url = url
self._manager = QNetworkAccessManager()
self._manager.setProxy(QNetworkProxy(QNetworkProxy.NoProxy))
self._reply = self._manager.get(QNetworkRequest(url))
@@ -292,8 +301,9 @@ class PACFetcher(QObject):
Return a list of QNetworkProxy objects in order of preference.
"""
self._wait()
from_file = self._pac_url.scheme() == 'file'
try:
return self._pac.resolve(query)
return self._pac.resolve(query, from_file=from_file)
except (EvalProxyError, ParseProxyError) as e:
log.network.exception("Error in PAC resolution: {}.".format(e))
# .invalid is guaranteed to be inaccessible in RFC 6761.
@@ -302,4 +312,4 @@ class PACFetcher(QObject):
# Later NetworkManager.createRequest will detect this and display
# an error message.
error_host = "pac-resolve-error.qutebrowser.invalid"
return QNetworkProxy(QNetworkProxy.HttpProxy, error_host, 9)
return [QNetworkProxy(QNetworkProxy.HttpProxy, error_host, 9)]

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,7 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015 Daniel Schadt
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -27,6 +27,7 @@ import collections
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QTimer
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
from qutebrowser.config import config
from qutebrowser.utils import message, usertypes, log, urlutils, utils
from qutebrowser.browser import downloads
from qutebrowser.browser.webkit import http
@@ -110,6 +111,9 @@ class DownloadItem(downloads.AbstractDownloadItem):
def _do_die(self):
"""Abort the download and emit an error."""
self._read_timer.stop()
if self._reply is None:
log.downloads.debug("Reply gone while dying")
return
self._reply.downloadProgress.disconnect()
self._reply.finished.disconnect()
self._reply.error.disconnect()
@@ -270,7 +274,7 @@ class DownloadItem(downloads.AbstractDownloadItem):
if self.fileobj is None or self._reply is None:
# No filename has been set yet (so we don't empty the buffer) or we
# got a readyRead after the reply was finished (which happens on
# qute:log for example).
# qute://log for example).
return
if not self._reply.isOpen():
raise OSError("Reply is closed!")
@@ -363,7 +367,8 @@ class DownloadManager(downloads.AbstractDownloadManager):
def __init__(self, win_id, parent=None):
super().__init__(parent)
self._networkmanager = networkmanager.NetworkManager(
win_id, None, self)
win_id=win_id, tab_id=None,
private=config.get('general', 'private-browsing'), parent=self)
@pyqtSlot('QUrl')
def get(self, url, *, user_agent=None, **kwargs):

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -17,23 +17,27 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""Backend-independent qute:* code.
"""Backend-independent qute://* code.
Module attributes:
pyeval_output: The output of the last :pyeval command.
_HANDLERS: The handlers registered via decorators.
"""
import json
import os
import sys
import time
import datetime
import urllib.parse
import datetime
import pkg_resources
from PyQt5.QtCore import QUrlQuery
from PyQt5.QtCore import QUrlQuery, QUrl
import qutebrowser
from qutebrowser.config import config
from qutebrowser.utils import (version, utils, jinja, log, message, docutils,
objreg)
objreg, usertypes, qtutils)
from qutebrowser.misc import objects
@@ -75,12 +79,25 @@ class QuteSchemeError(Exception):
super().__init__(errorstring)
class add_handler: # pylint: disable=invalid-name
class Redirect(Exception):
"""Decorator to register a qute:* URL handler.
"""Exception to signal a redirect should happen.
Attributes:
_name: The 'foo' part of qute:foo
url: The URL to redirect to, as a QUrl.
"""
def __init__(self, url):
super().__init__(url.toDisplayString())
self.url = url
class add_handler: # pylint: disable=invalid-name
"""Decorator to register a qute://* URL handler.
Attributes:
_name: The 'foo' part of qute://foo
backend: Limit which backends the handler can run with.
"""
@@ -103,7 +120,7 @@ class add_handler: # pylint: disable=invalid-name
def wrong_backend_handler(self, url):
"""Show an error page about using the invalid backend."""
html = jinja.render('error.html',
title="Error while opening qute:url",
title="Error while opening qute://url",
url=url.toDisplayString(),
error='{} is not available with this '
'backend'.format(url.toDisplayString()),
@@ -125,13 +142,19 @@ def data_for_url(url):
# A url like "qute:foo" is split as "scheme:path", not "scheme:host".
log.misc.debug("url: {}, path: {}, host {}".format(
url.toDisplayString(), path, host))
if path and not host:
new_url = QUrl()
new_url.setScheme('qute')
new_url.setHost(path)
new_url.setPath('/')
if new_url.host(): # path was a valid host
raise Redirect(new_url)
try:
handler = _HANDLERS[path]
handler = _HANDLERS[host]
except KeyError:
try:
handler = _HANDLERS[host]
except KeyError:
raise NoHandlerFound(url)
raise NoHandlerFound(url)
try:
mimetype, data = handler(url)
except OSError as e:
@@ -150,7 +173,7 @@ def data_for_url(url):
@add_handler('bookmarks')
def qute_bookmarks(_url):
"""Handler for qute:bookmarks. Display all quickmarks / bookmarks."""
"""Handler for qute://bookmarks. Display all quickmarks / bookmarks."""
bookmarks = sorted(objreg.get('bookmark-manager').marks.items(),
key=lambda x: x[1]) # Sort by title
quickmarks = sorted(objreg.get('quickmark-manager').marks.items(),
@@ -163,90 +186,160 @@ def qute_bookmarks(_url):
return 'text/html', html
@add_handler('history') # noqa
def qute_history(url):
"""Handler for qute:history. Display history."""
# Get current date from query parameter, if not given choose today.
curr_date = datetime.date.today()
try:
query_date = QUrlQuery(url).queryItemValue("date")
if query_date:
curr_date = datetime.datetime.strptime(query_date, "%Y-%m-%d")
curr_date = curr_date.date()
except ValueError:
log.misc.debug("Invalid date passed to qute:history: " + query_date)
def history_data(start_time): # noqa
"""Return history data
one_day = datetime.timedelta(days=1)
next_date = curr_date + one_day
prev_date = curr_date - one_day
Arguments:
start_time -- select history starting from this timestamp.
"""
def history_iter(start_time, reverse=False):
"""Iterate through the history and get items we're interested.
def history_iter(reverse):
"""Iterate through the history and get items we're interested in."""
curr_timestamp = time.mktime(curr_date.timetuple())
Arguments:
reverse -- whether to reverse the history_dict before iterating.
"""
history = objreg.get('web-history').history_dict.values()
if reverse:
history = reversed(history)
# when history_dict is not reversed, we need to keep track of last item
# so that we can yield its atime
last_item = None
# end is 24hrs earlier than start
end_time = start_time - 24*60*60
for item in history:
# If we can't apply the reverse performance trick below,
# at least continue as early as possible with old items.
# This gets us down from 550ms to 123ms with 500k old items on my
# machine.
if item.atime < curr_timestamp and not reverse:
continue
# Convert timestamp
try:
item_atime = datetime.datetime.fromtimestamp(item.atime)
except (ValueError, OSError, OverflowError):
log.misc.debug("Invalid timestamp {}.".format(item.atime))
continue
if reverse and item_atime.date() < curr_date:
# If we could reverse the history in-place, and this entry is
# older than today, only older entries will follow, so we can
# abort here.
return
# Skip items not on curr_date
# Skip redirects
# Skip qute:// links
is_internal = item.url.scheme() == 'qute'
is_not_today = item_atime.date() != curr_date
if item.redirect or is_internal or is_not_today:
if item.redirect or item.url.scheme() == 'qute':
continue
# Skip items out of time window
item_newer = item.atime > start_time
item_older = item.atime <= end_time
if reverse:
# history_dict is reversed, we are going back in history.
# so:
# abort if item is older than start_time+24hr
# skip if item is newer than start
if item_older:
yield {"next": int(item.atime)}
return
if item_newer:
continue
else:
# history_dict isn't reversed, we are going forward in history.
# so:
# abort if item is newer than start_time
# skip if item is older than start_time+24hrs
if item_older:
last_item = item
continue
if item_newer:
yield {"next": int(last_item.atime if last_item else -1)}
return
# Use item's url as title if there's no title.
item_url = item.url.toDisplayString()
item_title = item.title if item.title else item_url
display_atime = item_atime.strftime("%X")
item_time = int(item.atime * 1000)
yield (item_url, item_title, display_atime)
yield {"url": item_url, "title": item_title, "time": item_time}
# if we reached here, we had reached the end of history
yield {"next": int(last_item.atime if last_item else -1)}
if sys.hexversion >= 0x03050000:
# On Python >= 3.5 we can reverse the ordereddict in-place and thus
# apply an additional performance improvement in history_iter.
# On my machine, this gets us down from 550ms to 72us with 500k old
# items.
history = list(history_iter(reverse=True))
history = history_iter(start_time, reverse=True)
else:
# On Python 3.4, we can't do that, so we'd need to copy the entire
# history to a list. There, filter first and then reverse it here.
history = reversed(list(history_iter(reverse=False)))
history = reversed(list(history_iter(start_time, reverse=False)))
html = jinja.render('history.html',
title='History',
history=history,
curr_date=curr_date,
next_date=next_date,
prev_date=prev_date,
today=datetime.date.today())
return 'text/html', html
return list(history)
@add_handler('history')
def qute_history(url):
"""Handler for qute://history. Display and serve history."""
if url.path() == '/data':
# Use start_time in query or current time.
try:
start_time = QUrlQuery(url).queryItemValue("start_time")
start_time = float(start_time) if start_time else time.time()
except ValueError as e:
raise QuteSchemeError("Query parameter start_time is invalid", e)
return 'text/html', json.dumps(history_data(start_time))
else:
if (
config.get('content', 'allow-javascript') and
(objects.backend == usertypes.Backend.QtWebEngine or
qtutils.is_qtwebkit_ng())
):
return 'text/html', jinja.render(
'history.html',
title='History',
session_interval=config.get('ui', 'history-session-interval')
)
else:
# Get current date from query parameter, if not given choose today.
curr_date = datetime.date.today()
try:
query_date = QUrlQuery(url).queryItemValue("date")
if query_date:
curr_date = datetime.datetime.strptime(query_date,
"%Y-%m-%d").date()
except ValueError:
log.misc.debug("Invalid date passed to qute:history: " +
query_date)
one_day = datetime.timedelta(days=1)
next_date = curr_date + one_day
prev_date = curr_date - one_day
# start_time is the last second of curr_date
start_time = time.mktime(next_date.timetuple()) - 1
history = [
(i["url"], i["title"],
datetime.datetime.fromtimestamp(i["time"]/1000),
QUrl(i["url"]).host())
for i in history_data(start_time) if "next" not in i
]
return 'text/html', jinja.render(
'history_nojs.html',
title='History',
history=history,
curr_date=curr_date,
next_date=next_date,
prev_date=prev_date,
today=datetime.date.today(),
)
@add_handler('javascript')
def qute_javascript(url):
"""Handler for qute://javascript.
Return content of file given as query parameter.
"""
path = url.path()
if path:
path = "javascript" + os.sep.join(path.split('/'))
return 'text/html', utils.read_file(path, binary=False)
else:
raise QuteSchemeError("No file specified", ValueError())
@add_handler('pyeval')
def qute_pyeval(_url):
"""Handler for qute:pyeval."""
"""Handler for qute://pyeval."""
html = jinja.render('pre.html', title='pyeval', content=pyeval_output)
return 'text/html', html
@@ -254,7 +347,7 @@ def qute_pyeval(_url):
@add_handler('version')
@add_handler('verizon')
def qute_version(_url):
"""Handler for qute:version."""
"""Handler for qute://version."""
html = jinja.render('version.html', title='Version info',
version=version.version(),
copyright=qutebrowser.__copyright__)
@@ -263,7 +356,7 @@ def qute_version(_url):
@add_handler('plainlog')
def qute_plainlog(url):
"""Handler for qute:plainlog.
"""Handler for qute://plainlog.
An optional query parameter specifies the minimum log level to print.
For example, qute://log?level=warning prints warnings and errors.
@@ -283,7 +376,7 @@ def qute_plainlog(url):
@add_handler('log')
def qute_log(url):
"""Handler for qute:log.
"""Handler for qute://log.
An optional query parameter specifies the minimum log level to print.
For example, qute://log?level=warning prints warnings and errors.
@@ -304,13 +397,13 @@ def qute_log(url):
@add_handler('gpl')
def qute_gpl(_url):
"""Handler for qute:gpl. Return HTML content as string."""
"""Handler for qute://gpl. Return HTML content as string."""
return 'text/html', utils.read_file('html/COPYING.html')
@add_handler('help')
def qute_help(url):
"""Handler for qute:help."""
"""Handler for qute://help."""
try:
utils.read_file('html/doc/index.html')
except OSError:
@@ -339,3 +432,14 @@ def qute_help(url):
else:
data = utils.read_file(path)
return 'text/html', data
@add_handler('backend-warning')
def qute_backend_warning(_url):
"""Handler for qute://backend-warning."""
html = jinja.render('backend-warning.html',
distribution=version.distribution(),
Distribution=version.Distribution,
version=pkg_resources.parse_version,
title="Legacy backend warning")
return 'text/html', html

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -216,8 +216,10 @@ def get_tab(win_id, target):
win_id = win_id
bg_tab = True
elif target == usertypes.ClickTarget.window:
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=win_id)
from qutebrowser.mainwindow import mainwindow
window = mainwindow.MainWindow()
window = mainwindow.MainWindow(private=tabbed_browser.private)
window.show()
win_id = window.win_id
bg_tab = False

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,7 +1,7 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015-2016 Antoni Boucher <bouanto@zoho.com>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015-2017 Antoni Boucher <bouanto@zoho.com>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -22,9 +22,6 @@
Module attributes:
Group: Enum for different kinds of groups.
SELECTORS: CSS selectors for different groups of elements.
FILTERS: A dictionary of filter functions for the modes.
The filter for "links" filters javascript:-links and a-tags
without "href".
"""
import collections.abc
@@ -37,18 +34,16 @@ from qutebrowser.keyinput import modeman
from qutebrowser.utils import log, usertypes, utils, qtutils, objreg
Group = usertypes.enum('Group', ['all', 'links', 'images', 'url', 'prevnext',
'inputs'])
Group = usertypes.enum('Group', ['all', 'links', 'images', 'url', 'inputs'])
SELECTORS = {
Group.all: ('a, area, textarea, select, input:not([type=hidden]), button, '
'frame, iframe, link, [onclick], [onmousedown], [role=link], '
'[role=option], [role=button], img'),
Group.links: 'a, area, link, [role=link]',
Group.links: 'a[href], area[href], link[href], [role=link][href]',
Group.images: 'img',
Group.url: '[src], [href]',
Group.prevnext: 'a, area, button, link, [role=button]',
Group.inputs: ('input[type=text], input[type=email], input[type=url], '
'input[type=tel], input[type=number], '
'input[type=password], input[type=search], '
@@ -56,16 +51,6 @@ SELECTORS = {
}
def filter_links(elem):
return 'href' in elem and QUrl(elem['href']).scheme() != 'javascript'
FILTERS = {
Group.links: filter_links,
Group.prevnext: filter_links,
}
class Error(Exception):
"""Base class for WebElement errors."""
@@ -120,10 +105,6 @@ class AbstractWebElement(collections.abc.MutableMapping):
"""Get the geometry for this element."""
raise NotImplementedError
def style_property(self, name, *, strategy):
"""Get the element style resolved with the given strategy."""
raise NotImplementedError
def classes(self):
"""Get a list of classes assigned to this element."""
raise NotImplementedError
@@ -310,6 +291,11 @@ class AbstractWebElement(collections.abc.MutableMapping):
qtutils.ensure_valid(url)
return url
def is_link(self):
"""Return True if this AbstractWebElement is a link."""
href_tags = ['a', 'area', 'link']
return self.tag_name() in href_tags and 'href' in self
def _mouse_pos(self):
"""Get the position to click/hover."""
# Click the center of the largest square fitting into the top/left
@@ -326,6 +312,10 @@ class AbstractWebElement(collections.abc.MutableMapping):
raise Error("Element position is out of view!")
return pos
def _move_text_cursor(self):
"""Move cursor to end after clicking."""
raise NotImplementedError
def _click_fake_event(self, click_target):
"""Send a fake click event to the element."""
pos = self._mouse_pos()
@@ -356,11 +346,7 @@ class AbstractWebElement(collections.abc.MutableMapping):
for evt in events:
self._tab.send_event(evt)
def after_click():
"""Move cursor to end after clicking."""
if self.is_text_input() and self.is_editable():
self._tab.caret.move_to_end_of_document()
QTimer.singleShot(0, after_click)
QTimer.singleShot(0, self._move_text_cursor)
def _click_editable(self, click_target):
"""Fake a click on an editable input field."""
@@ -378,15 +364,16 @@ class AbstractWebElement(collections.abc.MutableMapping):
self._click_fake_event(click_target)
return
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=self._tab.win_id)
if click_target in [usertypes.ClickTarget.tab,
usertypes.ClickTarget.tab_bg]:
background = click_target == usertypes.ClickTarget.tab_bg
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=self._tab.win_id)
tabbed_browser.tabopen(url, background=background)
elif click_target == usertypes.ClickTarget.window:
from qutebrowser.mainwindow import mainwindow
window = mainwindow.MainWindow()
window = mainwindow.MainWindow(private=tabbed_browser.private)
window.show()
window.tabbed_browser.tabopen(url)
else:
@@ -407,9 +394,8 @@ class AbstractWebElement(collections.abc.MutableMapping):
self._click_fake_event(click_target)
return
href_tags = ['a', 'area', 'link']
if click_target == usertypes.ClickTarget.normal:
if self.tag_name() in href_tags:
if self.is_link():
log.webelem.debug("Clicking via JS click()")
self._click_js(click_target)
elif self.is_editable(strict=True):
@@ -422,7 +408,7 @@ class AbstractWebElement(collections.abc.MutableMapping):
elif click_target in [usertypes.ClickTarget.tab,
usertypes.ClickTarget.tab_bg,
usertypes.ClickTarget.window]:
if self.tag_name() in href_tags:
if self.is_link():
self._click_href(click_target)
else:
self._click_fake_event(click_target)

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -19,9 +19,7 @@
"""Wrapper over a QWebEngineCertificateError."""
# pylint: disable=no-name-in-module,import-error,useless-suppression
from PyQt5.QtWebEngineWidgets import QWebEngineCertificateError
# pylint: enable=no-name-in-module,import-error,useless-suppression
from qutebrowser.utils import usertypes, utils, debug

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -19,9 +19,7 @@
"""A request interceptor taking care of adblocking and custom headers."""
# pylint: disable=no-name-in-module,import-error,useless-suppression
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor
# pylint: enable=no-name-in-module,import-error,useless-suppression
from qutebrowser.config import config
from qutebrowser.browser import shared
@@ -57,8 +55,7 @@ class RequestInterceptor(QWebEngineUrlRequestInterceptor):
info: QWebEngineUrlRequestInfo &info
"""
# FIXME:qtwebengine only block ads for NavigationTypeOther?
if (bytes(info.requestMethod()) == b'GET' and
self._host_blocker.is_blocked(info.requestUrl())):
if self._host_blocker.is_blocked(info.requestUrl()):
log.webview.info("Request to {} blocked by host blocker.".format(
info.requestUrl().host()))
info.block(True)

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -25,9 +25,7 @@ import urllib
import functools
from PyQt5.QtCore import pyqtSlot, Qt
# pylint: disable=no-name-in-module,import-error,useless-suppression
from PyQt5.QtWebEngineWidgets import QWebEngineDownloadItem
# pylint: enable=no-name-in-module,import-error,useless-suppression
from qutebrowser.browser import downloads
from qutebrowser.utils import debug, usertypes, message, log, qtutils
@@ -78,32 +76,39 @@ class DownloadItem(downloads.AbstractDownloadItem):
self.stats.finish()
elif state == QWebEngineDownloadItem.DownloadInterrupted:
self.successful = False
self.done = True
# https://bugreports.qt.io/browse/QTBUG-56839
self.error.emit("Download failed")
self.stats.finish()
try:
reason = self._qt_item.interruptReasonString()
except AttributeError:
# Qt < 5.9
reason = "Download failed"
self._die(reason)
else:
raise ValueError("_on_state_changed was called with unknown state "
"{}".format(state_name))
def _do_die(self):
self._qt_item.downloadProgress.disconnect()
self._qt_item.cancel()
if self._qt_item.state() != QWebEngineDownloadItem.DownloadInterrupted:
self._qt_item.cancel()
def _do_cancel(self):
self._qt_item.cancel()
def retry(self):
# https://bugreports.qt.io/browse/QTBUG-56840
raise downloads.UnsupportedOperationError
raise downloads.UnsupportedOperationError(
"Retrying downloads is unsupported with QtWebEngine")
def _get_open_filename(self):
return self._filename
def _set_fileobj(self, fileobj):
def _set_fileobj(self, fileobj, *,
autoclose=True): # pylint: disable=unused-argument
raise downloads.UnsupportedOperationError
def _set_tempfile(self, fileobj):
fileobj.close()
self._set_filename(fileobj.name, force_overwrite=True,
remember_directory=False)
@@ -144,8 +149,8 @@ def _get_suggested_filename(path):
See https://bugreports.qt.io/browse/QTBUG-56978
"""
filename = os.path.basename(path)
filename = re.sub(r'\([0-9]+\)$', '', filename)
if not qtutils.version_check('5.8.1'):
filename = re.sub(r'\([0-9]+\)(?=\.|$)', '', filename)
if not qtutils.version_check('5.9'):
# https://bugreports.qt.io/browse/QTBUG-58155
filename = urllib.parse.unquote(filename)
# Doing basename a *second* time because there could be a %2F in

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -18,16 +18,14 @@
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# FIXME:qtwebengine remove this once the stubs are gone
# pylint: disable=unused-variable
# pylint: disable=unused-argument
"""QtWebEngine specific part of the web element API."""
from PyQt5.QtCore import QRect, Qt, QPoint, QEventLoop
from PyQt5.QtGui import QMouseEvent
from PyQt5.QtWidgets import QApplication
# pylint: disable=no-name-in-module,import-error,useless-suppression
from PyQt5.QtWebEngineWidgets import QWebEngineSettings
# pylint: enable=no-name-in-module,import-error,useless-suppression
from qutebrowser.utils import log, javascript
from qutebrowser.browser import webelem
@@ -39,6 +37,38 @@ class WebEngineElement(webelem.AbstractWebElement):
def __init__(self, js_dict, tab):
super().__init__(tab)
# Do some sanity checks on the data we get from JS
js_dict_types = {
'id': int,
'text': str,
'value': (str, int, float),
'tag_name': str,
'outer_xml': str,
'class_name': str,
'rects': list,
'attributes': dict,
}
assert set(js_dict.keys()).issubset(js_dict_types.keys())
for name, typ in js_dict_types.items():
if name in js_dict and not isinstance(js_dict[name], typ):
raise TypeError("Got {} for {} from JS but expected {}: "
"{}".format(type(js_dict[name]), name, typ,
js_dict))
for name, value in js_dict['attributes'].items():
if not isinstance(name, str):
raise TypeError("Got {} ({}) for attribute name from JS: "
"{}".format(name, type(name), js_dict))
if not isinstance(value, str):
raise TypeError("Got {} ({}) for attribute {} from JS: "
"{}".format(value, type(value), name, js_dict))
for rect in js_dict['rects']:
assert set(rect.keys()) == {'top', 'right', 'bottom', 'left',
'height', 'width'}, rect.keys()
for value in rect.values():
if not isinstance(value, (int, float)):
raise TypeError("Got {} ({}) for rect from JS: "
"{}".format(value, type(value), js_dict))
self._id = js_dict['id']
self._js_dict = js_dict
@@ -56,9 +86,7 @@ class WebEngineElement(webelem.AbstractWebElement):
def __setitem__(self, key, val):
self._js_dict['attributes'][key] = val
js_code = javascript.assemble('webelem', 'set_attribute', self._id,
key, val)
self._tab.run_js_async(js_code)
self._js_call('set_attribute', key, val)
def __delitem__(self, key):
log.stub()
@@ -69,6 +97,11 @@ class WebEngineElement(webelem.AbstractWebElement):
def __len__(self):
return len(self._js_dict['attributes'])
def _js_call(self, name, *args, callback=None):
"""Wrapper to run stuff from webelem.js."""
js_code = javascript.assemble('webelem', name, self._id, *args)
self._tab.run_js_async(js_code, callback=callback)
def has_frame(self):
return True
@@ -76,10 +109,6 @@ class WebEngineElement(webelem.AbstractWebElement):
log.stub()
return QRect()
def style_property(self, name, *, strategy):
log.stub()
return ''
def classes(self):
"""Get a list of classes assigned to this element."""
return self._js_dict['class_name'].split()
@@ -89,7 +118,9 @@ class WebEngineElement(webelem.AbstractWebElement):
The returned name will always be lower-case.
"""
return self._js_dict['tag_name'].lower()
tag = self._js_dict['tag_name']
assert isinstance(tag, str), tag
return tag.lower()
def outer_xml(self):
"""Get the full HTML representation of this element."""
@@ -99,15 +130,13 @@ class WebEngineElement(webelem.AbstractWebElement):
return self._js_dict.get('value', None)
def set_value(self, value):
js_code = javascript.assemble('webelem', 'set_value', self._id, value)
self._tab.run_js_async(js_code)
self._js_call('set_value', value)
def insert_text(self, text):
if not self.is_editable(strict=True):
raise webelem.Error("Element is not editable!")
log.webelem.debug("Inserting text into element {!r}".format(self))
js_code = javascript.assemble('webelem', 'insert_text', self._id, text)
self._tab.run_js_async(js_code)
self._js_call('insert_text', text)
def rect_on_view(self, *, elem_geometry=None, no_js=False):
"""Get the geometry of the element relative to the webview.
@@ -153,27 +182,27 @@ class WebEngineElement(webelem.AbstractWebElement):
def remove_blank_target(self):
if self._js_dict['attributes'].get('target') == '_blank':
self._js_dict['attributes']['target'] = '_top'
js_code = javascript.assemble('webelem', 'remove_blank_target',
self._id)
self._tab.run_js_async(js_code)
self._js_call('remove_blank_target')
def _move_text_cursor(self):
if self.is_text_input() and self.is_editable():
self._js_call('move_cursor_to_end')
def _click_editable(self, click_target):
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-58515
# pylint doesn't know about Qt.MouseEventSynthesizedBySystem
# because it was added in Qt 5.6, but we can be sure we use that with
# QtWebEngine.
# pylint: disable=no-member
ev = QMouseEvent(QMouseEvent.MouseButtonPress, QPoint(0, 0),
QPoint(0, 0), QPoint(0, 0), Qt.NoButton, Qt.NoButton,
Qt.NoModifier, Qt.MouseEventSynthesizedBySystem)
# pylint: enable=no-member
self._tab.send_event(ev)
# This actually "clicks" the element by calling focus() on it in JS.
js_code = javascript.assemble('webelem', 'focus', self._id)
self._tab.run_js_async(js_code)
self._js_call('focus')
self._move_text_cursor()
def _click_js(self, _click_target):
settings = QWebEngineSettings.globalSettings()
# FIXME:qtwebengine Have a proper API for this
# pylint: disable=protected-access
settings = self._tab._widget.settings()
# pylint: enable=protected-access
attribute = QWebEngineSettings.JavascriptCanOpenWindows
could_open_windows = settings.testAttribute(attribute)
settings.setAttribute(attribute, True)
@@ -189,5 +218,4 @@ class WebEngineElement(webelem.AbstractWebElement):
def reset_setting(_arg):
settings.setAttribute(attribute, could_open_windows)
js_code = javascript.assemble('webelem', 'click', self._id)
self._tab.run_js_async(js_code, reset_setting)
self._js_call('click', callback=reset_setting)

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -22,9 +22,7 @@
import os
from PyQt5.QtCore import QUrl
# pylint: disable=no-name-in-module,import-error,useless-suppression
from PyQt5.QtWebEngineWidgets import QWebEngineView
# pylint: enable=no-name-in-module,import-error,useless-suppression
from qutebrowser.browser import inspector

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -17,24 +17,22 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""QtWebEngine specific qute:* handlers and glue code."""
"""QtWebEngine specific qute://* handlers and glue code."""
from PyQt5.QtCore import QBuffer, QIODevice
# pylint: disable=no-name-in-module,import-error,useless-suppression
from PyQt5.QtWebEngineCore import (QWebEngineUrlSchemeHandler,
QWebEngineUrlRequestJob)
# pylint: enable=no-name-in-module,import-error,useless-suppression
from qutebrowser.browser import qutescheme
from qutebrowser.utils import log
from qutebrowser.utils import log, qtutils
class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
"""Handle qute:* requests on QtWebEngine."""
"""Handle qute://* requests on QtWebEngine."""
def install(self, profile):
"""Install the handler for qute: URLs on the given profile."""
"""Install the handler for qute:// URLs on the given profile."""
profile.installUrlSchemeHandler(b'qute', self)
def requestStarted(self, job):
@@ -58,12 +56,15 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
job.fail(QWebEngineUrlRequestJob.UrlNotFound)
except qutescheme.QuteSchemeOSError:
# FIXME:qtwebengine how do we show a better error here?
log.misc.exception("OSError while handling qute:* URL")
log.misc.exception("OSError while handling qute://* URL")
job.fail(QWebEngineUrlRequestJob.UrlNotFound)
except qutescheme.QuteSchemeError:
# FIXME:qtwebengine how do we show a better error here?
log.misc.exception("Error while handling qute:* URL")
log.misc.exception("Error while handling qute://* URL")
job.fail(QWebEngineUrlRequestJob.RequestFailed)
except qutescheme.Redirect as e:
qtutils.ensure_valid(e.url)
job.redirect(e.url)
else:
log.misc.debug("Returning {} data".format(mimetype))

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -17,6 +17,9 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# We get various "abstract but not overridden" warnings
# pylint: disable=abstract-method
"""Bridge from QWebEngineSettings to our own settings.
Module attributes:
@@ -25,80 +28,99 @@ Module attributes:
"""
import os
import sys
import ctypes
import ctypes.util
# pylint: disable=no-name-in-module,import-error,useless-suppression
from PyQt5.QtGui import QFont
from PyQt5.QtWebEngineWidgets import (QWebEngineSettings, QWebEngineProfile,
QWebEngineScript)
# pylint: enable=no-name-in-module,import-error,useless-suppression
from qutebrowser.browser import shared
from qutebrowser.config import config, websettings
from qutebrowser.utils import objreg, utils, standarddir, javascript
from qutebrowser.utils import objreg, utils, standarddir, javascript, qtutils
class Attribute(websettings.Attribute):
# The default QWebEngineProfile
default_profile = None
# The QWebEngineProfile used for private (off-the-record) windows
private_profile = None
class Base(websettings.Base):
"""Base settings class with appropriate _get_global_settings."""
def _get_global_settings(self):
return [default_profile.settings(), private_profile.settings()]
class Attribute(Base, websettings.Attribute):
"""A setting set via QWebEngineSettings::setAttribute."""
GLOBAL_SETTINGS = QWebEngineSettings.globalSettings
ENUM_BASE = QWebEngineSettings
class Setter(websettings.Setter):
class Setter(Base, websettings.Setter):
"""A setting set via QWebEngineSettings getter/setter methods."""
"""A setting set via a QWebEngineSettings setter method."""
GLOBAL_SETTINGS = QWebEngineSettings.globalSettings
pass
class NullStringSetter(websettings.NullStringSetter):
class FontFamilySetter(Base, websettings.FontFamilySetter):
"""A setter for settings requiring a null QString as default."""
"""A setter for a font family.
GLOBAL_SETTINGS = QWebEngineSettings.globalSettings
Gets the default value from QFont.
"""
def __init__(self, font):
# Mapping from WebEngineSettings::initDefaults in
# qtwebengine/src/core/web_engine_settings.cpp
font_to_qfont = {
QWebEngineSettings.StandardFont: QFont.Serif,
QWebEngineSettings.FixedFont: QFont.Monospace,
QWebEngineSettings.SerifFont: QFont.Serif,
QWebEngineSettings.SansSerifFont: QFont.SansSerif,
QWebEngineSettings.CursiveFont: QFont.Cursive,
QWebEngineSettings.FantasyFont: QFont.Fantasy,
}
super().__init__(setter=QWebEngineSettings.setFontFamily, font=font,
qfont=font_to_qfont[font])
class StaticSetter(websettings.StaticSetter):
"""A setting set via static QWebEngineSettings getter/setter methods."""
GLOBAL_SETTINGS = QWebEngineSettings.globalSettings
class ProfileSetter(websettings.Base):
class DefaultProfileSetter(websettings.Base):
"""A setting set on the QWebEngineProfile."""
def __init__(self, getter, setter):
super().__init__()
self._getter = getter
def __init__(self, setter, default=websettings.UNSET):
super().__init__(default)
self._setter = setter
def get(self, settings=None):
utils.unused(settings)
getter = getattr(QWebEngineProfile.defaultProfile(), self._getter)
return getter()
def __repr__(self):
return utils.get_repr(self, setter=self._setter, constructor=True)
def _set(self, value, settings=None):
utils.unused(settings)
setter = getattr(QWebEngineProfile.defaultProfile(), self._setter)
if settings is not None:
raise ValueError("'settings' may not be set with "
"DefaultProfileSetters!")
setter = getattr(default_profile, self._setter)
setter(value)
class PersistentCookiePolicy(ProfileSetter):
class PersistentCookiePolicy(DefaultProfileSetter):
"""The cookies -> store setting is different from other settings."""
def __init__(self):
super().__init__(getter='persistentCookiesPolicy',
setter='setPersistentCookiesPolicy')
def get(self, settings=None):
utils.unused(settings)
return config.get('content', 'cookies-store')
super().__init__('setPersistentCookiesPolicy')
def _set(self, value, settings=None):
utils.unused(settings)
if settings is not None:
raise ValueError("'settings' may not be set with "
"PersistentCookiePolicy!")
setter = getattr(QWebEngineProfile.defaultProfile(), self._setter)
setter(
QWebEngineProfile.AllowPersistentCookies if value else
@@ -112,9 +134,6 @@ def _init_stylesheet(profile):
Mostly inspired by QupZilla:
https://github.com/QupZilla/qupzilla/blob/v2.0/src/lib/app/mainapplication.cpp#L1063-L1101
https://github.com/QupZilla/qupzilla/blob/v2.0/src/lib/tools/scripts.cpp#L119-L132
FIXME:qtwebengine Use QWebEngineStyleSheet once that's available
https://codereview.qt-project.org/#/c/148671/
"""
old_script = profile.scripts().findScript('_qute_stylesheet')
if not old_script.isNull():
@@ -139,19 +158,43 @@ def _init_stylesheet(profile):
profile.scripts().insert(script)
def _init_profile(profile):
"""Initialize settings set on the QWebEngineProfile."""
profile.setCachePath(os.path.join(standarddir.cache(), 'webengine'))
profile.setPersistentStoragePath(
os.path.join(standarddir.data(), 'webengine'))
def _set_user_agent(profile):
"""Set the user agent for the given profile.
We override this per request in the URL interceptor (to allow for
per-domain user agents), but this one still gets used for things like
window.navigator.userAgent in JS.
"""
user_agent = config.get('network', 'user-agent')
profile.setHttpUserAgent(user_agent)
def update_settings(section, option):
"""Update global settings when qwebsettings changed."""
websettings.update_mappings(MAPPINGS, section, option)
profile = QWebEngineProfile.defaultProfile()
if section == 'ui' and option in ['hide-scrollbar', 'user-stylesheet']:
_init_stylesheet(profile)
_init_stylesheet(default_profile)
_init_stylesheet(private_profile)
elif section == 'network' and option == 'user-agent':
_set_user_agent(default_profile)
_set_user_agent(private_profile)
def _init_profiles():
"""Init the two used QWebEngineProfiles."""
global default_profile, private_profile
default_profile = QWebEngineProfile.defaultProfile()
default_profile.setCachePath(
os.path.join(standarddir.cache(), 'webengine'))
default_profile.setPersistentStoragePath(
os.path.join(standarddir.data(), 'webengine'))
_init_stylesheet(default_profile)
_set_user_agent(default_profile)
private_profile = QWebEngineProfile()
assert private_profile.isOffTheRecord()
_init_stylesheet(private_profile)
_set_user_agent(private_profile)
def init(args):
@@ -159,13 +202,17 @@ def init(args):
if args.enable_webengine_inspector:
os.environ['QTWEBENGINE_REMOTE_DEBUGGING'] = str(utils.random_port())
profile = QWebEngineProfile.defaultProfile()
_init_profile(profile)
_init_stylesheet(profile)
# WORKAROUND for
# https://bugs.launchpad.net/ubuntu/+source/python-qt4/+bug/941826
if sys.platform == 'linux':
ctypes.CDLL(ctypes.util.find_library("GL"), mode=ctypes.RTLD_GLOBAL)
_init_profiles()
# We need to do this here as a WORKAROUND for
# https://bugreports.qt.io/browse/QTBUG-58650
PersistentCookiePolicy().set(config.get('content', 'cookies-store'))
if not qtutils.version_check('5.9'):
PersistentCookiePolicy().set(config.get('content', 'cookies-store'))
Attribute(QWebEngineSettings.FullScreenSupportEnabled).set(True)
websettings.init_mappings(MAPPINGS)
@@ -186,7 +233,6 @@ def shutdown():
# - AllowRunningInsecureContent (5.8)
#
# Missing QtWebEngine fonts:
# - FantasyFont
# - PictographFont
@@ -208,9 +254,6 @@ MAPPINGS = {
Attribute(QWebEngineSettings.LocalContentCanAccessRemoteUrls),
'local-content-can-access-file-urls':
Attribute(QWebEngineSettings.LocalContentCanAccessFileUrls),
# https://bugreports.qt.io/browse/QTBUG-58650
# 'cookies-store':
# PersistentCookiePolicy(),
'webgl':
Attribute(QWebEngineSettings.WebGLEnabled),
},
@@ -222,44 +265,28 @@ MAPPINGS = {
},
'fonts': {
'web-family-standard':
Setter(getter=QWebEngineSettings.fontFamily,
setter=QWebEngineSettings.setFontFamily,
args=[QWebEngineSettings.StandardFont]),
FontFamilySetter(QWebEngineSettings.StandardFont),
'web-family-fixed':
Setter(getter=QWebEngineSettings.fontFamily,
setter=QWebEngineSettings.setFontFamily,
args=[QWebEngineSettings.FixedFont]),
FontFamilySetter(QWebEngineSettings.FixedFont),
'web-family-serif':
Setter(getter=QWebEngineSettings.fontFamily,
setter=QWebEngineSettings.setFontFamily,
args=[QWebEngineSettings.SerifFont]),
FontFamilySetter(QWebEngineSettings.SerifFont),
'web-family-sans-serif':
Setter(getter=QWebEngineSettings.fontFamily,
setter=QWebEngineSettings.setFontFamily,
args=[QWebEngineSettings.SansSerifFont]),
FontFamilySetter(QWebEngineSettings.SansSerifFont),
'web-family-cursive':
Setter(getter=QWebEngineSettings.fontFamily,
setter=QWebEngineSettings.setFontFamily,
args=[QWebEngineSettings.CursiveFont]),
FontFamilySetter(QWebEngineSettings.CursiveFont),
'web-family-fantasy':
Setter(getter=QWebEngineSettings.fontFamily,
setter=QWebEngineSettings.setFontFamily,
args=[QWebEngineSettings.FantasyFont]),
FontFamilySetter(QWebEngineSettings.FantasyFont),
'web-size-minimum':
Setter(getter=QWebEngineSettings.fontSize,
setter=QWebEngineSettings.setFontSize,
Setter(QWebEngineSettings.setFontSize,
args=[QWebEngineSettings.MinimumFontSize]),
'web-size-minimum-logical':
Setter(getter=QWebEngineSettings.fontSize,
setter=QWebEngineSettings.setFontSize,
Setter(QWebEngineSettings.setFontSize,
args=[QWebEngineSettings.MinimumLogicalFontSize]),
'web-size-default':
Setter(getter=QWebEngineSettings.fontSize,
setter=QWebEngineSettings.setFontSize,
Setter(QWebEngineSettings.setFontSize,
args=[QWebEngineSettings.DefaultFontSize]),
'web-size-default-fixed':
Setter(getter=QWebEngineSettings.fontSize,
setter=QWebEngineSettings.setFontSize,
Setter(QWebEngineSettings.setFontSize,
args=[QWebEngineSettings.DefaultFixedFontSize]),
},
'ui': {
@@ -270,15 +297,14 @@ MAPPINGS = {
'local-storage':
Attribute(QWebEngineSettings.LocalStorageEnabled),
'cache-size':
ProfileSetter(getter='httpCacheMaximumSize',
setter='setHttpCacheMaximumSize')
# 0: automatically managed by QtWebEngine
DefaultProfileSetter('setHttpCacheMaximumSize', default=0),
},
'general': {
'xss-auditing':
Attribute(QWebEngineSettings.XSSAuditingEnabled),
'default-encoding':
Setter(getter=QWebEngineSettings.defaultTextEncoding,
setter=QWebEngineSettings.setDefaultTextEncoding),
Setter(QWebEngineSettings.setDefaultTextEncoding),
}
}
@@ -288,3 +314,8 @@ try:
except AttributeError:
# Added in Qt 5.8
pass
if qtutils.version_check('5.9'):
# https://bugreports.qt.io/browse/QTBUG-58650
MAPPINGS['content']['cookies-store'] = PersistentCookiePolicy()

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -17,30 +17,27 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# FIXME:qtwebengine remove this once the stubs are gone
# pylint: disable=unused-variable
"""Wrapper over a QWebEngineView."""
import os
import math
import functools
import sip
from PyQt5.QtCore import pyqtSlot, Qt, QEvent, QPoint, QUrl, QTimer
from PyQt5.QtGui import QKeyEvent
from PyQt5.QtNetwork import QAuthenticator
# pylint: disable=no-name-in-module,import-error,useless-suppression
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import (QWebEnginePage, QWebEngineScript,
QWebEngineProfile)
# pylint: enable=no-name-in-module,import-error,useless-suppression
from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineScript
from qutebrowser.browser import browsertab, mouse, shared
from qutebrowser.browser.webengine import (webview, webengineelem, tabhistory,
interceptor, webenginequtescheme,
webenginedownloads)
webenginedownloads,
webenginesettings)
from qutebrowser.misc import miscwidgets
from qutebrowser.utils import (usertypes, qtutils, log, javascript, utils,
objreg, jinja)
objreg, jinja, debug, version)
_qute_scheme_handler = None
@@ -53,21 +50,31 @@ def init():
# https://www.riverbankcomputing.com/pipermail/pyqt/2016-September/038075.html
global _qute_scheme_handler
app = QApplication.instance()
profile = QWebEngineProfile.defaultProfile()
log.init.debug("Initializing qute:* handler...")
software_rendering = (os.environ.get('LIBGL_ALWAYS_SOFTWARE') == '1' or
'QT_XCB_FORCE_SOFTWARE_OPENGL' in os.environ)
if version.opengl_vendor() == 'nouveau' and not software_rendering:
# FIXME:qtwebengine display something more sophisticated here
raise browsertab.WebTabError(
"QtWebEngine is not supported with Nouveau graphics (unless "
"QT_XCB_FORCE_SOFTWARE_OPENGL is set as environment variable).")
log.init.debug("Initializing qute://* handler...")
_qute_scheme_handler = webenginequtescheme.QuteSchemeHandler(parent=app)
_qute_scheme_handler.install(profile)
_qute_scheme_handler.install(webenginesettings.default_profile)
_qute_scheme_handler.install(webenginesettings.private_profile)
log.init.debug("Initializing request interceptor...")
host_blocker = objreg.get('host-blocker')
req_interceptor = interceptor.RequestInterceptor(
host_blocker, parent=app)
req_interceptor.install(profile)
req_interceptor.install(webenginesettings.default_profile)
req_interceptor.install(webenginesettings.private_profile)
log.init.debug("Initializing QtWebEngine downloads...")
download_manager = webenginedownloads.DownloadManager(parent=app)
download_manager.install(profile)
download_manager.install(webenginesettings.default_profile)
download_manager.install(webenginesettings.private_profile)
objreg.register('webengine-download-manager', download_manager)
@@ -82,17 +89,17 @@ _JS_WORLD_MAP = {
class WebEngineAction(browsertab.AbstractAction):
"""QtWebKit implementations related to web actions."""
"""QtWebEngine implementations related to web actions."""
def _action(self, action):
self._widget.triggerPageAction(action)
action_class = QWebEnginePage
action_base = QWebEnginePage.WebAction
def exit_fullscreen(self):
self._action(QWebEnginePage.ExitFullScreen)
self._widget.triggerPageAction(QWebEnginePage.ExitFullScreen)
def save_page(self):
"""Save the current page."""
self._action(QWebEnginePage.SavePage)
self._widget.triggerPageAction(QWebEnginePage.SavePage)
class WebEnginePrinting(browsertab.AbstractPrinting):
@@ -128,12 +135,23 @@ class WebEngineSearch(browsertab.AbstractSearch):
super().__init__(parent)
self._flags = QWebEnginePage.FindFlags(0)
def _find(self, text, flags, cb=None):
"""Call findText on the widget with optional callback."""
if cb is None:
self._widget.findText(text, flags)
else:
self._widget.findText(text, flags, cb)
def _find(self, text, flags, callback, caller):
"""Call findText on the widget."""
self.search_displayed = True
def wrapped_callback(found):
"""Wrap the callback to do debug logging."""
found_text = 'found' if found else "didn't find"
if flags:
flag_text = 'with flags {}'.format(debug.qflags_key(
QWebEnginePage, flags, klass=QWebEnginePage.FindFlag))
else:
flag_text = ''
log.webview.debug(' '.join([caller, found_text, text, flag_text])
.strip())
if callback is not None:
callback(found)
self._widget.findText(text, flags, wrapped_callback)
def search(self, text, *, ignore_case=False, reverse=False,
result_cb=None):
@@ -148,9 +166,10 @@ class WebEngineSearch(browsertab.AbstractSearch):
self.text = text
self._flags = flags
self._find(text, flags, result_cb)
self._find(text, flags, result_cb, 'search')
def clear(self):
self.search_displayed = False
self._widget.findText('')
def prev_result(self, *, result_cb=None):
@@ -160,10 +179,10 @@ class WebEngineSearch(browsertab.AbstractSearch):
flags &= ~QWebEnginePage.FindBackward
else:
flags |= QWebEnginePage.FindBackward
self._find(self.text, flags, result_cb)
self._find(self.text, flags, result_cb, 'prev_result')
def next_result(self, *, result_cb=None):
self._find(self.text, self._flags, result_cb)
self._find(self.text, self._flags, result_cb, 'next_result')
class WebEngineCaret(browsertab.AbstractCaret):
@@ -237,8 +256,47 @@ class WebEngineCaret(browsertab.AbstractCaret):
raise browsertab.UnsupportedOperationError
return self._widget.selectedText()
def _follow_selected_cb(self, js_elem, tab=False):
"""Callback for javascript which clicks the selected element.
Args:
js_elem: The element serialized from javascript.
tab: Open in a new tab.
"""
if js_elem is None:
return
assert isinstance(js_elem, dict), js_elem
elem = webengineelem.WebEngineElement(js_elem, tab=self._tab)
if tab:
click_type = usertypes.ClickTarget.tab
else:
click_type = usertypes.ClickTarget.normal
# Only click if we see a link
if elem.is_link():
log.webview.debug("Found link in selection, clicking. ClickTarget "
"{}, elem {}".format(click_type, elem))
elem.click(click_type)
def follow_selected(self, *, tab=False):
log.stub()
if self._tab.search.search_displayed:
# We are currently in search mode.
# let's click the link via a fake-click
# https://bugreports.qt.io/browse/QTBUG-60673
self._tab.search.clear()
log.webview.debug("Clicking a searched link via fake key press.")
# send a fake enter, clicking the orange selection box
if tab:
self._tab.key_press(Qt.Key_Enter, modifier=Qt.ControlModifier)
else:
self._tab.key_press(Qt.Key_Enter)
else:
# click an existing blue selection
js_code = javascript.assemble('webelem', 'find_selected_link')
self._tab.run_js_async(js_code, lambda jsret:
self._follow_selected_cb(jsret, tab))
class WebEngineScroller(browsertab.AbstractScroller):
@@ -256,13 +314,10 @@ class WebEngineScroller(browsertab.AbstractScroller):
page = widget.page()
page.scrollPositionChanged.connect(self._update_pos)
def _key_press(self, key, count=1):
def _repeated_key_press(self, key, count=1, modifier=Qt.NoModifier):
"""Send count fake key presses to this scroller's WebEngineTab."""
for _ in range(min(count, 5000)):
press_evt = QKeyEvent(QEvent.KeyPress, key, Qt.NoModifier, 0, 0, 0)
release_evt = QKeyEvent(QEvent.KeyRelease, key, Qt.NoModifier,
0, 0, 0)
self._tab.send_event(press_evt)
self._tab.send_event(release_evt)
self._tab.key_press(key, modifier)
@pyqtSlot()
def _update_pos(self):
@@ -289,7 +344,7 @@ class WebEngineScroller(browsertab.AbstractScroller):
else:
perc_y = min(100, round(100 / dy * jsret['px']['y']))
self._at_bottom = dy >= jsret['px']['y']
self._at_bottom = math.ceil(jsret['px']['y']) >= dy
self._pos_perc = perc_x, perc_y
self.perc_changed.emit(*self._pos_perc)
@@ -319,28 +374,28 @@ class WebEngineScroller(browsertab.AbstractScroller):
self._tab.run_js_async(js_code)
def up(self, count=1):
self._key_press(Qt.Key_Up, count)
self._repeated_key_press(Qt.Key_Up, count)
def down(self, count=1):
self._key_press(Qt.Key_Down, count)
self._repeated_key_press(Qt.Key_Down, count)
def left(self, count=1):
self._key_press(Qt.Key_Left, count)
self._repeated_key_press(Qt.Key_Left, count)
def right(self, count=1):
self._key_press(Qt.Key_Right, count)
self._repeated_key_press(Qt.Key_Right, count)
def top(self):
self._key_press(Qt.Key_Home)
self._tab.key_press(Qt.Key_Home)
def bottom(self):
self._key_press(Qt.Key_End)
self._tab.key_press(Qt.Key_End)
def page_up(self, count=1):
self._key_press(Qt.Key_PageUp, count)
self._repeated_key_press(Qt.Key_PageUp, count)
def page_down(self, count=1):
self._key_press(Qt.Key_PageDown, count)
self._repeated_key_press(Qt.Key_PageDown, count)
def at_top(self):
return self.pos_px().y() == 0
@@ -369,11 +424,15 @@ class WebEngineHistory(browsertab.AbstractHistory):
return self._history.canGoForward()
def serialize(self):
# WORKAROUND for https://github.com/qutebrowser/qutebrowser/issues/2289
# FIXME:qtwebengine can we get rid of this with Qt 5.8.1?
scheme = self._history.currentItem().url().scheme()
if scheme in ['view-source', 'chrome']:
raise browsertab.WebTabError("Can't serialize special URL!")
if not qtutils.version_check('5.9'):
# WORKAROUND for
# https://github.com/qutebrowser/qutebrowser/issues/2289
# Don't use the history's currentItem here, because of
# https://bugreports.qt.io/browse/QTBUG-59599 and because it doesn't
# contain view-source.
scheme = self._tab.url().scheme()
if scheme in ['view-source', 'chrome']:
raise browsertab.WebTabError("Can't serialize special URL!")
return qtutils.serialize(self._history)
def deserialize(self, data):
@@ -443,18 +502,18 @@ class WebEngineElements(browsertab.AbstractElements):
callback(elem)
def find_css(self, selector, callback, *, only_visible=False):
js_code = javascript.assemble('webelem', 'find_all', selector,
js_code = javascript.assemble('webelem', 'find_css', selector,
only_visible)
js_cb = functools.partial(self._js_cb_multiple, callback)
self._tab.run_js_async(js_code, js_cb)
def find_id(self, elem_id, callback):
js_code = javascript.assemble('webelem', 'element_by_id', elem_id)
js_code = javascript.assemble('webelem', 'find_id', elem_id)
js_cb = functools.partial(self._js_cb_single, callback)
self._tab.run_js_async(js_code, js_cb)
def find_focused(self, callback):
js_code = javascript.assemble('webelem', 'focus_element')
js_code = javascript.assemble('webelem', 'find_focused')
js_cb = functools.partial(self._js_cb_single, callback)
self._tab.run_js_async(js_code, js_cb)
@@ -462,7 +521,7 @@ class WebEngineElements(browsertab.AbstractElements):
assert pos.x() >= 0
assert pos.y() >= 0
pos /= self._tab.zoom.factor()
js_code = javascript.assemble('webelem', 'element_at_pos',
js_code = javascript.assemble('webelem', 'find_at_pos',
pos.x(), pos.y())
js_cb = functools.partial(self._js_cb_single, callback)
self._tab.run_js_async(js_code, js_cb)
@@ -472,10 +531,11 @@ class WebEngineTab(browsertab.AbstractTab):
"""A QtWebEngine tab in the browser."""
def __init__(self, win_id, mode_manager, parent=None):
def __init__(self, *, win_id, mode_manager, private, parent=None):
super().__init__(win_id=win_id, mode_manager=mode_manager,
parent=parent)
widget = webview.WebEngineView(tabdata=self.data, win_id=win_id)
private=private, parent=parent)
widget = webview.WebEngineView(tabdata=self.data, win_id=win_id,
private=private)
self.history = WebEngineHistory(self)
self.scroller = WebEngineScroller(self, parent=self)
self.caret = WebEngineCaret(win_id=win_id, mode_manager=mode_manager,
@@ -556,9 +616,10 @@ class WebEngineTab(browsertab.AbstractTab):
def shutdown(self):
self.shutting_down.emit()
# WORKAROUND for
# https://bugreports.qt.io/browse/QTBUG-58563
self.search.clear()
if qtutils.version_check('5.8', exact=True):
# WORKAROUND for
# https://bugreports.qt.io/browse/QTBUG-58563
self.search.clear()
self._widget.shutdown()
def reload(self, *, force=False):
@@ -577,14 +638,12 @@ class WebEngineTab(browsertab.AbstractTab):
def icon(self):
return self._widget.icon()
def set_html(self, html, base_url=None):
def set_html(self, html, base_url=QUrl()):
# FIXME:qtwebengine
# check this and raise an exception if too big:
# Warning: The content will be percent encoded before being sent to the
# renderer via IPC. This may increase its size. The maximum size of the
# percent encoded content is 2 megabytes minus 30 bytes.
if base_url is None:
base_url = QUrl()
self._widget.setHtml(html, base_url)
def networkaccessmanager(self):
@@ -596,6 +655,13 @@ class WebEngineTab(browsertab.AbstractTab):
def clear_ssl_errors(self):
raise browsertab.UnsupportedOperationError
def key_press(self, key, modifier=Qt.NoModifier):
press_evt = QKeyEvent(QEvent.KeyPress, key, modifier, 0, 0, 0)
release_evt = QKeyEvent(QEvent.KeyRelease, key, modifier,
0, 0, 0)
self.send_event(press_evt)
self.send_event(release_evt)
@pyqtSlot()
def _on_history_trigger(self):
url = self.url()
@@ -639,12 +705,23 @@ class WebEngineTab(browsertab.AbstractTab):
def _on_fullscreen_requested(self, request):
request.accept()
on = request.toggleOn()
self.data.fullscreen = on
self.fullscreen_requested.emit(on)
if on:
notification = miscwidgets.FullscreenNotification(self)
notification.show()
notification.set_timeout(3000)
@pyqtSlot()
def _on_load_started(self):
"""Clear search when a new load is started if needed."""
if qtutils.version_check('5.9'):
# WORKAROUND for
# https://bugreports.qt.io/browse/QTBUG-61506
self.search.clear()
super()._on_load_started()
@pyqtSlot(QWebEnginePage.RenderProcessTerminationStatus, int)
def _on_render_process_terminated(self, status, exitcode):
"""Show an error when the renderer process terminated."""

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -23,12 +23,10 @@ import functools
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, PYQT_VERSION
from PyQt5.QtGui import QPalette
# pylint: disable=no-name-in-module,import-error,useless-suppression
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
# pylint: enable=no-name-in-module,import-error,useless-suppression
from qutebrowser.browser import shared
from qutebrowser.browser.webengine import certificateerror
from qutebrowser.browser.webengine import certificateerror, webenginesettings
from qutebrowser.config import config
from qutebrowser.utils import (log, debug, usertypes, jinja, urlutils, message,
objreg)
@@ -38,13 +36,19 @@ class WebEngineView(QWebEngineView):
"""Custom QWebEngineView subclass with qutebrowser-specific features."""
def __init__(self, tabdata, win_id, parent=None):
def __init__(self, *, tabdata, win_id, private, parent=None):
super().__init__(parent)
self._win_id = win_id
self._tabdata = tabdata
theme_color = self.style().standardPalette().color(QPalette.Base)
page = WebEnginePage(theme_color=theme_color, parent=self)
if private:
profile = webenginesettings.private_profile
assert profile.isOffTheRecord()
else:
profile = webenginesettings.default_profile
page = WebEnginePage(theme_color=theme_color, profile=profile,
parent=self)
self.setPage(page)
def shutdown(self):
@@ -124,8 +128,8 @@ class WebEnginePage(QWebEnginePage):
certificate_error = pyqtSignal()
shutting_down = pyqtSignal()
def __init__(self, theme_color, parent=None):
super().__init__(parent)
def __init__(self, *, theme_color, profile, parent=None):
super().__init__(profile, parent)
self._is_shutting_down = False
self.featurePermissionRequested.connect(
self._on_feature_permission_requested)

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -21,161 +21,35 @@
import os.path
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtNetwork import QNetworkDiskCache, QNetworkCacheMetaData
from PyQt5.QtNetwork import QNetworkDiskCache
from qutebrowser.config import config
from qutebrowser.utils import utils, objreg
from qutebrowser.utils import utils, objreg, qtutils
class DiskCache(QNetworkDiskCache):
"""Disk cache which sets correct cache dir and size.
Attributes:
_activated: Whether the cache should be used.
_cache_dir: The base directory for cache files (standarddir.cache())
"""
"""Disk cache which sets correct cache dir and size."""
def __init__(self, cache_dir, parent=None):
super().__init__(parent)
self._cache_dir = cache_dir
self._maybe_activate()
objreg.get('config').changed.connect(self.on_config_changed)
self.setCacheDirectory(os.path.join(cache_dir, 'http'))
self._set_cache_size()
objreg.get('config').changed.connect(self._set_cache_size)
def __repr__(self):
return utils.get_repr(self, size=self.cacheSize(),
maxsize=self.maximumCacheSize(),
path=self.cacheDirectory())
@config.change_filter('storage', 'cache-size')
def _set_cache_size(self):
"""Set the cache size based on the config."""
size = config.get('storage', 'cache-size')
if size is None:
size = 1024 * 1024 * 50 # default from QNetworkDiskCachePrivate
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-59909
if (qtutils.version_check('5.7.1') and
not qtutils.version_check('5.9')): # pragma: no cover
size = 0
self.setMaximumCacheSize(size)
def _maybe_activate(self):
"""Activate/deactivate the cache based on the config."""
if config.get('general', 'private-browsing'):
self._activated = False
else:
self._activated = True
self.setCacheDirectory(os.path.join(self._cache_dir, 'http'))
self._set_cache_size()
@pyqtSlot(str, str)
def on_config_changed(self, section, option):
"""Update cache size/activated if the config was changed."""
if (section, option) == ('storage', 'cache-size'):
self._set_cache_size()
elif (section, option) == ('general', # pragma: no branch
'private-browsing'):
self._maybe_activate()
def cacheSize(self):
"""Return the current size taken up by the cache.
Return:
An int.
"""
if self._activated:
return super().cacheSize()
else:
return 0
def fileMetaData(self, filename):
"""Return the QNetworkCacheMetaData for the cache file filename.
Args:
filename: The file name as a string.
Return:
A QNetworkCacheMetaData object.
"""
if self._activated:
return super().fileMetaData(filename)
else:
return QNetworkCacheMetaData()
def data(self, url):
"""Return the data associated with url.
Args:
url: A QUrl.
return:
A QIODevice or None.
"""
if self._activated:
return super().data(url)
else:
return None
def insert(self, device):
"""Insert the data in device and the prepared meta data into the cache.
Args:
device: A QIODevice.
"""
if self._activated:
super().insert(device)
else:
return None
def metaData(self, url):
"""Return the meta data for the url url.
Args:
url: A QUrl.
Return:
A QNetworkCacheMetaData object.
"""
if self._activated:
return super().metaData(url)
else:
return QNetworkCacheMetaData()
def prepare(self, meta_data):
"""Return the device that should be populated with the data.
Args:
meta_data: A QNetworkCacheMetaData object.
Return:
A QIODevice or None.
"""
if self._activated:
return super().prepare(meta_data)
else:
return None
def remove(self, url):
"""Remove the cache entry for url.
Return:
True on success, False otherwise.
"""
if self._activated:
return super().remove(url)
else:
return False
def updateMetaData(self, meta_data):
"""Update the cache meta date for the meta_data's url to meta_data.
Args:
meta_data: A QNetworkCacheMetaData object.
"""
if self._activated:
super().updateMetaData(meta_data)
else:
return
def clear(self):
"""Remove all items from the cache."""
if self._activated:
super().clear()
else:
return

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -41,7 +41,7 @@ class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
try:
# Qt >= 5.4
return hash(self._error)
except TypeError:
except TypeError: # pragma: no cover
return hash((self._error.certificate().toDer(),
self._error.error()))

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015-2016 Daniel Schadt
# Copyright 2015-2017 Daniel Schadt
#
# This file is part of qutebrowser.
#

View File

@@ -1,7 +1,7 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015-2016 Antoni Boucher (antoyo) <bouanto@zoho.com>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015-2017 Antoni Boucher (antoyo) <bouanto@zoho.com>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -121,13 +121,13 @@ class NetworkManager(QNetworkAccessManager):
reparented to the DownloadManager. This counts the
still running downloads, so the QNAM can clean
itself up when this reaches zero again.
_requests: Pending requests.
_scheme_handlers: A dictionary (scheme -> handler) of supported custom
schemes.
_win_id: The window ID this NetworkManager is associated with.
_tab_id: The tab ID this NetworkManager is associated with.
_rejected_ssl_errors: A {QUrl: [SslError]} dict of rejected errors.
_accepted_ssl_errors: A {QUrl: [SslError]} dict of accepted errors.
_private: Whether we're in private browsing mode.
Signals:
shutting_down: Emitted when the QNAM is shutting down.
@@ -135,7 +135,7 @@ class NetworkManager(QNetworkAccessManager):
shutting_down = pyqtSignal()
def __init__(self, win_id, tab_id, parent=None):
def __init__(self, *, win_id, tab_id, private, parent=None):
log.init.debug("Initializing NetworkManager")
with log.disable_qt_msghandler():
# WORKAROUND for a hang when a message is printed - See:
@@ -145,12 +145,12 @@ class NetworkManager(QNetworkAccessManager):
self.adopted_downloads = 0
self._win_id = win_id
self._tab_id = tab_id
self._requests = []
self._private = private
self._scheme_handlers = {
'qute': webkitqutescheme.QuteSchemeHandler(win_id),
'file': filescheme.FileSchemeHandler(win_id),
}
self._set_cookiejar(private=config.get('general', 'private-browsing'))
self._set_cookiejar()
self._set_cache()
self.sslErrors.connect(self.on_ssl_errors)
self._rejected_ssl_errors = collections.defaultdict(list)
@@ -158,15 +158,10 @@ class NetworkManager(QNetworkAccessManager):
self.authenticationRequired.connect(self.on_authentication_required)
self.proxyAuthenticationRequired.connect(
self.on_proxy_authentication_required)
objreg.get('config').changed.connect(self.on_config_changed)
def _set_cookiejar(self, private=False):
"""Set the cookie jar of the NetworkManager correctly.
Args:
private: Whether we're currently in private browsing mode.
"""
if private:
def _set_cookiejar(self):
"""Set the cookie jar of the NetworkManager correctly."""
if self._private:
cookie_jar = objreg.get('ram-cookie-jar')
else:
cookie_jar = objreg.get('cookie-jar')
@@ -178,11 +173,9 @@ class NetworkManager(QNetworkAccessManager):
cookie_jar.setParent(app)
def _set_cache(self):
"""Set the cache of the NetworkManager correctly.
We can't switch the whole cache in private mode because QNAM would
delete the old cache.
"""
"""Set the cache of the NetworkManager correctly."""
if self._private:
return
# We have a shared cache - we restore its parent so we don't take
# ownership of it.
app = QCoreApplication.instance()
@@ -206,9 +199,6 @@ class NetworkManager(QNetworkAccessManager):
def shutdown(self):
"""Abort all running requests."""
self.setNetworkAccessible(QNetworkAccessManager.NotAccessible)
for request in self._requests:
request.abort()
request.deleteLater()
self.shutting_down.emit()
# No @pyqtSlot here, see
@@ -324,17 +314,6 @@ class NetworkManager(QNetworkAccessManager):
authenticator.setPassword(answer.password)
_proxy_auth_cache[proxy_id] = answer
@config.change_filter('general', 'private-browsing')
def on_config_changed(self):
"""Set cookie jar when entering/leaving private browsing mode."""
private_browsing = config.get('general', 'private-browsing')
if private_browsing:
# switched from normal mode to private mode
self._set_cookiejar(private=True)
else:
# switched from private mode to normal mode
self._set_cookiejar()
@pyqtSlot()
def on_adopted_download_destroyed(self):
"""Check if we can clean up if an adopted download was destroyed.
@@ -386,9 +365,6 @@ class NetworkManager(QNetworkAccessManager):
def createRequest(self, op, req, outgoing_data):
"""Return a new QNetworkReply object.
Extend QNetworkAccessManager::createRequest to save requests in
self._requests and handle custom schemes.
Args:
op: Operation op
req: const QNetworkRequest & req
@@ -416,8 +392,7 @@ class NetworkManager(QNetworkAccessManager):
req.setRawHeader(header, value)
host_blocker = objreg.get('host-blocker')
if (op == QNetworkAccessManager.GetOperation and
host_blocker.is_blocked(req.url())):
if host_blocker.is_blocked(req.url()):
log.webview.info("Request to {} blocked by host blocker.".format(
req.url().host()))
return networkreply.ErrorNetworkReply(
@@ -454,6 +429,4 @@ class NetworkManager(QNetworkAccessManager):
reply = super().createRequest(op, req, outgoing_data)
else:
reply = super().createRequest(op, req, outgoing_data)
self._requests.append(reply)
reply.destroyed.connect(self._requests.remove)
return reply

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# Based on the Eric5 helpviewer,
# Copyright (c) 2009 - 2014 Detlev Offenbach <detlev@die-offenbachs.de>
@@ -19,6 +19,10 @@
#
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
#
# For some reason, a segfault will be triggered if the unnecessary lambdas in
# this file aren't there.
# pylint: disable=unnecessary-lambda
"""Special network replies.."""
@@ -114,9 +118,6 @@ class ErrorNetworkReply(QNetworkReply):
# the device to avoid getting a warning.
self.setOpenMode(QIODevice.ReadOnly)
self.setError(error, errorstring)
# For some reason, a segfault will be triggered if these lambdas aren't
# there.
# pylint: disable=unnecessary-lambda
QTimer.singleShot(0, lambda: self.error.emit(error))
QTimer.singleShot(0, lambda: self.finished.emit())
@@ -137,3 +138,20 @@ class ErrorNetworkReply(QNetworkReply):
def isRunning(self):
return False
class RedirectNetworkReply(QNetworkReply):
"""A reply which redirects to the given URL."""
def __init__(self, new_url, parent=None):
super().__init__(parent)
self.setAttribute(QNetworkRequest.RedirectionTargetAttribute, new_url)
QTimer.singleShot(0, lambda: self.finished.emit())
def abort(self):
"""Called when there's e.g. a redirection limit."""
pass
def readData(self, _maxlen):
return bytes()

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# Based on the Eric5 helpviewer,
# Copyright (c) 2009 - 2014 Detlev Offenbach <detlev@die-offenbachs.de>

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -17,7 +17,7 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
"""QtWebKit specific qute:* handlers and glue code."""
"""QtWebKit specific qute://* handlers and glue code."""
import mimetypes
import functools
@@ -28,13 +28,13 @@ from PyQt5.QtNetwork import QNetworkReply
from qutebrowser.browser import pdfjs, qutescheme
from qutebrowser.browser.webkit.network import schemehandler, networkreply
from qutebrowser.utils import jinja, log, message, objreg, usertypes
from qutebrowser.utils import jinja, log, message, objreg, usertypes, qtutils
from qutebrowser.config import configexc, configdata
class QuteSchemeHandler(schemehandler.SchemeHandler):
"""Scheme handler for qute: URLs."""
"""Scheme handler for qute:// URLs."""
def createRequest(self, _op, request, _outgoing_data):
"""Create a new request.
@@ -62,6 +62,9 @@ class QuteSchemeHandler(schemehandler.SchemeHandler):
except qutescheme.QuteSchemeError as e:
return networkreply.ErrorNetworkReply(request, e.errorstring,
e.error, self.parent())
except qutescheme.Redirect as e:
qtutils.ensure_valid(e.url)
return networkreply.RedirectNetworkReply(e.url, self.parent())
return networkreply.FixedDataNetworkReply(request, data, mimetype,
self.parent())
@@ -69,15 +72,15 @@ class QuteSchemeHandler(schemehandler.SchemeHandler):
class JSBridge(QObject):
"""Javascript-bridge for special qute:... pages."""
"""Javascript-bridge for special qute://... pages."""
@pyqtSlot(str, str, str)
def set(self, sectname, optname, value):
"""Slot to set a setting from qute:settings."""
"""Slot to set a setting from qute://settings."""
# https://github.com/qutebrowser/qutebrowser/issues/727
if ((sectname, optname) == ('content', 'allow-javascript') and
value == 'false'):
message.error("Refusing to disable javascript via qute:settings "
message.error("Refusing to disable javascript via qute://settings "
"as it needs javascript support.")
return
try:
@@ -88,7 +91,7 @@ class JSBridge(QObject):
@qutescheme.add_handler('settings', backend=usertypes.Backend.QtWebKit)
def qute_settings(_url):
"""Handler for qute:settings. View/change qute configuration."""
"""Handler for qute://settings. View/change qute configuration."""
config_getter = functools.partial(objreg.get('config').get, raw=True)
html = jinja.render('settings.html', title='settings', config=configdata,
confget=config_getter)

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -286,9 +286,6 @@ def normalize_ws(text):
def parse_headers(content_disposition):
"""Build a _ContentDisposition from header values."""
# WORKAROUND for https://bitbucket.org/logilab/pylint/issue/492/
# pylint: disable=no-member
# We allow non-ascii here (it will only be parsed inside of qdtext, and
# rejected by the grammar if it appears in other places), although parsing
# it can be ambiguous. Parsing it ensures that a non-ambiguous filename*

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -21,7 +21,6 @@
from PyQt5.QtCore import QByteArray, QDataStream, QIODevice, QUrl
from PyQt5.QtWebKit import qWebKitVersion
from qutebrowser.utils import qtutils
@@ -181,7 +180,7 @@ def serialize(items):
else:
current_idx = 0
if qtutils.is_qtwebkit_ng(qWebKitVersion()):
if qtutils.is_qtwebkit_ng():
_serialize_ng(items, current_idx, stream)
else:
_serialize_old(items, current_idx, stream)

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -96,16 +96,6 @@ class WebKitElement(webelem.AbstractWebElement):
self._check_vanished()
return self._elem.geometry()
def style_property(self, name, *, strategy):
self._check_vanished()
strategies = {
# FIXME:qtwebengine which ones do we actually need?
'inline': QWebElement.InlineStyle,
'computed': QWebElement.ComputedStyle,
}
qt_strategy = strategies[strategy]
return self._elem.styleProperty(name, qt_strategy)
def classes(self):
self._check_vanished()
return self._elem.classes()
@@ -122,7 +112,9 @@ class WebKitElement(webelem.AbstractWebElement):
def value(self):
self._check_vanished()
return self._elem.evaluateJavaScript('this.value')
val = self._elem.evaluateJavaScript('this.value')
assert isinstance(val, (int, float, str, type(None))), val
return val
def set_value(self, value):
self._check_vanished()
@@ -293,16 +285,24 @@ class WebKitElement(webelem.AbstractWebElement):
for _ in range(5):
if elem is None:
break
tag = elem.tag_name()
if tag == 'a' or tag == 'area':
if elem.is_link():
if elem.get('target', None) == '_blank':
elem['target'] = '_top'
break
elem = elem._parent() # pylint: disable=protected-access
def _move_text_cursor(self):
if self is None:
# old PyQt versions call the slot after the element is deleted.
return
if self.is_text_input() and self.is_editable():
self._tab.caret.move_to_end_of_document()
def _click_editable(self, click_target):
ok = self._elem.evaluateJavaScript('this.focus(); true;')
if not ok:
if ok:
self._move_text_cursor()
else:
log.webelem.debug("Failed to focus via JS, falling back to event")
self._click_fake_event(click_target)

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2015-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2015-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -17,6 +17,9 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
# We get various "abstract but not overridden" warnings
# pylint: disable=abstract-method
"""Bridge from QWebSettings to our own settings.
Module attributes:
@@ -26,43 +29,66 @@ Module attributes:
import os.path
from PyQt5.QtWebKit import QWebSettings, qWebKitVersion
from PyQt5.QtGui import QFont
from PyQt5.QtWebKit import QWebSettings
from qutebrowser.config import config, websettings
from qutebrowser.utils import standarddir, objreg, urlutils, qtutils, message
from qutebrowser.utils import standarddir, objreg, urlutils, qtutils
from qutebrowser.browser import shared
class Attribute(websettings.Attribute):
class Base(websettings.Base):
"""Base settings class with appropriate _get_global_settings."""
def _get_global_settings(self):
return [QWebSettings.globalSettings()]
class Attribute(Base, websettings.Attribute):
"""A setting set via QWebSettings::setAttribute."""
GLOBAL_SETTINGS = QWebSettings.globalSettings
ENUM_BASE = QWebSettings
class Setter(websettings.Setter):
class Setter(Base, websettings.Setter):
"""A setting set via QWebSettings getter/setter methods."""
"""A setting set via a QWebSettings setter method."""
GLOBAL_SETTINGS = QWebSettings.globalSettings
pass
class NullStringSetter(websettings.NullStringSetter):
class StaticSetter(Base, websettings.StaticSetter):
"""A setter for settings requiring a null QString as default."""
"""A setting set via a static QWebSettings setter method."""
GLOBAL_SETTINGS = QWebSettings.globalSettings
pass
class StaticSetter(websettings.StaticSetter):
class FontFamilySetter(Base, websettings.FontFamilySetter):
"""A setting set via static QWebSettings getter/setter methods."""
"""A setter for a font family.
GLOBAL_SETTINGS = QWebSettings.globalSettings
Gets the default value from QFont.
"""
def __init__(self, font):
# Mapping from QWebSettings::QWebSettings() in
# qtwebkit/Source/WebKit/qt/Api/qwebsettings.cpp
font_to_qfont = {
QWebSettings.StandardFont: QFont.Serif,
QWebSettings.FixedFont: QFont.Monospace,
QWebSettings.SerifFont: QFont.Serif,
QWebSettings.SansSerifFont: QFont.SansSerif,
QWebSettings.CursiveFont: QFont.Cursive,
QWebSettings.FantasyFont: QFont.Fantasy,
}
super().__init__(setter=QWebSettings.setFontFamily, font=font,
qfont=font_to_qfont[font])
class CookiePolicy(websettings.Base):
class CookiePolicy(Base):
"""The ThirdPartyCookiePolicy setting is different from other settings."""
@@ -73,12 +99,9 @@ class CookiePolicy(websettings.Base):
'no-unknown-3rdparty': QWebSettings.AllowThirdPartyWithExistingCookies,
}
def get(self, settings=None):
return config.get('content', 'cookies-accept')
def _set(self, value, settings=None):
QWebSettings.globalSettings().setThirdPartyCookiePolicy(
self.MAPPING[value])
for obj in self._get_settings(settings):
obj.setThirdPartyCookiePolicy(self.MAPPING[value])
def _set_user_stylesheet():
@@ -88,21 +111,9 @@ def _set_user_stylesheet():
QWebSettings.globalSettings().setUserStyleSheetUrl(url)
def _init_private_browsing():
if config.get('general', 'private-browsing'):
if qtutils.is_qtwebkit_ng(qWebKitVersion()):
message.warning("Private browsing is not fully implemented by "
"QtWebKit-NG!")
QWebSettings.setIconDatabasePath('')
else:
QWebSettings.setIconDatabasePath(standarddir.cache())
def update_settings(section, option):
"""Update global settings when qwebsettings changed."""
if (section, option) == ('general', 'private-browsing'):
_init_private_browsing()
elif section == 'ui' and option in ['hide-scrollbar', 'user-stylesheet']:
if section == 'ui' and option in ['hide-scrollbar', 'user-stylesheet']:
_set_user_stylesheet()
websettings.update_mappings(MAPPINGS, section, option)
@@ -113,8 +124,7 @@ def init(_args):
cache_path = standarddir.cache()
data_path = standarddir.data()
_init_private_browsing()
QWebSettings.setIconDatabasePath(standarddir.cache())
QWebSettings.setOfflineWebApplicationCachePath(
os.path.join(cache_path, 'application-cache'))
QWebSettings.globalSettings().setLocalStoragePath(
@@ -122,6 +132,13 @@ def init(_args):
QWebSettings.setOfflineStoragePath(
os.path.join(data_path, 'offline-storage'))
if (config.get('general', 'private-browsing') and
not qtutils.version_check('5.4.2')):
# WORKAROUND for https://codereview.qt-project.org/#/c/108936/
# Won't work when private browsing is not enabled globally, but that's
# the best we can do...
QWebSettings.setIconDatabasePath('')
websettings.init_mappings(MAPPINGS)
_set_user_stylesheet()
objreg.get('config').changed.connect(update_settings)
@@ -146,14 +163,10 @@ MAPPINGS = {
Attribute(QWebSettings.JavascriptCanCloseWindows),
'javascript-can-access-clipboard':
Attribute(QWebSettings.JavascriptCanAccessClipboard),
#'allow-java':
# Attribute(QWebSettings.JavaEnabled),
'allow-plugins':
Attribute(QWebSettings.PluginsEnabled),
'webgl':
Attribute(QWebSettings.WebGLEnabled),
'css-regions':
Attribute(QWebSettings.CSSRegionsEnabled),
'hyperlink-auditing':
Attribute(QWebSettings.HyperlinkAuditingEnabled),
'local-content-can-access-remote-urls':
@@ -175,44 +188,28 @@ MAPPINGS = {
},
'fonts': {
'web-family-standard':
Setter(getter=QWebSettings.fontFamily,
setter=QWebSettings.setFontFamily,
args=[QWebSettings.StandardFont]),
FontFamilySetter(QWebSettings.StandardFont),
'web-family-fixed':
Setter(getter=QWebSettings.fontFamily,
setter=QWebSettings.setFontFamily,
args=[QWebSettings.FixedFont]),
FontFamilySetter(QWebSettings.FixedFont),
'web-family-serif':
Setter(getter=QWebSettings.fontFamily,
setter=QWebSettings.setFontFamily,
args=[QWebSettings.SerifFont]),
FontFamilySetter(QWebSettings.SerifFont),
'web-family-sans-serif':
Setter(getter=QWebSettings.fontFamily,
setter=QWebSettings.setFontFamily,
args=[QWebSettings.SansSerifFont]),
FontFamilySetter(QWebSettings.SansSerifFont),
'web-family-cursive':
Setter(getter=QWebSettings.fontFamily,
setter=QWebSettings.setFontFamily,
args=[QWebSettings.CursiveFont]),
FontFamilySetter(QWebSettings.CursiveFont),
'web-family-fantasy':
Setter(getter=QWebSettings.fontFamily,
setter=QWebSettings.setFontFamily,
args=[QWebSettings.FantasyFont]),
FontFamilySetter(QWebSettings.FantasyFont),
'web-size-minimum':
Setter(getter=QWebSettings.fontSize,
setter=QWebSettings.setFontSize,
Setter(QWebSettings.setFontSize,
args=[QWebSettings.MinimumFontSize]),
'web-size-minimum-logical':
Setter(getter=QWebSettings.fontSize,
setter=QWebSettings.setFontSize,
Setter(QWebSettings.setFontSize,
args=[QWebSettings.MinimumLogicalFontSize]),
'web-size-default':
Setter(getter=QWebSettings.fontSize,
setter=QWebSettings.setFontSize,
Setter(QWebSettings.setFontSize,
args=[QWebSettings.DefaultFontSize]),
'web-size-default-fixed':
Setter(getter=QWebSettings.fontSize,
setter=QWebSettings.setFontSize,
Setter(QWebSettings.setFontSize,
args=[QWebSettings.DefaultFixedFontSize]),
},
'ui': {
@@ -221,9 +218,6 @@ MAPPINGS = {
'frame-flattening':
Attribute(QWebSettings.FrameFlatteningEnabled),
# user-stylesheet is handled separately
'css-media-type':
NullStringSetter(getter=QWebSettings.cssMediaType,
setter=QWebSettings.setCSSMediaType),
'smooth-scrolling':
Attribute(QWebSettings.ScrollAnimatorEnabled),
#'accelerated-compositing':
@@ -232,40 +226,22 @@ MAPPINGS = {
# Attribute(QWebSettings.TiledBackingStoreEnabled),
},
'storage': {
'offline-storage-database':
Attribute(QWebSettings.OfflineStorageDatabaseEnabled),
'offline-web-application-storage':
'offline-web-application-cache':
Attribute(QWebSettings.OfflineWebApplicationCacheEnabled),
'local-storage':
Attribute(QWebSettings.LocalStorageEnabled),
Attribute(QWebSettings.LocalStorageEnabled,
QWebSettings.OfflineStorageDatabaseEnabled),
'maximum-pages-in-cache':
StaticSetter(getter=QWebSettings.maximumPagesInCache,
setter=QWebSettings.setMaximumPagesInCache),
'object-cache-capacities':
StaticSetter(getter=None,
setter=QWebSettings.setObjectCacheCapacities,
unpack=True),
'offline-storage-default-quota':
StaticSetter(getter=QWebSettings.offlineStorageDefaultQuota,
setter=QWebSettings.setOfflineStorageDefaultQuota),
'offline-web-application-cache-quota':
StaticSetter(
getter=QWebSettings.offlineWebApplicationCacheQuota,
setter=QWebSettings.setOfflineWebApplicationCacheQuota),
StaticSetter(QWebSettings.setMaximumPagesInCache),
},
'general': {
'private-browsing':
Attribute(QWebSettings.PrivateBrowsingEnabled),
'developer-extras':
Attribute(QWebSettings.DeveloperExtrasEnabled),
'print-element-backgrounds':
Attribute(QWebSettings.PrintElementBackgrounds),
'xss-auditing':
Attribute(QWebSettings.XSSAuditingEnabled),
'site-specific-quirks':
Attribute(QWebSettings.SiteSpecificQuirksEnabled),
'default-encoding':
Setter(getter=QWebSettings.defaultTextEncoding,
setter=QWebSettings.setDefaultTextEncoding),
Setter(QWebSettings.setDefaultTextEncoding),
}
}

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2016-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -23,6 +23,7 @@ import sys
import functools
import xml.etree.ElementTree
import sip
from PyQt5.QtCore import (pyqtSlot, Qt, QEvent, QUrl, QPoint, QTimer, QSizeF,
QSize)
from PyQt5.QtGui import QKeyEvent
@@ -32,21 +33,14 @@ from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtPrintSupport import QPrinter
from qutebrowser.browser import browsertab
from qutebrowser.browser.network import proxy
from qutebrowser.browser.webkit import webview, tabhistory, webkitelem
from qutebrowser.browser.webkit.network import webkitqutescheme
from qutebrowser.utils import qtutils, objreg, usertypes, utils, log
from qutebrowser.utils import qtutils, objreg, usertypes, utils, log, debug
def init():
"""Initialize QtWebKit-specific modules."""
qapp = QApplication.instance()
if not qtutils.version_check('5.8'):
# Otherwise we initialize it globally in app.py
log.init.debug("Initializing proxy...")
proxy.init()
log.init.debug("Initializing js-bridge...")
js_bridge = webkitqutescheme.JSBridge(qapp)
objreg.register('js-bridge', js_bridge)
@@ -56,6 +50,9 @@ class WebKitAction(browsertab.AbstractAction):
"""QtWebKit implementations related to web actions."""
action_class = QWebPage
action_base = QWebPage.WebAction
def exit_fullscreen(self):
raise browsertab.UnsupportedOperationError
@@ -103,7 +100,7 @@ class WebKitSearch(browsertab.AbstractSearch):
super().__init__(parent)
self._flags = QWebPage.FindFlags(0)
def _call_cb(self, callback, found):
def _call_cb(self, callback, found, text, flags, caller):
"""Call the given callback if it's non-None.
Delays the call via a QTimer so the website is re-rendered in between.
@@ -111,17 +108,34 @@ class WebKitSearch(browsertab.AbstractSearch):
Args:
callback: What to call
found: If the text was found
text: The text searched for
flags: The flags searched with
caller: Name of the caller.
"""
found_text = 'found' if found else "didn't find"
# Removing FindWrapsAroundDocument to get the same logging as with
# QtWebEngine
debug_flags = debug.qflags_key(
QWebPage, flags & ~QWebPage.FindWrapsAroundDocument,
klass=QWebPage.FindFlag)
if debug_flags != '0x0000':
flag_text = 'with flags {}'.format(debug_flags)
else:
flag_text = ''
log.webview.debug(' '.join([caller, found_text, text, flag_text])
.strip())
if callback is not None:
QTimer.singleShot(0, functools.partial(callback, found))
def clear(self):
self.search_displayed = False
# We first clear the marked text, then the highlights
self._widget.findText('')
self._widget.findText('', QWebPage.HighlightAllOccurrences)
def search(self, text, *, ignore_case=False, reverse=False,
result_cb=None):
self.search_displayed = True
flags = QWebPage.FindWrapsAroundDocument
if ignore_case == 'smart':
if not text.islower():
@@ -136,13 +150,15 @@ class WebKitSearch(browsertab.AbstractSearch):
self._widget.findText(text, flags | QWebPage.HighlightAllOccurrences)
self.text = text
self._flags = flags
self._call_cb(result_cb, found)
self._call_cb(result_cb, found, text, flags, 'search')
def next_result(self, *, result_cb=None):
self.search_displayed = True
found = self._widget.findText(self.text, self._flags)
self._call_cb(result_cb, found)
self._call_cb(result_cb, found, self.text, self._flags, 'next_result')
def prev_result(self, *, result_cb=None):
self.search_displayed = True
# The int() here makes sure we get a copy of the flags.
flags = QWebPage.FindFlags(int(self._flags))
if flags & QWebPage.FindBackward:
@@ -150,7 +166,7 @@ class WebKitSearch(browsertab.AbstractSearch):
else:
flags |= QWebPage.FindBackward
found = self._widget.findText(self.text, flags)
self._call_cb(result_cb, found)
self._call_cb(result_cb, found, self.text, flags, 'prev_result')
class WebKitCaret(browsertab.AbstractCaret):
@@ -444,15 +460,11 @@ class WebKitScroller(browsertab.AbstractScroller):
# self._widget.setFocus()
for _ in range(min(count, 5000)):
press_evt = QKeyEvent(QEvent.KeyPress, key, Qt.NoModifier, 0, 0, 0)
release_evt = QKeyEvent(QEvent.KeyRelease, key, Qt.NoModifier,
0, 0, 0)
# Abort scrolling if the minimum/maximum was reached.
if (getter is not None and
frame.scrollBarValue(direction) == getter(direction)):
return
self._widget.keyPressEvent(press_evt)
self._widget.keyReleaseEvent(release_evt)
self._tab.key_press(key)
def up(self, count=1):
self._key_press(Qt.Key_Up, count, 'scrollBarMinimum', Qt.Vertical)
@@ -610,10 +622,13 @@ class WebKitTab(browsertab.AbstractTab):
"""A QtWebKit tab in the browser."""
def __init__(self, win_id, mode_manager, parent=None):
def __init__(self, *, win_id, mode_manager, private, parent=None):
super().__init__(win_id=win_id, mode_manager=mode_manager,
parent=parent)
widget = webview.WebView(win_id, self.tab_id, tab=self)
private=private, parent=parent)
widget = webview.WebView(win_id=win_id, tab_id=self.tab_id,
private=private, tab=self)
if private:
self._make_private(widget)
self.history = WebKitHistory(self)
self.scroller = WebKitScroller(self, parent=self)
self.caret = WebKitCaret(win_id=win_id, mode_manager=mode_manager,
@@ -630,6 +645,10 @@ class WebKitTab(browsertab.AbstractTab):
def _install_event_filter(self):
self._widget.installEventFilter(self._mouse_event_filter)
def _make_private(self, widget):
settings = widget.settings()
settings.setAttribute(QWebSettings.PrivateBrowsingEnabled, True)
def openurl(self, url):
self._openurl_prepare(url)
self._widget.openurl(url)
@@ -678,13 +697,20 @@ class WebKitTab(browsertab.AbstractTab):
def clear_ssl_errors(self):
self.networkaccessmanager().clear_all_ssl_errors()
def key_press(self, key, modifier=Qt.NoModifier):
press_evt = QKeyEvent(QEvent.KeyPress, key, modifier, 0, 0, 0)
release_evt = QKeyEvent(QEvent.KeyRelease, key, modifier,
0, 0, 0)
self.send_event(press_evt)
self.send_event(release_evt)
@pyqtSlot()
def _on_history_trigger(self):
url = self.url()
requested_url = self.url(requested=True)
self.add_history_item.emit(url, requested_url, self.title())
def set_html(self, html, base_url):
def set_html(self, html, base_url=QUrl()):
self._widget.setHtml(html, base_url)
def networkaccessmanager(self):
@@ -707,6 +733,9 @@ class WebKitTab(browsertab.AbstractTab):
@pyqtSlot()
def _on_webkit_icon_changed(self):
"""Emit iconChanged with a QIcon like QWebEngineView does."""
if sip.isdeleted(self._widget):
log.webview.debug("Got _on_webkit_icon_changed for deleted view!")
return
self.icon_changed.emit(self._widget.icon())
@pyqtSlot(QWebFrame)

View File

@@ -1,6 +1,6 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2014-2016 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
# Copyright 2014-2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
#
# This file is part of qutebrowser.
#
@@ -59,7 +59,7 @@ class BrowserPage(QWebPage):
shutting_down = pyqtSignal()
reloading = pyqtSignal(QUrl)
def __init__(self, win_id, tab_id, tabdata, parent=None):
def __init__(self, win_id, tab_id, tabdata, private, parent=None):
super().__init__(parent)
self._win_id = win_id
self._tabdata = tabdata
@@ -72,7 +72,7 @@ class BrowserPage(QWebPage):
self.error_occurred = False
self.open_target = usertypes.ClickTarget.normal
self._networkmanager = networkmanager.NetworkManager(
win_id, tab_id, self)
win_id=win_id, tab_id=tab_id, private=private, parent=self)
self.setNetworkAccessManager(self._networkmanager)
self.setForwardUnsupportedContent(True)
self.reloading.connect(self._networkmanager.clear_rejected_ssl_errors)

Some files were not shown because too many files have changed in this diff Show More