libuiohook
libuiohook copied to clipboard
[Feature Request] Add support for Mac Catalyst
Would it be possible to compile libuiohook for Mac Catalyst in addition to macOS? I've tried to fiddle with CMake, but didn't achieve much with it. I don't know if it's even possible to support Mac Catalyst without changes to the code.
I'm asking for this because one of the most popular UI frameworks for .NET - MAUI - uses Mac Catalyst to run apps on macOS (it doesn't provide a way to run apps as normal macOS apps). Several people have asked me to add support for MAUI on macOS to my libuiohook wrapper for .NET, and I don't know how to make it work as I don't have experience with CMake.
I've managed to add support for Mac Catalyst in my fork, but I feel that it's full of hacks. Nevertheless it works. You can check out this commit in my fork.
This is how it can be built:
export CC=clang
export CFLAGS='-O2 -g -target arm64-apple-ios13.1-macabi -miphoneos-version-min=13.1 -fembed-bitcode'
cmake -B ./build \
-G "Unix Makefiles" \
-D CMAKE_INSTALL_PREFIX=./dist/darwin/catalyst \
-D CMAKE_VERBOSE_MAKEFILE=true \
-D CMAKE_OSX_ARCHITECTURES='arm64' \
-D BUILD_SHARED_LIBS=ON \
-D MAC_CATALYST=ON \
-D USE_APPLICATION_SERVICES=OFF \
-D USE_IOKIT=OFF \
-D USE_APPKIT=OFF \
-D USE_EPOCH_TIME=ON
cmake --build ${{github.workspace}}/build \
--parallel 2 \
--config RelWithDebInfo \
--clean-first
cmake --install ${{github.workspace}}/build --config RelWithDebInfo
This will build the arm64 version - the x86_64 can be built the same way basically, just changing arm64 to x86_64.
I just dug thought your changes. It looks pretty doable. I have some questions:
I guess the first thing I am trying to figure out is what is "Mac Catalyst" and why does it require the library be compiled differently for use with it? I don't know much about Apples ecosystem so this is just so I can figure out why we are doing this.
Looking though your changes, I would prefer not to have the MAC_CATALYST
define for enabling this. I don't think its really needed based on what I see in the commit you linked. We can just drop the #include <Carbon/Carbon.h>
as everything else in there has been deprecated for years and in typical fashion, no replacement API was ever provided. I think everything you have below in the input_help.h will cover the need for Carbon.h
.
I am not sure where kVK_RightCommand
is usually defined. I think it was missing from the older headers which is why I added it here, but if its now magically provided we can just do something like the following:
#ifndef kVK_RightCommand
#define kVK_RightCommand 0x36
#endif
I am trying to figure out why you removed the following. It shouldn't have any effect on Catalyst support.
#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1050
typedef void* dispatch_queue_t;
#endif
The last bit is the difference in build flags:
if(MAC_CATALYST)
add_compile_definitions(uiohook PRIVATE MAC_CATALYST)
find_library(CORE_FOUNDATION CoreFoundation REQUIRED)
target_include_directories(uiohook PRIVATE "${CORE_FOUNDATION}")
target_link_libraries(uiohook "${CORE_FOUNDATION}")
find_library(CORE_GRAPHICS CoreGraphics REQUIRED)
target_include_directories(uiohook PRIVATE "${CORE_GRAPHICS}")
target_link_libraries(uiohook "${CORE_GRAPHICS}")
else()
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15")
find_package(Threads REQUIRED)
target_link_libraries(uiohook "${CMAKE_THREAD_LIBS_INIT}")
find_library(CARBON Carbon REQUIRED)
target_include_directories(uiohook PRIVATE "${CARBON}")
target_link_libraries(uiohook "${CARBON}")
endif()
Changing CMAKE_OSX_DEPLOYMENT_TARGET
should probably happen on the command-line at build time. I think you can override it with something like -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15
. This library still officially supports 10.5 and will probably still build for 10.4.
I am guessing that we need to look for CoreFoundation
in the MAC_CATALYST
enabled build because it gets sucked in by Carbon
normally. If we pull in the HIToolbox stuff into input_helper.h
I think we can just use the CoreFoundation
library. I am guessing all of the above also applies to CoreGraphics
.
How did we get away with dropping support for Threads
? I think pthreads are still required for some mutex locking in input_hook.c
to get the key typed chars.
If you would like to open a PR, please do so and we can get this merged into 1.3.
Mac Catalyst is a macOS system which enables running apps for iOS and iPadOS on macOS. As I've said, MAUI - a cross-platform UI framework for .NET - uses Mac Catalyst for macOS apps, so that's why SharpHook needs to support it.
Apps and libraries must be compiled for iOS in order to work on Mac Catalyst, that's why we need a different build of libuiohook. Since Carbon.h
is not available on iOS, I needed to make adjustments.
Regarding macOS version support, Mac Catalyst itself appeared in version 10.15, so if we're building for Mac Catalyst, we're automatically building for 10.15+. Mac Catalyst versions correspond with iOS versions, and the earliest supported iOS version is 13.1. I've decided to drop support for versions of macOS older than 10.15 in my fork, because .NET itself doesn't officially support them. That's why I've removed some definitions from headers. Obviously, they should be kept if you want to support 10.5.
Regarding Threads
, CoreFoundation
etc. - I just hacked around to make it compile, I'm sure there are ways to make it better. As far as I remember, Threads
was not available for Mac Catalyst, but I'm not sure. But I tested it, and it works (maybe, it's now open to some race conditions, I don't know to be honest).
And regarding CMAKE_OSX_DEPLOYMENT_TARGET
- same thing, I just hacked around to make it work, I'm really not proficient in cmake at all, so if there are better ways to do that, I just didn't know.
I can make a PR with these changes, but I'm sure I didn't implement it in the best way possible (or even in a good way), so if you can improve on it, it would be awesome.
Well, I understand what you did, but I cant seem to get it to compile. I keep seeing this warning clang: warning: using sysroot for 'iPhoneOS' but targeting 'MacOSX'
which doesn't really make sense to me. We are manually specifying the target and it's clearly iOS.
Well, it compiles but I dont have any way of testing it. I still don't think cmake is setup correctly for ios so I still need to look into that.
Okey, so I think this is as good as it will get and I hope it works. I need you to do some testing because I have no idea how to use the output of this build. Ideally we should be able to do something like this, however, CMake does not support building for catalyst and it doesn't look like that support is showing up anytime soon.
export CC=clang
export CFLAGS='-O2'
cmake -B ./build \
-G "Unix Makefiles" \
-D CMAKE_INSTALL_PREFIX=./dist/ios/arm64 \
-D CMAKE_VERBOSE_MAKEFILE=true \
-D CMAKE_SYSTEM_NAME=iOS \
-D CMAKE_OSX_SYSROOT=`xcrun --sdk macosx --show-sdk-path` \
-D CMAKE_OSX_ARCHITECTURES=arm64 \
-D CMAKE_OSX_DEPLOYMENT_TARGET=13.1 \
-D BUILD_SHARED_LIBS=ON \
-D USE_APPLICATION_SERVICES=OFF \
-D USE_IOKIT=OFF \
-D USE_APPKIT=OFF \
-D BUILD_DEMO=OFF
The main issue is that the system name is required to be iOS which is how cmake converts CMAKE_OSX_DEPLOYMENT_TARGET=13.1
into the -miphoneos-version-min=13.1
argument, but if we set that it complains that the -isysroot
specified with CMAKE_OSX_SYSROOT=xcrun --sdk macosx --show-sdk-path
is not an iPhone SDK. If we try and compile with the iPhone SDK we get a bunch of errors becaues things like CGEventRef
are not defined for iOS. If you try to build with CMAKE_SYSTEM_NAME=Darwin
you get the correct macOS SDK, but you then get -mmacosx-version-min=13.1
which is also not correct. The only way I can get this to somewhat work correctly is by using the -target
you provided.
Sorry for not answering earlier, I see that you've tinkered with it quite a lot. I'll test my fork with this configuration and let you know whether it works in the next couple days.
When I first tried building libuiohook for Mac Catalyst, I tried creating an app in XCode in Objective-C, target Mac Catalyst, and link libuiohook to it, but it got nowhere since I don't know anything about Apple toolchains or Objective-C. Maybe, you'll have more luck if you try that.
I've just tested a build of libuiohook for Mac Catalyst, and everything seems to work fine. I've tested global hooks, input simulation, and mouse properties.
I've used this configuration from the latest commit on your branch:
cmake -B ./build \
-G "Unix Makefiles" \
-D CMAKE_INSTALL_PREFIX=./dist/catalyst/arm64 \
-D CMAKE_VERBOSE_MAKEFILE=true \
-D BUILD_SHARED_LIBS=ON \
-D BUILD_DEMO=ON \
-D USE_APPLICATION_SERVICES=OFF \
-D USE_IOKIT=OFF \
-D USE_APPKIT=OFF \
-D BUILD_DEMO=OFF
This configuration works great.
But the configuration from your last comment doesn't work, it gives out this error:
CMake Error at /opt/homebrew/Cellar/cmake/3.29.2/share/cmake/Modules/Platform/iOS-Initialize.cmake:4 (message):
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk
is not an iOS SDK
Call Stack (most recent call first):
/opt/homebrew/Cellar/cmake/3.29.2/share/cmake/Modules/CMakeSystemSpecificInitialize.cmake:34 (include)
CMakeLists.txt:20 (project)