mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibWebView: Add common source loop source for deferred_invoke() on macOS
Previously, `EventLoopImplementationMacOS` didn't process
`deferred_invoke()` callbacks during window resizing because they were
scheduled in the "default" run-loop mode, which isn't serviced while the
run loop is in "Event Tracking" mode.
Commit 3bbe1b0c changed socket notifiers to schedule in
`kCFRunLoopCommonModes`, which kept IPC reads responsive during resizing
(we process IPC messages in the notifier's read hook). This change does
the same for `deferred_invoke()`: it installs a `CFRunLoopSource` in
`kCFRunLoopCommonModes` and signals it whenever a deferred callback is
enqueued.
This commit is contained in:
parent
d4deafe5fe
commit
6c71960425
|
|
@ -43,8 +43,13 @@ public:
|
|||
virtual bool was_exit_requested() const override;
|
||||
virtual void post_event(Core::EventReceiver& receiver, NonnullOwnPtr<Core::Event>&&) override;
|
||||
|
||||
virtual ~EventLoopImplementationMacOS() override;
|
||||
|
||||
private:
|
||||
EventLoopImplementationMacOS() = default;
|
||||
EventLoopImplementationMacOS();
|
||||
|
||||
struct Impl;
|
||||
NonnullOwnPtr<Impl> m_impl;
|
||||
|
||||
int m_exit_code { 0 };
|
||||
};
|
||||
|
|
|
|||
|
|
@ -202,6 +202,40 @@ static void post_application_event()
|
|||
[NSApp postEvent:event atStart:NO];
|
||||
}
|
||||
|
||||
struct EventLoopImplementationMacOS::Impl {
|
||||
Impl(EventLoopImplementationMacOS& event_loop_implementation)
|
||||
: run_loop(CFRunLoopGetCurrent())
|
||||
{
|
||||
CFRunLoopSourceContext context {};
|
||||
context.info = &event_loop_implementation;
|
||||
context.perform = [](void* info) {
|
||||
auto& self = *static_cast<EventLoopImplementationMacOS*>(info);
|
||||
self.m_impl->deferred_source_pending = false;
|
||||
self.m_thread_event_queue.process();
|
||||
};
|
||||
|
||||
deferred_source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
|
||||
CFRunLoopAddSource(run_loop, deferred_source, kCFRunLoopCommonModes);
|
||||
}
|
||||
|
||||
~Impl()
|
||||
{
|
||||
CFRunLoopRemoveSource(run_loop, deferred_source, kCFRunLoopCommonModes);
|
||||
CFRelease(deferred_source);
|
||||
}
|
||||
|
||||
CFRunLoopRef run_loop { nullptr };
|
||||
CFRunLoopSourceRef deferred_source { nullptr };
|
||||
Atomic<bool> deferred_source_pending { false };
|
||||
};
|
||||
|
||||
EventLoopImplementationMacOS::EventLoopImplementationMacOS()
|
||||
: m_impl(make<Impl>(*this))
|
||||
{
|
||||
}
|
||||
|
||||
EventLoopImplementationMacOS::~EventLoopImplementationMacOS() = default;
|
||||
|
||||
NonnullOwnPtr<Core::EventLoopImplementation> EventLoopManagerMacOS::make_implementation()
|
||||
{
|
||||
return EventLoopImplementationMacOS::create();
|
||||
|
|
@ -306,7 +340,7 @@ void EventLoopManagerMacOS::unregister_notifier(Core::Notifier& notifier)
|
|||
|
||||
void EventLoopManagerMacOS::did_post_event()
|
||||
{
|
||||
post_application_event();
|
||||
CFRunLoopWakeUp(CFRunLoopGetCurrent());
|
||||
}
|
||||
|
||||
static void handle_signal(CFFileDescriptorRef f, CFOptionFlags callback_types, void* info)
|
||||
|
|
@ -407,8 +441,10 @@ void EventLoopImplementationMacOS::post_event(Core::EventReceiver& receiver, Non
|
|||
{
|
||||
m_thread_event_queue.post_event(receiver, move(event));
|
||||
|
||||
if (&m_thread_event_queue != &Core::ThreadEventQueue::current())
|
||||
wake();
|
||||
bool expected = false;
|
||||
if (m_impl->deferred_source && m_impl->deferred_source_pending.compare_exchange_strong(expected, true)) {
|
||||
CFRunLoopSourceSignal(m_impl->deferred_source);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user