LibWebView+UI: Launch the DevTools server if --devtools is specified

This replaces the --devtools-port flag with a --devtools flag, which
optionally accepts a port. If the --devtools flag is set, we will now
automatically launch the DevTools server.
This commit is contained in:
Timothy Flynn 2025-07-02 12:42:53 -04:00 committed by Tim Flynn
commit b55d2909f6
Notes: github-actions[bot] 2025-07-02 19:29:12 +00:00
5 changed files with 43 additions and 11 deletions

View file

@ -5,10 +5,10 @@ with the DevTools client.
## Using DevTools ## Using DevTools
The DevTools server may be enabled in the "Inspect" menu via the "Enable DevTools" menu item. A banner will be displayed The DevTools server may be enabled in the "Inspect" menu via the "Enable DevTools" menu item, or with the `--devtools`
in Ladybird with the port on which the DevTools server is listening. This port may be changed with the `--devtools-port` command line flag. A banner will be displayed in Ladybird with the port on which the DevTools server is listening. This
command line flag. To disable DevTools, use the same menu item (which will now be titled "Disable DevTools"), or close port may be changed by providing a port to the command line flag, e.g. `--devtools=6001`. To disable DevTools, use the
the banner. menu item (which will now be titled "Disable DevTools"), or close the banner.
Once DevTools is enabled, in Firefox, navigate to `about:debugging` and select the "Setup" tab. In the "Network Location" Once DevTools is enabled, in Firefox, navigate to `about:debugging` and select the "Setup" tab. In the "Network Location"
form, enter the DevTools server address. In the above example, this will be `localhost:6000`. You will only have to form, enter the DevTools server address. In the above example, this will be `localhost:6000`. You will only have to

View file

