From 9563fb5e73425a2ee0370162178964cceb559d5d Mon Sep 17 00:00:00 2001 From: David Runge <dave@sleepmap.de> Date: Mon, 16 Nov 2020 12:00:22 +0100 Subject: [PATCH] Backport #5014 for 3.11.2 Backport the linker error patches (https://github.com/supercollider/supercollider/pull/5014) for 3.11.2. --- common/SC_Apple.hpp | 14 ------ common/SC_Apple.mm | 60 ------------------------- common/SC_AppleEventLoop.hpp | 34 ++++++++++++++ common/SC_AppleEventLoop.mm | 80 +++++++++++++++++++++++++++++++++ common/SC_EventLoop.hpp | 3 +- server/scsynth/CMakeLists.txt | 8 +++- server/supernova/CMakeLists.txt | 9 +++- 7 files changed, 131 insertions(+), 77 deletions(-) create mode 100644 common/SC_AppleEventLoop.hpp create mode 100644 common/SC_AppleEventLoop.mm diff --git a/common/SC_Apple.hpp b/common/SC_Apple.hpp index 958d097f36..c7e53e9fcc 100644 --- a/common/SC_Apple.hpp +++ b/common/SC_Apple.hpp @@ -23,19 +23,5 @@ namespace SC { namespace Apple { void disableAppNap(); -namespace EventLoop { - -// Setup the main application. This function must be called in the -// main thread and before any other calls to Cocoa methods. -void setup(); -// Run the event loop. This function must be called in the main thread. -// It blocks until the event loop finishes. -void run(); -// Ask the event loop to stop and terminate the program. -// This function can be called from any thread. -void quit(); - -} // EventLoop - } // namespace Apple } // namespace SC diff --git a/common/SC_Apple.mm b/common/SC_Apple.mm index a4e10a66cd..dbb7ddbb7d 100644 --- a/common/SC_Apple.mm +++ b/common/SC_Apple.mm @@ -42,65 +42,5 @@ void disableAppNap() { } } -namespace EventLoop { - -static std::atomic_bool g_running; - -void setup() { - // The following code would transform the process into a foreground application. - // For now it's the plugin's responsibility to do this (early or lazily) - // because we don't want to always show an icon in the docker. - // ProcessSerialNumber psn = { 0, kCurrentProcess }; - // TransformProcessType(&psn, kProcessTransformToForegroundApplication); - - // Create NSApplication - [NSApplication sharedApplication]; -} - -void run() { -#if 0 - // this doesn't work... - [NSApp run]; -#else - // Kudos to https://www.cocoawithlove.com/2009/01/demystifying-nsapplication-by.html - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - [NSApp finishLaunching]; - g_running = true; - - while (g_running) { - [pool release]; - pool = [[NSAutoreleasePool alloc] init]; - NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantFuture] - inMode:NSDefaultRunLoopMode - dequeue:YES]; - if (event) { - [NSApp sendEvent:event]; - [NSApp updateWindows]; - } - } - [pool release]; -#endif -} - -void quit() { - // break from event loop instead of [NSApp terminate:nil] - g_running = false; - // send dummy event to wake up event loop - NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined - location:NSMakePoint(0, 0) - modifierFlags:0 - timestamp:0 - windowNumber:0 - context:nil - subtype:0 - data1:0 - data2:0]; - [NSApp postEvent:event atStart:NO]; -} - -} // EventLoop - } // namespace Apple } // namespace SC diff --git a/common/SC_AppleEventLoop.hpp b/common/SC_AppleEventLoop.hpp new file mode 100644 index 0000000000..6f19bb2818 --- /dev/null +++ b/common/SC_AppleEventLoop.hpp @@ -0,0 +1,34 @@ +/************************************************************************ + * + * Copyright 2019 Christof Ressi <info@christofressi.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ************************************************************************/ + +#pragma once + +namespace SC { namespace Apple { namespace EventLoop { + +// Setup the main application. This function must be called in the +// main thread and before any other calls to Cocoa methods. +void setup(); +// Run the event loop. This function must be called in the main thread. +// It blocks until the event loop finishes. +void run(); +// Ask the event loop to stop and terminate the program. +// This function can be called from any thread. +void quit(); + +}}} // namespace SC::Apple::EventLoop diff --git a/common/SC_AppleEventLoop.mm b/common/SC_AppleEventLoop.mm new file mode 100644 index 0000000000..cfcf42ddfe --- /dev/null +++ b/common/SC_AppleEventLoop.mm @@ -0,0 +1,80 @@ +/************************************************************************ + * + * Copyright 2019 Christof Ressi <info@christofressi.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ************************************************************************/ + +#include "SC_AppleEventLoop.hpp" +#include <atomic> + +#import <Cocoa/Cocoa.h> + +namespace SC { namespace Apple { namespace EventLoop { + +static std::atomic_bool g_running; + +void setup() { + // The following code would transform the process into a foreground application. + // For now it's the plugin's responsibility to do this (early or lazily) + // because we don't want to always show an icon in the docker. + // ProcessSerialNumber psn = { 0, kCurrentProcess }; + // TransformProcessType(&psn, kProcessTransformToForegroundApplication); + + // Create NSApplication + [NSApplication sharedApplication]; +} + +void run() { + // this doesn't work... + // [NSApp run]; + // Kudos to https://www.cocoawithlove.com/2009/01/demystifying-nsapplication-by.html + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + [NSApp finishLaunching]; + g_running = true; + + while (g_running) { + [pool release]; + pool = [[NSAutoreleasePool alloc] init]; + NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantFuture] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + if (event) { + [NSApp sendEvent:event]; + [NSApp updateWindows]; + } + } + [pool release]; +} + +void quit() { + // break from event loop instead of [NSApp terminate:nil] + g_running = false; + // send dummy event to wake up event loop + NSEvent* event = [NSEvent otherEventWithType:NSApplicationDefined + location:NSMakePoint(0, 0) + modifierFlags:0 + timestamp:0 + windowNumber:0 + context:nil + subtype:0 + data1:0 + data2:0]; + [NSApp postEvent:event atStart:NO]; +} + +}}} // namespace SC::Apple::EventLoop diff --git a/common/SC_EventLoop.hpp b/common/SC_EventLoop.hpp index 1d62b4de89..6e58208cc0 100644 --- a/common/SC_EventLoop.hpp +++ b/common/SC_EventLoop.hpp @@ -2,7 +2,7 @@ #include <functional> #ifdef __APPLE__ -# include "SC_Apple.hpp" +# include "SC_AppleEventLoop.hpp" # include <thread> #endif @@ -21,6 +21,7 @@ class EventLoop { SC::Apple::EventLoop::setup(); #endif } + // Run the event loop until 'waitFunction' returns. static void run(std::function<void()> waitFunction) { #ifdef __APPLE__ diff --git a/server/scsynth/CMakeLists.txt b/server/scsynth/CMakeLists.txt index fa8daf12aa..c60ae72ffc 100644 --- a/server/scsynth/CMakeLists.txt +++ b/server/scsynth/CMakeLists.txt @@ -230,7 +230,13 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux") target_link_libraries(libscsynth rt) endif() -add_executable(scsynth scsynth_main.cpp) +add_executable(scsynth + scsynth_main.cpp + + # these files contain code only used in main() + ${CMAKE_SOURCE_DIR}/common/SC_ServerBootDelayWarning.cpp + $<$<BOOL:${APPLE}>: ${CMAKE_SOURCE_DIR}/common/SC_AppleEventLoop.mm > + ) target_link_libraries(scsynth libscsynth) if (PTHREADS_FOUND) diff --git a/server/supernova/CMakeLists.txt b/server/supernova/CMakeLists.txt index 923a3aa4e4..ce8388e475 100644 --- a/server/supernova/CMakeLists.txt +++ b/server/supernova/CMakeLists.txt @@ -182,7 +182,14 @@ if(WIN32) endif() -add_executable(supernova server/main.cpp ${supernova_headers}) +add_executable(supernova + server/main.cpp + ${supernova_headers} + + # these files contain code only used in main() + ${CMAKE_SOURCE_DIR}/common/SC_ServerBootDelayWarning.cpp + $<$<BOOL:${APPLE}>: ${CMAKE_SOURCE_DIR}/common/SC_AppleEventLoop.mm > + ) target_link_libraries(supernova libsupernova) if(WIN32)