Days 39/40/41: Lots of features!

A new blogpost is overdue, as I worked on qutebrowser again for the past three days! A lot of new features arrived, and this will hopefully make QtWebEngine usable as a daily driver for some people!

Adblocking

Perhaps the most exciting news first: adblocking is now available with QtWebEngine! The used Qt API is quite powerful, and hopefully will make it possible to implement something like uMatrix for qutebrowser somewhen in the coming months!

Right now, adblocking works the same as it did with QtWebKit, using the existing host block lists.

While implementing it, I noticed an interesting issue: qutebrowser did freeze and crash when there was an exception inside the request interceptor used to block the request. This is probably due to it running in Chromium's IO thread, which makes it impossible for us to display the usual crash report window. Instead, I added the utils.prevent_exceptions decorator in order to simply log exceptions happening there.

Opening windows via javascript

Some people already noticed how Qt ignored javascript trying to open a new window (via window.open()).

Support for that is now implemented, however unfortunately I did run into a Qt bug causing the qutebrowser javascript code not being loaded for windows opened that way (or, according to that report, possibly crashing).

This will be fixed in Qt 5.6.2 and 5.7.1, however neither is released yet. Their plan is to release Qt 5.6.2 in the coming weeks and then release 5.7.1 after that.

Those requests are currently silently ignored with older Qt versions. I tried adding an error message when that happens, however it was also displayed when opening a new link using middle-/ctrl-click, and I didn't find a way to tell the two apart.

If you don't want to wait until the release and happen to be on Archlinux, you can also use my qt-debug packages and set QUTE_QTBUG54419_PATCHED=1 in your environment. Note if you do that and don't have those fixed packages installed, stuff will break and I'll probably ignore all related crash logs ;)

On other distributions, you'll need to rebuild QtWebEngine with this patch.

Session support

Another feature many people missed was support for sessions, which is now implemented! Unfortunately (like Qt 5.6's QtWebKit), QtWebEngine has no API to manipulate the history of a tab programmatically, so qutebrowser instead creates a binary stream in Qt's internal serialization format and then loads that.

This was definitely made much easier by an existing implementation in Otter Browser (thanks!) and of course by QtWebEngine/Chromium being open source.

Initially, when loading the history, qutebrowser just segfaulted. After some debugging in Chromium's C++ code I figured out that was because I set the current history index to 0 instead of -1 when there are no history entries.

With this fixed, everything seems to work fine so far! The only thing missing (due to missing Qt API) is storing zoom level and scroll positions for earlier pages in the history (i.e., everything except the currently viewed one). However, I doubt many people will notice.

Running without QtWebKit

Since I wanted to get the OS X tests to run again (which lack QtWebKit due to it being removed from the Homebrew package manager), I looked into getting qutebrowser (and tests) to run without QtWebKit installed. After various small changes to how things are imported, this is now the case.

Tests and CI

Until now, qutebrowser with QtWebEngine wasn't tested on CI. This now changed, by adding a job for QtWebEngine with Archlinux.

With the session support added, I was also able to activate around 150 tests which were disabled before. This uncovered some smaller bugs like invalid URLs being added to the history sometimes (causing a warning to be printed), or cloning the zoom level when cloning a tab not working properly. Some tests (mainly for scrolling) also needed some additional waiting since scrolling now happens async (via javascript) with QtWebEngine.

There also were various small improvements to the output when tests fail, for cases I discovered thanks to those failing tests.

Unfortunately, a handful of tests are still flaky (failing sometimes), so I added a @qtwebengine_flaky marker and applied it to all tests which fail sometimes and I don't see an easy fix for yet.

Other bits and bytes

  • qutebrowser now knows when the scroll position is at the very bottom, so :scroll-page with --bottom-navigate works.
  • I tried making colors -> webpage.bg work, but without any luck.
  • The auto-insert-mode setting now works.
  • The :insert-text and :paste-primary commands were implemented.
  • webelem.classes got implemented for QtWebEngine which means the insert mode will now work correctly with things like the ACE editor (with a corresponding test added).
  • Custom HTTP headers, including the do-not-track and accept-language settings are now available with QtWebEngine
  • Qt 5.6.0 or newer is now enforced when using --backend webengine. This will probably stay the minimum version required for QtWebEngine support, I don't intend to add support for Qt 5.4 and 5.5.
  • Various blocks of now-unneeded or dead code got removed:
  • And probably some other stuff I forgot - as you can see, a lot happened in those three days!