fix(mac): Remove Cocoa app loop and fix macOS event tap for Qt threading
This commit is contained in:
parent
29352d97b3
commit
aaef600ffa
7 changed files with 30 additions and 44 deletions
|
|
@ -23,7 +23,6 @@
|
|||
#include <stdexcept>
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
#include "platform/OSXCocoaApp.h"
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -172,7 +171,4 @@ void App::handleScreenError() const
|
|||
void App::runEventsLoop(const void *)
|
||||
{
|
||||
m_events->loop();
|
||||
#if defined(Q_OS_MAC)
|
||||
stopCocoaLoop();
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,9 +37,6 @@
|
|||
#endif
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
#include "base/TMethodJob.h"
|
||||
#include "mt/Thread.h"
|
||||
#include "platform/OSXCocoaApp.h"
|
||||
#include "platform/OSXScreen.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -330,17 +327,7 @@ int ClientApp::mainLoop()
|
|||
// later. the timer installed by startClient() will take care of
|
||||
// that.
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
Thread thread(new TMethodJob<ClientApp>(this, &ClientApp::runEventsLoop, nullptr));
|
||||
|
||||
// wait until carbon loop is ready
|
||||
OSXScreen *screen = dynamic_cast<OSXScreen *>(m_clientScreen->getPlatformScreen());
|
||||
screen->waitForCarbonLoop();
|
||||
|
||||
runCocoaApp();
|
||||
#else
|
||||
getEvents()->loop();
|
||||
#endif
|
||||
|
||||
// close down
|
||||
LOG_DEBUG("stopping client");
|
||||
|
|
|
|||
|
|
@ -43,9 +43,6 @@
|
|||
#endif
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
#include "base/TMethodJob.h"
|
||||
#include "mt/Thread.h"
|
||||
#include "platform/OSXCocoaApp.h"
|
||||
#include "platform/OSXScreen.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -541,18 +538,7 @@ int ServerApp::mainLoop()
|
|||
// later. the timer installed by startServer() will take care of
|
||||
// that.
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
|
||||
Thread thread(new TMethodJob<ServerApp>(this, &ServerApp::runEventsLoop, nullptr));
|
||||
|
||||
// wait until carbon loop is ready
|
||||
OSXScreen *screen = dynamic_cast<OSXScreen *>(m_serverScreen->getPlatformScreen());
|
||||
screen->waitForCarbonLoop();
|
||||
|
||||
runCocoaApp();
|
||||
#else
|
||||
getEvents()->loop();
|
||||
#endif
|
||||
|
||||
// close down
|
||||
LOG_DEBUG("stopping server");
|
||||
|
|
|
|||
|
|
@ -58,16 +58,11 @@ IEventQueueBuffer::Type OSXEventQueueBuffer::getEvent(Event &event, uint32_t &da
|
|||
|
||||
bool OSXEventQueueBuffer::addEvent(uint32_t dataID)
|
||||
{
|
||||
// Use GCD to dispatch event addition on the main queue
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
std::scoped_lock lock{this->m_mutex};
|
||||
std::scoped_lock lock{m_mutex};
|
||||
LOG_DEBUG2("adding user event with dataID: %u", dataID);
|
||||
this->m_dataQueue.push(dataID);
|
||||
this->m_cond.notify_one();
|
||||
m_dataQueue.push(dataID);
|
||||
m_cond.notify_one();
|
||||
LOG_DEBUG2("user event added to queue, dataID=%u", dataID);
|
||||
});
|
||||
|
||||
// Always return true since dispatch_async does not fail under normal conditions
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
#include "base/IEventQueueBuffer.h"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <dispatch/dispatch.h>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <bitset>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
extern "C"
|
||||
|
|
@ -292,6 +293,8 @@ private:
|
|||
// Quartz input event support
|
||||
CFMachPortRef m_eventTapPort;
|
||||
CFRunLoopSourceRef m_eventTapRLSR;
|
||||
std::thread m_eventTapThread;
|
||||
CFRunLoopRef m_eventTapRunLoop = nullptr;
|
||||
|
||||
// for double click coalescing.
|
||||
double m_lastClickTime;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <AppKit/NSEvent.h>
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <IOKit/hidsystem/event_status_driver.h>
|
||||
#include <dispatch/dispatch.h>
|
||||
#include <libproc.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <math.h>
|
||||
|
|
@ -686,7 +687,20 @@ void OSXScreen::enable()
|
|||
if (m_eventTapPort) {
|
||||
m_eventTapRLSR = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, m_eventTapPort, 0);
|
||||
if (m_eventTapRLSR) {
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), m_eventTapRLSR, kCFRunLoopDefaultMode);
|
||||
// Run the event tap on a dedicated thread with its own CFRunLoop so it fires
|
||||
// independently of whatever event loop the calling thread runs (e.g. QCoreApplication).
|
||||
// Use a semaphore to ensure m_eventTapRunLoop is set before enable() returns.
|
||||
auto sem = dispatch_semaphore_create(0);
|
||||
m_eventTapThread = std::thread([this, sem]() {
|
||||
m_eventTapRunLoop = CFRunLoopGetCurrent();
|
||||
CFRunLoopAddSource(m_eventTapRunLoop, m_eventTapRLSR, kCFRunLoopDefaultMode);
|
||||
dispatch_semaphore_signal(sem);
|
||||
CFRunLoopRun();
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_eventTapRLSR, kCFRunLoopDefaultMode);
|
||||
m_eventTapRunLoop = nullptr;
|
||||
});
|
||||
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
|
||||
dispatch_release(sem);
|
||||
} else {
|
||||
LOG_ERR("failed to create a CFRunLoopSourceRef for the quartz event tap");
|
||||
}
|
||||
|
|
@ -701,8 +715,14 @@ void OSXScreen::disable()
|
|||
|
||||
// FIXME -- stop watching jump zones, stop capturing input
|
||||
|
||||
if (m_eventTapRunLoop) {
|
||||
CFRunLoopStop(m_eventTapRunLoop);
|
||||
}
|
||||
if (m_eventTapThread.joinable()) {
|
||||
m_eventTapThread.join();
|
||||
}
|
||||
|
||||
if (m_eventTapRLSR) {
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_eventTapRLSR, kCFRunLoopDefaultMode);
|
||||
CFRelease(m_eventTapRLSR);
|
||||
m_eventTapRLSR = nullptr;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue