Hey,

On Wed, Mar 06, 2019 at 02:07:31PM -0800, Jay Kamat wrote:
> 
> Florian Bruhin writes:
> 
> > - Chromium embedded framework (CEF) [1][2] - has Python bindings[3] with
> >   Qt integration[4], so the only one which would be reasonably possible
> >   to integrate with qutebrowser. However, I don't see much benefit over
> >   QtWebEngine, seeing that both are based on Chromium, and I'm not aware
> >   of any killer features (like Chromium extension support) which would
> >   be a good reason to look into it.
> 
> One killer feature would be avoiding qtwebengine bugs (if cef is any better).

I can't say I've tried, but I have my doubts that it is. Certainly not
to the point (IMHO) that it'd be worth the effort.

> I don't think cef is in any repos though, so it's probably not
> practical for most people.

Yeah, that was one big reason that I've never looked at it in detail. I
think the idea is that you bundle it with your application (like e.g.
Steam does) and compile it from source. There aren't even any official
builds (though Spotify provides[1] unofficial ones).

[1] http://opensource.spotify.com/cefbuilds/index.html

> >> In many cases, I found bugs in patches I submitted by running them
> >> against QtWebKit (that affected QtWebEngine in subtler ways) and vice 
> >> versa,
> >> so to me, even if no one uses QtWebKit it remains useful.
> >
> > Do you have examples for that?
> 
> I find that qtwebkit is more aggressive on cleaning up resources on the C
> side. Running a trivial manual/automated test in qtwebkit for a behavior often
> exposes use-after-free bugs.
> 
> The most recent one is this commit:
> 
> https://github.com/qutebrowser/qutebrowser/pull/4498/commits/128d17fe91db7fb1819d741c0aab072934abb3bb
> 
> Of course, there are other cases as well, I've seen qtwebkit tests catch other
> random bugs (which were bugs on the webengine side too but untested or
> flakey).

Fair point - that indeed sounds useful to have, but probably still not
useful enough for me to want to continue maintaining QtWebKit support
(even more so with Qt/PyQt 6 on the horizon, where I bet things will get
real painful) :-/

> >> The multiple backend approach works because there are multiple backends
> >> supported through similar (and in some cases, the same) PyQt5/Qt apis. 
> >> Adding
> >> support for another engine would be pretty difficult as you would need to
> >> integrate it into both qt (and PyQt5).
> >>
> >> I think it would be extremely difficult to add support for a renderer not
> >> integrated into qt, as qutebrowser is heavily dependent on qt for many 
> >> things.
> >
> > If you check the CEF example[4] it's actually not that bad - in brief:
> >
> > - Integrate the renderer's main loop with Qt (or configure it to run it
> >   its own thread, like I think done there).
> >
> > - Get the renderer to render into your window, by giving it a low-level
> >   window handle like in that example, or by providing it with an OpenGL
> >   thingy (surface?) to render on (which is what QtWebEngine does with
> >   Chromium, I think).
> >
> > - Dispatch some events like the window being moved/resized to the
> >   renderer.
> >
> > - Depending how things are implemented, dispatch input events as well,
> >   if Qt is getting them instead of the renderer (doesn't seem to be
> >   necessary in the CEF example).
> 
> I don't think that's necessarily the hard part. The hard part is syncing up
> the entire API so everything works seamlessly. Since the QtWebEngine/WebKit
> apis are large, this isn't trivial. That looks like a bare minimum
> implementation, but for proper integration into qutebrowser there are many
> more APIs that need to be exposed for everything to work as expected.

Whatever renderer we're talking about would already expose those APIs,
right? So there are "only" two things to consider:

