ladybird/Services/WebContent/PageHost.cpp
Aliaksandr Kalenik 626dc6ff3f LibWebView+WebContent: Make page IDs browser-assigned
Page IDs were allocated independently by each WebContent PageHost,
starting at zero for every process. That made them unsuitable as a
global identity for page-presenting compositor contexts, because the
same numeric page ID could exist in multiple WebContent processes.

Move page ID allocation to WebView::Application and initialize each
WebContent process with its browser-assigned first page ID over IPC.
New view requests now get a browser-assigned page ID before
WebContent creates the PageClient, and PageHost no longer owns a
local page counter.

This gives page-presenting compositor contexts a stable global page
identity, which will allow their context IDs to be derived from page
IDs and simplify compositor context allocation in a follow-up.
2026-05-30 17:30:00 +01:00

67 lines
1.7 KiB
C++

/*
* Copyright (c) 2020-2023, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Bindings/MainThreadVM.h>
#include <LibWeb/Compositor/CompositorHost.h>
#include <LibWeb/HTML/TraversableNavigable.h>
#include <WebContent/ConnectionFromClient.h>
#include <WebContent/PageClient.h>
#include <WebContent/PageHost.h>
#include <WebContent/WebContentCompositorHost.h>
#include <WebContent/WebDriverConnection.h>
namespace WebContent {
PageHost::PageHost(ConnectionFromClient& client)
: m_client(client)
{
}
void PageHost::initialize(u64 initial_page_id)
{
VERIFY(m_pages.is_empty());
auto& first_page = create_page(initial_page_id);
Web::HTML::TraversableNavigable::create_a_fresh_top_level_traversable(first_page.page(), URL::about_blank());
}
PageClient& PageHost::create_page(u64 page_id)
{
VERIFY(page_id > 0);
VERIFY(!m_pages.contains(page_id));
m_pages.set(page_id, PageClient::create(Web::Bindings::main_thread_vm(), *this, page_id));
return *m_pages.get(page_id).value();
}
void PageHost::remove_page(Badge<PageClient>, u64 page_id)
{
m_pages.remove(page_id);
}
Optional<PageClient&> PageHost::page(u64 page_id)
{
return m_pages.get(page_id).map([](auto& value) -> PageClient& {
return *value;
});
}
PageHost::~PageHost() = default;
void PageHost::ensure_compositor_host()
{
if (m_compositor_host)
return;
m_compositor_host = create_web_content_compositor_host(m_client);
}
void PageHost::compositor_process_reconnected()
{
for (auto& [_, page] : m_pages)
page->compositor_process_reconnected();
}
}