EventLoopImplementationQt.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * Copyright (c) 2022-2023, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "EventLoopImplementationQt.h"
  7. #include "EventLoopImplementationQtEventTarget.h"
  8. #include <AK/IDAllocator.h>
  9. #include <LibCore/Event.h>
  10. #include <LibCore/EventReceiver.h>
  11. #include <LibCore/Notifier.h>
  12. #include <LibCore/ThreadEventQueue.h>
  13. #include <QCoreApplication>
  14. #include <QTimer>
  15. namespace Ladybird {
  16. struct ThreadData;
  17. static thread_local ThreadData* s_thread_data;
  18. struct ThreadData {
  19. static ThreadData& the()
  20. {
  21. if (!s_thread_data) {
  22. // FIXME: Don't leak this.
  23. s_thread_data = new ThreadData;
  24. }
  25. return *s_thread_data;
  26. }
  27. IDAllocator timer_id_allocator;
  28. HashMap<int, NonnullOwnPtr<QTimer>> timers;
  29. HashMap<Core::Notifier*, NonnullOwnPtr<QSocketNotifier>> notifiers;
  30. };
  31. EventLoopImplementationQt::EventLoopImplementationQt()
  32. {
  33. }
  34. EventLoopImplementationQt::~EventLoopImplementationQt() = default;
  35. int EventLoopImplementationQt::exec()
  36. {
  37. if (is_main_loop())
  38. return QCoreApplication::exec();
  39. return m_event_loop.exec();
  40. }
  41. size_t EventLoopImplementationQt::pump(PumpMode mode)
  42. {
  43. auto result = Core::ThreadEventQueue::current().process();
  44. auto qt_mode = mode == PumpMode::WaitForEvents ? QEventLoop::WaitForMoreEvents : QEventLoop::AllEvents;
  45. if (is_main_loop())
  46. QCoreApplication::processEvents(qt_mode);
  47. else
  48. m_event_loop.processEvents(qt_mode);
  49. result += Core::ThreadEventQueue::current().process();
  50. return result;
  51. }
  52. void EventLoopImplementationQt::quit(int code)
  53. {
  54. if (is_main_loop())
  55. QCoreApplication::exit(code);
  56. else
  57. m_event_loop.exit(code);
  58. }
  59. void EventLoopImplementationQt::wake()
  60. {
  61. if (!is_main_loop())
  62. m_event_loop.wakeUp();
  63. }
  64. void EventLoopImplementationQt::post_event(Core::EventReceiver& receiver, NonnullOwnPtr<Core::Event>&& event)
  65. {
  66. m_thread_event_queue.post_event(receiver, move(event));
  67. if (&m_thread_event_queue != &Core::ThreadEventQueue::current())
  68. wake();
  69. }
  70. static void qt_timer_fired(Core::TimerShouldFireWhenNotVisible should_fire_when_not_visible, Core::EventReceiver& object)
  71. {
  72. if (should_fire_when_not_visible == Core::TimerShouldFireWhenNotVisible::No) {
  73. if (!object.is_visible_for_timer_purposes())
  74. return;
  75. }
  76. Core::TimerEvent event;
  77. object.dispatch_event(event);
  78. }
  79. int EventLoopManagerQt::register_timer(Core::EventReceiver& object, int milliseconds, bool should_reload, Core::TimerShouldFireWhenNotVisible should_fire_when_not_visible)
  80. {
  81. auto& thread_data = ThreadData::the();
  82. auto timer = make<QTimer>();
  83. timer->setInterval(milliseconds);
  84. timer->setSingleShot(!should_reload);
  85. auto timer_id = thread_data.timer_id_allocator.allocate();
  86. auto weak_object = object.make_weak_ptr();
  87. QObject::connect(timer, &QTimer::timeout, [should_fire_when_not_visible, weak_object = move(weak_object)] {
  88. auto object = weak_object.strong_ref();
  89. if (!object)
  90. return;
  91. qt_timer_fired(should_fire_when_not_visible, *object);
  92. });
  93. timer->start();
  94. thread_data.timers.set(timer_id, move(timer));
  95. return timer_id;
  96. }
  97. bool EventLoopManagerQt::unregister_timer(int timer_id)
  98. {
  99. auto& thread_data = ThreadData::the();
  100. thread_data.timer_id_allocator.deallocate(timer_id);
  101. return thread_data.timers.remove(timer_id);
  102. }
  103. static void qt_notifier_activated(Core::Notifier& notifier)
  104. {
  105. Core::NotifierActivationEvent event(notifier.fd(), notifier.type());
  106. notifier.dispatch_event(event);
  107. }
  108. void EventLoopManagerQt::register_notifier(Core::Notifier& notifier)
  109. {
  110. QSocketNotifier::Type type;
  111. switch (notifier.type()) {
  112. case Core::Notifier::Type::Read:
  113. type = QSocketNotifier::Read;
  114. break;
  115. case Core::Notifier::Type::Write:
  116. type = QSocketNotifier::Write;
  117. break;
  118. default:
  119. TODO();
  120. }
  121. auto socket_notifier = make<QSocketNotifier>(notifier.fd(), type);
  122. QObject::connect(socket_notifier, &QSocketNotifier::activated, [&notifier] {
  123. qt_notifier_activated(notifier);
  124. });
  125. ThreadData::the().notifiers.set(&notifier, move(socket_notifier));
  126. }
  127. void EventLoopManagerQt::unregister_notifier(Core::Notifier& notifier)
  128. {
  129. ThreadData::the().notifiers.remove(&notifier);
  130. }
  131. void EventLoopManagerQt::did_post_event()
  132. {
  133. QCoreApplication::postEvent(m_main_thread_event_target.ptr(), new QtEventLoopManagerEvent(QtEventLoopManagerEvent::process_event_queue_event_type()));
  134. }
  135. bool EventLoopManagerQt::event_target_received_event(Badge<EventLoopImplementationQtEventTarget>, QEvent* event)
  136. {
  137. if (event->type() == QtEventLoopManagerEvent::process_event_queue_event_type()) {
  138. Core::ThreadEventQueue::current().process();
  139. return true;
  140. }
  141. return false;
  142. }
  143. EventLoopManagerQt::EventLoopManagerQt()
  144. : m_main_thread_event_target(make<EventLoopImplementationQtEventTarget>())
  145. {
  146. }
  147. EventLoopManagerQt::~EventLoopManagerQt() = default;
  148. NonnullOwnPtr<Core::EventLoopImplementation> EventLoopManagerQt::make_implementation()
  149. {
  150. return adopt_own(*new EventLoopImplementationQt);
  151. }
  152. }