diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 40ada3e1..847c4c40 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -14,7 +14,7 @@ macro(DeployMacOS TARGET) install(CODE "set(PLUGIN_DIR \"${QT_PLUGIN_DIR}\")" COMPONENT "Hyperion") install(CODE "set(BUILD_DIR \"${CMAKE_BINARY_DIR}\")" COMPONENT "Hyperion") install(CODE "set(ENABLE_EFFECTENGINE \"${ENABLE_EFFECTENGINE}\")" COMPONENT "Hyperion") - + install(CODE [[ file(GET_RUNTIME_DEPENDENCIES @@ -36,6 +36,7 @@ macro(DeployMacOS TARGET) FILES "${dependency}" DESTINATION "${CMAKE_INSTALL_PREFIX}/${TARGET_BUNDLE_NAME}/Contents/lib" TYPE SHARED_LIBRARY + FOLLOW_SYMLINK_CHAIN ) endif() endforeach() @@ -48,7 +49,6 @@ macro(DeployMacOS TARGET) foreach(PLUGIN "platforms" "sqldrivers" "imageformats") if(EXISTS ${PLUGIN_DIR}/${PLUGIN}) file(GLOB files "${PLUGIN_DIR}/${PLUGIN}/*") - list(FILTER files EXCLUDE REGEX ".*libqwebp\\.dylib$") foreach(file ${files}) file(GET_RUNTIME_DEPENDENCIES EXECUTABLES ${file} @@ -61,6 +61,7 @@ macro(DeployMacOS TARGET) DESTINATION "${CMAKE_INSTALL_PREFIX}/${TARGET_BUNDLE_NAME}/Contents/lib" TYPE SHARED_LIBRARY FILES ${DEPENDENCY} + FOLLOW_SYMLINK_CHAIN ) endforeach() @@ -76,25 +77,27 @@ macro(DeployMacOS TARGET) endif() endforeach() - include(BundleUtilities) + include(BundleUtilities) fixup_bundle("${CMAKE_INSTALL_PREFIX}/${TARGET_BUNDLE_NAME}" "${QT_PLUGINS}" "${CMAKE_INSTALL_PREFIX}/${TARGET_BUNDLE_NAME}/Contents/lib" IGNORE_ITEM "python;python3;Python;Python3;.Python;.Python3") if(ENABLE_EFFECTENGINE) # Detect the Python version and modules directory - find_package(Python3 3.5 REQUIRED) - execute_process( - COMMAND ${Python3_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(standard_lib=True))" - OUTPUT_VARIABLE PYTHON_MODULES_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE - ) + if(NOT CMAKE_VERSION VERSION_LESS "3.12") + find_package(Python3 COMPONENTS Interpreter Development REQUIRED) + set(PYTHON_VERSION_MAJOR_MINOR "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}") + set(PYTHON_MODULES_DIR ${Python3_STDLIB}) + else() + find_package (PythonLibs ${PYTHON_VERSION_STRING} EXACT) + set(PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") + set(PYTHON_MODULES_DIR ${Python_STDLIB}) + endif() MESSAGE("Add Python ${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR} to bundle") MESSAGE("PYTHON_MODULES_DIR: ${PYTHON_MODULES_DIR}") # Copy Python modules to '/../Frameworks/Python.framework/Versions/Current/lib/PythonMAJOR.MINOR' and ignore the unnecessary stuff listed below if (PYTHON_MODULES_DIR) - set(PYTHON_VERSION_MAJOR_MINOR "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}") file( COPY ${PYTHON_MODULES_DIR}/ DESTINATION "${CMAKE_INSTALL_PREFIX}/${TARGET_BUNDLE_NAME}/Contents/Frameworks/Python.framework/Versions/Current/lib/python${PYTHON_VERSION_MAJOR_MINOR}" @@ -167,9 +170,9 @@ macro(DeployLinux TARGET) # Extract dependencies ignoring the system ones get_prerequisites(${TARGET_FILE} DEPENDENCIES 0 1 "" "") - + message(STATUS "Dependencies for target file: ${DEPENDENCIES}") - + # Append symlink and non-symlink dependencies to the list set(PREREQUISITE_LIBS "") foreach(DEPENDENCY ${DEPENDENCIES}) @@ -276,15 +279,13 @@ macro(DeployLinux TARGET) if(ENABLE_EFFECTENGINE) # Detect the Python version and modules directory if (NOT CMAKE_VERSION VERSION_LESS "3.12") + find_package(Python3 COMPONENTS Interpreter Development REQUIRED) set(PYTHON_VERSION_MAJOR_MINOR "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}") - set(PYTHON_MODULES_DIR "${Python3_STDLIB}") + set(PYTHON_MODULES_DIR ${Python3_STDLIB}) else() + find_package (PythonLibs ${PYTHON_VERSION_STRING} EXACT) set(PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") - execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(standard_lib=True))" - OUTPUT_VARIABLE PYTHON_MODULES_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE - ) + set(PYTHON_MODULES_DIR ${Python_STDLIB}) endif() # Copy Python modules to 'share/hyperion/lib/pythonMAJOR.MINOR' and ignore the unnecessary stuff listed below @@ -381,19 +382,25 @@ macro(DeployWindows TARGET) list(GET openssl_versions 0 openssl_version_major) list(GET openssl_versions 1 openssl_version_minor) - set(library_suffix "-${openssl_version_major}_${openssl_version_minor}") + set(open_ssl_version_suffix) + if (openssl_version_major VERSION_EQUAL 1 AND openssl_version_minor VERSION_EQUAL 1) + set(open_ssl_version_suffix "-1_1") + else() + set(open_ssl_version_suffix "-3") + endif() + if (CMAKE_SIZEOF_VOID_P EQUAL 8) - string(APPEND library_suffix "-x64") + string(APPEND open_ssl_version_suffix "-x64") endif() find_file(OPENSSL_SSL - NAMES "libssl${library_suffix}.dll" + NAMES "libssl${open_ssl_version_suffix}.dll" PATHS ${OPENSSL_INCLUDE_DIR}/.. ${OPENSSL_INCLUDE_DIR}/../bin NO_DEFAULT_PATH ) find_file(OPENSSL_CRYPTO - NAMES "libcrypto${library_suffix}.dll" + NAMES "libcrypto${open_ssl_version_suffix}.dll" PATHS ${OPENSSL_INCLUDE_DIR}/.. ${OPENSSL_INCLUDE_DIR}/../bin NO_DEFAULT_PATH ) diff --git a/include/events/OsEventHandler.h b/include/events/OsEventHandler.h index 3ca05c79..0dffea38 100644 --- a/include/events/OsEventHandler.h +++ b/include/events/OsEventHandler.h @@ -106,28 +106,21 @@ private: using OsEventHandler = OsEventHandlerLinux; #elif defined(__APPLE__) -#include - class OsEventHandlerMacOS : public OsEventHandlerBase { Q_OBJECT - static void notificationCenterCallBack(CFNotificationCenterRef center, void* observer, CFStringRef name, const void* object, CFDictionaryRef userInfo) - { - OsEventHandlerMacOS::getInstance()->handleSignal(name); - } - public: - void handleSignal (CFStringRef lock_unlock); + OsEventHandlerMacOS(); private: - static OsEventHandlerMacOS* getInstance(); - - CFStringRef lockSignal = CFSTR("com.apple.screenIsLocked"); - CFStringRef unlockSignal = CFSTR("com.apple.screenIsUnlocked"); + bool registerOsEventHandler() override; + void unregisterOsEventHandler() override; bool registerLockHandler() override; void unregisterLockHandler() override; + void *_sleepEventHandler; + void *_lockEventHandler; }; using OsEventHandler = OsEventHandlerMacOS; diff --git a/libsrc/events/CMakeLists.txt b/libsrc/events/CMakeLists.txt index a0d41ae6..9eb4fd00 100644 --- a/libsrc/events/CMakeLists.txt +++ b/libsrc/events/CMakeLists.txt @@ -1,31 +1,28 @@ -# Define the current source/header locations -SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/events) -SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/events) - add_library(events - ${CURRENT_HEADER_DIR}/EventEnum.h - ${CURRENT_HEADER_DIR}/EventHandler.h - ${CURRENT_SOURCE_DIR}/EventHandler.cpp - ${CURRENT_HEADER_DIR}/OsEventHandler.h - ${CURRENT_SOURCE_DIR}/OsEventHandler.cpp + ${CMAKE_SOURCE_DIR}/include/events/EventEnum.h + ${CMAKE_SOURCE_DIR}/include/events/EventHandler.h + ${CMAKE_SOURCE_DIR}/include/events/OsEventHandler.h + ${CMAKE_SOURCE_DIR}/libsrc/events/EventHandler.cpp + ${CMAKE_SOURCE_DIR}/libsrc/events/OsEventHandler.cpp ) -if (UNIX) - find_package(Qt${QT_VERSION_MAJOR} COMPONENTS DBus QUIET ) - if (Qt${QT_VERSION_MAJOR}DBus_FOUND) +if(UNIX AND NOT APPLE) + find_package(Qt${QT_VERSION_MAJOR} COMPONENTS DBus QUIET) + if(Qt${QT_VERSION_MAJOR}DBus_FOUND) target_link_libraries(events Qt${QT_VERSION_MAJOR}::DBus) - if (NOT APPLE) - target_compile_definitions(events PUBLIC HYPERION_HAS_DBUS) - endif() + target_compile_definitions(events PRIVATE HYPERION_HAS_DBUS) endif() -endif(UNIX) +endif() + +target_link_libraries(events hyperion-utils) + +if(APPLE) + # find_library(FOUNDATION_LIBRARY Foundation REQUIRED) + set_source_files_properties(OsEventHandler.cpp PROPERTIES COMPILE_FLAGS "-x objective-c++") + # target_link_libraries(events ${FOUNDATION_LIBRARY}) + # target_include_directories(events PRIVATE ${FOUNDATION_LIBRARY}) +endif() + + -target_include_directories(events PUBLIC - ${CURRENT_HEADER_DIR} -) -target_link_libraries(events - hyperion-utils - Qt${QT_VERSION_MAJOR}::Core - Qt${QT_VERSION_MAJOR}::Widgets -) diff --git a/libsrc/events/OsEventHandler.cpp b/libsrc/events/OsEventHandler.cpp index c7ea0564..6cf25f4e 100644 --- a/libsrc/events/OsEventHandler.cpp +++ b/libsrc/events/OsEventHandler.cpp @@ -1,4 +1,4 @@ -#include "OsEventHandler.h" +#include "events/OsEventHandler.h" #include #include @@ -16,6 +16,8 @@ #include #pragma comment( lib, "wtsapi32.lib" ) +#elif defined(__APPLE__) +#import #endif OsEventHandlerBase::OsEventHandlerBase() @@ -447,43 +449,152 @@ void OsEventHandlerLinux::unregisterLockHandler() #elif defined(__APPLE__) -OsEventHandlerMacOS* OsEventHandlerMacOS::getInstance() +OsEventHandlerMacOS::OsEventHandlerMacOS() + : _sleepEventHandler(nullptr) + , _lockEventHandler(nullptr) { - static OsEventHandlerMacOS instance; - return &instance; } -void OsEventHandlerMacOS::handleSignal (CFStringRef lock_unlock) +@interface SleepEvents : NSObject { - if (CFEqual(lock_unlock, CFSTR("com.apple.screenIsLocked"))) + OsEventHandlerMacOS *_eventHandler; +} +- (id)initSleepEvents:(OsEventHandlerMacOS *)osEventHandler; +@end + +@implementation SleepEvents +- (id)initSleepEvents:(OsEventHandlerMacOS *)osEventHandler +{ + if ((self = [super init])) { - lock(true); + _eventHandler = osEventHandler; + id notifCenter = [[NSWorkspace sharedWorkspace] notificationCenter]; + [notifCenter addObserver:self selector:@selector(receiveSleepWake:) name:NSWorkspaceWillSleepNotification object:nil]; + [notifCenter addObserver:self selector:@selector(receiveSleepWake:) name:NSWorkspaceDidWakeNotification object:nil]; + } + + return self; +} + +- (void)dealloc +{ + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self]; + _eventHandler = nullptr; + [super dealloc]; +} + +- (void) receiveSleepWake:(NSNotification*)notification +{ + if (!_eventHandler) return; + if (notification.name == NSWorkspaceWillSleepNotification) + { + _eventHandler->suspend(true); } - else if (CFEqual(lock_unlock, CFSTR("com.apple.screenIsUnlocked"))) + else if (notification.name == NSWorkspaceDidWakeNotification) + { + _eventHandler->suspend(false); + } +} +@end + +bool OsEventHandlerMacOS::registerOsEventHandler() +{ + bool isRegistered {_isSuspendRegistered}; + if (!_isSuspendRegistered) { - lock(false); + _sleepEventHandler = [[SleepEvents alloc] initSleepEvents:this]; + if (_sleepEventHandler) + { + Debug(_log, "Registered for suspend/resume events"); + isRegistered = true; + } + else + { + Error(_log, "Could not register for suspend/resume events"); + } + + if (isRegistered) + { + _isSuspendRegistered = true; + } + } + return isRegistered; +} + +void OsEventHandlerMacOS::unregisterOsEventHandler() +{ + if (_isSuspendRegistered && _sleepEventHandler) + { + [(SleepEvents *)_sleepEventHandler release], _sleepEventHandler = nil; + if (!_sleepEventHandler) + { + Debug(_log, "Unregistered for suspend/resume events"); + _isSuspendRegistered = false; + } + else + { + Error(_log, "Could not unregister for suspend/resume events"); + } } } +@interface LockEvents : NSObject +{ + OsEventHandlerMacOS *_eventHandler; +} +- (id)initLockEvents:(OsEventHandlerMacOS *)osEventHandler; +@end + +@implementation LockEvents +- (id)initLockEvents:(OsEventHandlerMacOS *)osEventHandler +{ + if ((self = [super init])) + { + _eventHandler = osEventHandler; + id defCenter = [NSDistributedNotificationCenter defaultCenter]; + [defCenter addObserver:self selector:@selector(receiveLockUnlock:) name:@"com.apple.screenIsLocked" object:nil]; + [defCenter addObserver:self selector:@selector(receiveLockUnlock:) name:@"com.apple.screenIsUnlocked" object:nil]; + } + + return self; +} + +- (void)dealloc +{ + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self]; + _eventHandler = nullptr; + [super dealloc]; +} + +- (void) receiveLockUnlock:(NSNotification*)notification +{ + if (!_eventHandler) return; + if (CFEqual(notification.name, CFSTR("com.apple.screenIsLocked"))) + { + _eventHandler->lock(true); + } + else if (CFEqual(notification.name, CFSTR("com.apple.screenIsUnlocked"))) + { + _eventHandler->lock(false); + } +} +@end + bool OsEventHandlerMacOS::registerLockHandler() { bool isRegistered{ _isLockRegistered }; if (!_isLockRegistered) { - CFNotificationCenterRef distCenter; - - distCenter = CFNotificationCenterGetDistributedCenter(); - if (distCenter != nullptr) + _lockEventHandler = [[LockEvents alloc] initLockEvents:this]; + if (_lockEventHandler) { - CFNotificationCenterAddObserver(distCenter, this, &OsEventHandlerMacOS::notificationCenterCallBack, lockSignal, nullptr, CFNotificationSuspensionBehaviorDeliverImmediately); - CFNotificationCenterAddObserver(distCenter, this, &OsEventHandlerMacOS::notificationCenterCallBack, unlockSignal, nullptr, CFNotificationSuspensionBehaviorDeliverImmediately); + Debug(_log, "Registered for lock/unlock events"); isRegistered = true; } else { Error(_log, "Could not register for lock/unlock events!"); } - } if (isRegistered) @@ -495,10 +606,18 @@ bool OsEventHandlerMacOS::registerLockHandler() void OsEventHandlerMacOS::unregisterLockHandler() { - if (_isLockRegistered) + if (_isLockRegistered && _lockEventHandler) { - CFNotificationCenterRemoveEveryObserver(CFNotificationCenterGetDistributedCenter(), this); - _isLockRegistered = false; + [(LockEvents *)_lockEventHandler release], _lockEventHandler = nil; + if (!_lockEventHandler) + { + Debug(_log, "Unregistered for lock/unlock events"); + _isLockRegistered = false; + } + else + { + Error(_log, "Could not unregister for lock/unlock events"); + } } }