diff --git a/browser-mac.h b/browser-mac.h index cb07721ee..514b9c02c 100644 --- a/browser-mac.h +++ b/browser-mac.h @@ -44,6 +44,8 @@ bool ExecuteNextBrowserTask(); void ExecuteTask(MessageTask task); void ExecuteSyncTask(MessageTask task); void DoCefMessageLoop(int ms); +void DoCefMessageLoopTimer(float ms); +void StopCefMessageLoopTimer(); void Process(); #if 0 // REMOVE_DUPLICATE void QueueBrowserTask(CefRefPtr browser, BrowserFunc func); diff --git a/browser-mac.mm b/browser-mac.mm index 0606801ab..52ef1ca23 100644 --- a/browser-mac.mm +++ b/browser-mac.mm @@ -26,6 +26,7 @@ std::mutex browserTaskMutex; std::deque browserTasks; +static NSTimer *cefTimer = nil; bool ExecuteNextBrowserTask() { @@ -45,16 +46,26 @@ bool ExecuteNextBrowserTask() void ExecuteTask(MessageTask task) { - dispatch_async(dispatch_get_main_queue(), ^{ + // Protect against exception if already on main thread + if ([NSThread isMainThread]) { task(); - }); + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + task(); + }); + } } void ExecuteSyncTask(MessageTask task) { - dispatch_sync(dispatch_get_main_queue(), ^{ + // Protect against exception if already on main thread + if ([NSThread isMainThread]) { task(); - }); + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ + task(); + }); + } } void DoCefMessageLoop(int) @@ -64,6 +75,22 @@ void DoCefMessageLoop(int) }); } +void DoCefMessageLoopTimer(float ms) +{ + cefTimer = [NSTimer + scheduledTimerWithTimeInterval:ms + repeats:YES + block:^(NSTimer *) { + CefDoMessageLoopWork(); + }]; +} + +void StopCefMessageLoopTimer() +{ + [cefTimer invalidate]; + cefTimer = nil; +} + void Process() { dispatch_async(dispatch_get_main_queue(), ^{ diff --git a/obs-browser-plugin.cpp b/obs-browser-plugin.cpp index 2db193608..fb6211ff2 100644 --- a/obs-browser-plugin.cpp +++ b/obs-browser-plugin.cpp @@ -333,7 +333,8 @@ static obs_data_array_t *browser_source_get_messages(void *data) messages = obs_data_array_create(); for (const auto &message : bs->messagesToApp) { obs_data_t *msg_data = obs_data_create(); - obs_data_set_string(msg_data, "message", message.c_str()); + obs_data_set_string(msg_data, "message", + message.c_str()); obs_data_array_push_back(messages, msg_data); obs_data_release(msg_data); } @@ -529,15 +530,9 @@ static void BrowserShutdown(void) #ifndef ENABLE_BROWSER_QT_LOOP static void BrowserManagerThread(obs_data_t *settings) { -#ifdef __APPLE__ - ExecuteSyncTask([&settings]() { -#endif - BrowserInit(settings); - CefRunMessageLoop(); - BrowserShutdown(); -#ifdef __APPLE__ - }); -#endif + BrowserInit(settings); + CefRunMessageLoop(); + BrowserShutdown(); } #endif @@ -546,6 +541,12 @@ extern "C" EXPORT void obs_browser_initialize(obs_data_t *settings) if (!os_atomic_set_bool(&manager_initialized, true)) { #ifdef ENABLE_BROWSER_QT_LOOP BrowserInit(settings); +#elif __APPLE__ + + ExecuteTask([&settings]() { + BrowserInit(settings); + DoCefMessageLoopTimer(0.01f); // Do not block the main queue so we avoid calling CefRunMessageLoop() + }); #else auto binded_fn = bind(BrowserManagerThread, settings); manager_thread = thread(binded_fn); @@ -956,6 +957,11 @@ void obs_module_unload(void) { #ifdef USE_UI_LOOP BrowserShutdown(); +#elif __APPLE__ + ExecuteSyncTask([]() { + StopCefMessageLoopTimer(); + BrowserShutdown(); + }); #else if (manager_thread.joinable()) { while (!QueueCEFTask([]() { CefQuitMessageLoop(); }))