diff --git a/CMakeLists.txt b/CMakeLists.txt index 95fb560356b..ecea1b97769 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,12 +68,6 @@ endif() add_cxx_compile_options(-Wno-expansion-to-defined) add_cxx_compile_options(-Wno-user-defined-literals) -if (ANDROID OR APPLE) - serenity_option(ENABLE_QT OFF CACHE BOOL "Build ladybird application using Qt GUI") -else() - serenity_option(ENABLE_QT ON CACHE BOOL "Build ladybird application using Qt GUI") -endif() - if (ANDROID AND ENABLE_QT) message(STATUS "Disabling Qt for Android") set(ENABLE_QT OFF CACHE BOOL "" FORCE) diff --git a/Libraries/LibWebView/CMakeLists.txt b/Libraries/LibWebView/CMakeLists.txt index 9c68e489287..65bfe3414b4 100644 --- a/Libraries/LibWebView/CMakeLists.txt +++ b/Libraries/LibWebView/CMakeLists.txt @@ -19,6 +19,20 @@ set(SOURCES ${PUBLIC_SUFFIX_SOURCES} ) +if (ENABLE_QT) + list(APPEND SOURCES + EventLoop/EventLoopImplementationQt.cpp + EventLoop/EventLoopImplementationQtEventTarget.cpp + ) + + set(CMAKE_AUTOMOC ON) + find_package(Qt6 REQUIRED COMPONENTS Core) +elseif (APPLE) + list(APPEND SOURCES + EventLoop/EventLoopImplementationMacOS.mm + ) +endif() + set(GENERATED_SOURCES ${CURRENT_LIB_GENERATED}) embed_as_string( @@ -53,6 +67,12 @@ target_compile_definitions(LibWebView PRIVATE ENABLE_PUBLIC_SUFFIX=$ + * Copyright (c) 2023-2024, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -10,9 +10,9 @@ #include #include -namespace Ladybird { +namespace WebView { -class CFEventLoopManager final : public Core::EventLoopManager { +class EventLoopManagerMacOS final : public Core::EventLoopManager { public: virtual NonnullOwnPtr make_implementation() override; @@ -28,12 +28,12 @@ public: virtual void unregister_signal(int) override; }; -class CFEventLoopImplementation final : public Core::EventLoopImplementation { +class EventLoopImplementationMacOS final : public Core::EventLoopImplementation { public: // FIXME: This currently only manages the main NSApp event loop, as that is all we currently // interact with. When we need multiple event loops, or an event loop that isn't the // NSApp loop, we will need to create our own CFRunLoop. - static NonnullOwnPtr create(); + static NonnullOwnPtr create(); virtual int exec() override; virtual size_t pump(PumpMode) override; @@ -47,7 +47,7 @@ public: virtual void notify_forked_and_in_child() override { } private: - CFEventLoopImplementation() = default; + EventLoopImplementationMacOS() = default; int m_exit_code { 0 }; }; diff --git a/UI/AppKit/Application/EventLoopImplementation.mm b/Libraries/LibWebView/EventLoop/EventLoopImplementationMacOS.mm similarity index 90% rename from UI/AppKit/Application/EventLoopImplementation.mm rename to Libraries/LibWebView/EventLoop/EventLoopImplementationMacOS.mm index b6b03677306..4362367d273 100644 --- a/UI/AppKit/Application/EventLoopImplementation.mm +++ b/Libraries/LibWebView/EventLoop/EventLoopImplementationMacOS.mm @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Tim Flynn + * Copyright (c) 2023-2024, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -11,8 +11,8 @@ #include #include #include +#include -#import #import #import @@ -20,7 +20,7 @@ #include #include -namespace Ladybird { +namespace WebView { struct ThreadData { static ThreadData& the() @@ -201,12 +201,12 @@ static void post_application_event() [NSApp postEvent:event atStart:NO]; } -NonnullOwnPtr CFEventLoopManager::make_implementation() +NonnullOwnPtr EventLoopManagerMacOS::make_implementation() { - return CFEventLoopImplementation::create(); + return EventLoopImplementationMacOS::create(); } -intptr_t CFEventLoopManager::register_timer(Core::EventReceiver& receiver, int interval_milliseconds, bool should_reload, Core::TimerShouldFireWhenNotVisible should_fire_when_not_visible) +intptr_t EventLoopManagerMacOS::register_timer(Core::EventReceiver& receiver, int interval_milliseconds, bool should_reload, Core::TimerShouldFireWhenNotVisible should_fire_when_not_visible) { auto& thread_data = ThreadData::the(); @@ -240,7 +240,7 @@ intptr_t CFEventLoopManager::register_timer(Core::EventReceiver& receiver, int i return timer_id; } -void CFEventLoopManager::unregister_timer(intptr_t timer_id) +void EventLoopManagerMacOS::unregister_timer(intptr_t timer_id) { auto& thread_data = ThreadData::the(); thread_data.timer_id_allocator.deallocate(static_cast(timer_id)); @@ -269,7 +269,7 @@ static void socket_notifier(CFSocketRef socket, CFSocketCallBackType notificatio post_application_event(); } -void CFEventLoopManager::register_notifier(Core::Notifier& notifier) +void EventLoopManagerMacOS::register_notifier(Core::Notifier& notifier) { auto notification_type = kCFSocketNoCallBack; @@ -301,7 +301,7 @@ void CFEventLoopManager::register_notifier(Core::Notifier& notifier) ThreadData::the().notifiers.set(¬ifier, source); } -void CFEventLoopManager::unregister_notifier(Core::Notifier& notifier) +void EventLoopManagerMacOS::unregister_notifier(Core::Notifier& notifier) { if (auto source = ThreadData::the().notifiers.take(¬ifier); source.has_value()) { CFRunLoopRemoveSource(CFRunLoopGetCurrent(), *source, kCFRunLoopCommonModes); @@ -309,7 +309,7 @@ void CFEventLoopManager::unregister_notifier(Core::Notifier& notifier) } } -void CFEventLoopManager::did_post_event() +void EventLoopManagerMacOS::did_post_event() { post_application_event(); } @@ -328,7 +328,7 @@ static void handle_signal(CFFileDescriptorRef f, CFOptionFlags callback_types, v signal_handlers->dispatch(); } -int CFEventLoopManager::register_signal(int signal_number, Function handler) +int EventLoopManagerMacOS::register_signal(int signal_number, Function handler) { VERIFY(signal_number != 0); auto& info = *signals_info(); @@ -343,7 +343,7 @@ int CFEventLoopManager::register_signal(int signal_number, Function h } } -void CFEventLoopManager::unregister_signal(int handler_id) +void EventLoopManagerMacOS::unregister_signal(int handler_id) { VERIFY(handler_id != 0); int remove_signal_number = 0; @@ -360,18 +360,18 @@ void CFEventLoopManager::unregister_signal(int handler_id) info.signal_handlers.remove(remove_signal_number); } -NonnullOwnPtr CFEventLoopImplementation::create() +NonnullOwnPtr EventLoopImplementationMacOS::create() { - return adopt_own(*new CFEventLoopImplementation); + return adopt_own(*new EventLoopImplementationMacOS); } -int CFEventLoopImplementation::exec() +int EventLoopImplementationMacOS::exec() { [NSApp run]; return m_exit_code; } -size_t CFEventLoopImplementation::pump(PumpMode mode) +size_t EventLoopImplementationMacOS::pump(PumpMode mode) { auto* wait_until = mode == PumpMode::WaitForEvents ? [NSDate distantFuture] : [NSDate distantPast]; @@ -392,18 +392,18 @@ size_t CFEventLoopImplementation::pump(PumpMode mode) return 0; } -void CFEventLoopImplementation::quit(int exit_code) +void EventLoopImplementationMacOS::quit(int exit_code) { m_exit_code = exit_code; [NSApp stop:nil]; } -void CFEventLoopImplementation::wake() +void EventLoopImplementationMacOS::wake() { CFRunLoopWakeUp(CFRunLoopGetCurrent()); } -void CFEventLoopImplementation::post_event(Core::EventReceiver& receiver, NonnullOwnPtr&& event) +void EventLoopImplementationMacOS::post_event(Core::EventReceiver& receiver, NonnullOwnPtr&& event) { m_thread_event_queue.post_event(receiver, move(event)); diff --git a/UI/Qt/EventLoopImplementationQt.cpp b/Libraries/LibWebView/EventLoop/EventLoopImplementationQt.cpp similarity index 93% rename from UI/Qt/EventLoopImplementationQt.cpp rename to Libraries/LibWebView/EventLoop/EventLoopImplementationQt.cpp index 0b3c767f849..15d64919c18 100644 --- a/UI/Qt/EventLoopImplementationQt.cpp +++ b/Libraries/LibWebView/EventLoop/EventLoopImplementationQt.cpp @@ -12,13 +12,16 @@ #include #include #include -#include -#include +#include +#include #include +#include +#include +#include #include -namespace Ladybird { +namespace WebView { struct ThreadData; static thread_local ThreadData* s_thread_data; @@ -36,6 +39,20 @@ struct ThreadData { HashMap> notifiers; }; +class QtEventLoopManagerEvent final : public QEvent { +public: + static QEvent::Type process_event_queue_event_type() + { + static auto const type = static_cast(QEvent::registerEventType()); + return type; + } + + QtEventLoopManagerEvent(QEvent::Type type) + : QEvent(type) + { + } +}; + class SignalHandlers : public RefCounted { AK_MAKE_NONCOPYABLE(SignalHandlers); AK_MAKE_NONMOVABLE(SignalHandlers); @@ -165,6 +182,7 @@ static void dispatch_signal(int signal_number) } EventLoopImplementationQt::EventLoopImplementationQt() + : m_event_loop(make()) { } @@ -174,7 +192,7 @@ int EventLoopImplementationQt::exec() { if (is_main_loop()) return QCoreApplication::exec(); - return m_event_loop.exec(); + return m_event_loop->exec(); } size_t EventLoopImplementationQt::pump(PumpMode mode) @@ -184,7 +202,7 @@ size_t EventLoopImplementationQt::pump(PumpMode mode) if (is_main_loop()) QCoreApplication::processEvents(qt_mode); else - m_event_loop.processEvents(qt_mode); + m_event_loop->processEvents(qt_mode); result += Core::ThreadEventQueue::current().process(); return result; } @@ -194,13 +212,13 @@ void EventLoopImplementationQt::quit(int code) if (is_main_loop()) QCoreApplication::exit(code); else - m_event_loop.exit(code); + m_event_loop->exit(code); } void EventLoopImplementationQt::wake() { if (!is_main_loop()) - m_event_loop.wakeUp(); + m_event_loop->wakeUp(); } void EventLoopImplementationQt::post_event(Core::EventReceiver& receiver, NonnullOwnPtr&& event) diff --git a/UI/Qt/EventLoopImplementationQt.h b/Libraries/LibWebView/EventLoop/EventLoopImplementationQt.h similarity index 82% rename from UI/Qt/EventLoopImplementationQt.h rename to Libraries/LibWebView/EventLoop/EventLoopImplementationQt.h index de9d0c0acef..05358cff1a7 100644 --- a/UI/Qt/EventLoopImplementationQt.h +++ b/Libraries/LibWebView/EventLoop/EventLoopImplementationQt.h @@ -7,17 +7,14 @@ #pragma once #include -#include #include -#include #include -#include -#include -#include -#include +class QEvent; +class QEventLoop; +class QSocketNotifier; -namespace Ladybird { +namespace WebView { class EventLoopImplementationQt; class EventLoopImplementationQtEventTarget; @@ -50,20 +47,6 @@ private: int m_signal_socket_fds[2] = { -1, -1 }; }; -class QtEventLoopManagerEvent final : public QEvent { -public: - static QEvent::Type process_event_queue_event_type() - { - static auto const type = static_cast(QEvent::registerEventType()); - return type; - } - - QtEventLoopManagerEvent(QEvent::Type type) - : QEvent(type) - { - } -}; - class EventLoopImplementationQt final : public Core::EventLoopImplementation { public: static NonnullOwnPtr create() { return adopt_own(*new EventLoopImplementationQt); } @@ -89,7 +72,7 @@ private: EventLoopImplementationQt(); bool is_main_loop() const { return m_main_loop; } - QEventLoop m_event_loop; + NonnullOwnPtr m_event_loop; bool m_main_loop { false }; }; diff --git a/UI/Qt/EventLoopImplementationQtEventTarget.cpp b/Libraries/LibWebView/EventLoop/EventLoopImplementationQtEventTarget.cpp similarity index 63% rename from UI/Qt/EventLoopImplementationQtEventTarget.cpp rename to Libraries/LibWebView/EventLoop/EventLoopImplementationQtEventTarget.cpp index 258abc4a57f..2bdca22f9b5 100644 --- a/UI/Qt/EventLoopImplementationQtEventTarget.cpp +++ b/Libraries/LibWebView/EventLoop/EventLoopImplementationQtEventTarget.cpp @@ -4,9 +4,10 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include +#include -namespace Ladybird { +namespace WebView { bool EventLoopImplementationQtEventTarget::event(QEvent* event) { diff --git a/UI/Qt/EventLoopImplementationQtEventTarget.h b/Libraries/LibWebView/EventLoop/EventLoopImplementationQtEventTarget.h similarity index 81% rename from UI/Qt/EventLoopImplementationQtEventTarget.h rename to Libraries/LibWebView/EventLoop/EventLoopImplementationQtEventTarget.h index e9a723282a5..4bc251e1915 100644 --- a/UI/Qt/EventLoopImplementationQtEventTarget.h +++ b/Libraries/LibWebView/EventLoop/EventLoopImplementationQtEventTarget.h @@ -6,11 +6,10 @@ #pragma once -#include - #include +#include -namespace Ladybird { +namespace WebView { class EventLoopImplementationQtEventTarget final : public QObject { Q_OBJECT diff --git a/Meta/CMake/lagom_options.cmake b/Meta/CMake/lagom_options.cmake index be16e578cc0..c7ad2d30337 100644 --- a/Meta/CMake/lagom_options.cmake +++ b/Meta/CMake/lagom_options.cmake @@ -14,3 +14,9 @@ serenity_option(LAGOM_TOOLS_ONLY OFF CACHE BOOL "Don't build libraries, utilitie serenity_option(ENABLE_LAGOM_CCACHE ON CACHE BOOL "Enable ccache for Lagom builds") serenity_option(LAGOM_USE_LINKER "" CACHE STRING "The linker to use (e.g. lld, mold) instead of the system default") serenity_option(ENABLE_LAGOM_COVERAGE_COLLECTION OFF CACHE STRING "Enable code coverage instrumentation for lagom binaries in clang") + +if (ANDROID OR APPLE) + serenity_option(ENABLE_QT OFF CACHE BOOL "Build ladybird application using Qt GUI") +else() + serenity_option(ENABLE_QT ON CACHE BOOL "Build ladybird application using Qt GUI") +endif() diff --git a/Services/WebContent/CMakeLists.txt b/Services/WebContent/CMakeLists.txt index a4cd5bf056f..03b9e1b336a 100644 --- a/Services/WebContent/CMakeLists.txt +++ b/Services/WebContent/CMakeLists.txt @@ -40,12 +40,7 @@ if (HAS_FONTCONFIG) endif() if (ENABLE_QT) - qt_add_executable(WebContent - ${LADYBIRD_SOURCE_DIR}/UI/Qt/EventLoopImplementationQt.cpp - ${LADYBIRD_SOURCE_DIR}/UI/Qt/EventLoopImplementationQtEventTarget.cpp - ${LADYBIRD_SOURCE_DIR}/UI/Qt/StringUtils.cpp - main.cpp - ) + qt_add_executable(WebContent main.cpp) target_link_libraries(WebContent PRIVATE Qt::Core) target_compile_definitions(WebContent PRIVATE HAVE_QT=1) diff --git a/Services/WebContent/main.cpp b/Services/WebContent/main.cpp index bc60b241c13..880966bfc52 100644 --- a/Services/WebContent/main.cpp +++ b/Services/WebContent/main.cpp @@ -34,8 +34,8 @@ #include #if defined(HAVE_QT) +# include # include -# include # if defined(HAVE_QT_MULTIMEDIA) # include @@ -71,7 +71,7 @@ ErrorOr serenity_main(Main::Arguments arguments) #if defined(HAVE_QT) QCoreApplication app(arguments.argc, arguments.argv); - Core::EventLoopManager::install(*new Ladybird::EventLoopManagerQt); + Core::EventLoopManager::install(*new WebView::EventLoopManagerQt); #endif Core::EventLoop event_loop; diff --git a/Services/WebWorker/CMakeLists.txt b/Services/WebWorker/CMakeLists.txt index a06e859e4c7..8e413591d91 100644 --- a/Services/WebWorker/CMakeLists.txt +++ b/Services/WebWorker/CMakeLists.txt @@ -25,13 +25,7 @@ if (HAS_FONTCONFIG) endif() if (ENABLE_QT) - qt_add_executable(WebWorker - ${LADYBIRD_SOURCE_DIR}/UI/Qt/EventLoopImplementationQt.cpp - ${LADYBIRD_SOURCE_DIR}/UI/Qt/EventLoopImplementationQtEventTarget.cpp - ${LADYBIRD_SOURCE_DIR}/UI/Qt/StringUtils.cpp - main.cpp - ) - target_link_libraries(WebWorker PRIVATE Qt::Core) + qt_add_executable(WebWorker main.cpp) target_link_libraries(WebWorker PRIVATE webworkerservice LibWebSocket) target_compile_definitions(WebWorker PRIVATE HAVE_QT=1) else() diff --git a/Services/WebWorker/main.cpp b/Services/WebWorker/main.cpp index 2433674dde9..570c28c8083 100644 --- a/Services/WebWorker/main.cpp +++ b/Services/WebWorker/main.cpp @@ -25,8 +25,8 @@ #include #if defined(HAVE_QT) +# include # include -# include #endif static ErrorOr initialize_resource_loader(JS::Heap&, int request_server_socket); @@ -52,7 +52,7 @@ ErrorOr serenity_main(Main::Arguments arguments) #if defined(HAVE_QT) QCoreApplication app(arguments.argc, arguments.argv); - Core::EventLoopManager::install(*new Ladybird::EventLoopManagerQt); + Core::EventLoopManager::install(*new WebView::EventLoopManagerQt); #endif Core::EventLoop event_loop; diff --git a/UI/AppKit/CMakeLists.txt b/UI/AppKit/CMakeLists.txt index e9e727f3b5d..690c1a56fde 100644 --- a/UI/AppKit/CMakeLists.txt +++ b/UI/AppKit/CMakeLists.txt @@ -2,7 +2,6 @@ add_library(ladybird_impl STATIC ${LADYBIRD_SOURCES} Application/Application.mm Application/ApplicationDelegate.mm - Application/EventLoopImplementation.mm Interface/Event.mm Interface/Inspector.mm Interface/InspectorController.mm diff --git a/UI/AppKit/main.mm b/UI/AppKit/main.mm index 819cef60048..43767071d87 100644 --- a/UI/AppKit/main.mm +++ b/UI/AppKit/main.mm @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024, Tim Flynn + * Copyright (c) 2023-2024, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,6 @@ #import #import -#import #import #import @@ -48,7 +48,7 @@ ErrorOr serenity_main(Main::Arguments arguments) Application* application = [Application sharedApplication]; - Core::EventLoopManager::install(*new Ladybird::CFEventLoopManager); + Core::EventLoopManager::install(*new WebView::EventLoopManagerMacOS); [application setupWebViewApplication:arguments newTabPageURL:Browser::default_new_tab_url]; platform_init(); diff --git a/UI/Qt/CMakeLists.txt b/UI/Qt/CMakeLists.txt index ce3d78fa0e9..ec171bee255 100644 --- a/UI/Qt/CMakeLists.txt +++ b/UI/Qt/CMakeLists.txt @@ -3,8 +3,6 @@ target_sources(ladybird PRIVATE Application.cpp AutoComplete.cpp BrowserWindow.cpp - EventLoopImplementationQt.cpp - EventLoopImplementationQtEventTarget.cpp FindInPageWidget.cpp Icon.cpp InspectorWidget.cpp diff --git a/UI/Qt/main.cpp b/UI/Qt/main.cpp index 1fc82956f66..f9204f7d6b8 100644 --- a/UI/Qt/main.cpp +++ b/UI/Qt/main.cpp @@ -12,12 +12,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -64,11 +64,11 @@ ErrorOr serenity_main(Main::Arguments arguments) { AK::set_rich_debug_enabled(true); - Core::EventLoopManager::install(*new Ladybird::EventLoopManagerQt); + Core::EventLoopManager::install(*new WebView::EventLoopManagerQt); auto app = Ladybird::Application::create(arguments, ak_url_from_qstring(Ladybird::Settings::the()->new_tab_page())); - static_cast(Core::EventLoop::current().impl()).set_main_loop(); + static_cast(Core::EventLoop::current().impl()).set_main_loop(); TRY(handle_attached_debugger()); platform_init();