LibWebView+UI: Migrate some UI process init to LibWebView

No need to do this setup in every UI's main().
This commit is contained in:
Timothy Flynn 2025-06-10 19:20:46 -04:00 committed by Tim Flynn
parent 6430b215af
commit 39da2d9a2f
Notes: github-actions[bot] 2025-06-11 11:27:28 +00:00
10 changed files with 80 additions and 91 deletions

View file

@ -24,6 +24,10 @@
#include <LibWebView/Utilities.h> #include <LibWebView/Utilities.h>
#include <LibWebView/WebContentClient.h> #include <LibWebView/WebContentClient.h>
#if defined(AK_OS_MACOS)
# include <LibWebView/MachPortServer.h>
#endif
namespace WebView { namespace WebView {
Application* Application::s_the = nullptr; Application* Application::s_the = nullptr;
@ -46,7 +50,7 @@ struct ApplicationSettingsObserver : public SettingsObserver {
} }
}; };
Application::Application() Application::Application(Optional<ByteString> ladybird_binary_path)
: m_settings(Settings::create({})) : m_settings(Settings::create({}))
{ {
VERIFY(!s_the); VERIFY(!s_the);
@ -73,6 +77,8 @@ Application::Application()
m_process_manager.on_process_exited = [this](Process&& process) { m_process_manager.on_process_exited = [this](Process&& process) {
process_did_exit(move(process)); process_did_exit(move(process));
}; };
platform_init(move(ladybird_binary_path));
} }
Application::~Application() Application::~Application()
@ -83,16 +89,30 @@ Application::~Application()
s_the = nullptr; s_the = nullptr;
} }
void Application::initialize(Main::Arguments const& arguments) ErrorOr<void> Application::initialize(Main::Arguments const& arguments)
{ {
TRY(handle_attached_debugger());
m_arguments = arguments; m_arguments = arguments;
#ifndef AK_OS_WINDOWS #if !defined(AK_OS_WINDOWS)
// Increase the open file limit, as the default limits on Linux cause us to run out of file descriptors with around 15 tabs open. // Increase the open file limit, as the default limits on Linux cause us to run out of file descriptors with around 15 tabs open.
if (auto result = Core::System::set_resource_limits(RLIMIT_NOFILE, 8192); result.is_error()) if (auto result = Core::System::set_resource_limits(RLIMIT_NOFILE, 8192); result.is_error())
warnln("Unable to increase open file limit: {}", result.error()); warnln("Unable to increase open file limit: {}", result.error());
#endif #endif
#if defined(AK_OS_MACOS)
m_mach_port_server = make<MachPortServer>();
set_mach_server_name(m_mach_port_server->server_port_name());
m_mach_port_server->on_receive_child_mach_port = [this](auto pid, auto port) {
set_process_mach_port(pid, move(port));
};
m_mach_port_server->on_receive_backing_stores = [](MachPortServer::BackingStoresMessage message) {
if (auto view = WebContentClient::view_for_pid_and_page_id(message.pid, message.page_id); view.has_value())
view->did_allocate_iosurface_backing_stores(message.front_backing_store_id, move(message.front_backing_store_port), message.back_backing_store_id, move(message.back_backing_store_port));
};
#endif
Vector<ByteString> raw_urls; Vector<ByteString> raw_urls;
Vector<ByteString> certificates; Vector<ByteString> certificates;
Optional<HeadlessMode> headless_mode; Optional<HeadlessMode> headless_mode;
@ -256,6 +276,9 @@ void Application::initialize(Main::Arguments const& arguments)
create_platform_options(m_browser_options, m_web_content_options); create_platform_options(m_browser_options, m_web_content_options);
m_event_loop = create_platform_event_loop(); m_event_loop = create_platform_event_loop();
TRY(launch_services());
return {};
} }
static ErrorOr<NonnullRefPtr<WebContentClient>> create_web_content_client(Optional<ViewImplementation&> view) static ErrorOr<NonnullRefPtr<WebContentClient>> create_web_content_client(Optional<ViewImplementation&> view)

View file