- Making that API usable from Python via bindings (those already exist
  for CEF, but no idea how tricky it'd be to bind Rust for Servo).
- Using the Python API inside qutebrowser - I don't see a big difference
  between a Qt renderer and one independent from Qt here. Sure, you
  might need to convert e.g. URLs from whatever URL type it uses to
  QUrl, but that shouldn't be too big, compared to the work adding a new
  renderer takes anyways.

> >> It would probably be easier to just update QtWebKit to use a newer version 
> >> of
> >> WebKit.
> >
> > I doubt it. Doing that is not something a single developer is able to
> > do, as we saw with QtWebKit. Annulen isn't the only one who seems to
> > have given up either: https://github.com/annulen/webkit/issues/775
> > Like said above, I don't have any hopes of it happening without a
> > company picking it up (which doesn't seem to be happening either).
> 
> Updating QtWebKit must be easier because it's the exact same task (porting
> webkitgtk or plain webkit to qt) with a huge advantage - it already has a
> working example on an older version. (non chromium) browser engines don't have
> that advantage.

True - however, note that Qt primarely abandoned WebKit because it was
unmaintable (and I don't blame them). I've been watching QtWebKit (and
later QtWebEngine) development pretty much since the beginning of 2014,
and it became more and more apparent that they struggled to keep it
up-to-date (it diverged from upstream WebKit for quite a bit before they
decided to abandon it).

> There are several browser wrappers floating out there that are maintained by
> small groups - see this project for an example. The problem is that no one
> cares enough to maintain qtwebkit at the moment, not that it's a
> monumental/impossible task.
> 
> https://github.com/zserge/webview

You're comparing apples to oranges. That project (and other small ones)
are wildly different from something like QtWebKit, for two reasons:

- They just wrap existing abstractions which provide a stable API - in
  case of that project, they even use WebKitGTK on Linux.

- They only provide a very shallow API - not much more than loading a
  page and injecting JS into it.

That project is more comparable to webkittab.py/webenginetab.py in
qutebrowser. It's also quite small - 2265 lines of C (in a single header
file...) plus 572 lines with (hand-written) bindings to Go.

Things like QtWebKit/QtWebEngine/CEF/... are vastly bigger, exposing a
bigger API. They also need to patch the upstream sources because
upstream usually doesn't care much about them, and they need to keep
up-to-date with a crazy amount of changes (and changing APIs). We're
talking millions of changed lines with each Chromium update - IIRC, one
talk about QtWebEngine I watched said they spend around a man-month or
two each Qt release just for the Chromium upgrade.

I don't think things are looking any different with WebKit. For a while,
things apparently looked good with QtWebKit being a part of upstream
WebKit, but that changed mid-2013 when they were removed from there and
became a downstream port (forking the whole WebKit project - essentially
what QtWebEngine does with Chromium because Google doesn't care about
third-party projects).

Ever since, QtWebKit was lagging behind upstream WebKit, usually by some
years. I guess it was okay when I started qutebrowser and they still
were able to keep up with upstream, but it only got worse, even before
QtWebKit was officially deprecated.

I'm not sure how things are looking for CEF, but I doubt it's much
different. If it's any indication, I see builds since February based on
Chromium 72. Qt currently is at 71, working on 72 and 73[2][3]

(Chromium 72 is current, while 73 while be released in a few days[4])

[2] 
https://codereview.qt-project.org/#/q/branch:upstream-master+project:qt/qtwebengine-chromium,n,z
[3] 
https://codereview.qt-project.org/#/q/message:Adaptations+project:qt/qtwebengine,n,z
[4] https://www.chromium.org/developers/calendar

> In some ways, qtwebengine is maintained even worse than qtwebkit

It depends on how strongly you care about "does it keep up-to-date with
upstream changes, especially security fixes". I care a lot - if you use
something other than Qt 5.9 LTS/5.12, or if you use QtWebKit, you don't
care at all (or your distribution doesn't, hi Debian stable!).

If you don't care at all, maintaining suddenly gets a lot easier,
because you suddenly have a stable API (if you never update from
upstream) and some months of developer-time to spend.

It also means you'll be full of security issues, and run into
compatibility issues a few months to years down the road (see: GitHub
being broken with QtWebKit).

Fortunately, QtWebEngine developers do care. ;-)

> as it has multiple bugs which have never been present in qtwebkit

Contrary to QtWebKit, it doesn't segfault/freeze all the time.

> and it is struggling to add features which have been present in webkit
> for a long time.

For some of those (say, deeper network integration like with
QNetworkAccessManager, or a web element API for C++/Python, or the user
style sheet thing you linked), that's by design. If those aren't doable
with the API they get upstream from Chromium, implementing those would
cause the Chromium fork to diverge more from upstream, causing another
QtWebKit-like situation: A thing nobody wants to (or possibly can)
maintain anymore.

QtWebEngine saying "no" to those features is a good thing. I'd take me
writing some JS over QtWebEngine turning into an unmaintainable mess any
day, and I don't like JS.

Our best bet is waiting for some of Chromium's extension API to be
supported - it's also quite a maintenance burden for QtWebEngine most
likely, but it enables so many things that it seems to be worth it from
them, from what I've seen so far.

As for other things (like notifications): Yeah - I'm not too happy about
how long things take, but that's how things are. Qt has multiple (I'd
say five or so?) people working full-time on QtWebEngine, and a lot of
the time they're busy with running after Chromium upstream. That leaves
little time for new features. Pretty much the contrary - every major new
feature will mean slightly more time spent on Chromium updates in the
future.

I can't say I'm happy with the situation, but there's really no one to
blame. QtWebEngine-developers are doing great work (and most of it is
rather invisible, it seems), and The Qt Company can't really be blamed
for not hiring more people for QtWebEngine either (their main focus also
probably isn't a real web browser, but a web rendering component,
similar to how CEF is usually used).

If anything, I'd blame Google for not caring more about third-party
projects like CEF/QtWebEngine. If they'd make Chromium usable as a
library with a stable API, a lot would improve (and it'd probably make
it possible to upgrade Chromium separately from QtWebEngine). Then
again, it'd probably make things easier for Brave/Vivaldi/Opera/... as
well, and I guess Google isn't interested in that :D

I had high hopes for Servo there, but apparently embedders isn't what
Mozilla is after either. I'm not actually sure what the goal of Servo
is, as replacing Firefox isn't either. Probably to serve as a research
project for ideas which might later land in Firefox (like it happened
with Stylo, the component handling CSS). I guess if it's that, having a
stable API for embedders is also pretty much against their goals,
because experimenting and stability usually don't mix.

Maybe CEF has more manpower (at least some big companies are using it),
but again, I doubt things are looking much different there.

One person alone doing all that maintenance work in their spare time
just isn't going to happen.

> https://bugreports.qt.io/browse/QTBUG-51772
> - White flashes on page load (seems to be getting worse every release)

At least those two are present in Chromium as well, IIRC.
I agree some of the others are/were quite frustrating...

Living up to the "email is not SMS" link in my signature,

Florian

-- 
https://www.qutebrowser.org | m...@the-compiler.org (Mail/XMPP)
   GPG: 916E B0C8 FD55 A072 | https://the-compiler.org/pubkey.asc
         I love long mails! | https://email.is-not-s.ms/

Attachment: signature.asc
Description: PGP signature

Reply via email to