@ -101,7 +101,7 @@ ErrorOr<void> Application::initialize(Main::Arguments const& arguments)
bool allow_popups = false; bool allow_popups = false;
bool disable_scripting = false; bool disable_scripting = false;
bool disable_sql_database = false; bool disable_sql_database = false;
u16 devtools_port = WebView::default_devtools_port; Optional<u16> devtools_port;
Optional<StringView> debug_process; Optional<StringView> debug_process;
Optional<StringView> profile_process; Optional<StringView> profile_process;
Optional<StringView> webdriver_content_ipc_path; Optional<StringView> webdriver_content_ipc_path;
@ -157,7 +157,6 @@ ErrorOr<void> Application::initialize(Main::Arguments const& arguments)
args_parser.add_option(debug_process, "Wait for a debugger to attach to the given process name (WebContent, RequestServer, etc.)", "debug-process", 0, "process-name"); args_parser.add_option(debug_process, "Wait for a debugger to attach to the given process name (WebContent, RequestServer, etc.)", "debug-process", 0, "process-name");
args_parser.add_option(profile_process, "Enable callgrind profiling of the given process name (WebContent, RequestServer, etc.)", "profile-process", 0, "process-name"); args_parser.add_option(profile_process, "Enable callgrind profiling of the given process name (WebContent, RequestServer, etc.)", "profile-process", 0, "process-name");
args_parser.add_option(webdriver_content_ipc_path, "Path to WebDriver IPC for WebContent", "webdriver-content-path", 0, "path", Core::ArgsParser::OptionHideMode::CommandLineAndMarkdown); args_parser.add_option(webdriver_content_ipc_path, "Path to WebDriver IPC for WebContent", "webdriver-content-path", 0, "path", Core::ArgsParser::OptionHideMode::CommandLineAndMarkdown);
args_parser.add_option(devtools_port, "Set the Firefox DevTools server port ", "devtools-port", 0, "port");
args_parser.add_option(layout_test_mode, "Enable layout test mode", "layout-test-mode"); args_parser.add_option(layout_test_mode, "Enable layout test mode", "layout-test-mode");
args_parser.add_option(log_all_js_exceptions, "Log all JavaScript exceptions", "log-all-js-exceptions"); args_parser.add_option(log_all_js_exceptions, "Log all JavaScript exceptions", "log-all-js-exceptions");
args_parser.add_option(disable_site_isolation, "Disable site isolation", "disable-site-isolation"); args_parser.add_option(disable_site_isolation, "Disable site isolation", "disable-site-isolation");
@ -174,6 +173,21 @@ ErrorOr<void> Application::initialize(Main::Arguments const& arguments)
args_parser.add_option(use_dns_over_tls, "Use DNS over TLS", "dot"); args_parser.add_option(use_dns_over_tls, "Use DNS over TLS", "dot");
args_parser.add_option(validate_dnssec_locally, "Validate DNSSEC locally", "dnssec"); args_parser.add_option(validate_dnssec_locally, "Validate DNSSEC locally", "dnssec");
args_parser.add_option(Core::ArgsParser::Option {
.argument_mode = Core::ArgsParser::OptionArgumentMode::Optional,
.help_string = "Enable the Firefox DevTools server, with an optional port",
.long_name = "devtools",
.value_name = "port",
.accept_value = [&](StringView value) {
if (value.is_empty())
devtools_port = WebView::default_devtools_port;
else
devtools_port = value.to_number<u16>();
return devtools_port.has_value();
},
});
args_parser.add_option(Core::ArgsParser::Option { args_parser.add_option(Core::ArgsParser::Option {
.argument_mode = Core::ArgsParser::OptionArgumentMode::Required, .argument_mode = Core::ArgsParser::OptionArgumentMode::Required,
.help_string = "Name of the User-Agent preset to use in place of the default User-Agent", .help_string = "Name of the User-Agent preset to use in place of the default User-Agent",
@ -350,6 +364,10 @@ ErrorOr<void> Application::launch_services()
TRY(launch_request_server()); TRY(launch_request_server());
TRY(launch_image_decoder_server()); TRY(launch_image_decoder_server());
if (m_browser_options.devtools_port.has_value())
TRY(launch_devtools_server());
return {}; return {};
} }
@ -395,7 +413,11 @@ ErrorOr<void> Application::launch_image_decoder_server()
ErrorOr<void> Application::launch_devtools_server() ErrorOr<void> Application::launch_devtools_server()
{ {
VERIFY(!m_devtools); VERIFY(!m_devtools);
m_devtools = TRY(DevTools::DevToolsServer::create(*this, m_browser_options.devtools_port));
if (!m_browser_options.devtools_port.has_value())
m_browser_options.devtools_port = WebView::default_devtools_port;
m_devtools = TRY(DevTools::DevToolsServer::create(*this, *m_browser_options.devtools_port));
return {}; return {};
} }

View file

@ -84,7 +84,7 @@ struct BrowserOptions {
Optional<ProcessType> profile_helper_process {}; Optional<ProcessType> profile_helper_process {};
Optional<ByteString> webdriver_content_ipc_path {}; Optional<ByteString> webdriver_content_ipc_path {};
Optional<DNSSettings> dns_settings {}; Optional<DNSSettings> dns_settings {};
u16 devtools_port { default_devtools_port }; Optional<u16> devtools_port;
}; };
enum class IsLayoutTestMode { enum class IsLayoutTestMode {

View file

@ -753,9 +753,14 @@
- (void)applicationDidFinishLaunching:(NSNotification*)notification - (void)applicationDidFinishLaunching:(NSNotification*)notification
{ {
auto const& browser_options = WebView::Application::browser_options();
if (browser_options.devtools_port.has_value())
[self devtoolsEnabled];
Tab* tab = nil; Tab* tab = nil;
for (auto const& url : WebView::Application::browser_options().urls) { for (auto const& url : browser_options.urls) {
auto activate_tab = tab == nil ? Web::HTML::ActivateTab::Yes : Web::HTML::ActivateTab::No; auto activate_tab = tab == nil ? Web::HTML::ActivateTab::Yes : Web::HTML::ActivateTab::No;
auto* controller = [self createNewTab:url auto* controller = [self createNewTab:url

View file

@ -75,6 +75,8 @@ BrowserWindow::BrowserWindow(Vector<URL::URL> const& initial_urls, IsPopupWindow
, m_new_tab_button_toolbar(new QToolBar("New Tab", m_tabs_container)) , m_new_tab_button_toolbar(new QToolBar("New Tab", m_tabs_container))
, m_is_popup_window(is_popup_window) , m_is_popup_window(is_popup_window)
{ {
auto const& browser_options = WebView::Application::browser_options();
setWindowIcon(app_icon()); setWindowIcon(app_icon());
// Listen for DPI changes // Listen for DPI changes
@ -549,7 +551,7 @@ BrowserWindow::BrowserWindow(Vector<URL::URL> const& initial_urls, IsPopupWindow
m_enable_scripting_action = new QAction("Enable Scripting", this); m_enable_scripting_action = new QAction("Enable Scripting", this);
m_enable_scripting_action->setCheckable(true); m_enable_scripting_action->setCheckable(true);
m_enable_scripting_action->setChecked(WebView::Application::browser_options().disable_scripting == WebView::DisableScripting::No); m_enable_scripting_action->setChecked(browser_options.disable_scripting == WebView::DisableScripting::No);
debug_menu->addAction(m_enable_scripting_action); debug_menu->addAction(m_enable_scripting_action);
QObject::connect(m_enable_scripting_action, &QAction::triggered, this, [this] { QObject::connect(m_enable_scripting_action, &QAction::triggered, this, [this] {
bool state = m_enable_scripting_action->isChecked(); bool state = m_enable_scripting_action->isChecked();
@ -571,7 +573,7 @@ BrowserWindow::BrowserWindow(Vector<URL::URL> const& initial_urls, IsPopupWindow
m_block_pop_ups_action = new QAction("Block Pop-ups", this); m_block_pop_ups_action = new QAction("Block Pop-ups", this);
m_block_pop_ups_action->setCheckable(true); m_block_pop_ups_action->setCheckable(true);
m_block_pop_ups_action->setChecked(WebView::Application::browser_options().allow_popups == WebView::AllowPopups::No); m_block_pop_ups_action->setChecked(browser_options.allow_popups == WebView::AllowPopups::No);
debug_menu->addAction(m_block_pop_ups_action); debug_menu->addAction(m_block_pop_ups_action);
QObject::connect(m_block_pop_ups_action, &QAction::triggered, this, [this] { QObject::connect(m_block_pop_ups_action, &QAction::triggered, this, [this] {
bool state = m_block_pop_ups_action->isChecked(); bool state = m_block_pop_ups_action->isChecked();
@ -683,6 +685,9 @@ BrowserWindow::BrowserWindow(Vector<URL::URL> const& initial_urls, IsPopupWindow
setCentralWidget(m_tabs_container); setCentralWidget(m_tabs_container);
setContextMenuPolicy(Qt::PreventContextMenu); setContextMenuPolicy(Qt::PreventContextMenu);
if (browser_options.devtools_port.has_value())
devtools_enabled();
} }
void BrowserWindow::devtools_disabled() void BrowserWindow::devtools_disabled()