@ -50,7 +50,6 @@ public:
static ProcessManager& process_manager() { return the().m_process_manager; } static ProcessManager& process_manager() { return the().m_process_manager; }
ErrorOr<NonnullRefPtr<WebContentClient>> launch_web_content_process(ViewImplementation&); ErrorOr<NonnullRefPtr<WebContentClient>> launch_web_content_process(ViewImplementation&);
ErrorOr<void> launch_services();
void add_child_process(Process&&); void add_child_process(Process&&);
@ -70,9 +69,9 @@ public:
void refresh_tab_list(); void refresh_tab_list();
protected: protected:
Application(); explicit Application(Optional<ByteString> ladybird_binary_path = {});
void initialize(Main::Arguments const&); ErrorOr<void> initialize(Main::Arguments const&);
virtual void process_did_exit(Process&&); virtual void process_did_exit(Process&&);
@ -85,6 +84,7 @@ protected:
Main::Arguments& arguments() { return m_arguments; } Main::Arguments& arguments() { return m_arguments; }
private: private:
ErrorOr<void> launch_services();
void launch_spare_web_content_process(); void launch_spare_web_content_process();
ErrorOr<void> launch_request_server(); ErrorOr<void> launch_request_server();
ErrorOr<void> launch_image_decoder_server(); ErrorOr<void> launch_image_decoder_server();
@ -145,24 +145,28 @@ private:
ProcessManager m_process_manager; ProcessManager m_process_manager;
bool m_in_shutdown { false }; bool m_in_shutdown { false };
#if defined(AK_OS_MACOS)
OwnPtr<MachPortServer> m_mach_port_server;
#endif
OwnPtr<DevTools::DevToolsServer> m_devtools; OwnPtr<DevTools::DevToolsServer> m_devtools;
} SWIFT_IMMORTAL_REFERENCE; } SWIFT_IMMORTAL_REFERENCE;
} }
#define WEB_VIEW_APPLICATION(ApplicationType) \ #define WEB_VIEW_APPLICATION(ApplicationType) \
public: \ public: \
template<typename... ApplicationArguments> \ template<typename... ApplicationArguments> \
static NonnullOwnPtr<ApplicationType> create(Main::Arguments const& arguments, ApplicationArguments&&... application_arguments) \ static ErrorOr<NonnullOwnPtr<ApplicationType>> create(Main::Arguments const& arguments, ApplicationArguments&&... application_arguments) \
{ \ { \
auto app = adopt_own(*new ApplicationType { forward<ApplicationArguments>(application_arguments)... }); \ auto app = adopt_own(*new ApplicationType { forward<ApplicationArguments>(application_arguments)... }); \
app->initialize(arguments); \ TRY(app->initialize(arguments)); \
return app; \ return app; \
} \ } \
\ \
static ApplicationType& the() \ static ApplicationType& the() \
{ \ { \
return static_cast<ApplicationType&>(WebView::Application::the()); \ return static_cast<ApplicationType&>(WebView::Application::the()); \
} \ } \
\ \
private: private:

View file

@ -6,6 +6,7 @@
#pragma once #pragma once
#include <AK/Platform.h>
#include <AK/Traits.h> #include <AK/Traits.h>
namespace WebView { namespace WebView {
@ -21,6 +22,10 @@ class ViewImplementation;
class WebContentClient; class WebContentClient;
class WebUI; class WebUI;
#if defined(AK_OS_MACOS)
class MachPortServer;
#endif
struct Attribute; struct Attribute;
struct AutocompleteEngine; struct AutocompleteEngine;
struct BrowserOptions; struct BrowserOptions;

View file

@ -9,6 +9,7 @@
#include <AK/Platform.h> #include <AK/Platform.h>
#include <LibCore/Directory.h> #include <LibCore/Directory.h>
#include <LibCore/Environment.h> #include <LibCore/Environment.h>
#include <LibCore/Process.h>
#include <LibCore/Resource.h> #include <LibCore/Resource.h>
#include <LibCore/ResourceImplementationFile.h> #include <LibCore/ResourceImplementationFile.h>
#include <LibCore/System.h> #include <LibCore/System.h>
@ -122,4 +123,18 @@ ErrorOr<Vector<ByteString>> get_paths_for_helper_process(StringView process_name
return paths; return paths;
} }
ErrorOr<void> handle_attached_debugger()
{
#if defined(AK_OS_LINUX)
// Let's ignore SIGINT if we're being debugged because GDB incorrectly forwards the signal to us even when it's set
// to "nopass". See https://sourceware.org/bugzilla/show_bug.cgi?id=9425 for details.
if (TRY(Core::Process::is_being_debugged())) {
dbgln("Debugger is attached, ignoring SIGINT");
TRY(Core::System::signal(SIGINT, SIG_IGN));
}
#endif
return {};
}
} }

