2023-08-20 16:14:31 -04:00
|
|
|
/*
|
2024-07-30 14:01:05 -04:00
|
|
|
* Copyright (c) 2023-2024, Tim Flynn <trflynn89@serenityos.org>
|
2023-08-20 16:14:31 -04:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
|
*/
|
|
|
|
|
|
2024-11-09 12:50:33 -05:00
|
|
|
#include <Interface/LadybirdWebViewBridge.h>
|
2023-08-20 16:14:31 -04:00
|
|
|
#include <LibCore/EventLoop.h>
|
2024-04-28 10:48:29 -04:00
|
|
|
#include <LibCore/ThreadEventQueue.h>
|
2024-08-19 19:17:49 -04:00
|
|
|
#include <LibImageDecoderClient/Client.h>
|
|
|
|
|
#include <LibRequests/RequestClient.h>
|
|
|
|
|
#include <LibWebView/Application.h>
|
2024-11-10 10:26:07 -05:00
|
|
|
#include <LibWebView/HelperProcess.h>
|
|
|
|
|
#include <LibWebView/Utilities.h>
|
2024-04-15 17:39:48 -06:00
|
|
|
#include <LibWebView/WebContentClient.h>
|
2024-08-28 15:45:55 -04:00
|
|
|
#include <Utilities/Conversions.h>
|
2023-08-20 16:14:31 -04:00
|
|
|
|
|
|
|
|
#import <Application/Application.h>
|
|
|
|
|
|
|
|
|
|
#if !__has_feature(objc_arc)
|
|
|
|
|
# error "This project requires ARC"
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-08-19 19:17:49 -04:00
|
|
|
namespace Ladybird {
|
|
|
|
|
|
|
|
|
|
class ApplicationBridge : public WebView::Application {
|
|
|
|
|
WEB_VIEW_APPLICATION(ApplicationBridge)
|
2024-08-28 15:45:55 -04:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
virtual Optional<ByteString> ask_user_for_download_folder() const override
|
|
|
|
|
{
|
|
|
|
|
auto* panel = [NSOpenPanel openPanel];
|
|
|
|
|
[panel setAllowsMultipleSelection:NO];
|
|
|
|
|
[panel setCanChooseDirectories:YES];
|
|
|
|
|
[panel setCanChooseFiles:NO];
|
|
|
|
|
[panel setMessage:@"Select download directory"];
|
|
|
|
|
|
|
|
|
|
if ([panel runModal] != NSModalResponseOK)
|
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
return Ladybird::ns_string_to_byte_string([[panel URL] path]);
|
|
|
|
|
}
|
2024-08-19 19:17:49 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ApplicationBridge::ApplicationBridge(Badge<WebView::Application>, Main::Arguments&)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-20 16:14:31 -04:00
|
|
|
@interface Application ()
|
2024-04-15 17:39:48 -06:00
|
|
|
{
|
|
|
|
|
OwnPtr<Ladybird::ApplicationBridge> m_application_bridge;
|
2024-08-19 19:17:49 -04:00
|
|
|
|
|
|
|
|
RefPtr<Requests::RequestClient> m_request_server_client;
|
|
|
|
|
RefPtr<ImageDecoderClient::Client> m_image_decoder_client;
|
2024-04-15 17:39:48 -06:00
|
|
|
}
|
|
|
|
|
|
2023-08-20 16:14:31 -04:00
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@implementation Application
|
|
|
|
|
|
2024-07-30 14:01:05 -04:00
|
|
|
#pragma mark - Public methods
|
2024-04-15 17:39:48 -06:00
|
|
|
|
2024-07-30 14:01:05 -04:00
|
|
|
- (void)setupWebViewApplication:(Main::Arguments&)arguments
|
|
|
|
|
newTabPageURL:(URL::URL)new_tab_page_url
|
|
|
|
|
{
|
|
|
|
|
m_application_bridge = Ladybird::ApplicationBridge::create(arguments, move(new_tab_page_url));
|
2024-04-15 17:39:48 -06:00
|
|
|
}
|
|
|
|
|
|
2024-07-30 14:01:05 -04:00
|
|
|
- (ErrorOr<void>)launchRequestServer
|
2024-04-15 17:39:48 -06:00
|
|
|
{
|
2024-11-10 10:26:07 -05:00
|
|
|
auto request_server_paths = TRY(WebView::get_paths_for_helper_process("RequestServer"sv));
|
|
|
|
|
m_request_server_client = TRY(WebView::launch_request_server_process(request_server_paths, WebView::s_ladybird_resource_root));
|
2024-08-19 19:17:49 -04:00
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>> launch_new_image_decoder()
|
|
|
|
|
{
|
2024-11-10 10:26:07 -05:00
|
|
|
auto image_decoder_paths = TRY(WebView::get_paths_for_helper_process("ImageDecoder"sv));
|
|
|
|
|
return WebView::launch_image_decoder_process(image_decoder_paths);
|
2024-04-15 17:39:48 -06:00
|
|
|
}
|
|
|
|
|
|
2024-06-26 13:44:42 -06:00
|
|
|
- (ErrorOr<void>)launchImageDecoder
|
|
|
|
|
{
|
2024-08-19 19:17:49 -04:00
|
|
|
m_image_decoder_client = TRY(launch_new_image_decoder());
|
|
|
|
|
|
|
|
|
|
__weak Application* weak_self = self;
|
|
|
|
|
|
|
|
|
|
m_image_decoder_client->on_death = [weak_self]() {
|
|
|
|
|
Application* self = weak_self;
|
|
|
|
|
if (self == nil) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_image_decoder_client = nullptr;
|
|
|
|
|
|
|
|
|
|
if (auto err = [self launchImageDecoder]; 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 {};
|
2024-06-26 13:44:42 -06:00
|
|
|
}
|
|
|
|
|
|
2024-04-15 17:39:48 -06:00
|
|
|
- (ErrorOr<NonnullRefPtr<WebView::WebContentClient>>)launchWebContent:(Ladybird::WebViewBridge&)web_view_bridge
|
|
|
|
|
{
|
2024-08-19 19:17:49 -04:00
|
|
|
// FIXME: Fail to open the tab, rather than crashing the whole application if this fails
|
2024-11-10 10:26:07 -05:00
|
|
|
auto request_server_socket = TRY(WebView::connect_new_request_server_client(*m_request_server_client));
|
|
|
|
|
auto image_decoder_socket = TRY(WebView::connect_new_image_decoder_client(*m_image_decoder_client));
|
2024-08-19 19:17:49 -04:00
|
|
|
|
2024-11-10 10:26:07 -05:00
|
|
|
auto web_content_paths = TRY(WebView::get_paths_for_helper_process("WebContent"sv));
|
|
|
|
|
auto web_content = TRY(WebView::launch_web_content_process(web_view_bridge, web_content_paths, move(image_decoder_socket), move(request_server_socket)));
|
2024-08-19 19:17:49 -04:00
|
|
|
|
|
|
|
|
return web_content;
|
2024-04-15 17:39:48 -06:00
|
|
|
}
|
|
|
|
|
|
2024-04-17 18:44:39 -06:00
|
|
|
- (ErrorOr<IPC::File>)launchWebWorker
|
2024-04-15 17:39:48 -06:00
|
|
|
{
|
2024-11-10 10:26:07 -05:00
|
|
|
auto web_worker_paths = TRY(WebView::get_paths_for_helper_process("WebWorker"sv));
|
|
|
|
|
auto worker_client = TRY(WebView::launch_web_worker_process(web_worker_paths, *m_request_server_client));
|
2024-08-19 19:17:49 -04:00
|
|
|
|
2024-10-22 15:47:33 -06:00
|
|
|
return worker_client->clone_transport();
|
2024-04-15 17:39:48 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - NSApplication
|
|
|
|
|
|
2023-08-20 16:14:31 -04:00
|
|
|
- (void)terminate:(id)sender
|
|
|
|
|
{
|
|
|
|
|
Core::EventLoop::current().quit(0);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-28 10:48:29 -04:00
|
|
|
- (void)sendEvent:(NSEvent*)event
|
|
|
|
|
{
|
|
|
|
|
if ([event type] == NSEventTypeApplicationDefined) {
|
|
|
|
|
Core::ThreadEventQueue::current().process();
|
|
|
|
|
} else {
|
|
|
|
|
[super sendEvent:event];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-20 16:14:31 -04:00
|
|
|
@end
|