Merge branch 'master' into jay/prompt-on-click
This commit is contained in:
commit
28a2482cf7
@ -23,14 +23,18 @@ matrix:
|
|||||||
language: python
|
language: python
|
||||||
python: 3.6
|
python: 3.6
|
||||||
env: TESTENV=py36-pyqt571
|
env: TESTENV=py36-pyqt571
|
||||||
|
- os: linux
|
||||||
|
language: python
|
||||||
|
python: 3.6
|
||||||
|
env: TESTENV=py36-pyqt58
|
||||||
- os: linux
|
- os: linux
|
||||||
language: python
|
language: python
|
||||||
python: 3.5
|
python: 3.5
|
||||||
env: TESTENV=py35-pyqt58
|
env: TESTENV=py35-pyqt59
|
||||||
- os: linux
|
- os: linux
|
||||||
language: python
|
language: python
|
||||||
python: 3.6
|
python: 3.6
|
||||||
env: TESTENV=py36-pyqt58
|
env: TESTENV=py36-pyqt59
|
||||||
- os: osx
|
- os: osx
|
||||||
env: TESTENV=py36 OSX=elcapitan
|
env: TESTENV=py36 OSX=elcapitan
|
||||||
osx_image: xcode7.3
|
osx_image: xcode7.3
|
||||||
|
@ -14,8 +14,8 @@ This project adheres to http://semver.org/[Semantic Versioning].
|
|||||||
// `Fixed` for any bug fixes.
|
// `Fixed` for any bug fixes.
|
||||||
// `Security` to invite users to upgrade in case of vulnerabilities.
|
// `Security` to invite users to upgrade in case of vulnerabilities.
|
||||||
|
|
||||||
v0.11.0 (unreleased)
|
v0.11.0
|
||||||
--------------------
|
-------
|
||||||
|
|
||||||
New dependencies
|
New dependencies
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
@ -28,7 +28,10 @@ New dependencies
|
|||||||
Added
|
Added
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
- New `-p` flag for `:open` to open a private window.
|
- 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
|
- New "pinned tabs" feature, with a new `:tab-pin` command (bound
|
||||||
to `<Ctrl-p>` by default).
|
to `<Ctrl-p>` by default).
|
||||||
- (QtWebEngine) Implemented `:follow-selected`.
|
- (QtWebEngine) Implemented `:follow-selected`.
|
||||||
@ -45,6 +48,8 @@ Added
|
|||||||
customize statusbar colors for private windows.
|
customize statusbar colors for private windows.
|
||||||
- New `{private}` field displaying `[Private Mode]` for
|
- New `{private}` field displaying `[Private Mode]` for
|
||||||
`ui -> window-title-format` and `tabs -> title-format`.
|
`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
|
Changed
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
@ -52,62 +57,51 @@ Changed
|
|||||||
- To prevent elaborate phishing attacks, the Punycode version (`xn--*`) is now
|
- To prevent elaborate phishing attacks, the Punycode version (`xn--*`) is now
|
||||||
shown in addition to the decoded version for international domain names
|
shown in addition to the decoded version for international domain names
|
||||||
(IDN).
|
(IDN).
|
||||||
- Private browsing is now implemented for QtWebEngine, and changed it's
|
- Starting with legacy QtWebKit now shows a warning message.
|
||||||
behavior: The `general -> private-browsing` setting now only applies to newly
|
*With the next release, support for it will be removed.*
|
||||||
opened windows, and you can use the `-p` flag to `:open` to open a private
|
|
||||||
window.
|
|
||||||
- Improved `qute://history` page (with lazy loading)
|
|
||||||
- Starting with legacy QtWebKit now shows a warning message once.
|
|
||||||
- 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.
|
|
||||||
- PAC on QtWebKit now supports SOCKS5 as type.
|
|
||||||
- Comments in the config file are now 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.
|
|
||||||
- (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.
|
|
||||||
- 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.
|
|
||||||
- (QtWebEngine) The underlying Chromium version is now shown in the version
|
|
||||||
info.
|
|
||||||
- `qute:*` pages now use `qute://*` instead (e.g. `qute://version` instead of
|
|
||||||
`qute:version`), but the old versions are automatically redirected.
|
|
||||||
- The Windows releases are redone from scratch, which means:
|
- The Windows releases are redone from scratch, which means:
|
||||||
- They now use the new QtWebEngine backend
|
- They now use the new QtWebEngine backend
|
||||||
- The bundled Qt is updated from 5.5 to 5.9
|
- The bundled Qt is updated from 5.5 to 5.9
|
||||||
- The bundled Python is updated from 3.4 to 3.6
|
- The bundled Python is updated from 3.4 to 3.6
|
||||||
- They are now generated with PyInstaller instead of cx_Freeze
|
- They are now generated with PyInstaller instead of cx_Freeze
|
||||||
- The installer is now generated using NSIS instead of being a MSI
|
- 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.
|
- Texts in prompts are now selectable.
|
||||||
- Renderer process crashes now show an error page.
|
|
||||||
- (QtWebKit) storage -> offline-web-application-storage` got renamed to `...-cache`
|
|
||||||
- The default level for `:messages` is now `info`, not `error`
|
- The default level for `:messages` is now `info`, not `error`
|
||||||
- Trying to focus the currently focused tab with `:tab-focus` now focuses the
|
- Trying to focus the currently focused tab with `:tab-focus` now focuses the
|
||||||
last viewed tab.
|
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
|
Fixed
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
- The macOS .dmg is now built against Qt 5.9 which fixes various
|
- The macOS .dmg is now built against Qt 5.9 which fixes various
|
||||||
important issues (such as not being able to type dead keys).
|
important issues (such as not being able to type dead keys).
|
||||||
- (QtWebEngine) Added a workaround for a black screen with some setups
|
|
||||||
(the workaround requires PyOpenGL to be installed, but it's optional)
|
|
||||||
- (QtWebEngine) Starting with Nouveau graphics now shows an error message
|
|
||||||
instead of crashing in Qt. This adds a new dependency on `PyQt5.QtOpenGL`.
|
|
||||||
- (QtWebEngine) Retrying downloads now shows an error instead of crashing.
|
|
||||||
- (QtWebEngine) Cloning a view-source tab now doesn't crash anymore.
|
|
||||||
- (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.
|
|
||||||
- Fixed crash with `:download` on PyQt 5.9.
|
- Fixed crash with `:download` on PyQt 5.9.
|
||||||
- Cloning a page without history doesn't crash anymore.
|
- Cloning a page without history doesn't crash anymore.
|
||||||
- When a download results in a HTTP error, it now shows the error correctly
|
- When a download results in a HTTP error, it now shows the error correctly
|
||||||
@ -117,7 +111,6 @@ Fixed
|
|||||||
- Fixed crash when unbinding an unbound key in the key config.
|
- 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 when using `:debug-log-filter` when `--filter` wasn't given on startup.
|
||||||
- Fixed crash with some invalid setting values.
|
- Fixed crash with some invalid setting values.
|
||||||
- (QtWebKit) Fixed Crash when a PAC file returns an invalid value.
|
|
||||||
- Continuing a search after clearing it now works correctly.
|
- Continuing a search after clearing it now works correctly.
|
||||||
- The tabbar and completion should now be more consistently and correctly
|
- The tabbar and completion should now be more consistently and correctly
|
||||||
styled with various system styles.
|
styled with various system styles.
|
||||||
@ -125,18 +118,27 @@ Fixed
|
|||||||
- The validation for colors in stylesheets is now less strict,
|
- The validation for colors in stylesheets is now less strict,
|
||||||
allowing for all valid Qt values.
|
allowing for all valid Qt values.
|
||||||
- `data:` URLs now aren't added to the history anymore.
|
- `data:` URLs now aren't added to the history anymore.
|
||||||
- (QtWebEngine) `window.navigator.userAgent` is now set correctly when
|
|
||||||
customizing the user agent.
|
|
||||||
- Accidentally starting with Python 2 now shows a proper error message again.
|
- Accidentally starting with Python 2 now shows a proper error message again.
|
||||||
- (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.
|
|
||||||
- For some people, running some userscripts crashed - this should now be fixed.
|
- For some people, running some userscripts crashed - this should now be fixed.
|
||||||
- Various other rare crashes 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
|
- The settings documentation was truncated with v0.10.1 which should now be
|
||||||
fixed.
|
fixed.
|
||||||
- Scrolling to an anchor in a background tab now works correctly, and javascript
|
- Scrolling to an anchor in a background tab now works correctly, and javascript
|
||||||
gets the correct window size for background tabs.
|
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
|
v0.10.1
|
||||||
-------
|
-------
|
||||||
|
@ -682,8 +682,9 @@ qutebrowser release
|
|||||||
|
|
||||||
* Add newest config to `tests/unit/config/old_configs` and update `test_upgrade_version`
|
* Add newest config to `tests/unit/config/old_configs` and update `test_upgrade_version`
|
||||||
- `python -m qutebrowser --basedir conf :quit`
|
- `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`
|
- `rm -r conf`
|
||||||
|
- git add
|
||||||
- commit
|
- commit
|
||||||
* Adjust `__version_info__` in `qutebrowser/__init__.py`.
|
* Adjust `__version_info__` in `qutebrowser/__init__.py`.
|
||||||
* Update changelog (remove *(unreleased)*)
|
* Update changelog (remove *(unreleased)*)
|
||||||
|
@ -99,10 +99,10 @@ Requirements
|
|||||||
The following software and libraries are required to run qutebrowser:
|
The following software and libraries are required to run qutebrowser:
|
||||||
|
|
||||||
* http://www.python.org/[Python] 3.4 or newer (3.5 recommended)
|
* http://www.python.org/[Python] 3.4 or newer (3.5 recommended)
|
||||||
* http://qt.io/[Qt] 5.2.0 or newer (5.9.0 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
|
* 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
|
* http://www.riverbankcomputing.com/software/pyqt/intro[PyQt] 5.2.0 or newer
|
||||||
(5.8.1 recommended) for Python 3
|
(5.9 recommended) for Python 3
|
||||||
* https://pypi.python.org/pypi/setuptools/[pkg_resources/setuptools]
|
* https://pypi.python.org/pypi/setuptools/[pkg_resources/setuptools]
|
||||||
* http://fdik.org/pyPEG/[pyPEG2]
|
* http://fdik.org/pyPEG/[pyPEG2]
|
||||||
* http://jinja.pocoo.org/[jinja2]
|
* http://jinja.pocoo.org/[jinja2]
|
||||||
|
@ -85,7 +85,7 @@ It is possible to run or bind multiple commands by separating them with `;;`.
|
|||||||
|<<tab-pin,tab-pin>>|Pin/Unpin the current/[count]th tab.
|
|<<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.
|
|<<tab-prev,tab-prev>>|Switch to the previous tab, or switch [count] tabs back.
|
||||||
|<<unbind,unbind>>|Unbind a keychain.
|
|<<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.
|
|<<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.
|
|<<window-only,window-only>>|Close all windows except for the current one.
|
||||||
|<<wq,wq>>|Save open pages and quit.
|
|<<wq,wq>>|Save open pages and quit.
|
||||||
@ -936,7 +936,7 @@ Unbind a keychain.
|
|||||||
|
|
||||||
[[undo]]
|
[[undo]]
|
||||||
=== undo
|
=== undo
|
||||||
Re-open a closed tab (optionally skipping [count] closed tabs).
|
Re-open a closed tab.
|
||||||
|
|
||||||
[[view-source]]
|
[[view-source]]
|
||||||
=== view-source
|
=== view-source
|
||||||
|
@ -789,8 +789,6 @@ The proxy to use.
|
|||||||
|
|
||||||
In addition to the listed values, you can use a `socks://...` or `http://...` URL.
|
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:
|
Valid values:
|
||||||
|
|
||||||
* +system+: Use the system wide proxy.
|
* +system+: Use the system wide proxy.
|
||||||
|
@ -57,7 +57,7 @@ show it.
|
|||||||
How URLs should be opened if there is already a qutebrowser instance running.
|
How URLs should be opened if there is already a qutebrowser instance running.
|
||||||
|
|
||||||
*--backend* '{webkit,webengine}'::
|
*--backend* '{webkit,webengine}'::
|
||||||
Which backend to use (webengine backend is EXPERIMENTAL!).
|
Which backend to use.
|
||||||
|
|
||||||
*--enable-webengine-inspector*::
|
*--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.
|
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.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||||
|
|
||||||
PyQt5==5.8.2
|
PyQt5==5.9
|
||||||
sip==4.19.2
|
sip==4.19.3
|
||||||
|
@ -45,6 +45,7 @@ qt_log_ignore =
|
|||||||
^QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to .*
|
^QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to .*
|
||||||
^QGeoclueMaster error creating GeoclueMasterClient\.
|
^QGeoclueMaster error creating GeoclueMasterClient\.
|
||||||
^Geoclue error: Process org\.freedesktop\.Geoclue\.Master exited with status 127
|
^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'
|
||||||
^QObject::connect: Cannot connect \(null\)::stateChanged\(QNetworkSession::State\) to QNetworkReplyHttpImpl::_q_networkSessionStateChanged\(QNetworkSession::State\)
|
^QObject::connect: Cannot connect \(null\)::stateChanged\(QNetworkSession::State\) to QNetworkReplyHttpImpl::_q_networkSessionStateChanged\(QNetworkSession::State\)
|
||||||
^QXcbClipboard: Cannot transfer data, no data available
|
^QXcbClipboard: Cannot transfer data, no data available
|
||||||
^load glyph failed
|
^load glyph failed
|
||||||
|
@ -26,7 +26,7 @@ __copyright__ = "Copyright 2014-2017 Florian Bruhin (The Compiler)"
|
|||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
__maintainer__ = __author__
|
__maintainer__ = __author__
|
||||||
__email__ = "mail@qutebrowser.org"
|
__email__ = "mail@qutebrowser.org"
|
||||||
__version_info__ = (0, 10, 1)
|
__version_info__ = (0, 11, 0)
|
||||||
__version__ = '.'.join(str(e) for e in __version_info__)
|
__version__ = '.'.join(str(e) for e in __version_info__)
|
||||||
__description__ = "A keyboard-driven, vim-like browser based on PyQt5."
|
__description__ = "A keyboard-driven, vim-like browser based on PyQt5."
|
||||||
|
|
||||||
|
@ -410,10 +410,8 @@ def _init_modules(args, crash_handler):
|
|||||||
log.init.debug("Initializing network...")
|
log.init.debug("Initializing network...")
|
||||||
networkmanager.init()
|
networkmanager.init()
|
||||||
|
|
||||||
if qtutils.version_check('5.8'):
|
log.init.debug("Initializing proxy...")
|
||||||
# Otherwise we can only initialize it for QtWebKit because of crashes
|
proxy.init()
|
||||||
log.init.debug("Initializing proxy...")
|
|
||||||
proxy.init()
|
|
||||||
|
|
||||||
log.init.debug("Initializing readline-bridge...")
|
log.init.debug("Initializing readline-bridge...")
|
||||||
readline_bridge = readline.ReadlineBridge()
|
readline_bridge = readline.ReadlineBridge()
|
||||||
|
@ -281,9 +281,7 @@ class CommandDispatcher:
|
|||||||
return
|
return
|
||||||
|
|
||||||
to_pin = not tab.data.pinned
|
to_pin = not tab.data.pinned
|
||||||
tab_index = self._current_index() if count is None else count - 1
|
self._tabbed_browser.set_tab_pinned(tab, to_pin)
|
||||||
cmdutils.check_overflow(tab_index + 1, 'int')
|
|
||||||
self._tabbed_browser.set_tab_pinned(tab_index, to_pin)
|
|
||||||
|
|
||||||
@cmdutils.register(instance='command-dispatcher', name='open',
|
@cmdutils.register(instance='command-dispatcher', name='open',
|
||||||
maxsplit=0, scope='window')
|
maxsplit=0, scope='window')
|
||||||
@ -516,7 +514,7 @@ class CommandDispatcher:
|
|||||||
newtab.data.keep_icon = True
|
newtab.data.keep_icon = True
|
||||||
newtab.history.deserialize(history)
|
newtab.history.deserialize(history)
|
||||||
newtab.zoom.set_factor(curtab.zoom.factor())
|
newtab.zoom.set_factor(curtab.zoom.factor())
|
||||||
new_tabbed_browser.set_tab_pinned(idx, curtab.data.pinned)
|
new_tabbed_browser.set_tab_pinned(newtab, curtab.data.pinned)
|
||||||
return newtab
|
return newtab
|
||||||
|
|
||||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||||
@ -933,7 +931,7 @@ class CommandDispatcher:
|
|||||||
|
|
||||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||||
def undo(self):
|
def undo(self):
|
||||||
"""Re-open a closed tab (optionally skipping [count] closed tabs)."""
|
"""Re-open a closed tab."""
|
||||||
try:
|
try:
|
||||||
self._tabbed_browser.undo()
|
self._tabbed_browser.undo()
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
@ -132,9 +132,6 @@ def _init_stylesheet(profile):
|
|||||||
Mostly inspired by QupZilla:
|
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/app/mainapplication.cpp#L1063-L1101
|
||||||
https://github.com/QupZilla/qupzilla/blob/v2.0/src/lib/tools/scripts.cpp#L119-L132
|
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')
|
old_script = profile.scripts().findScript('_qute_stylesheet')
|
||||||
if not old_script.isNull():
|
if not old_script.isNull():
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"""Wrapper over a QWebEngineView."""
|
"""Wrapper over a QWebEngineView."""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import math
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
import sip
|
import sip
|
||||||
@ -342,7 +343,7 @@ class WebEngineScroller(browsertab.AbstractScroller):
|
|||||||
else:
|
else:
|
||||||
perc_y = min(100, round(100 / dy * jsret['px']['y']))
|
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._pos_perc = perc_x, perc_y
|
||||||
|
|
||||||
self.perc_changed.emit(*self._pos_perc)
|
self.perc_changed.emit(*self._pos_perc)
|
||||||
|
@ -33,7 +33,6 @@ from PyQt5.QtWebKit import QWebSettings
|
|||||||
from PyQt5.QtPrintSupport import QPrinter
|
from PyQt5.QtPrintSupport import QPrinter
|
||||||
|
|
||||||
from qutebrowser.browser import browsertab
|
from qutebrowser.browser import browsertab
|
||||||
from qutebrowser.browser.network import proxy
|
|
||||||
from qutebrowser.browser.webkit import webview, tabhistory, webkitelem
|
from qutebrowser.browser.webkit import webview, tabhistory, webkitelem
|
||||||
from qutebrowser.browser.webkit.network import webkitqutescheme
|
from qutebrowser.browser.webkit.network import webkitqutescheme
|
||||||
from qutebrowser.utils import qtutils, objreg, usertypes, utils, log, debug
|
from qutebrowser.utils import qtutils, objreg, usertypes, utils, log, debug
|
||||||
@ -42,12 +41,6 @@ from qutebrowser.utils import qtutils, objreg, usertypes, utils, log, debug
|
|||||||
def init():
|
def init():
|
||||||
"""Initialize QtWebKit-specific modules."""
|
"""Initialize QtWebKit-specific modules."""
|
||||||
qapp = QApplication.instance()
|
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...")
|
log.init.debug("Initializing js-bridge...")
|
||||||
js_bridge = webkitqutescheme.JSBridge(qapp)
|
js_bridge = webkitqutescheme.JSBridge(qapp)
|
||||||
objreg.register('js-bridge', js_bridge)
|
objreg.register('js-bridge', js_bridge)
|
||||||
|
@ -437,14 +437,10 @@ def data(readonly=False):
|
|||||||
"User agent to send. Empty to send the default."),
|
"User agent to send. Empty to send the default."),
|
||||||
|
|
||||||
('proxy',
|
('proxy',
|
||||||
SettingValue(typ.Proxy(), 'system',
|
SettingValue(typ.Proxy(), 'system'),
|
||||||
backends=(None if qtutils.version_check('5.8')
|
|
||||||
else [usertypes.Backend.QtWebKit])),
|
|
||||||
"The proxy to use.\n\n"
|
"The proxy to use.\n\n"
|
||||||
"In addition to the listed values, you can use a `socks://...` "
|
"In addition to the listed values, you can use a `socks://...` "
|
||||||
"or `http://...` URL.\n\n"
|
"or `http://...` URL."),
|
||||||
"This setting only works with Qt 5.8 or newer when using the "
|
|
||||||
"QtWebEngine backend."),
|
|
||||||
|
|
||||||
('proxy-dns-requests',
|
('proxy-dns-requests',
|
||||||
SettingValue(typ.Bool(), 'true',
|
SettingValue(typ.Bool(), 'true',
|
||||||
|
@ -343,7 +343,7 @@ class TabbedBrowser(tabwidget.TabWidget):
|
|||||||
newtab = self.tabopen(url, background=False, idx=idx)
|
newtab = self.tabopen(url, background=False, idx=idx)
|
||||||
|
|
||||||
newtab.history.deserialize(history_data)
|
newtab.history.deserialize(history_data)
|
||||||
self.set_tab_pinned(idx, pinned)
|
self.set_tab_pinned(newtab, pinned)
|
||||||
|
|
||||||
@pyqtSlot('QUrl', bool)
|
@pyqtSlot('QUrl', bool)
|
||||||
def openurl(self, url, newtab):
|
def openurl(self, url, newtab):
|
||||||
|
@ -26,7 +26,7 @@ from PyQt5.QtCore import (pyqtSignal, pyqtSlot, Qt, QSize, QRect, QPoint,
|
|||||||
QTimer, QUrl)
|
QTimer, QUrl)
|
||||||
from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle,
|
from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle,
|
||||||
QStyle, QStylePainter, QStyleOptionTab,
|
QStyle, QStylePainter, QStyleOptionTab,
|
||||||
QStyleFactory)
|
QStyleFactory, QWidget)
|
||||||
from PyQt5.QtGui import QIcon, QPalette, QColor
|
from PyQt5.QtGui import QIcon, QPalette, QColor
|
||||||
|
|
||||||
from qutebrowser.utils import qtutils, objreg, utils, usertypes, log
|
from qutebrowser.utils import qtutils, objreg, utils, usertypes, log
|
||||||
@ -94,17 +94,18 @@ class TabWidget(QTabWidget):
|
|||||||
bar.set_tab_data(idx, 'indicator-color', color)
|
bar.set_tab_data(idx, 'indicator-color', color)
|
||||||
bar.update(bar.tabRect(idx))
|
bar.update(bar.tabRect(idx))
|
||||||
|
|
||||||
def set_tab_pinned(self, idx, pinned, *, loading=False):
|
def set_tab_pinned(self, tab: QWidget,
|
||||||
|
pinned: bool, *, loading: bool = False) -> None:
|
||||||
"""Set the tab status as pinned.
|
"""Set the tab status as pinned.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
idx: The tab index.
|
tab: The tab to pin
|
||||||
pinned: Pinned tab state to set.
|
pinned: Pinned tab state to set.
|
||||||
loading: Whether to ignore current data state when
|
loading: Whether to ignore current data state when
|
||||||
counting pinned_count.
|
counting pinned_count.
|
||||||
"""
|
"""
|
||||||
bar = self.tabBar()
|
bar = self.tabBar()
|
||||||
tab = self.widget(idx)
|
idx = self.indexOf(tab)
|
||||||
|
|
||||||
# Only modify pinned_count if we had a change
|
# Only modify pinned_count if we had a change
|
||||||
# always modify pinned_count if we are loading
|
# always modify pinned_count if we are loading
|
||||||
|
@ -336,6 +336,7 @@ def check_libraries(backend):
|
|||||||
"http://pyyaml.org/download/pyyaml/ (py3.4) "
|
"http://pyyaml.org/download/pyyaml/ (py3.4) "
|
||||||
"or Install via pip.",
|
"or Install via pip.",
|
||||||
pip="PyYAML"),
|
pip="PyYAML"),
|
||||||
|
'PyQt5.QtQml': _missing_str("PyQt5.QtQml"),
|
||||||
}
|
}
|
||||||
if backend == 'webengine':
|
if backend == 'webengine':
|
||||||
modules['PyQt5.QtWebEngineWidgets'] = _missing_str("QtWebEngine",
|
modules['PyQt5.QtWebEngineWidgets'] = _missing_str("QtWebEngine",
|
||||||
|
@ -406,7 +406,7 @@ class SessionManager(QObject):
|
|||||||
tab_to_focus = i
|
tab_to_focus = i
|
||||||
if new_tab.data.pinned:
|
if new_tab.data.pinned:
|
||||||
tabbed_browser.set_tab_pinned(
|
tabbed_browser.set_tab_pinned(
|
||||||
i, new_tab.data.pinned, loading=True)
|
new_tab, new_tab.data.pinned, loading=True)
|
||||||
if tab_to_focus is not None:
|
if tab_to_focus is not None:
|
||||||
tabbed_browser.setCurrentIndex(tab_to_focus)
|
tabbed_browser.setCurrentIndex(tab_to_focus)
|
||||||
if win.get('active', False):
|
if win.get('active', False):
|
||||||
|
@ -64,8 +64,7 @@ def get_argparser():
|
|||||||
help="How URLs should be opened if there is already a "
|
help="How URLs should be opened if there is already a "
|
||||||
"qutebrowser instance running.")
|
"qutebrowser instance running.")
|
||||||
parser.add_argument('--backend', choices=['webkit', 'webengine'],
|
parser.add_argument('--backend', choices=['webkit', 'webengine'],
|
||||||
help="Which backend to use (webengine backend is "
|
help="Which backend to use.")
|
||||||
"EXPERIMENTAL!).")
|
|
||||||
parser.add_argument('--enable-webengine-inspector', action='store_true',
|
parser.add_argument('--enable-webengine-inspector', action='store_true',
|
||||||
help="Enable the web inspector for QtWebEngine. Note "
|
help="Enable the web inspector for QtWebEngine. Note "
|
||||||
"that this is a SECURITY RISK and you should not "
|
"that this is a SECURITY RISK and you should not "
|
||||||
|
@ -64,7 +64,7 @@ def call_tox(toxenv, *args, python=sys.executable):
|
|||||||
env['PYTHON'] = python
|
env['PYTHON'] = python
|
||||||
env['PATH'] = os.environ['PATH'] + os.pathsep + os.path.dirname(python)
|
env['PATH'] = os.environ['PATH'] + os.pathsep + os.path.dirname(python)
|
||||||
subprocess.check_call(
|
subprocess.check_call(
|
||||||
[sys.executable, '-m', 'tox', '-v', '-e', toxenv] + list(args),
|
[sys.executable, '-m', 'tox', '-vv', '-e', toxenv] + list(args),
|
||||||
env=env)
|
env=env)
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,6 +43,12 @@ travis_retry() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apt_install() {
|
apt_install() {
|
||||||
|
sudo tee /etc/apt/sources.list <<EOF
|
||||||
|
deb http://us.archive.ubuntu.com/ubuntu/ trusty main
|
||||||
|
deb http://us.archive.ubuntu.com/ubuntu/ trusty-security main
|
||||||
|
deb http://us.archive.ubuntu.com/ubuntu/ trusty-updates main
|
||||||
|
EOF
|
||||||
|
sudo rm -rf /etc/apt/sources.list.d
|
||||||
travis_retry sudo apt-get -y -q update
|
travis_retry sudo apt-get -y -q update
|
||||||
travis_retry sudo apt-get -y -q install --no-install-recommends "$@"
|
travis_retry sudo apt-get -y -q install --no-install-recommends "$@"
|
||||||
}
|
}
|
||||||
@ -64,8 +70,9 @@ npm_install() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
install_node() {
|
install_node() {
|
||||||
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
|
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
|
||||||
apt_install nodejs
|
travis_retry sudo apt-get -y -q update
|
||||||
|
travis_retry sudo apt-get -y -q install --no-install-recommends nodejs
|
||||||
}
|
}
|
||||||
|
|
||||||
check_pyqt() {
|
check_pyqt() {
|
||||||
|
@ -365,8 +365,7 @@ def generate_commands(filename):
|
|||||||
|
|
||||||
def _generate_setting_section(f, sectname, sect):
|
def _generate_setting_section(f, sectname, sect):
|
||||||
"""Generate documentation for a single section."""
|
"""Generate documentation for a single section."""
|
||||||
version_dependent_options = [('network', 'proxy'),
|
version_dependent_options = [('general', 'print-element-backgrounds')]
|
||||||
('general', 'print-element-backgrounds')]
|
|
||||||
for optname, option in sect.items():
|
for optname, option in sect.items():
|
||||||
f.write("\n")
|
f.write("\n")
|
||||||
f.write('[[{}-{}]]'.format(sectname, optname) + "\n")
|
f.write('[[{}-{}]]'.format(sectname, optname) + "\n")
|
||||||
|
@ -579,9 +579,9 @@ Feature: Downloading things from a website.
|
|||||||
And I wait until the download is finished
|
And I wait until the download is finished
|
||||||
Then the downloaded file content-size should exist
|
Then the downloaded file content-size should exist
|
||||||
|
|
||||||
@posix
|
|
||||||
Scenario: Downloading to unwritable destination
|
Scenario: Downloading to unwritable destination
|
||||||
When I set storage -> prompt-download-directory to false
|
When the unwritable dir is unwritable
|
||||||
|
And I set storage -> prompt-download-directory to false
|
||||||
And I run :download http://localhost:(port)/data/downloads/download.bin --dest (tmpdir)/downloads/unwritable
|
And I run :download http://localhost:(port)/data/downloads/download.bin --dest (tmpdir)/downloads/unwritable
|
||||||
Then the error "Download error: Permission denied" should be shown
|
Then the error "Download error: Permission denied" should be shown
|
||||||
|
|
||||||
|
@ -292,6 +292,13 @@ Feature: Scrolling
|
|||||||
And I run :scroll-page --bottom-navigate next 0 1
|
And I run :scroll-page --bottom-navigate next 0 1
|
||||||
Then data/hello2.txt should be loaded
|
Then data/hello2.txt should be loaded
|
||||||
|
|
||||||
|
Scenario: :scroll-page with --bottom-navigate when not at the bottom
|
||||||
|
When I run :scroll-px 0 10
|
||||||
|
And I wait until the scroll position changed
|
||||||
|
And I run :scroll-page --bottom-navigate next 0 1
|
||||||
|
Then the following tabs should be open:
|
||||||
|
- data/scroll/simple.html
|
||||||
|
|
||||||
Scenario: :scroll-page with --top-navigate
|
Scenario: :scroll-page with --top-navigate
|
||||||
When I run :scroll-page --top-navigate prev 0 -1
|
When I run :scroll-page --top-navigate prev 0 -1
|
||||||
Then data/hello3.txt should be loaded
|
Then data/hello3.txt should be loaded
|
||||||
|
@ -1073,6 +1073,16 @@ Feature: Tab management
|
|||||||
- data/numbers/2.txt (pinned)
|
- data/numbers/2.txt (pinned)
|
||||||
- data/numbers/3.txt (active)
|
- data/numbers/3.txt (active)
|
||||||
|
|
||||||
|
Scenario: :tab-pin with an invalid count
|
||||||
|
When I open data/numbers/1.txt
|
||||||
|
And I open data/numbers/2.txt in a new tab
|
||||||
|
And I open data/numbers/3.txt in a new tab
|
||||||
|
And I run :tab-pin with count 23
|
||||||
|
Then the following tabs should be open:
|
||||||
|
- data/numbers/1.txt
|
||||||
|
- data/numbers/2.txt
|
||||||
|
- data/numbers/3.txt (active)
|
||||||
|
|
||||||
Scenario: Pinned :tab-close prompt yes
|
Scenario: Pinned :tab-close prompt yes
|
||||||
When I open data/numbers/1.txt
|
When I open data/numbers/1.txt
|
||||||
And I run :tab-pin
|
And I run :tab-pin
|
||||||
|
@ -21,6 +21,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import shlex
|
import shlex
|
||||||
|
|
||||||
|
import pytest
|
||||||
import pytest_bdd as bdd
|
import pytest_bdd as bdd
|
||||||
bdd.scenarios('downloads.feature')
|
bdd.scenarios('downloads.feature')
|
||||||
|
|
||||||
@ -53,6 +54,14 @@ def clean_old_downloads(quteproc):
|
|||||||
quteproc.send_cmd(':download-clear')
|
quteproc.send_cmd(':download-clear')
|
||||||
|
|
||||||
|
|
||||||
|
@bdd.when("the unwritable dir is unwritable")
|
||||||
|
def check_unwritable(tmpdir):
|
||||||
|
unwritable = tmpdir / 'downloads' / 'unwritable'
|
||||||
|
if os.access(str(unwritable), os.W_OK):
|
||||||
|
# Docker container or similar
|
||||||
|
pytest.skip("Unwritable dir was writable")
|
||||||
|
|
||||||
|
|
||||||
@bdd.when("I wait until the download is finished")
|
@bdd.when("I wait until the download is finished")
|
||||||
def wait_for_download_finished(quteproc):
|
def wait_for_download_finished(quteproc):
|
||||||
quteproc.wait_for(category='downloads', message='Download * finished')
|
quteproc.wait_for(category='downloads', message='Download * finished')
|
||||||
|
251
tests/unit/config/old_configs/qutebrowser-v0.11.0.conf
Normal file
251
tests/unit/config/old_configs/qutebrowser-v0.11.0.conf
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
[general]
|
||||||
|
ignore-case = smart
|
||||||
|
startpage = https://start.duckduckgo.com
|
||||||
|
yank-ignored-url-parameters = ref,utm_source,utm_medium,utm_campaign,utm_term,utm_content
|
||||||
|
default-open-dispatcher =
|
||||||
|
default-page = ${startpage}
|
||||||
|
auto-search = naive
|
||||||
|
auto-save-config = true
|
||||||
|
auto-save-interval = 15000
|
||||||
|
editor = gvim -f "{}"
|
||||||
|
editor-encoding = utf-8
|
||||||
|
private-browsing = false
|
||||||
|
developer-extras = false
|
||||||
|
print-element-backgrounds = true
|
||||||
|
xss-auditing = false
|
||||||
|
default-encoding = iso-8859-1
|
||||||
|
new-instance-open-target = tab
|
||||||
|
new-instance-open-target.window = last-focused
|
||||||
|
log-javascript-console = debug
|
||||||
|
save-session = false
|
||||||
|
session-default-name =
|
||||||
|
url-incdec-segments = path,query
|
||||||
|
[ui]
|
||||||
|
history-session-interval = 30
|
||||||
|
zoom-levels = 25%,33%,50%,67%,75%,90%,100%,110%,125%,150%,175%,200%,250%,300%,400%,500%
|
||||||
|
default-zoom = 100%
|
||||||
|
downloads-position = top
|
||||||
|
status-position = bottom
|
||||||
|
message-timeout = 2000
|
||||||
|
message-unfocused = false
|
||||||
|
confirm-quit = never
|
||||||
|
zoom-text-only = false
|
||||||
|
frame-flattening = false
|
||||||
|
user-stylesheet =
|
||||||
|
hide-scrollbar = true
|
||||||
|
smooth-scrolling = false
|
||||||
|
remove-finished-downloads = -1
|
||||||
|
hide-statusbar = false
|
||||||
|
statusbar-padding = 1,1,0,0
|
||||||
|
window-title-format = {perc}{title}{title_sep}qutebrowser
|
||||||
|
modal-js-dialog = false
|
||||||
|
hide-wayland-decoration = false
|
||||||
|
keyhint-blacklist =
|
||||||
|
keyhint-delay = 500
|
||||||
|
prompt-radius = 8
|
||||||
|
prompt-filebrowser = true
|
||||||
|
[network]
|
||||||
|
do-not-track = true
|
||||||
|
accept-language = en-US,en
|
||||||
|
referer-header = same-domain
|
||||||
|
user-agent =
|
||||||
|
proxy = system
|
||||||
|
proxy-dns-requests = true
|
||||||
|
ssl-strict = ask
|
||||||
|
dns-prefetch = true
|
||||||
|
custom-headers =
|
||||||
|
netrc-file =
|
||||||
|
[completion]
|
||||||
|
show = always
|
||||||
|
download-path-suggestion = path
|
||||||
|
timestamp-format = %Y-%m-%d
|
||||||
|
height = 50%
|
||||||
|
cmd-history-max-items = 100
|
||||||
|
web-history-max-items = 1000
|
||||||
|
quick-complete = true
|
||||||
|
shrink = false
|
||||||
|
scrollbar-width = 12
|
||||||
|
scrollbar-padding = 2
|
||||||
|
[input]
|
||||||
|
timeout = 500
|
||||||
|
partial-timeout = 5000
|
||||||
|
insert-mode-on-plugins = false
|
||||||
|
auto-leave-insert-mode = true
|
||||||
|
auto-insert-mode = false
|
||||||
|
forward-unbound-keys = auto
|
||||||
|
spatial-navigation = false
|
||||||
|
links-included-in-focus-chain = true
|
||||||
|
rocker-gestures = false
|
||||||
|
mouse-zoom-divider = 512
|
||||||
|
[tabs]
|
||||||
|
background-tabs = false
|
||||||
|
select-on-remove = next
|
||||||
|
new-tab-position = next
|
||||||
|
new-tab-position-explicit = last
|
||||||
|
last-close = ignore
|
||||||
|
show = always
|
||||||
|
show-switching-delay = 800
|
||||||
|
wrap = true
|
||||||
|
movable = true
|
||||||
|
close-mouse-button = middle
|
||||||
|
position = top
|
||||||
|
show-favicons = true
|
||||||
|
favicon-scale = 1.0
|
||||||
|
width = 20%
|
||||||
|
pinned-width = 43
|
||||||
|
indicator-width = 3
|
||||||
|
tabs-are-windows = false
|
||||||
|
title-format = {index}: {title}
|
||||||
|
title-format-pinned = {index}
|
||||||
|
title-alignment = left
|
||||||
|
mousewheel-tab-switching = true
|
||||||
|
padding = 0,0,5,5
|
||||||
|
indicator-padding = 2,2,0,4
|
||||||
|
[storage]
|
||||||
|
download-directory =
|
||||||
|
prompt-download-directory = true
|
||||||
|
remember-download-directory = true
|
||||||
|
maximum-pages-in-cache = 0
|
||||||
|
offline-web-application-cache = true
|
||||||
|
local-storage = true
|
||||||
|
cache-size =
|
||||||
|
[content]
|
||||||
|
allow-images = true
|
||||||
|
allow-javascript = true
|
||||||
|
allow-plugins = false
|
||||||
|
webgl = true
|
||||||
|
hyperlink-auditing = false
|
||||||
|
geolocation = ask
|
||||||
|
notifications = ask
|
||||||
|
media-capture = ask
|
||||||
|
javascript-can-open-windows-automatically = false
|
||||||
|
javascript-can-close-windows = false
|
||||||
|
javascript-can-access-clipboard = false
|
||||||
|
ignore-javascript-prompt = false
|
||||||
|
ignore-javascript-alert = false
|
||||||
|
local-content-can-access-remote-urls = false
|
||||||
|
local-content-can-access-file-urls = true
|
||||||
|
cookies-accept = no-3rdparty
|
||||||
|
cookies-store = true
|
||||||
|
host-block-lists = https://www.malwaredomainlist.com/hostslist/hosts.txt,http://someonewhocares.org/hosts/hosts,http://winhelp2002.mvps.org/hosts.zip,http://malwaredomains.lehigh.edu/files/justdomains.zip,https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext
|
||||||
|
host-blocking-enabled = true
|
||||||
|
host-blocking-whitelist = piwik.org
|
||||||
|
enable-pdfjs = false
|
||||||
|
[hints]
|
||||||
|
border = 1px solid #E3BE23
|
||||||
|
mode = letter
|
||||||
|
chars = asdfghjkl
|
||||||
|
min-chars = 1
|
||||||
|
scatter = true
|
||||||
|
uppercase = false
|
||||||
|
dictionary = /usr/share/dict/words
|
||||||
|
auto-follow = unique-match
|
||||||
|
auto-follow-timeout = 0
|
||||||
|
next-regexes = \bnext\b,\bmore\b,\bnewer\b,\b[>→≫]\b,\b(>>|»)\b,\bcontinue\b
|
||||||
|
prev-regexes = \bprev(ious)?\b,\bback\b,\bolder\b,\b[<←≪]\b,\b(<<|«)\b
|
||||||
|
find-implementation = python
|
||||||
|
hide-unmatched-rapid-hints = true
|
||||||
|
[searchengines]
|
||||||
|
DEFAULT = https://duckduckgo.com/?q={}
|
||||||
|
[aliases]
|
||||||
|
[colors]
|
||||||
|
completion.fg = white
|
||||||
|
completion.bg = #333333
|
||||||
|
completion.alternate-bg = #444444
|
||||||
|
completion.category.fg = white
|
||||||
|
completion.category.bg = qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #888888, stop:1 #505050)
|
||||||
|
completion.category.border.top = black
|
||||||
|
completion.category.border.bottom = ${completion.category.border.top}
|
||||||
|
completion.item.selected.fg = black
|
||||||
|
completion.item.selected.bg = #e8c000
|
||||||
|
completion.item.selected.border.top = #bbbb00
|
||||||
|
completion.item.selected.border.bottom = ${completion.item.selected.border.top}
|
||||||
|
completion.match.fg = #ff4444
|
||||||
|
completion.scrollbar.fg = ${completion.fg}
|
||||||
|
completion.scrollbar.bg = ${completion.bg}
|
||||||
|
statusbar.fg = white
|
||||||
|
statusbar.bg = black
|
||||||
|
statusbar.fg.private = ${statusbar.fg}
|
||||||
|
statusbar.bg.private = #666666
|
||||||
|
statusbar.fg.insert = ${statusbar.fg}
|
||||||
|
statusbar.bg.insert = darkgreen
|
||||||
|
statusbar.fg.command = ${statusbar.fg}
|
||||||
|
statusbar.bg.command = ${statusbar.bg}
|
||||||
|
statusbar.fg.command.private = ${statusbar.fg.private}
|
||||||
|
statusbar.bg.command.private = ${statusbar.bg.private}
|
||||||
|
statusbar.fg.caret = ${statusbar.fg}
|
||||||
|
statusbar.bg.caret = purple
|
||||||
|
statusbar.fg.caret-selection = ${statusbar.fg}
|
||||||
|
statusbar.bg.caret-selection = #a12dff
|
||||||
|
statusbar.progress.bg = white
|
||||||
|
statusbar.url.fg = ${statusbar.fg}
|
||||||
|
statusbar.url.fg.success = white
|
||||||
|
statusbar.url.fg.success.https = lime
|
||||||
|
statusbar.url.fg.error = orange
|
||||||
|
statusbar.url.fg.warn = yellow
|
||||||
|
statusbar.url.fg.hover = aqua
|
||||||
|
tabs.fg.odd = white
|
||||||
|
tabs.bg.odd = grey
|
||||||
|
tabs.fg.even = white
|
||||||
|
tabs.bg.even = darkgrey
|
||||||
|
tabs.fg.selected.odd = white
|
||||||
|
tabs.bg.selected.odd = black
|
||||||
|
tabs.fg.selected.even = ${tabs.fg.selected.odd}
|
||||||
|
tabs.bg.selected.even = ${tabs.bg.selected.odd}
|
||||||
|
tabs.bg.bar = #555555
|
||||||
|
tabs.indicator.start = #0000aa
|
||||||
|
tabs.indicator.stop = #00aa00
|
||||||
|
tabs.indicator.error = #ff0000
|
||||||
|
tabs.indicator.system = rgb
|
||||||
|
hints.fg = black
|
||||||
|
hints.bg = qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 247, 133, 0.8), stop:1 rgba(255, 197, 66, 0.8))
|
||||||
|
hints.fg.match = green
|
||||||
|
downloads.bg.bar = black
|
||||||
|
downloads.fg.start = white
|
||||||
|
downloads.bg.start = #0000aa
|
||||||
|
downloads.fg.stop = ${downloads.fg.start}
|
||||||
|
downloads.bg.stop = #00aa00
|
||||||
|
downloads.fg.system = rgb
|
||||||
|
downloads.bg.system = rgb
|
||||||
|
downloads.fg.error = white
|
||||||
|
downloads.bg.error = red
|
||||||
|
webpage.bg = white
|
||||||
|
keyhint.fg = #FFFFFF
|
||||||
|
keyhint.fg.suffix = #FFFF00
|
||||||
|
keyhint.bg = rgba(0, 0, 0, 80%)
|
||||||
|
messages.fg.error = white
|
||||||
|
messages.bg.error = red
|
||||||
|
messages.border.error = #bb0000
|
||||||
|
messages.fg.warning = white
|
||||||
|
messages.bg.warning = darkorange
|
||||||
|
messages.border.warning = #d47300
|
||||||
|
messages.fg.info = white
|
||||||
|
messages.bg.info = black
|
||||||
|
messages.border.info = #333333
|
||||||
|
prompts.fg = white
|
||||||
|
prompts.bg = darkblue
|
||||||
|
prompts.selected.bg = #308cc6
|
||||||
|
[fonts]
|
||||||
|
_monospace = xos4 Terminus, Terminus, Monospace, "DejaVu Sans Mono", Monaco, "Bitstream Vera Sans Mono", "Andale Mono", "Courier New", Courier, "Liberation Mono", monospace, Fixed, Consolas, Terminal
|
||||||
|
completion = 8pt ${_monospace}
|
||||||
|
completion.category = bold ${completion}
|
||||||
|
tabbar = 8pt ${_monospace}
|
||||||
|
statusbar = 8pt ${_monospace}
|
||||||
|
downloads = 8pt ${_monospace}
|
||||||
|
hints = bold 13px ${_monospace}
|
||||||
|
debug-console = 8pt ${_monospace}
|
||||||
|
web-family-standard =
|
||||||
|
web-family-fixed =
|
||||||
|
web-family-serif =
|
||||||
|
web-family-sans-serif =
|
||||||
|
web-family-cursive =
|
||||||
|
web-family-fantasy =
|
||||||
|
web-size-minimum = 0
|
||||||
|
web-size-minimum-logical = 6
|
||||||
|
web-size-default = 16
|
||||||
|
web-size-default-fixed = 13
|
||||||
|
keyhint = 8pt ${_monospace}
|
||||||
|
messages.error = 8pt ${_monospace}
|
||||||
|
messages.warning = 8pt ${_monospace}
|
||||||
|
messages.info = 8pt ${_monospace}
|
||||||
|
prompts = 8pt sans-serif
|
@ -408,7 +408,7 @@ class TestDefaultConfig:
|
|||||||
If it did change, place a new qutebrowser-vx.y.z.conf in old_configs
|
If it did change, place a new qutebrowser-vx.y.z.conf in old_configs
|
||||||
and then increment the version.
|
and then increment the version.
|
||||||
"""
|
"""
|
||||||
assert qutebrowser.__version__ == '0.10.1'
|
assert qutebrowser.__version__ == '0.11.0'
|
||||||
|
|
||||||
@pytest.mark.parametrize('filename',
|
@pytest.mark.parametrize('filename',
|
||||||
os.listdir(os.path.join(os.path.dirname(__file__), 'old_configs')),
|
os.listdir(os.path.join(os.path.dirname(__file__), 'old_configs')),
|
||||||
|
@ -123,24 +123,30 @@ class TestFileHandling:
|
|||||||
|
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
|
|
||||||
@pytest.mark.posix
|
|
||||||
def test_unreadable(self, message_mock, editor, caplog):
|
def test_unreadable(self, message_mock, editor, caplog):
|
||||||
"""Test file handling when closing with an unreadable file."""
|
"""Test file handling when closing with an unreadable file."""
|
||||||
editor.edit("")
|
editor.edit("")
|
||||||
filename = editor._file.name
|
filename = editor._file.name
|
||||||
assert os.path.exists(filename)
|
assert os.path.exists(filename)
|
||||||
os.chmod(filename, 0o077)
|
os.chmod(filename, 0o077)
|
||||||
|
if os.access(filename, os.R_OK):
|
||||||
|
# Docker container or similar
|
||||||
|
pytest.skip("File was still readable")
|
||||||
|
|
||||||
with caplog.at_level(logging.ERROR):
|
with caplog.at_level(logging.ERROR):
|
||||||
editor._proc.finished.emit(0, QProcess.NormalExit)
|
editor._proc.finished.emit(0, QProcess.NormalExit)
|
||||||
assert not os.path.exists(filename)
|
assert not os.path.exists(filename)
|
||||||
msg = message_mock.getmsg(usertypes.MessageLevel.error)
|
msg = message_mock.getmsg(usertypes.MessageLevel.error)
|
||||||
assert msg.text.startswith("Failed to read back edited file: ")
|
assert msg.text.startswith("Failed to read back edited file: ")
|
||||||
|
|
||||||
@pytest.mark.posix
|
|
||||||
def test_unwritable(self, monkeypatch, message_mock, editor, tmpdir,
|
def test_unwritable(self, monkeypatch, message_mock, editor, tmpdir,
|
||||||
caplog):
|
caplog):
|
||||||
"""Test file handling when the initial file is not writable."""
|
"""Test file handling when the initial file is not writable."""
|
||||||
tmpdir.chmod(0)
|
tmpdir.chmod(0)
|
||||||
|
if os.access(str(tmpdir), os.W_OK):
|
||||||
|
# Docker container or similar
|
||||||
|
pytest.skip("File was still writable")
|
||||||
|
|
||||||
monkeypatch.setattr(editormod.tempfile, 'tempdir', str(tmpdir))
|
monkeypatch.setattr(editormod.tempfile, 'tempdir', str(tmpdir))
|
||||||
|
|
||||||
with caplog.at_level(logging.ERROR):
|
with caplog.at_level(logging.ERROR):
|
||||||
|
24
tox.ini
24
tox.ini
@ -4,7 +4,7 @@
|
|||||||
# and then run "tox" from this directory.
|
# and then run "tox" from this directory.
|
||||||
|
|
||||||
[tox]
|
[tox]
|
||||||
envlist = py34,py35,py36-cov,misc,vulture,flake8,pylint,pyroma,check-manifest
|
envlist = py36-cov,misc,vulture,flake8,pylint,pyroma,check-manifest,eslint
|
||||||
distshare = {toxworkdir}
|
distshare = {toxworkdir}
|
||||||
skipsdist = true
|
skipsdist = true
|
||||||
|
|
||||||
@ -111,6 +111,28 @@ deps =
|
|||||||
PyQt5==5.8.2
|
PyQt5==5.8.2
|
||||||
commands = {envpython} -bb -m pytest {posargs:tests}
|
commands = {envpython} -bb -m pytest {posargs:tests}
|
||||||
|
|
||||||
|
[testenv:py35-pyqt59]
|
||||||
|
basepython = python3.5
|
||||||
|
setenv =
|
||||||
|
{[testenv]setenv}
|
||||||
|
QUTE_BDD_WEBENGINE=true
|
||||||
|
passenv = {[testenv]passenv}
|
||||||
|
deps =
|
||||||
|
{[testenv]deps}
|
||||||
|
PyQt5==5.9
|
||||||
|
commands = {envpython} -bb -m pytest {posargs:tests}
|
||||||
|
|
||||||
|
[testenv:py36-pyqt59]
|
||||||
|
basepython = {env:PYTHON:python3.6}
|
||||||
|
setenv =
|
||||||
|
{[testenv]setenv}
|
||||||
|
QUTE_BDD_WEBENGINE=true
|
||||||
|
passenv = {[testenv]passenv}
|
||||||
|
deps =
|
||||||
|
{[testenv]deps}
|
||||||
|
PyQt5==5.9
|
||||||
|
commands = {envpython} -bb -m pytest {posargs:tests}
|
||||||
|
|
||||||
# other envs
|
# other envs
|
||||||
|
|
||||||
[testenv:mkvenv]
|
[testenv:mkvenv]
|
||||||
|
Loading…
Reference in New Issue
Block a user