changeset 194:8548dc425697

sys/osx: remove all objective-c++ stuff mmmm :)
author Paper <mrpapersonic@gmail.com>
date Thu, 07 Dec 2023 03:17:05 -0500
parents 0ad2507c3e60
children 975a3f0965e2
files CMakeLists.txt dep/animia/src/util/osx.cc include/sys/osx/dark_theme.h include/sys/osx/filesystem.h src/core/filesystem.cc src/sys/osx/dark_theme.cc src/sys/osx/dark_theme.mm src/sys/osx/filesystem.cc src/sys/osx/filesystem.mm
diffstat 9 files changed, 187 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Thu Dec 07 01:56:39 2023 -0500
+++ b/CMakeLists.txt	Thu Dec 07 03:17:05 2023 -0500
@@ -1,10 +1,6 @@
 cmake_minimum_required(VERSION 3.18)
 project(minori LANGUAGES CXX VERSION 0.1.0)
 
-if(APPLE)
-	enable_language(OBJCXX)
-endif()
-
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
@@ -162,8 +158,8 @@
 	set_source_files_properties(${app_icon_osx} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
 
 	list(APPEND SRC_FILES
-		src/sys/osx/dark_theme.mm
-		src/sys/osx/filesystem.mm
+		src/sys/osx/dark_theme.cc
+		src/sys/osx/filesystem.cc
 		${app_icon_osx}
 	)
 elseif(WIN32) # Windows
--- a/dep/animia/src/util/osx.cc	Thu Dec 07 01:56:39 2023 -0500
+++ b/dep/animia/src/util/osx.cc	Thu Dec 07 03:17:05 2023 -0500
@@ -99,7 +99,7 @@
 		return false;
 
 	result.resize(CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), kCFStringEncodingUTF8) + 1);
-	if (!CFStringGetCString(string, &result.front(), result.length(), result.length()))
+	if (!CFStringGetCString(string, &result.front(), result.length(), kCFStringEncodingUTF8))
 		return false;
 
 	return true;
--- a/include/sys/osx/dark_theme.h	Thu Dec 07 01:56:39 2023 -0500
+++ b/include/sys/osx/dark_theme.h	Thu Dec 07 03:17:05 2023 -0500
@@ -5,8 +5,8 @@
 
 bool DarkThemeAvailable();
 bool IsInDarkTheme();
-void SetToDarkTheme();
-void SetToLightTheme();
+bool SetToDarkTheme();
+bool SetToLightTheme();
 void SetToAutoTheme();
 
 } // namespace osx
--- a/include/sys/osx/filesystem.h	Thu Dec 07 01:56:39 2023 -0500
+++ b/include/sys/osx/filesystem.h	Thu Dec 07 03:17:05 2023 -0500
@@ -5,7 +5,7 @@
 
 namespace osx {
 
-std::string GetApplicationSupportDirectory();
+bool GetApplicationSupportDirectory(std::string& result);
 
 }
 
--- a/src/core/filesystem.cc	Thu Dec 07 01:56:39 2023 -0500
+++ b/src/core/filesystem.cc	Thu Dec 07 03:17:05 2023 -0500
@@ -49,7 +49,11 @@
 
 	return path / CONFIG_DIR;
 #elif defined(MACOSX)
-	return std::filesystem::path(osx::GetApplicationSupportDirectory()) / CONFIG_DIR;
+	std::string appsupport;
+	if (!osx::GetApplicationSupportDirectory(appsupport))
+		return "";
+
+	return std::filesystem::path(appsupport) / CONFIG_DIR;
 #else // just assume POSIX
 	std::filesystem::path path;
 	const char* home = getenv("HOME");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sys/osx/dark_theme.cc	Thu Dec 07 03:17:05 2023 -0500
