When a tab or nested traversable navigable is closed, there might be
messages still in the pipe from the UI process that we need to
gracefully drop, rather than crash trying to access an invalid pointer.
The IPC layer between chromes and LibWeb now understands that multiple
top level traversables can live in each WebContent process.
This largely mechanical change adds a billion page_id/page_index
arguments to make sure that pages that end up opening new WebViews
through mechanisms like window.open() still work properly with those
extra windows.
This is a first step towards simplifying the ownership model of
Web::Page. Soon Web::Page will store its WebClient as a
NonnullGCPtr to help solve lifetime issues of the client being
destroyed before the page.
In order for same-origin NavigableContainers (iframe, frame, embed, ...)
and window.open() WindowProxies to have the proper JS access to their
embedder/opener, we need to host multiple top level traversables in the
same WebContent process. As a first step, make WebContent::PageHost hold
a HashMap of PageClient objects, each holding their own Web::Page that
represents a TraversableNavigable's API surface with the UI process.
The `page_did_request_scroll_to` API takes a CSS position, and thus
callers should not scale to device pixels before invoking it. Instead,
align this API with (most) other PageHost APIs which scale to device
pixels before sending the corresponding IPC message.
In the AppKit chrome, convert the provided device pixel position to a
widget position.
For each stacking context with an opacity less than 1, we create a
separate framebuffer. We then blit the texture attached to this
framebuffer with the specified opacity.
To avoid the performance overhead of reading pixels from the texture
into Gfx::Bitmap, a new method that allows for direct blitting from
the texture is introduced, named blit_scaled_texture().
This is an internal object that must be explicitly enabled by the chrome
before it is added to the Window. The Inspector object will be used by a
special WebView that will replace all chrome-specific inspector windows.
The IDL defines methods that this WebView will need to inform the chrome
of various events, such as the user clicking a DOM node.
Framebuffer object is allocated using OpenGL's API and is not platform
specific which means it could be used on both macOS and Linux unlike
EGL specific PBuffer.
In the upcoming changes, Painter will be used to store the state of
OpenGL context. For example, if Painter is aware of the shader that
have already been loaded, it will be possible to reuse them across
repaints. Also, it would be possible to manage state of loaded textures
and add/remove them depending on which ones are present in the next
sequence of painting commands.
Instead of relying on AK_OS_LINUX, actually use the more accurate
HAS_ACCELERATED_GRAPHICS define to figure out if we should try to use
the generic LibAccelGfx GPU painter.
This modification introduces a new layer to the painting process. The
stacking context traversal no longer immediately calls the
Gfx::Painter methods. Instead, it writes serialized painting commands
into newly introduced RecordingPainter. Created list of commands is
executed later to produce resulting bitmap.
Producing painting command list will make it easier to add new
optimizations:
- It's simpler to check if the painting result is not visible in the
viewport at the command level rather than during stacking context
traversal.
- Run painting in a separate thread. The painting thread can process
serialized painting commands, while the main thread can work on the
next paintable tree and safely invalidate the previous one.
- As we consider GPU-accelerated painting support, it would be easier
to back each painting command rather than constructing an alternative
for the entire Gfx::Painter API.
This commit introduces 3 things:
- Support for the color type in HTMLInputElement itself
- A mechanism for handling non event loop blocking dialogs in Page
- The associated plumbing up to ViewImplementation
Frontends may add support for the color picker with the
ViewImplementation.on_request_color_picker function
Fixes regression introduced in b4fe118dff
The `WebContentConsoleClient` needs to be created not just once, but
for every new document. Although the JS Console window allows
communication only with the active document associated with the
top-level browsing context, we still need a console client for each
iframe's document to ensure their console logs are printed.
In the future, we might consider adding the ability to switch which
document the JS Console window communicates with.
Fixes https://github.com/SerenityOS/serenity/issues/21117
Previously, we used `on_load_finish` to determine when the text test
was completed. This method did not allow testing of async functions
because there was no way to indicate that the runner should wait for
the async call to end.
This change introduces a function in the `internals` object that is
intended to be called when the text test execution is completed. The
text test runner will now ignore `on_load_finish` which means a test
will timeout if this new function is never called.
`test(f)` function in `include.js` has been modified to automatically
terminate a test once `load` event is fired on `window`.
new `asyncTest(f)` function has been introduces. `f` receives function
that will terminate a test as a first argument.
Every test is expected to call either `test()` or `asyncTest()` to
complete. If not, it will remain hanging until a timeout occurs.
Before page_did_create_main_document() only initialized ConsoleClient
for top-level browsing context which means that nested browsing context
could not print into the console.
With this change, ConsoleClient is initialized for documents created
for nested browsing context too. One ConsoleClient is shared between
all browsing contexts within the same page.
On Serenity and on my Linux machine, we have a 1:1 CSS-to-device pixel
ratio. On macOS, we have a 2:1 ratio. This did not affect the Qt chrome,
because we are ignoring this position and placing the context menu at
the globally-accessible mouse position. The AppKit chrome will be using
this position, though.
This might be what caused the issue worked around by commit 8177ecb.
Having all 4 of these methods together makes it more immediately obvious
that the 2 moved here are not correct (we are not converting the CSS
pixel point to a device pixel point).
Importantly, we now only consider overflow from descendants with
explicltly visible overflow, and only from descendants that have the
measured box as their containing block.
Also, we now measure scrollable overflow for all boxes, not just scroll
containers. This will allow us to fix a long-standing paint problem in
the next commit.
The data we want to send out of the WebContent process is identical for
audio and video elements. Rather than just duplicating all of this for
audio, generalize the names used for this IPC for all media elements.
This also encapsulates that data into a struct. This makes adding new
fields to be sent much easier (such as an upcoming field for muting the
element).
Although DistinctNumeric, which is supposed to abstract the underlying
type, was used to represent CSSPixels, we have a whole bunch of places
in the layout code that assume CSSPixels::value() returns a
floating-point type. This assumption makes it difficult to replace the
underlying type in CSSPixels with a non-floating type.
To make it easier to transition CSSPixels to fixed-point math, one step
we can take is to prevent access to the underlying type using value()
and instead use explicit conversions with the to_float(), to_double(),
and to_int() methods.
This allows for the browser process to control the play/pause state,
whether we paint user agent controls on the video, and whether the video
loops when it finishes playing.
This just sets up the IPC to notify the browser process of context menu
requests on video elements. The IPC contains a few pieces of information
about the state of the video element.
It returns a PaintableBox (a PaintableWithLines, to be specific), not a
'PaintBox'. paintable_box() without the cast is already available
through BlockContainer's Box base class, we don't need to shadow it.
Currently, on Serenity, we connect to WebDriver from the browser-side of
the WebContent connection for both Browser and headless-browser.
On Lagom, we connect from within the WebContent process itself, signaled
by a command line flag.
This patch changes Lagom browsers to connect to WebDriver the same way
that Serenity browsers do. This will ensure we can do other initializers
in the same order across all platforms and browsers.
LibGUI and WebDriver (read: JSON) API boundaries use DeprecatedString,
so that is as far as these changes can reach.
The one change which isn't just a DeprecatedString to String replacement
is handling the "null" prompt response. We previously checked for the
null DeprecatedString, whereas we now represent this as an empty
Optional<String>.
The name "initial containing block" was wrong for this, as it doesn't
correspond to the HTML element, and that's specifically what it's
supposed to do! :^)
There is currently a memory leak with these file request objects due to
the callback on_file_request_finish referencing itself in its capture
list. This object does not need to be reference counted or allocated on
the heap. It is only ever stored in a HashMap until a response is
received from the browser, and it is not shared.