View file

@ -22,4 +22,6 @@ extern ByteString s_ladybird_resource_root;
Optional<ByteString const&> mach_server_name(); Optional<ByteString const&> mach_server_name();
void set_mach_server_name(ByteString name); void set_mach_server_name(ByteString name);
ErrorOr<void> handle_attached_debugger();
} }

View file

@ -10,12 +10,12 @@
#include <LibCore/ArgsParser.h> #include <LibCore/ArgsParser.h>
#include <LibCore/Environment.h> #include <LibCore/Environment.h>
#include <LibCore/System.h> #include <LibCore/System.h>
#include <LibWebView/Utilities.h>
namespace TestWeb { namespace TestWeb {
Application::Application() Application::Application(Optional<ByteString> ladybird_binary_path)
: test_concurrency(Core::System::hardware_concurrency()) : WebView::Application(move(ladybird_binary_path))
, test_concurrency(Core::System::hardware_concurrency())
, python_executable_path("python3") , python_executable_path("python3")
{ {
if (auto ladybird_source_dir = Core::Environment::get("LADYBIRD_SOURCE_DIR"sv); ladybird_source_dir.has_value()) if (auto ladybird_source_dir = Core::Environment::get("LADYBIRD_SOURCE_DIR"sv); ladybird_source_dir.has_value())

View file

@ -17,7 +17,7 @@ class Application : public WebView::Application {
WEB_VIEW_APPLICATION(Application) WEB_VIEW_APPLICATION(Application)
public: public:
explicit Application(); explicit Application(Optional<ByteString> ladybird_binary_path);
~Application(); ~Application();
virtual void create_platform_arguments(Core::ArgsParser&) override; virtual void create_platform_arguments(Core::ArgsParser&) override;

View file

@ -711,14 +711,11 @@ static ErrorOr<int> run_tests(Core::AnonymousBuffer const& theme, Web::DevicePix
ErrorOr<int> serenity_main(Main::Arguments arguments) ErrorOr<int> serenity_main(Main::Arguments arguments)
{ {
#if defined(LADYBIRD_BINARY_PATH) #if defined(LADYBIRD_BINARY_PATH)
WebView::platform_init(LADYBIRD_BINARY_PATH); auto app = TRY(TestWeb::Application::create(arguments, LADYBIRD_BINARY_PATH));
#else #else
WebView::platform_init(); auto app = TRY(TestWeb::Application::create(arguments, OptionalNone {}));
#endif #endif
auto app = TestWeb::Application::create(arguments);
TRY(app->launch_services());
auto theme_path = LexicalPath::join(WebView::s_ladybird_resource_root, "themes"sv, "Default.ini"sv); auto theme_path = LexicalPath::join(WebView::s_ladybird_resource_root, "themes"sv, "Default.ini"sv);
auto theme = TRY(Gfx::load_system_theme(theme_path.string())); auto theme = TRY(Gfx::load_system_theme(theme_path.string()));

View file

@ -8,11 +8,7 @@
#include <LibMain/Main.h> #include <LibMain/Main.h>
#include <LibWebView/Application.h> #include <LibWebView/Application.h>
#include <LibWebView/BrowserProcess.h> #include <LibWebView/BrowserProcess.h>
#include <LibWebView/MachPortServer.h>
#include <LibWebView/URL.h> #include <LibWebView/URL.h>
#include <LibWebView/Utilities.h>
#include <LibWebView/ViewImplementation.h>
#include <LibWebView/WebContentClient.h>
#import <Application/Application.h> #import <Application/Application.h>
#import <Application/ApplicationDelegate.h> #import <Application/ApplicationDelegate.h>
@ -43,22 +39,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
{ {
AK::set_rich_debug_enabled(true); AK::set_rich_debug_enabled(true);
auto app = Ladybird::Application::create(arguments); auto app = TRY(Ladybird::Application::create(arguments));
WebView::platform_init();
auto mach_port_server = make<WebView::MachPortServer>();
WebView::set_mach_server_name(mach_port_server->server_port_name());
mach_port_server->on_receive_child_mach_port = [&](auto pid, auto port) {
app->set_process_mach_port(pid, move(port));
};
mach_port_server->on_receive_backing_stores = [](WebView::MachPortServer::BackingStoresMessage message) {
if (auto view = WebView::WebContentClient::view_for_pid_and_page_id(message.pid, message.page_id); view.has_value())
view->did_allocate_iosurface_backing_stores(message.front_backing_store_id, move(message.front_backing_store_port), message.back_backing_store_id, move(message.back_backing_store_port));
};
WebView::BrowserProcess browser_process; WebView::BrowserProcess browser_process;
TRY(app->launch_services());
if (auto const& browser_options = WebView::Application::browser_options(); !browser_options.headless_mode.has_value()) { if (auto const& browser_options = WebView::Application::browser_options(); !browser_options.headless_mode.has_value()) {
if (browser_options.force_new_process == WebView::ForceNewProcess::No) { if (browser_options.force_new_process == WebView::ForceNewProcess::No) {

View file

@ -4,8 +4,6 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibCore/Process.h>
#include <LibCore/System.h>
#include <LibMain/Main.h> #include <LibMain/Main.h>
#include <LibWebView/Application.h> #include <LibWebView/Application.h>
#include <LibWebView/BrowserProcess.h> #include <LibWebView/BrowserProcess.h>
@ -19,10 +17,6 @@
# include <QStyleHints> # include <QStyleHints>
#endif #endif
#if defined(AK_OS_MACOS)
# include <LibWebView/MachPortServer.h>
#endif
namespace Ladybird { namespace Ladybird {
// FIXME: Find a place to put this declaration (and other helper functions). // FIXME: Find a place to put this declaration (and other helper functions).
@ -45,47 +39,14 @@ bool is_using_dark_system_theme(QWidget& widget)
} }
static ErrorOr<void> handle_attached_debugger()
{
#ifdef AK_OS_LINUX
// Let's ignore SIGINT if we're being debugged because GDB
// incorrectly forwards the signal to us even when it's set to
// "nopass". See https://sourceware.org/bugzilla/show_bug.cgi?id=9425
// for details.
if (TRY(Core::Process::is_being_debugged())) {
dbgln("Debugger is attached, ignoring SIGINT");
TRY(Core::System::signal(SIGINT, SIG_IGN));
}
#endif
return {};
}
ErrorOr<int> serenity_main(Main::Arguments arguments) ErrorOr<int> serenity_main(Main::Arguments arguments)
{ {
AK::set_rich_debug_enabled(true); AK::set_rich_debug_enabled(true);
auto app = Ladybird::Application::create(arguments); auto app = TRY(Ladybird::Application::create(arguments));
TRY(handle_attached_debugger());
WebView::platform_init();
WebView::copy_default_config_files(Ladybird::Settings::the()->directory());
#if defined(AK_OS_MACOS)
auto mach_port_server = make<WebView::MachPortServer>();
WebView::set_mach_server_name(mach_port_server->server_port_name());
mach_port_server->on_receive_child_mach_port = [&app](auto pid, auto port) {
app->set_process_mach_port(pid, move(port));
};
mach_port_server->on_receive_backing_stores = [](WebView::MachPortServer::BackingStoresMessage message) {
if (auto view = WebView::WebContentClient::view_for_pid_and_page_id(message.pid, message.page_id); view.has_value())
view->did_allocate_iosurface_backing_stores(message.front_backing_store_id, move(message.front_backing_store_port), message.back_backing_store_id, move(message.back_backing_store_port));
};
#endif
WebView::BrowserProcess browser_process; WebView::BrowserProcess browser_process;
TRY(app->launch_services());
WebView::copy_default_config_files(Ladybird::Settings::the()->directory());
if (auto const& browser_options = Ladybird::Application::browser_options(); !browser_options.headless_mode.has_value()) { if (auto const& browser_options = Ladybird::Application::browser_options(); !browser_options.headless_mode.has_value()) {
if (browser_options.force_new_process == WebView::ForceNewProcess::No) { if (browser_options.force_new_process == WebView::ForceNewProcess::No) {