Application.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <Ladybird/HelperProcess.h>
  7. #include <Ladybird/Qt/Application.h>
  8. #include <Ladybird/Qt/Settings.h>
  9. #include <Ladybird/Qt/StringUtils.h>
  10. #include <Ladybird/Qt/TaskManagerWindow.h>
  11. #include <Ladybird/Utilities.h>
  12. #include <LibCore/ArgsParser.h>
  13. #include <LibWebView/URL.h>
  14. #include <QFileDialog>
  15. #include <QFileOpenEvent>
  16. namespace Ladybird {
  17. Application::Application(Badge<WebView::Application>, Main::Arguments& arguments)
  18. : QApplication(arguments.argc, arguments.argv)
  19. {
  20. }
  21. void Application::create_platform_arguments(Core::ArgsParser& args_parser)
  22. {
  23. args_parser.add_option(m_enable_qt_networking, "Enable Qt as the backend networking service", "enable-qt-networking");
  24. }
  25. void Application::create_platform_options(WebView::ChromeOptions&, WebView::WebContentOptions& web_content_options)
  26. {
  27. web_content_options.config_path = Settings::the()->directory();
  28. web_content_options.use_lagom_networking = m_enable_qt_networking ? WebView::UseLagomNetworking::No : WebView::UseLagomNetworking::Yes;
  29. }
  30. Application::~Application()
  31. {
  32. close_task_manager_window();
  33. }
  34. bool Application::event(QEvent* event)
  35. {
  36. switch (event->type()) {
  37. case QEvent::FileOpen: {
  38. if (!on_open_file)
  39. break;
  40. auto const& open_event = *static_cast<QFileOpenEvent const*>(event);
  41. auto file = ak_string_from_qstring(open_event.file());
  42. if (auto file_url = WebView::sanitize_url(file); file_url.has_value())
  43. on_open_file(file_url.release_value());
  44. break;
  45. }
  46. default:
  47. break;
  48. }
  49. return QApplication::event(event);
  50. }
  51. static ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>> launch_new_image_decoder()
  52. {
  53. auto paths = TRY(get_paths_for_helper_process("ImageDecoder"sv));
  54. return launch_image_decoder_process(paths);
  55. }
  56. ErrorOr<void> Application::initialize_image_decoder()
  57. {
  58. m_image_decoder_client = TRY(launch_new_image_decoder());
  59. m_image_decoder_client->on_death = [this] {
  60. m_image_decoder_client = nullptr;
  61. if (auto err = this->initialize_image_decoder(); err.is_error()) {
  62. dbgln("Failed to restart image decoder: {}", err.error());
  63. VERIFY_NOT_REACHED();
  64. }
  65. auto num_clients = WebView::WebContentClient::client_count();
  66. auto new_sockets = m_image_decoder_client->send_sync_but_allow_failure<Messages::ImageDecoderServer::ConnectNewClients>(num_clients);
  67. if (!new_sockets || new_sockets->sockets().size() == 0) {
  68. dbgln("Failed to connect {} new clients to ImageDecoder", num_clients);
  69. VERIFY_NOT_REACHED();
  70. }
  71. WebView::WebContentClient::for_each_client([sockets = new_sockets->take_sockets()](WebView::WebContentClient& client) mutable {
  72. client.async_connect_to_image_decoder(sockets.take_last());
  73. return IterationDecision::Continue;
  74. });
  75. };
  76. return {};
  77. }
  78. void Application::show_task_manager_window()
  79. {
  80. if (!m_task_manager_window) {
  81. m_task_manager_window = new TaskManagerWindow(nullptr);
  82. }
  83. m_task_manager_window->show();
  84. m_task_manager_window->activateWindow();
  85. m_task_manager_window->raise();
  86. }
  87. void Application::close_task_manager_window()
  88. {
  89. if (m_task_manager_window) {
  90. m_task_manager_window->close();
  91. delete m_task_manager_window;
  92. m_task_manager_window = nullptr;
  93. }
  94. }
  95. BrowserWindow& Application::new_window(Vector<URL::URL> const& initial_urls, WebView::CookieJar& cookie_jar, BrowserWindow::IsPopupWindow is_popup_window, Tab* parent_tab, Optional<u64> page_index)
  96. {
  97. auto* window = new BrowserWindow(initial_urls, cookie_jar, is_popup_window, parent_tab, move(page_index));
  98. set_active_window(*window);
  99. window->show();
  100. if (initial_urls.is_empty()) {
  101. auto* tab = window->current_tab();
  102. if (tab) {
  103. tab->set_url_is_hidden(true);
  104. tab->focus_location_editor();
  105. }
  106. }
  107. window->activateWindow();
  108. window->raise();
  109. return *window;
  110. }
  111. Optional<ByteString> Application::ask_user_for_download_folder() const
  112. {
  113. auto path = QFileDialog::getExistingDirectory(nullptr, "Select download directory", QDir::homePath());
  114. if (path.isNull())
  115. return {};
  116. return ak_byte_string_from_qstring(path);
  117. }
  118. }