annotate dep/animone/src/win/quartz.cc @ 337:a7d4e5107531

dep/animone: REFACTOR ALL THE THINGS 1: animone now has its own syntax divergent from anisthesia, making different platforms actually have their own sections 2: process names in animone are now called `comm' (this will probably break things). this is what its called in bsd/linux so I'm just going to use it everywhere 3: the X11 code now checks for the existence of a UTF-8 window title and passes it if available 4: ANYTHING THATS NOT LINUX IS 100% UNTESTED AND CAN AND WILL BREAK! I still actually need to test the bsd code. to be honest I'm probably going to move all of the bsds into separate files because they're all essentially different operating systems at this point
author Paper <paper@paper.us.eu.org>
date Wed, 19 Jun 2024 12:51:15 -0400
parents 246017a7907a
children adb79bdde329
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
1 /*
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
2 * win/quartz.cc: support for macOS (the Quartz Compositor)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
3 *
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
4 * This file does not require an Objective-C++ compiler,
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
5 * but it *does* require an Objective-C runtime.
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
6 */
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
7 #include "animone/win/quartz.h"
299
246017a7907a dep/animone: clean up OS X code
Paper <paper@paper.us.eu.org>
parents: 272
diff changeset
8 #include "animone/fd.h"
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
9 #include "animone.h"
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
10
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
11 #include <objc/message.h>
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
12 #include <objc/runtime.h>
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
13
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
14 #include <ApplicationServices/ApplicationServices.h>
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
15 #include <CoreFoundation/CoreFoundation.h>
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
16 #include <CoreGraphics/CoreGraphics.h>
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
17
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
18 namespace animone::internal::quartz {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
19
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
20 template<typename T>
271
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
21 struct CFDeconstructor {
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
22 using pointer = T;
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
23 void operator()(pointer t) const { ::CFRelease(t); };
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
24 };
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
25
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
26 template<typename T>
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
27 using CFPtr = std::unique_ptr<T, CFDeconstructor<T>>;
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
28
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
29 #if __LP64__
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
30 typedef long NSInteger;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
31 #else
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
32 typedef int NSInteger;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
33 #endif
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
34 typedef int CGSConnection;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
35
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
36 typedef CGSConnection (*CGSDefaultConnectionForThreadSpec)(void);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
37 typedef CGError (*CGSCopyWindowPropertySpec)(const CGSConnection, NSInteger, CFStringRef, CFStringRef*);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
38
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
39 static CGSDefaultConnectionForThreadSpec CGSDefaultConnectionForThread = nullptr;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
40 static CGSCopyWindowPropertySpec CGSCopyWindowProperty = nullptr;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
41
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
42 static const CFStringRef kCoreGraphicsBundleID = CFSTR("com.apple.CoreGraphics");
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
43
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
44 /* Objective-C */
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
45 typedef id (*object_message_send)(id, SEL, ...);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
46 typedef id (*class_message_send)(Class, SEL, ...);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
47
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
48 static const object_message_send obj_send = reinterpret_cast<object_message_send>(objc_msgSend);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
49 static const class_message_send cls_send = reinterpret_cast<class_message_send>(objc_msgSend);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
50
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
51 static bool GetCoreGraphicsPrivateSymbols() {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
52 CFBundleRef core_graphics_bundle = CFBundleGetBundleWithIdentifier(kCoreGraphicsBundleID);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
53 if (!core_graphics_bundle)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
54 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
55
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
56 CGSDefaultConnectionForThread = (CGSDefaultConnectionForThreadSpec)CFBundleGetFunctionPointerForName(
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
57 core_graphics_bundle, CFSTR("CGSDefaultConnectionForThread"));
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
58 if (!CGSDefaultConnectionForThread)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
59 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
60
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
61 CGSCopyWindowProperty = (CGSCopyWindowPropertySpec)CFBundleGetFunctionPointerForName(
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
62 core_graphics_bundle, CFSTR("CGSCopyWindowProperty"));
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
63 if (!CGSCopyWindowProperty)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
64 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
65
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
66 return true;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
67 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
68
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
69 template<typename T>
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
70 static bool GetCFNumber(CFNumberRef num, T& result) {
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
71 if (!num)
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
72 return false;
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
73
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
74 int64_t res;
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
75 if (!CFNumberGetValue(num, static_cast<CFNumberType>(4), &res))
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
76 return false;
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
77
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
78 result = static_cast<T>(res);
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
79 return true;
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
80 }
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
81
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
82 static bool StringFromCFString(CFStringRef string, std::string& result) {
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
83 if (!string)
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
84 return false;
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
85
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
86 result.resize(CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), kCFStringEncodingUTF8) + 1);
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
87 if (!CFStringGetCString(string, &result.front(), result.length(), kCFStringEncodingUTF8))
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
88 return false;
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
89
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
90 return true;
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
91 }
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
92
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
93 template<typename T>
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
94 static bool CFDictionaryGetValue(CFDictionaryRef thedict, CFStringRef key, T& out) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
95 CFTypeRef data = nullptr;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
96 if (!CFDictionaryGetValueIfPresent(thedict, key, reinterpret_cast<const void**>(&data)) || !data)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
97 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
98
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
99 if constexpr (std::is_arithmetic<T>::value)
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
100 GetCFNumber(reinterpret_cast<CFNumberRef>(data), out);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
101 else if constexpr (std::is_same<T, std::string>::value)
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
102 StringFromCFString(reinterpret_cast<CFStringRef>(data), out);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
103 else
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
104 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
105
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
106 return true;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
107 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
108
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
109 static bool GetWindowTitleAccessibility(unsigned int wid, pid_t pid, std::string& result) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
110 CGRect bounds = {0};
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
111 {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
112 const CGWindowID wids[1] = {wid};
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
113 CFPtr<CFArrayRef> arr(CFArrayCreate(kCFAllocatorDefault, (CFTypeRef*)wids, 1, NULL));
271
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
114 CFPtr<CFArrayRef> dicts(CGWindowListCreateDescriptionFromArray(arr.get()));
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
115
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
116 if (!dicts.get() || CFArrayGetCount(dicts.get()) < 1)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
117 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
118
271
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
119 CFDictionaryRef dict = reinterpret_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(dicts.get(), 0));
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
120 if (!dict)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
121 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
122
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
123 CFDictionaryRef bounds_dict = nullptr;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
124 if (!CFDictionaryGetValueIfPresent(dict, kCGWindowBounds, reinterpret_cast<CFTypeRef*>(&bounds_dict)) ||
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
125 !bounds_dict)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
126 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
127
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
128 if (!CGRectMakeWithDictionaryRepresentation(bounds_dict, &bounds))
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
129 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
130 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
131
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
132 /* now we can actually do stuff */
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
133 AXUIElementRef axapp = AXUIElementCreateApplication(pid);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
134 CFPtr<CFArrayRef> windows;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
135 {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
136 CFArrayRef ref;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
137 if ((AXUIElementCopyAttributeValue(axapp, kAXWindowsAttribute, reinterpret_cast<CFTypeRef*>(&ref)) !=
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
138 kAXErrorSuccess) ||
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
139 !windows)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
140 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
141
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
142 windows.reset(ref);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
143 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
144
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
145 const CFIndex count = CFArrayGetCount(windows.get());
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
146 for (CFIndex i = 0; i < count; i++) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
147 const AXUIElementRef window = reinterpret_cast<AXUIElementRef>(CFArrayGetValueAtIndex(windows.get(), i));
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
148
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
149 /* does this leak memory? probably. */
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
150 AXValueRef val;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
151 if (AXUIElementCopyAttributeValue(window, kAXPositionAttribute, reinterpret_cast<CFTypeRef*>(&val)) ==
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
152 kAXErrorSuccess) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
153 CGPoint point;
272
5437009cb10e dep/animone: get macOS side building
Paper <paper@paper.us.eu.org>
parents: 271
diff changeset
154 if (!AXValueGetValue(val, static_cast<AXValueType>(kAXValueCGPointType), reinterpret_cast<void*>(&point)) ||
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
155 (point.x != bounds.origin.x || point.y != bounds.origin.y)) {
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
156 CFRelease(val);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
157 continue;
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
158 }
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
159 } else {
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
160 CFRelease(val);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
161 continue;
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
162 }
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
163
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
164 CFRelease(val);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
165
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
166 if (AXUIElementCopyAttributeValue(window, kAXSizeAttribute, reinterpret_cast<CFTypeRef*>(&val)) ==
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
167 kAXErrorSuccess) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
168 CGSize size;
272
5437009cb10e dep/animone: get macOS side building
Paper <paper@paper.us.eu.org>
parents: 271
diff changeset
169 if (!AXValueGetValue(val, static_cast<AXValueType>(kAXValueCGSizeType), reinterpret_cast<void*>(&size)) ||
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
170 (size.width != bounds.size.width || size.height != bounds.size.height)) {
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
171 CFRelease(val);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
172 continue;
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
173 }
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
174 } else {
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
175 CFRelease(val);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
176 continue;
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
177 }
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
178
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
179 CFRelease(val);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
180
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
181 CFStringRef title;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
182 if (AXUIElementCopyAttributeValue(window, kAXTitleAttribute, reinterpret_cast<CFTypeRef*>(&title)) ==
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
183 kAXErrorSuccess) {
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
184 bool success = StringFromCFString(title, result);
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
185 CFRelease(title);
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
186 return success;
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
187 }
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
188 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
189
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
190 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
191 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
192
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
193 static bool GetWindowTitle(unsigned int wid, pid_t pid, std::string& result) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
194 /* try using CoreGraphics (only usable on old versions of OS X) */
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
195 if ((CGSDefaultConnectionForThread && CGSCopyWindowProperty) || GetCoreGraphicsPrivateSymbols()) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
196 CFPtr<CFStringRef> title;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
197 {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
198 CFStringRef t = nullptr;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
199 CGSCopyWindowProperty(CGSDefaultConnectionForThread(), wid, CFSTR("kCGSWindowTitle"), &t);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
200 title.reset(t);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
201 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
202
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
203 if (title && CFStringGetLength(title.get()) && StringFromCFString(title.get(), result))
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
204 return true;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
205 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
206
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
207 /* then try linking to a window using the accessibility API */
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
208 return AXIsProcessTrusted() ? GetWindowTitleAccessibility(wid, pid, result) : false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
209 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
210
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
211 static bool GetProcessBundleIdentifierNew(pid_t pid, std::string& result) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
212 /* 10.6 and higher */
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
213 const id app =
271
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
214 cls_send((Class)objc_getClass("NSRunningApplication"), sel_getUid("runningApplicationWithProcessIdentifier:"), pid);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
215 if (!app)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
216 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
217
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
218 CFStringRef bundle_id = reinterpret_cast<CFStringRef>(obj_send(app, sel_getUid("bundleIdentifier")));
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
219 if (!bundle_id)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
220 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
221
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
222 return StringFromCFString(bundle_id, result);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
223 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
224
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
225 static bool GetProcessBundleIdentifierOld(pid_t pid, std::string& result) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
226 /* OS X 10.2; deprecated in 10.9 */
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
227 ProcessSerialNumber psn;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
228 if (GetProcessForPID(pid, &psn))
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
229 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
230
271
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
231 CFPtr<CFDictionaryRef> info(ProcessInformationCopyDictionary(&psn, kProcessDictionaryIncludeAllInformationMask));
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
232 if (!info)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
233 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
234
271
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
235 CFStringRef value = reinterpret_cast<CFStringRef>(CFDictionaryGetValue(info.get(), CFSTR("CFBundleIdentifier")));
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
236 if (!value)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
237 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
238
268
382b50754fe4 dep/animone: make osx code a bit less hacky
Paper <paper@paper.us.eu.org>
parents: 258
diff changeset
239 return StringFromCFString(value, result);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
240 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
241
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
242 static bool GetProcessBundleIdentifier(pid_t pid, std::string& result) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
243 /* The Bundle ID is essentially OS X's solution to Windows'
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
244 * "class name"; theoretically, it should be different for
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
245 * each program, although it requires an app bundle.
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
246 */
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
247 if (GetProcessBundleIdentifierNew(pid, result))
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
248 return true;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
249
271
f01b6e9c8fa2 dep/animone: make OS X code build
Paper <paper@paper.us.eu.org>
parents: 268
diff changeset
250 return GetProcessBundleIdentifierOld(pid, result);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
251 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
252
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
253 bool EnumerateWindows(window_proc_t window_proc) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
254 if (!window_proc)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
255 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
256
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
257 const CFArrayRef windows = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
258 if (!windows)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
259 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
260
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
261 const CFIndex count = CFArrayGetCount(windows);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
262 for (CFIndex i = 0; i < count; i++) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
263 CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(windows, i));
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
264 if (!window)
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
265 continue;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
266
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
267 Process proc;
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
268 proc.platform = ExecutablePlatform::Xnu;
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
269 CFDictionaryGetValue(window, CFSTR("kCGWindowOwnerPID"), proc.pid);
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
270 if (!CFDictionaryGetValue(window, CFSTR("kCGWindowOwnerName"), proc.comm))
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
271 fd::GetProcessName(proc.pid, proc.comm);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
272
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
273 Window win;
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
274 win.platform = WindowPlatform::Quartz;
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
275 CFDictionaryGetValue(window, CFSTR("kCGWindowNumber"), win.id);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
276
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
277 GetProcessBundleIdentifier(proc.pid, win.class_name);
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
278 GetWindowTitle(win.id, proc.pid, win.text);
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
279
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
280 if (!window_proc(proc, win)) {
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
281 CFRelease(windows);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
282 return false;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
283 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
284 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
285
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
286 CFRelease(windows);
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
287
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
288 return true;
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
289 }
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
290
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents:
diff changeset
291 } // namespace animone::internal::quartz