Instead of painting synchronously whenever a Paint request comes in,
the WebContent process will now buffer pending paints and coalesce
them and defer the actual paint using a zero-timer.
This significantly reduces flickering already, without doing any
double-buffering in the WebContentView widget.
The WebContentView widget now inherits from GUI::ScrollableWidget and
will pass its scroll offset over to the WebContent process as it's
changing. This is not super efficient and can get a bit laggy, but it
will do fine as an initial scrolling implementation.
Just like the single-process Web::PageView widget, WebContentView also
paints scrolled content by translating the Gfx::Painter.
Port the WebContent service to the new MultiInstance mechanism that
Sergey added. This means that every new WebContentView gets its very
own segregated WebContent process.
"Paint" matches what we call this in the rest of the system. Let's not
confuse things by mixing paint/render/draw all the time. I'm guilty of
this in more places..
Also rename RenderingContext => PaintContext.
CSS defines a very specific paint order. This patch starts steering us
towards respecting that by introducing the PaintPhase enum with values:
- Background
- Border
- Foreground
- Overlay (internal overlays used by inspector)
Basically, to get the right visual result, we have to render the page
multiple times, going one phase at a time.
After layout, we may want to repaint the page, so we now listen for the
PageClient::page_did_invalidate() notification and use it to drive a
client-side repaint.
Note that an invalidation request from LibWeb makes a full roundtrip
to the WebContent client and back since the client drives painting.
The "WebContent" service provides a very restricted instance of LibWeb
running as an unprivileged user account. This will be used to implement
process separation in Browser, among other things.
This first cut of the service only spawns a single WebContent process
when someone connects to /tmp/portal/webcontent. We will soon switch
this over to spawning a new process for each connection.
Since this feature is very immature, we'll be bringing it up inside of
Demos/WebView as a separate demo program. Eventually this will become
a reusable widget that anyone can embed and easily get out-of-process
web content in their GUI.
This is pretty, pretty cool! :^)