mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-07 08:39:22 +00:00
LibWebView+UI: Do not create a QApplication in headless mode
This is causing errors on the WPT runner, which does not have a display output. To do this requires shuffling around the Main::Arguments struct, as we now need access to it from overridden WebView::Application methods after construction.
This commit is contained in:
parent
f66cac3417
commit
fa164083fd
Notes:
github-actions[bot]
2025-06-10 22:11:59 +00:00
Author: https://github.com/trflynn89
Commit: fa164083fd
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5051
Reviewed-by: https://github.com/tcl3 ✅
6 changed files with 64 additions and 49 deletions
|
@ -85,6 +85,8 @@ Application::~Application()
|
||||||
|
|
||||||
void Application::initialize(Main::Arguments const& arguments)
|
void Application::initialize(Main::Arguments const& arguments)
|
||||||
{
|
{
|
||||||
|
m_arguments = arguments;
|
||||||
|
|
||||||
#ifndef AK_OS_WINDOWS
|
#ifndef 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())
|
||||||
|
@ -184,7 +186,7 @@ void Application::initialize(Main::Arguments const& arguments)
|
||||||
});
|
});
|
||||||
|
|
||||||
create_platform_arguments(args_parser);
|
create_platform_arguments(args_parser);
|
||||||
args_parser.parse(arguments);
|
args_parser.parse(m_arguments);
|
||||||
|
|
||||||
// Our persisted SQL storage assumes it runs in a singleton process. If we have multiple UI processes accessing
|
// Our persisted SQL storage assumes it runs in a singleton process. If we have multiple UI processes accessing
|
||||||
// the same underlying database, one of them is likely to fail.
|
// the same underlying database, one of them is likely to fail.
|
||||||
|
@ -235,7 +237,7 @@ void Application::initialize(Main::Arguments const& arguments)
|
||||||
m_browser_options.webdriver_content_ipc_path = *webdriver_content_ipc_path;
|
m_browser_options.webdriver_content_ipc_path = *webdriver_content_ipc_path;
|
||||||
|
|
||||||
m_web_content_options = {
|
m_web_content_options = {
|
||||||
.command_line = MUST(String::join(' ', arguments.strings)),
|
.command_line = MUST(String::join(' ', m_arguments.strings)),
|
||||||
.executable_path = MUST(String::from_byte_string(MUST(Core::System::current_executable_path()))),
|
.executable_path = MUST(String::from_byte_string(MUST(Core::System::current_executable_path()))),
|
||||||
.user_agent_preset = move(user_agent_preset),
|
.user_agent_preset = move(user_agent_preset),
|
||||||
.is_layout_test_mode = layout_test_mode ? IsLayoutTestMode::Yes : IsLayoutTestMode::No,
|
.is_layout_test_mode = layout_test_mode ? IsLayoutTestMode::Yes : IsLayoutTestMode::No,
|
||||||
|
|
|
@ -72,9 +72,9 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template<DerivedFrom<Application> ApplicationType>
|
template<DerivedFrom<Application> ApplicationType>
|
||||||
static NonnullOwnPtr<ApplicationType> create(Main::Arguments& arguments)
|
static NonnullOwnPtr<ApplicationType> create(Main::Arguments const& arguments)
|
||||||
{
|
{
|
||||||
auto app = adopt_own(*new ApplicationType { {}, arguments });
|
auto app = adopt_own(*new ApplicationType { {} });
|
||||||
app->initialize(arguments);
|
app->initialize(arguments);
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
|
@ -90,6 +90,8 @@ protected:
|
||||||
|
|
||||||
virtual Optional<ByteString> ask_user_for_download_folder() const { return {}; }
|
virtual Optional<ByteString> ask_user_for_download_folder() const { return {}; }
|
||||||
|
|
||||||
|
Main::Arguments& arguments() { return m_arguments; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize(Main::Arguments const& arguments);
|
void initialize(Main::Arguments const& arguments);
|
||||||
|
|
||||||
|
@ -134,6 +136,7 @@ private:
|
||||||
Settings m_settings;
|
Settings m_settings;
|
||||||
OwnPtr<ApplicationSettingsObserver> m_settings_observer;
|
OwnPtr<ApplicationSettingsObserver> m_settings_observer;
|
||||||
|
|
||||||
|
Main::Arguments m_arguments;
|
||||||
BrowserOptions m_browser_options;
|
BrowserOptions m_browser_options;
|
||||||
WebContentOptions m_web_content_options;
|
WebContentOptions m_web_content_options;
|
||||||
|
|
||||||
|
@ -157,16 +160,16 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define WEB_VIEW_APPLICATION(ApplicationType) \
|
#define WEB_VIEW_APPLICATION(ApplicationType) \
|
||||||
public: \
|
public: \
|
||||||
static NonnullOwnPtr<ApplicationType> create(Main::Arguments& arguments) \
|
static NonnullOwnPtr<ApplicationType> create(Main::Arguments const& arguments) \
|
||||||
{ \
|
{ \
|
||||||
return WebView::Application::create<ApplicationType>(arguments); \
|
return WebView::Application::create<ApplicationType>(arguments); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static ApplicationType& the() \
|
static ApplicationType& the() \
|
||||||
{ \
|
{ \
|
||||||
return static_cast<ApplicationType&>(WebView::Application::the()); \
|
return static_cast<ApplicationType&>(WebView::Application::the()); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
ApplicationType(Badge<WebView::Application>, Main::Arguments&);
|
ApplicationType(Badge<WebView::Application>);
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
namespace TestWeb {
|
namespace TestWeb {
|
||||||
|
|
||||||
Application::Application(Badge<WebView::Application>, Main::Arguments&)
|
Application::Application(Badge<WebView::Application>)
|
||||||
: test_concurrency(Core::System::hardware_concurrency())
|
: test_concurrency(Core::System::hardware_concurrency())
|
||||||
, python_executable_path("python3")
|
, python_executable_path("python3")
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
namespace Ladybird {
|
namespace Ladybird {
|
||||||
|
|
||||||
Application::Application(Badge<WebView::Application>, Main::Arguments&)
|
Application::Application(Badge<WebView::Application>)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,39 @@
|
||||||
|
|
||||||
namespace Ladybird {
|
namespace Ladybird {
|
||||||
|
|
||||||
Application::Application(Badge<WebView::Application>, Main::Arguments& arguments)
|
class LadybirdQApplication : public QApplication {
|
||||||
: QApplication(arguments.argc, arguments.argv)
|
public:
|
||||||
|
explicit LadybirdQApplication(Main::Arguments& arguments)
|
||||||
|
: QApplication(arguments.argc, arguments.argv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool event(QEvent* event) override
|
||||||
|
{
|
||||||
|
auto& application = static_cast<Application&>(WebView::Application::the());
|
||||||
|
|
||||||
|
switch (event->type()) {
|
||||||
|
case QEvent::FileOpen: {
|
||||||
|
if (!application.on_open_file)
|
||||||
|
break;
|
||||||
|
|
||||||
|
auto const& open_event = *static_cast<QFileOpenEvent const*>(event);
|
||||||
|
auto file = ak_string_from_qstring(open_event.file());
|
||||||
|
|
||||||
|
if (auto file_url = WebView::sanitize_url(file); file_url.has_value())
|
||||||
|
application.on_open_file(file_url.release_value());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QApplication::event(event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Application::Application(Badge<WebView::Application>)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +61,11 @@ void Application::create_platform_options(WebView::BrowserOptions&, WebView::Web
|
||||||
|
|
||||||
NonnullOwnPtr<Core::EventLoop> Application::create_platform_event_loop()
|
NonnullOwnPtr<Core::EventLoop> Application::create_platform_event_loop()
|
||||||
{
|
{
|
||||||
Core::EventLoopManager::install(*new WebView::EventLoopManagerQt);
|
if (!browser_options().headless_mode.has_value()) {
|
||||||
|
m_application = make<LadybirdQApplication>(arguments());
|
||||||
|
Core::EventLoopManager::install(*new WebView::EventLoopManagerQt);
|
||||||
|
}
|
||||||
|
|
||||||
auto event_loop = WebView::Application::create_platform_event_loop();
|
auto event_loop = WebView::Application::create_platform_event_loop();
|
||||||
|
|
||||||
if (!browser_options().headless_mode.has_value())
|
if (!browser_options().headless_mode.has_value())
|
||||||
|
@ -39,27 +74,6 @@ NonnullOwnPtr<Core::EventLoop> Application::create_platform_event_loop()
|
||||||
return event_loop;
|
return event_loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::event(QEvent* event)
|
|
||||||
{
|
|
||||||
switch (event->type()) {
|
|
||||||
case QEvent::FileOpen: {
|
|
||||||
if (!on_open_file)
|
|
||||||
break;
|
|
||||||
|
|
||||||
auto const& open_event = *static_cast<QFileOpenEvent const*>(event);
|
|
||||||
auto file = ak_string_from_qstring(open_event.file());
|
|
||||||
|
|
||||||
if (auto file_url = WebView::sanitize_url(file); file_url.has_value())
|
|
||||||
on_open_file(file_url.release_value());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return QApplication::event(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
BrowserWindow& Application::new_window(Vector<URL::URL> const& initial_urls, BrowserWindow::IsPopupWindow is_popup_window, Tab* parent_tab, Optional<u64> page_index)
|
BrowserWindow& Application::new_window(Vector<URL::URL> const& initial_urls, BrowserWindow::IsPopupWindow is_popup_window, Tab* parent_tab, Optional<u64> page_index)
|
||||||
{
|
{
|
||||||
auto* window = new BrowserWindow(initial_urls, is_popup_window, parent_tab, move(page_index));
|
auto* window = new BrowserWindow(initial_urls, is_popup_window, parent_tab, move(page_index));
|
||||||
|
|
|
@ -15,17 +15,12 @@
|
||||||
|
|
||||||
namespace Ladybird {
|
namespace Ladybird {
|
||||||
|
|
||||||
class Application
|
class Application : public WebView::Application {
|
||||||
: public QApplication
|
|
||||||
, public WebView::Application {
|
|
||||||
Q_OBJECT
|
|
||||||
WEB_VIEW_APPLICATION(Application)
|
WEB_VIEW_APPLICATION(Application)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~Application() override;
|
virtual ~Application() override;
|
||||||
|
|
||||||
virtual bool event(QEvent* event) override;
|
|
||||||
|
|
||||||
Function<void(URL::URL)> on_open_file;
|
Function<void(URL::URL)> on_open_file;
|
||||||
|
|
||||||
BrowserWindow& new_window(Vector<URL::URL> const& initial_urls, BrowserWindow::IsPopupWindow is_popup_window = BrowserWindow::IsPopupWindow::No, Tab* parent_tab = nullptr, Optional<u64> page_index = {});
|
BrowserWindow& new_window(Vector<URL::URL> const& initial_urls, BrowserWindow::IsPopupWindow is_popup_window = BrowserWindow::IsPopupWindow::No, Tab* parent_tab = nullptr, Optional<u64> page_index = {});
|
||||||
|
@ -39,6 +34,7 @@ private:
|
||||||
|
|
||||||
virtual Optional<ByteString> ask_user_for_download_folder() const override;
|
virtual Optional<ByteString> ask_user_for_download_folder() const override;
|
||||||
|
|
||||||
|
OwnPtr<QApplication> m_application;
|
||||||
BrowserWindow* m_active_window { nullptr };
|
BrowserWindow* m_active_window { nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue