ladybird/Ladybird/Qt/Application.cpp
Timothy Flynn ed3c450359
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-22.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-14, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-22.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-22.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-22.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
LibWebView+UI: Move the database and cookie jar to WebView::Application
The main motivator here was noticing that --disable-sql-database did not
work with AppKit. Rather than re-implementing this there, move ownership
of these classes to WebView::Application, so that each UI does not need
to individually worry about it.
2024-09-05 19:45:47 -04:00

140 lines
4.3 KiB
C++

/*
* Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Ladybird/HelperProcess.h>
#include <Ladybird/Qt/Application.h>
#include <Ladybird/Qt/Settings.h>
#include <Ladybird/Qt/StringUtils.h>
#include <Ladybird/Qt/TaskManagerWindow.h>
#include <Ladybird/Utilities.h>
#include <LibCore/ArgsParser.h>
#include <LibWebView/URL.h>
#include <QFileDialog>
#include <QFileOpenEvent>
namespace Ladybird {
Application::Application(Badge<WebView::Application>, Main::Arguments& arguments)
: QApplication(arguments.argc, arguments.argv)
{
}
void Application::create_platform_arguments(Core::ArgsParser& args_parser)
{
args_parser.add_option(m_enable_qt_networking, "Enable Qt as the backend networking service", "enable-qt-networking");
}
void Application::create_platform_options(WebView::ChromeOptions&, WebView::WebContentOptions& web_content_options)
{
web_content_options.config_path = Settings::the()->directory();
web_content_options.use_lagom_networking = m_enable_qt_networking ? WebView::UseLagomNetworking::No : WebView::UseLagomNetworking::Yes;
}
Application::~Application()
{
close_task_manager_window();
}
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);
}
static ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>> launch_new_image_decoder()
{
auto paths = TRY(get_paths_for_helper_process("ImageDecoder"sv));
return launch_image_decoder_process(paths);
}
ErrorOr<void> Application::initialize_image_decoder()
{
m_image_decoder_client = TRY(launch_new_image_decoder());
m_image_decoder_client->on_death = [this] {
m_image_decoder_client = nullptr;
if (auto err = this->initialize_image_decoder(); err.is_error()) {
dbgln("Failed to restart image decoder: {}", err.error());
VERIFY_NOT_REACHED();
}
auto num_clients = WebView::WebContentClient::client_count();
auto new_sockets = m_image_decoder_client->send_sync_but_allow_failure<Messages::ImageDecoderServer::ConnectNewClients>(num_clients);
if (!new_sockets || new_sockets->sockets().size() == 0) {
dbgln("Failed to connect {} new clients to ImageDecoder", num_clients);
VERIFY_NOT_REACHED();
}
WebView::WebContentClient::for_each_client([sockets = new_sockets->take_sockets()](WebView::WebContentClient& client) mutable {
client.async_connect_to_image_decoder(sockets.take_last());
return IterationDecision::Continue;
});
};
return {};
}
void Application::show_task_manager_window()
{
if (!m_task_manager_window) {
m_task_manager_window = new TaskManagerWindow(nullptr);
}
m_task_manager_window->show();
m_task_manager_window->activateWindow();
m_task_manager_window->raise();
}
void Application::close_task_manager_window()
{
if (m_task_manager_window) {
m_task_manager_window->close();
delete m_task_manager_window;
m_task_manager_window = nullptr;
}
}
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));
set_active_window(*window);
window->show();
if (initial_urls.is_empty()) {
auto* tab = window->current_tab();
if (tab) {
tab->set_url_is_hidden(true);
tab->focus_location_editor();
}
}
window->activateWindow();
window->raise();
return *window;
}
Optional<ByteString> Application::ask_user_for_download_folder() const
{
auto path = QFileDialog::getExistingDirectory(nullptr, "Select download directory", QDir::homePath());
if (path.isNull())
return {};
return ak_byte_string_from_qstring(path);
}
}