@@ -0,0 +1,133 @@
+#include "sys/osx/dark_theme.h"
+
+#include <objc/runtime.h>
+#include <objc/message.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <AvailabilityMacros.h>
+
+#include <QOperatingSystemVersion>
+
+namespace osx {
+
+typedef id (*object_message_send)(id, SEL, ...);
+typedef id (*class_message_send)(Class, SEL, ...);
+
+static const object_message_send obj_send = reinterpret_cast<object_message_send>(objc_msgSend);
+static const class_message_send cls_send = reinterpret_cast<class_message_send>(objc_msgSend);
+
+static CFStringRef NSAppearanceNameAqua = nullptr;
+static CFStringRef NSAppearanceNameDarkAqua = nullptr;
+
+static const CFStringRef kLaunchServicesBundleID = CFSTR("com.apple.AppKit");
+
+bool RetrieveAppearanceNames() {
+	CFBundleRef appkit_bundle = CFBundleGetBundleWithIdentifier(kLaunchServicesBundleID);
+	if (!appkit_bundle)
+		return false;
+
+	NSAppearanceNameAqua = *reinterpret_cast<CFStringRef*>(CFBundleGetDataPointerForName(appkit_bundle, CFSTR("NSAppearanceNameAqua")));
+	if (!NSAppearanceNameAqua)
+		return false;
+
+	NSAppearanceNameDarkAqua = *reinterpret_cast<CFStringRef*>(CFBundleGetDataPointerForName(appkit_bundle, CFSTR("NSAppearanceNameDarkAqua")));
+	if (!NSAppearanceNameDarkAqua)
+		return false;
+
+	return true;
+}
+
+bool DarkThemeAvailable() {
+	return (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave);
+}
+
+bool IsInDarkTheme() {
+	if (!DarkThemeAvailable())
+		return false;
+
+	if (!NSAppearanceNameAqua || !NSAppearanceNameDarkAqua)
+		if (!RetrieveAppearanceNames())
+			return false;
+
+	CFArrayRef array = []() -> CFArrayRef {
+		CFStringRef refs[] = {NSAppearanceNameAqua, NSAppearanceNameDarkAqua};
+		return CFArrayCreate(NULL, reinterpret_cast<const void**>(refs), 2, &kCFTypeArrayCallBacks);
+	}();
+
+	// NSApplication* app = [NSApplication sharedApplication];
+	const id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication"));
+
+	// NSAppearance* effectiveAppearance = [app effectiveAppearance];
+	const id effectiveAppearance = obj_send(app, sel_getUid("effectiveAppearance"));
+	if (!effectiveAppearance) {
+		CFRelease(array);
+		return false;
+	}
+
+	// NSAppearance* appearance = [effectiveAppearance bestMatchFromAppearancesWithNames: array];
+	const id appearance = obj_send(effectiveAppearance, sel_getUid("bestMatchFromAppearancesWithNames:"), array);
+
+	CFRelease(array);
+
+	if (!appearance)
+		return false;
+
+	return CFEqual(appearance, NSAppearanceNameDarkAqua);
+}
+
+bool SetToDarkTheme() {
+	// https://stackoverflow.com/questions/55925862/how-can-i-set-my-os-x-application-theme-in-code
+	if (!DarkThemeAvailable())
+		return false;
+
+	if (!NSAppearanceNameAqua || !NSAppearanceNameDarkAqua)
+		if (!RetrieveAppearanceNames())
+			return false;
+
+	// NSApplication* app = [NSApplication sharedApplication];
+	const id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication"));
+
+	// NSAppearance* appearance = [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua];
+	const id appearance = cls_send(objc_getClass("NSAppearance"), sel_getUid("appearanceNamed:"), NSAppearanceNameDarkAqua);
+	if (!appearance)
+		return false;
+
+	// [app setAppearance: appearance];
+	obj_send(app, sel_getUid("setAppearance:"), appearance);
+	return true;
+}
+
+bool SetToLightTheme() {
+	// https://stackoverflow.com/questions/55925862/how-can-i-set-my-os-x-application-theme-in-code
+	if (!DarkThemeAvailable())
+		return false;
+
+	if (!NSAppearanceNameAqua || !NSAppearanceNameDarkAqua)
+		if (!RetrieveAppearanceNames())
+			return false;
+
+	// NSApplication* app = [NSApplication sharedApplication];
+	const id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication"));
+
+	// NSAppearance* appearance = [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua];
+	const id appearance = cls_send(objc_getClass("NSAppearance"), sel_getUid("appearanceNamed:"), NSAppearanceNameAqua);
+	if (!appearance)
+		return false;
+
+	// [app setAppearance: appearance];
+	obj_send(app, sel_getUid("setAppearance:"), appearance);
+	return true;
+}
+
+void SetToAutoTheme() {
+	if (!DarkThemeAvailable())
+		return;
+
+	// NSApplication* app = [NSApplication sharedApplication];
+	const id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication"));
+
+	// [app setAppearance: null];
+	obj_send(app, sel_getUid("setAppearance:"), nullptr);
+}
+
+} // namespace osx
--- a/src/sys/osx/dark_theme.mm	Thu Dec 07 01:56:39 2023 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#include "sys/osx/dark_theme.h"
-
-#import <AppKit/AppKit.h>
-
-namespace osx {
-
-/* I remember clang giving a hissy fit when I tried simplifying this to just
- * a return; does it still do that?
-*/
-bool DarkThemeAvailable() {
-	if (@available(macOS 10.14, *))
-		return true;
-	else
-		return false;
-}
-
-bool IsInDarkTheme() {
-	if (@available(macOS 10.14, *)) {
-		auto appearance = [NSApp.effectiveAppearance
-		    bestMatchFromAppearancesWithNames:@[ NSAppearanceNameAqua, NSAppearanceNameDarkAqua ]];
-		return [appearance isEqualToString:NSAppearanceNameDarkAqua];
-	}
-	return false;
-}
-
-void SetToDarkTheme() {
-	// https://stackoverflow.com/questions/55925862/how-can-i-set-my-os-x-application-theme-in-code
-	if (@available(macOS 10.14, *)) {
-		[NSApp setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameDarkAqua]];
-	}
-}
-
-void SetToLightTheme() {
-	// https://stackoverflow.com/questions/55925862/how-can-i-set-my-os-x-application-theme-in-code
-	if (@available(macOS 10.14, *)) {
-		[NSApp setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameAqua]];
-	}
-}
-
-void SetToAutoTheme() {
-	if (@available(macOS 10.14, *)) {
-		[NSApp setAppearance:nil];
-	}
-}
-
-} // namespace osx
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sys/osx/filesystem.cc	Thu Dec 07 03:17:05 2023 -0500
@@ -0,0 +1,43 @@
+#include "sys/osx/filesystem.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <string>
+
+static constexpr unsigned long NSApplicationSupportDirectory = 14;
+static constexpr unsigned long NSUserDomainMask = 1;
+
+extern "C" {
+	CFArrayRef NSSearchPathForDirectoriesInDomains(unsigned long directory, unsigned long domainMask, int expandTilde);
+}
+
+namespace osx {
+
+bool GetApplicationSupportDirectory(std::string& result) {
+	const CFArrayRef strings = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, true);
+	if (!strings)
+		return false;
+
+	const CFIndex count = CFArrayGetCount(strings);
+	if (count < 1) {
+		CFRelease(strings);
+		return false;
+	}
+
+	const CFStringRef string = reinterpret_cast<CFStringRef>(CFArrayGetValueAtIndex(strings, 0));
+	if (!string) {
+		CFRelease(strings);
+		return false;
+	}
+
+	result.resize(CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), kCFStringEncodingUTF8) + 1);
+	if (!CFStringGetCString(string, &result.front(), result.length(), kCFStringEncodingUTF8)) {
+		CFRelease(strings);
+		return false;
+	}
+	result.resize(result.find('\0'));
+
+	return true;
+}
+
+} // namespace osx
--- a/src/sys/osx/filesystem.mm	Thu Dec 07 01:56:39 2023 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-#include "sys/osx/filesystem.h"
-
-#include <string>
-
-#import <Foundation/Foundation.h>
-
-namespace osx {
-
-std::string GetApplicationSupportDirectory() {
-	NSArray* strings = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, true);
-	if (!strings || [strings count] < 1)
-		return ""; // ack
-
-	return [[strings objectAtIndex:0] UTF8String];
-}
-
-} // namespace osx