1899e313fd as a fix for #3631 broke :unbind, as
the config system treats None and '' equally.
Instead, allow None/'' again, but just handle it as "no binding".
This mostly reverts 4ef5db1bc4 for #1966, but
fixes#3684 by allowing numbers to be bound again. If the user wants to bind
numbers instead of using them for a count, why not let them.
With QtWebKit it's probably okay to still use it (*cough* Hyperbola
GNU/Linux-libre^tm *cough*), and only blacklisting it with QtWebEngine would be
quite some effort.
Fixes#3608
This handles Qt.KeypadModifier (Num+...) correctly, adds tests for converting
modifiers to strings, and strips Qt.GroupSwitchModifier as QKeySequence doesn't
know about it.
Fixes#3675
When pressing a key which doesn't exist as Qt.Key, we don't get Qt.Key_unknown
like we'd expect, but we get 0x0 instead...
Let's add that as a new "nil" key (to not conflict with None/unknown/zero/...)
and handle it appropriately.
This can be reproduced by doing:
setxkbmap -layout us,gr -option grp:alt_shift_toggle
and pressing Alt-Shift/Shift-Alt.
Turns out when we press yY, we get three events:
Qt.Key_Y, Qt.NoModifier
Qt.Key_Shift, Qt.ShiftModifier
Qt.Key_Y, Qt.ShiftModifier
If we don't ignore the second one, our keychain will be interrupted by the Shift
keypress.
Now that we don't rely on str(KeyInfo) being empty anywhere, there's no reason
to return an empty string for only-modifier keypresses anymore.
While those keys can't be bound (QKeySequence('Shift') == Qt.Key_unknown)
there's also no reason to explicitly ignore them.
Hopefully closes#3627
This feels like fixing the symptom instead of the problem but I am not
sure how such a situation would arise. Never the less, the crash logs
clearly show that `_inject_userjs()` is being called with a deleted
frame sometimes. It is being called from a closure that gets triggered
on frame.loadFinished so I am not sure how frame could be deleted at
that time unless:
* the error message is misleading and it is actually some reference to
the object that is no longer valid
* the frame gets deleted from some other handler of loadFinished.
Previously to add a greasemonkey script you had to write it to the
greasemonkey data directory and call load_scripts(). Now you can just
make a new GreasemonkeyScript and pass it to add_script(), yay.
There are no users of the method yet although I could have used it while
writing the tests.
When `@require`ing local files (with the `file://` scheme) the
greasemonkey manager was not catching the DownloadItem.finished signal
because it was being emitted before it had managed to connect.
I didn't see this happening while testing with files that should have
been in cache but I wouldn't be surprised.
I had to change the download mock to be able to give it the appearance
of asynchronicity. Now when using it one must set download.successful
appropriately before firing download.finished. I also added a list of
downloads to the stub so a test could enumerate them in case the
unit-under-test didn't have a reference to them.
This is for the case where a script uses `@require` to pull down another
greasemonkey script. Since QWebEngineScript doesn't support `@require`
we pass scripts to it with any required ones pre-pended. To avoid
QWebEngineScript parsing the first metadata block, the one from the
required script, we indent the whole lot. Because the greasemonkey spec
says that the //==UserScript== text must start in the first column.
Apparently the currently available QtWebkit's javascript engine doesn't
support Object.entries[1]. It was only using that because I had copied
it from the official gm4 polyfill (maybe I should open an issue there?).
Tested with libqt5webkit5 version 5.212.0~alpha2-5 (debian) and I was
getting the same type of failures as Travis so it looks like this is the
case in arch too.
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
This is to support the non-interactive use case of setting a
`FileDownloadTarget` and passing auto_remove and not caring if the target
file exists or not.
An alternative to adding the attribute to `FileDownloadTarget` and
having set_target pull it out would be to add a new param to `fetch()`
and `set_target()`. But it would only be used for one target type
anyway.
Based on the gm4-polyfill.js script from the greasemonkey devs. But not
the same because that script doesn't work for us for a couple of
reasons:
* It assumes all GM_* functions are attributes of `this` which in
this case is the global window object. Which breaks it out of our iife.
It is possible to change what `this` is within the iife but then we
would have to do something weird to ensure the functions were available
with the leading `this.`. And I don't think user javascripts tend to
call GM functions like that anyway, that polyfill script is just making
weird assumptions and then claiming it'll work for "any user script
engine".
* It tries to provide implementations of GM_registerMenuCommand and
GM_getResource text which do unexpected thins or implement a circular
dependency on the new version, respectively.
The greasemonkey spec states that user scripts should be able to put the URL
of a javascript source as the value of an `@require` key and expect to have
that script available in its scope. This commit supports deferring a user
script from being available until it's required scripts are downloaded,
downloading the scripts and prepending them onto the userscripts code before
placing it all in an iffe.
TODO:
* should I be saving the scripts somewhere else? Maybe the cache dir?
The are just going to data/greasemonkey/requires/ atm.
When min_chars is nonzero, if the first command that opens the
completion has < min_chars on the word under the cursor, it triggers a
check for a condition where last_cursor_pos is None.
By setting last_cursor_pos=-1 we ensure that the completer always
updates the first time it is opened, and that there is never a check
against None.
This adds a test for the min_chars feature.
Resolves#3635.
The --pygment argument allows to use the pygment version of view-source
over the qtwebengine internal one.
This version is slightly different in what's processed before the site
is generated, so some javascript created texts can be available.
On some pages like Qt's Gerrit, Indiegogo or Telegram Web, this caused a crash
with QtWebEngine and Qt 5.10.1 in
QtWebEngineCore::WebContentsAdapter::webContents().
I'm not sure what causes the crash exactly, but I'm guessing it's some kind of
race condition between loading the URL initially and deserializing the history,
which both ends up loading the URL.
Since restoring the history means we end up on the given URL anyways, let's just
not open the URL beforehand, which seems to fix this.
Fixes#3619.
This is emitted when we know that we're going to visit some URL, but Qt doesn't
know yet. This way, we can change the settings early, and since we know which
settings have actually changed, prevent a change needing a reload in
_on_navigation_request.
This refactors the whole web(kit|engine|) settings mess a bit so there's a
Web(Kit|Engine)Settings object for (non-static) settings set on a
QWeb(Engine)Settings object in Qt. Everything else is set on module-level a bit
less declaratively.
The whole inheritance mess is gone, and we can now also construct a
Web(Kit|Engine)Settings object for a given tab.
Fixes#2701
Those follow the following pattern:
1) "t" for 'toggle"
2) "s" for "scripts", upper-casing ("S") to make the toggle permanent
3) "h" for host, "H" for host with subdomains, "u" for the exact URL
There were two reasons why we deepcopy mutable objects in the config:
1) So mutations don't mess with our internal/default values.
2) So we can detect mutations and update the config.
If we're going to copy the value for 1) in maybe_copy(), we know the original
value is not going to be mutated, so we can use that directly for self._mutables
instead of making another copy.
The toggle option was failing to fire the changed signal when it removed
a bookmark. This means the bookmark file would not be marked as dirty,
and would not be saved on exit/autosave (unless another change was
made).
We originally made it per-window in b502280c06 for
issue #228, but that was back when we still needed window IDs for stuff like
message.info.
Nowadays, there's no reason for it to be per-window anymore. The rest of the
download code can deal with one global download manager (because QtWebEngine has
one), and apart from QNAM code which wasn't used here anyways (as tab_id=None)
there was nothing using the window ID anymore.
Also see #3456 which was the original motivation for this change.
We call 'update_tab_titles' a lot of times which calls 'setTabText' on
every tab. 'setTabText' calls tabSizeHint and minTabSizeHint on every
tab as well, meaning this is an n^2 operation repeated many times.
First, this prevents setTabText from being called unless it's needed,
removing most of the work done.
Second, I remove tabs in reverse, to avoid recomputing the above for
every tab on shutdown (which is at least n^3)
- fix test_renamed_key()
- fix test_deleted_key()
- combine both test_merge_persist tests using @pytest.mark.parametrize
- fix _handle_migrations(): mark data dirty for renamed and deleted
If we try to remove watched files but we couldn't actually watch any earlier,
we'd get a Qt warning message:
QtWarningMsg: QFileSystemWatcher::removePaths: list is empty
Added a --paste flag to the :version command and a JS button with corresponding qutescheme URL in the Version debug page to enable pastebinning version.
It was broken at least since caret support was introduced and it was only
available for QtWebKit anyways, so let's just drop it. This also makes the tab
API a bit simpler.
It looks like getting the selection via the widget has issues even with Qt 5.10.
On Windows, we always get wrong results.
On Linux, it seems to be flaky. I first thought this was because of a race
between JavaScript setting the selection and Qt getting it, as now we don't use
JS to get the selection anymore, so it's possible that we get it before the
older JS code finished running. However, even calling selectedText() from a JS
callback didn't seem to help...
Since has_selection also is flawed and it taking a callback would make code more
complex as well, let's just assume there is a selection if the text is not
empty. In fact, that is exactly what QtWebEngine does for hasSelection anyways!
Fixes#3523
This allows a second level of indirection quite cheaply, but is a
band-aid fix.
This commit should be taken as temporary until command arguments are
reworked.
Scope down the new trigger-on-save behavior to only open-editor and
config-edit. Other uses of the editor such as edit-url and edit-command
will behave as before.
With the previous code, the editor could miss the final signal on a
save-and-exit. This is avoided by always running the file changed
handler on a successful exit, but only firing the signal if the content
actually changed (to avoid double-signalling).
Now that the editor fires editing_finished on every write, the unit
tests had to be updated.
- Add qtbot to the editor fixture to resolve `QtWarningMsg:
QSocketNotifier: Can only be used with threads started with QThread`
- Use removePaths instead of disconnect to stop the watcher from
signalling. This avoids an error when the editor is forcibly cleaned
up by the tests without the signal ever being connected, but otherwise
has the same behavior as disconnecting the singal.
- wait for a signal on write instead of proc closed
- wait for _watcher.fileChanged in test_unreadable to ensure the write
event is fired before the test exits.
For any command that spawns an editor, tirgger an update on save, not
just on exit.
- :open-editor writes the text field on save
- :edit-url navigates on save
- :edit-url -t opens a new tab on each save
- :edit-command updates the statusbar text on save
- :edit-command --run runs a command on each save
- :config-edit reloads the config on save
Resolves#2307.
Helps mitigate #1596 by allowing users to 'save' partial work, and
notice if there was an error without closing the editor.
Use WebEngine's view-source: scheme for "view-source" command.
Also add missing URL when viewing source for WebKit.
Resolves#3490Resolves#2395Resolves#2948
When highlighting the matched part of the text, we need to html-escape
the pattern used to find the matching text so it will replace terms that
have been escaped in the text, like &.
Resolves#3508.
Enable write-ahead-logging and reduce the synchronous level to NORMAL.
This should reduce the number of writes to disk and avoid some of the
hangs users are experiencing.
Resolves#3507.
Resolves#2930 (optimistically, reopen if not fixed).
See https://sqlite.org/pragma.html and https://www.sqlite.org/wal.html.
Apparently is is not an unusual situation to leave it unset and rely on
the default. Logging a warning about this could be unnecerasily
confusing for users.
I'm leaving the log message in there if it is set to something weird
like `window-load` or `document-complete` which scriptish may support.
Like the spec says, if a value for the @include or @exclude rules starts
and ends with a '/' it should be parsed as a regular expression.
Technically a ECMAScript syntax regular expression, but I am not sure of
the differences and I assume they are far fewer than the similarities.
One that I did see mentioned was that javascript RegExp doesn't support
unicode. Although it apparently does support a 'u' flag now.
Note that code will only be ran for QtWebkit and QWebEngine < 5.8
we rely on the builtin support for metadata it QWebEngine for most
things greasemonkey related. Sadly it seems that they missed the regex
requirement too. I've opened a ticket to track that https://bugreports.qt.io/browse/QTBUG-65484
Always interpret the first word in the command string as the command to
offer completions for, even if that word looks like a flag.
Fixes#3460, where the command string `:-w open` would attempt to offer
completions for `open` but crash because the parsing was thrown off.
By moving the flag-stripping logic to _after_ we determine the command,
`:-w open` interprets `:-w` as the command. Since that is not a valid
command, we won't offer any completions.
Added spaces to comments, use python naming conventions, remove
_load_progress_fake as unnecessary, rename _on_load_*_fake to
_on_load_*_workaround (for less confusion), and use qtutils rather than
QT_VERSION_STR
This uses the much more reliable `loadProgress(100)` in place of
`loadFinished(true)` for WebEngine, with `loadProgressFake` and
`loadFinishedFake` used instead of the 'official' variants.
Update the description to mention the number of columns and change the
default to ["white", "white", "white"] to make it more obvious that
multiple colors can be specified. This also satisfies the config test
that expects the default value for ListOrValue types to be a list.
One other test had to be tweaked to use a config option that is still
just a QtColor rather than a ListOrValue.
While it is possible to provide just two colors, it is "undefined
behavior". It will use the first color as the third color, but that is
an artifact of the implementation and therefore not documented (though
also not an error, as it is harmless).
When QtWebEngine shuts down, it calls pending callbacks, which means we access
an invalid 'settings' object when that happens. The stack would look something
like this:
0 QtWebEngineCore::WebEngineSettings::setAttribute(QtWebEngineCore::WebEngineSettings::Attribute, bool)
12 QtWebEngineCore::CallbackDirectory::invokeEmptyInternal<QVariant const&>(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<QVariant const&>*)
14 QtWebEngineCore::CallbackDirectory::~CallbackDirectory()
19 QWebEnginePage::~QWebEnginePage()
If we instead get the settings from the view freshly, we get a RuntimeError from
PyQt telling us that it's dead. Not sure why it doesn't know about settings
being dead...
With that, we'd get a RuntimeError, which we can simply ignore as it doesn't
matter anyways if the tab is gone.
Fixes#3399
This means something like this:
:hint ;; later 20 follow-hint a ;; later 20 tab-close
Won't crash anymore, as the webelem.Error will be shown in the statusbar.
This gives us slightly different values it seems, but I think they are more
correct (and don't need the "+ 5" above).
Taking the width directly (not the sizeHint width) returned values like 100 or
so when the scrollbar wasn't shown yet, so that seems wrong.
The situation where there's no scroll bar at the point the column widths are
calculated is a very rare one. What happens more often is that the scroll bar
disappears due to filtering, in which case we didn't recalculate the column
widths anyways.
Furthermore, we can even go wrong with this calculation, when we calculate the
column widths while the entire completion is invisible - then the scroll bar
won't be visible either, and we won't subtract the space needed for it.
Let's not try to optimize for this uncommon case, and just always subtract the
scrollbar, even if it's not there initially.
Fixes#3359Closes#3389
Now colors.completion.fg may be set to a list to specify a different
color for each completion column. For example:
:set colors.completion.fg [black,blue,white] will use black text for the
first column, blue for the second, and white for the third.
Setting to a single value still works and behaves as before. The default
is unchanged from 'white'.
Resolves#1794.
command-accept --rapid will run the command without clearing the prompt,
allowing "rapid fire" commands. For example, one could open completion
for `open -t` and open several tabs in a row.
The default binding is ctrl+enter.
Resolves#588.
I mistakenly checked the length of wheres instead of words. This fixes
that check, renames 'wheres' to 'where_clause' to be clear
that it is a string and not an array, and adds a test.
Previously this simply crashed if there was ever malformed utf-8 in the
stderr or stdout streams, perhaps as a result of an incorrectly spawned
command. See e.g. #3222
re.match features an implicit left anchor, which can be surprising.
re.fullmatch features implicit anchors on both sides, but is aptly named
and unsurprising.
re.search has no such implicit anchors, which ought to be the default
even if a single anchor is needed.
Perviously, 'foo bar' would match 'foo/bar' but not 'bar/foo'. Now it
will match both, using a query with a WHERE clause like:
WHERE ((url || title) like '%foo%' AND (url || title) like '%bar%')
This does not seem to change the performance benchmark. However, it does
create a new query for every character added rather than re-running the
same query with different parameters. We could re-use queries if we
maintained a list like self._queries=[1_arg_query, 2_arg_query, ...].
However, it isn't clear that such a complexity would be necessary.
Resolves#1651.
This change makes it so that stderr and stdout is unconditionally read
from for a completed process, and sent to qute://spawn-output. This
allows the user to see the results of the previous process, even if they
had forgotten to use --output.
This fixes the following problems found in a review:
1. Manual modification of the asciidoc has been undone.
2. --output-to-tab has been renamed to the less verbose --output.
3. spawn_output has been changed to spawn-output in the url.
4. Erroneous newline in imports has been removed.
5. output in guiprocess.py has been marked private.
6. If there is no output for either stderr or stdout, say so.
7. Missing space in a text line was added.
8. Redundant initialising of an empty string removed.
This implements the orphaned editor fix for WebKit. Webkit wasn't
crashing before, but this causes webkit to show the same warning
webengine does if the editor is orhpaned (rather than silently
continuing). This allows the same BDD test to pass for both webkit and
webengine.
Instead of rewiring signals on tab.shutting_down, have the webelem check
if its parent tab is deleted, and throw a specific exception.
This is only necessary in WebEngine, Webkit does not crash when the
editor is orphaned.
I tried to write a test for is_deleted, but could not get it to pass:
```
def test_is_deleted(qtbot, view, config_stub, tab_registry, mode_manager):
tab_w = Tab(win_id=0, mode_manager=mode_manager)
qtbot.add_widget(tab_w)
tab_w._set_widget(view)
assert not tab_w.is_deleted()
sip.delete(view)
#assert tab_w.is_deleted()
```
The qtbot post-test cleanup would error due to the deleted view.
This reverts commit e72e8b8556.
Now that the SQL category works in isolation, it is possible to hide
quickmarks/bookmarks when those categories are empty.
Fixes#960
While QSortFilterProxyModel emits layoutChanged when changing the
pattern, QSqlQueryModel emits modelReset. As only layoutChanged was
connected, a HistoryCategory would only work in a model that also had at
least one ListCategory.
The simplest solution is to have the parent model emit the signal
directly. This also emits a single signal on a pattern change rather
that one for each child model.
Resolves#3016.
The signal we were using to inject greasemonkey scripts registered to
run at document-start (javaScriptWindowObjectCleared) was unreliable to
non-existant. The initialLayoutCompleted signal is a bit of an odd duck
too I suppose. Anyway, we don't anticipate any scripts would break from
being injected when the page is finished loaded that wouldn't already
have been flaky due to the complexities of the modern web. If there is
an issue hopefully someone raises an issue and we can look into it.
We weren't actually picking up the @noframes greasemonkey directive
because of this. I haven't tested this very extensively but it seems to
work for making the property value optional.
Use the `QWebPage.frameCreated` signal to get notifications of subframes
and connect the javascript injection triggering signals on those frames
too.
I had to add a `url = url() or requestedUrl()` bit in there because the
inject_userjs method was getting called to early or something when
frame.url() wasn't set or was set to the previous page so we were
passing the wrong url to greasemonkey.scripts_for().
I ran into a bizarre (I maybe it is completely obvious and I just don't
see it) issue where the signals attached to the main frame that were
connected to a partial function with the main frame as an argument were
not getting emitted, or at least those partial functions were not being
called. I worked around it by using None to mean defaulting to the main
frame in a couple of places.
Thanks to @sandrosc. A few breaking changes fixed (default method to
GM_xhr not working, GM_listvalues not cleaning up output, GM_setvalue
param checking logic wrong) and a few hygenic changes made.
Add qute version to GM_info object in GM wrapper.
Support using the greasemonkey @namespace metadata for its intended
purpose of avoiding name collisions.
Get a nice utf8 encoded string from a QUrl more better.
QTWebEngine 5.8 added support for parsing greasemonkey metadata blocks
and scripts added to the QWebEngineScriptCollection of a page or its
profile and then deciding what urls to run those scripts on and at what
point in the load process to run them. For earlier versions we must do
that work ourselves. But with the additional handicap of the less rich
qtwebengine api.
We have acceptNavigationRequest, loadStarted, loadProgress,
loadFinished, urlChanged to choose from regarding points at which to
register scripts for the current page.
Adding scripts on acceptNavigation loadStarted and loadFinished causes
scripts to run too early or too late (eg on the pages being navigated
from/to) and not run on the desired page at the time they are inserted.
We could maybe do some more sophisticated stuff with loadProgress but it
didn't have any better behaviour in the brief testing I gave it.
Registering scripts on the urlChanged event seems to work fine. Even if
it seems like there could be problems with the signal firing too often,
due to not necessarily being tied to the page load progress, that
doesn't seem to have an effect in practice. The event is fired when, for
example, the url fragment changes and even if we add a new script to the
collection (or remove an existing one) it doesn't have an effect on what
is running on the page.
I suspect all of those timing issues is due to the signals being
forwarded fairly directly from the underlying chomium/blink code but the
webengine script stuff only being pushed back to the implementation on
certain events.
Anyway, using urlChanged seems to work fine due to some quirk(s) of the
implementation. That might change with later development but this
codepath is only ever going to be used for version 5.7.
There are other potential optimizations like not removing and then
re-adding scripts for the current page. But they probably wouldn't do
anything anyway, or at least anything that you would expect.
This change requires urls specified in @include, @exclude and @matches
directives in metadata blocks to be in the same form that
QUrl.toEncoded() returns. That is a punycoded domain and percent encoded
path and query. This seems to be what Tampermonkey on chrome expects to.
Also changes the scripts_for() function to take a QUrl arg so the caller
doesn't need to worry about encodings.
This regex was broken since the original PR and subsequent code seemed to be
working around it. Before re.split was returning [everything up to
/UserScript, everything else], now it returns [before UserScript, metadata,
after /UserScript], which is good.
Also I added the check for the UserScript line starting at column 0 as per
spec.
These argument type restrictions are mentioned on the greasespot pages for
these value storage functions. We could call JSON.dumps() instead but better
to push that onto the caller so we don't have to try handle deserialization.
Also removes the check for localstorage because everyone has supported that
for years.
WebEngine only. Previously we were just removing every script from the
main world. But some other scripts might got here in the future so new
we are overriding the name field to add a GM- prefix so hopefully we
only remove greasemonkey scripts before adding new ones.
For qtwebengine 5.8+ only. This is because as of 5.8 some greasemonkey
script support is in upstream. That is, qtwebenginescript(collection)
parses the greasemonkey metadata block and uses @include/match/exclude
to decide what sites to inject a script onto and @run-at to decide when
to inject it, which saves us the trouble. Notes on doing this in <5.8
are below.
Scripts are currently injected into the main "world", that is the same
world as the javascript from the page. This is good because it means
userscripts can modify more stuff on the page but it would be nice if we
could have more isolation without sacrificing functionality. I'm still
looking into why my more feature-full scripts are not having any effect
on the page while running in a separate world.
Userscripts are added to both the default and private profile because I
that if people have scripts installed they want them to run in private mode
too.
We are grabbing the scripts from the greasemonkey module, as opposed to
reading them directly from disk, because the module adds some GM_* functions
that the scripts may expect, and because that is used for webkit anyway.
I have code to support qtwebengine <5.8 but didn't because I am not
happy with the timing of some of the signals that we are provided
regarding page load state, and the actual load state. While the
difference between document-end and document-idle isn't so bad,
injecting document-start scripts when a urlChanged event is emitted
results in the script being injected into the environment for the page
being navigated away from. Anyway, if anyone wants this for earlier
webengines I can oblige them.
Supposed to be after all the assets have finished loading and in page js
has run. Not that we can garuntee that last bit. If a script misbehaves
because a precondition isn't yet met I suggest adding a defer method to
the script that adds a timer until the precondition is met.
Also changed the map/filter calls to use list comprehensions to keep
pylint happy. Even if it does look uglier.
WebKit backend only for now. Loads all .js files from a directory,
specified in the greasemonkey-directory key in the storage section,
defaulting to data/greasemonkey, and wraps them in a minimal environment
providing some GM_* functions. Makes those scripts available via the
"greasemonkey" registered object in objreg and injects scripts at appropriate
times in a page load base on @run-at directives.
I can't reproduce this, but someone on KDE reported always getting a crash (as
msg.splitlines()[0] gives an IndexError) when trying to select a file with
Qt 5.9.3.
If an editor is open on a form in a tab and that tab is closed, rewire
the callback to print a warning. Previously, the callback would access a
deleted C++ object and cause a crash.
Resolves#2758.
Updated requirements and adjusted the configuration in `.flake8`; other
files have been modified where the lack of per-file auto-ignore caused
problems, where putty's `# flake8: disable=` syntax could be replaced
with a simpler `noqa`, or where pylint directives already suppressed the
same error.
Show an error message if the user edits the command such that it is
missing a start character (:, /, or ?). Previously, this would cause the
browser to crash.
Resolves#3326.
While 64-bit values are allowed with QtWebKit/QNetworkDiskCache, QtWebEngine
only allows 32-bit values here. With the updated sip's strict overflow checking,
that means we get an exception when setting a too big value.
:edit-command opens the current command line in an editor, and updates
the command line if the editor exits successfully. If --run is passed,
the command is executed when the editor exits sucessfully.
Resolves#2453.
If there are no quickmarks/bookmarks, hide the entire category in url
completion. Note that this only hides the category if
quickmarks/bookmarks is empty to begin with. An empty category is still
shown if the completion pattern filters out all items in that category.
See #960.