diff dep/animia/src/win/quartz.mm @ 155:d2bbb5773616

dep/animia: add quartz backend for windows
author Paper <mrpapersonic@gmail.com>
date Wed, 15 Nov 2023 15:24:39 -0500
parents
children cdf79282d647
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dep/animia/src/win/quartz.mm	Wed Nov 15 15:24:39 2023 -0500
@@ -0,0 +1,71 @@
+#include "animia/win/quartz.h"
+#include "animia.h"
+
+#include <Foundation/Foundation.h>
+#include <CoreGraphics/CoreGraphics.h>
+#include <AppKit/AppKit.h>
+
+namespace animia::internal::quartz {
+
+template<typename T>
+static bool IntegerFromNSNumber(NSNumber* num, T& result) {
+	if (!num)
+		return false;
+	result = [num intValue];
+	return true;
+}
+
+static bool GetWindowTitle(unsigned int wid, std::string& result) {
+	NSWindow* window = [NSApp windowWithWindowNumber: wid];
+	if (!window)
+		return false;
+
+	NSString* title = [window title];
+	if (!title)
+		return false;
+
+	result = [title UTF8String];
+
+	return true;
+}
+
+static bool StringFromNSString(NSString* string, std::string& result) {
+	if (!string)
+		return false;
+	result = [string UTF8String];
+	return true;
+}
+
+bool QuartzWinTools::EnumerateWindows(window_proc_t window_proc) {
+	if (!window_proc)
+		return false;
+
+	NSMutableArray* windows = (NSMutableArray*)CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
+	if (!windows)
+		return false;
+
+	for (NSDictionary* window in windows) {
+		if (!window)
+			continue;
+
+		Process proc;
+		{
+			IntegerFromNSNumber([window objectForKey:@"kCGWindowOwnerPID"], proc.pid);
+			StringFromNSString([window objectForKey:@"kCGWindowOwnerName"], proc.name);
+		}
+
+		Window win;
+		{
+			IntegerFromNSNumber([window objectForKey:@"kCGWindowNumber"], win.id);
+			StringFromNSString([window objectForKey:@"kCGWindowName"], win.class_name);
+			GetWindowTitle(win.id, win.text);
+		}
+
+		if (!window_proc(proc, win))
+			return false;
+	}
+
+	return true;
+}
+
+} // namespace animia::win::detail