Mercurial > minori
comparison dep/animone/src/win/quartz.cc @ 271:f01b6e9c8fa2
dep/animone: make OS X code build
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Sun, 14 Apr 2024 22:28:50 -0400 |
parents | 382b50754fe4 |
children | 5437009cb10e |
comparison
equal
deleted
inserted
replaced
270:0718f538c5f9 | 271:f01b6e9c8fa2 |
---|---|
16 #include <CoreGraphics/CoreGraphics.h> | 16 #include <CoreGraphics/CoreGraphics.h> |
17 | 17 |
18 namespace animone::internal::quartz { | 18 namespace animone::internal::quartz { |
19 | 19 |
20 template<typename T> | 20 template<typename T> |
21 using CFPtr = std::unique_ptr<T, CFDecontructor<T>>; | 21 struct CFDeconstructor { |
22 using pointer = T; | |
23 void operator()(pointer t) const { ::CFRelease(t); }; | |
24 }; | |
25 | |
26 template<typename T> | |
27 using CFPtr = std::unique_ptr<T, CFDeconstructor<T>>; | |
22 | 28 |
23 #if __LP64__ | 29 #if __LP64__ |
24 typedef long NSInteger; | 30 typedef long NSInteger; |
25 #else | 31 #else |
26 typedef int NSInteger; | 32 typedef int NSInteger; |
98 return false; | 104 return false; |
99 | 105 |
100 return true; | 106 return true; |
101 } | 107 } |
102 | 108 |
103 template<typename T> | |
104 struct CFDeconstructor { | |
105 using pointer = T; | |
106 void operator()(pointer t) const { ::CFRelease(t); }; | |
107 }; | |
108 | |
109 static bool GetWindowTitleAccessibility(unsigned int wid, pid_t pid, std::string& result) { | 109 static bool GetWindowTitleAccessibility(unsigned int wid, pid_t pid, std::string& result) { |
110 CGRect bounds = {0}; | 110 CGRect bounds = {0}; |
111 { | 111 { |
112 const CGWindowID wids[1] = {wid}; | 112 const CGWindowID wids[1] = {wid}; |
113 CFPtr<CFArrayRef> arr(CFArrayCreate(kCFAllocatorDefault, (CFTypeRef*)wids, 1, NULL)); | 113 CFPtr<CFArrayRef> arr(CFArrayCreate(kCFAllocatorDefault, (CFTypeRef*)wids, 1, NULL)); |
114 CFPtr<CFArrayRef> dicts(CGWindowListCreateDescriptionFromArray(arr)); | 114 CFPtr<CFArrayRef> dicts(CGWindowListCreateDescriptionFromArray(arr.get())); |
115 | 115 |
116 if (!dicts.get() || CFArrayGetCount(dicts.get()) < 1) | 116 if (!dicts.get() || CFArrayGetCount(dicts.get()) < 1) |
117 return false; | 117 return false; |
118 | 118 |
119 CFDictionaryRef dict = reinterpret_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(dicts, 0)); | 119 CFDictionaryRef dict = reinterpret_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(dicts.get(), 0)); |
120 if (!dict) | 120 if (!dict) |
121 return false; | 121 return false; |
122 | 122 |
123 CFDictionaryRef bounds_dict = nullptr; | 123 CFDictionaryRef bounds_dict = nullptr; |
124 if (!CFDictionaryGetValueIfPresent(dict, kCGWindowBounds, reinterpret_cast<CFTypeRef*>(&bounds_dict)) || | 124 if (!CFDictionaryGetValueIfPresent(dict, kCGWindowBounds, reinterpret_cast<CFTypeRef*>(&bounds_dict)) || |
149 /* does this leak memory? probably. */ | 149 /* does this leak memory? probably. */ |
150 AXValueRef val; | 150 AXValueRef val; |
151 if (AXUIElementCopyAttributeValue(window, kAXPositionAttribute, reinterpret_cast<CFTypeRef*>(&val)) == | 151 if (AXUIElementCopyAttributeValue(window, kAXPositionAttribute, reinterpret_cast<CFTypeRef*>(&val)) == |
152 kAXErrorSuccess) { | 152 kAXErrorSuccess) { |
153 CGPoint point; | 153 CGPoint point; |
154 if (!AXValueGetValue(val, kAXValueTypeCGPoint, reinterpret_cast<CFTypeRef>(&point)) || | 154 if (!AXValueGetValue(val, kAXValueCGPointType, reinterpret_cast<void*>(&point)) || |
155 (point.x != bounds.origin.x || point.y != bounds.origin.y)) { | 155 (point.x != bounds.origin.x || point.y != bounds.origin.y)) { |
156 CFRelease(val); | 156 CFRelease(val); |
157 continue; | 157 continue; |
158 } | 158 } |
159 } else { | 159 } else { |
164 CFRelease(val); | 164 CFRelease(val); |
165 | 165 |
166 if (AXUIElementCopyAttributeValue(window, kAXSizeAttribute, reinterpret_cast<CFTypeRef*>(&val)) == | 166 if (AXUIElementCopyAttributeValue(window, kAXSizeAttribute, reinterpret_cast<CFTypeRef*>(&val)) == |
167 kAXErrorSuccess) { | 167 kAXErrorSuccess) { |
168 CGSize size; | 168 CGSize size; |
169 if (!AXValueGetValue(val, kAXValueTypeCGSize, reinterpret_cast<CFTypeRef>(&size)) || | 169 if (!AXValueGetValue(val, kAXValueCGSizeType, reinterpret_cast<void*>(&size)) || |
170 (size.width != bounds.size.width || size.height != bounds.size.height)) { | 170 (size.width != bounds.size.width || size.height != bounds.size.height)) { |
171 CFRelease(val); | 171 CFRelease(val); |
172 continue; | 172 continue; |
173 } | 173 } |
174 } else { | 174 } else { |
209 } | 209 } |
210 | 210 |
211 static bool GetProcessBundleIdentifierNew(pid_t pid, std::string& result) { | 211 static bool GetProcessBundleIdentifierNew(pid_t pid, std::string& result) { |
212 /* 10.6 and higher */ | 212 /* 10.6 and higher */ |
213 const id app = | 213 const id app = |
214 cls_send(objc_getClass("NSRunningApplication"), sel_getUid("runningApplicationWithProcessIdentifier:"), pid); | 214 cls_send((Class)objc_getClass("NSRunningApplication"), sel_getUid("runningApplicationWithProcessIdentifier:"), pid); |
215 if (!app) | 215 if (!app) |
216 return false; | 216 return false; |
217 | 217 |
218 CFStringRef bundle_id = reinterpret_cast<CFStringRef>(obj_send(app, sel_getUid("bundleIdentifier"))); | 218 CFStringRef bundle_id = reinterpret_cast<CFStringRef>(obj_send(app, sel_getUid("bundleIdentifier"))); |
219 if (!bundle_id) | 219 if (!bundle_id) |
226 /* OS X 10.2; deprecated in 10.9 */ | 226 /* OS X 10.2; deprecated in 10.9 */ |
227 ProcessSerialNumber psn; | 227 ProcessSerialNumber psn; |
228 if (GetProcessForPID(pid, &psn)) | 228 if (GetProcessForPID(pid, &psn)) |
229 return false; | 229 return false; |
230 | 230 |
231 CFPtr<CFDictionaryRef> info = ProcessInformationCopyDictionary(psn, kProcessDictionaryIncludeAllInformationMask); | 231 CFPtr<CFDictionaryRef> info(ProcessInformationCopyDictionary(&psn, kProcessDictionaryIncludeAllInformationMask)); |
232 if (!info) | 232 if (!info) |
233 return false; | 233 return false; |
234 | 234 |
235 CFStringRef value = reinterpret_cast<CFStringRef>(CFDictionaryGetValue(dict, CFSTR("CFBundleIdentifier"))); | 235 CFStringRef value = reinterpret_cast<CFStringRef>(CFDictionaryGetValue(info.get(), CFSTR("CFBundleIdentifier"))); |
236 if (!value) | 236 if (!value) |
237 return false; | 237 return false; |
238 | 238 |
239 return StringFromCFString(value, result); | 239 return StringFromCFString(value, result); |
240 } | 240 } |
245 * each program, although it requires an app bundle. | 245 * each program, although it requires an app bundle. |
246 */ | 246 */ |
247 if (GetProcessBundleIdentifierNew(pid, result)) | 247 if (GetProcessBundleIdentifierNew(pid, result)) |
248 return true; | 248 return true; |
249 | 249 |
250 return GetProcessBundleIdentifierOld(); | 250 return GetProcessBundleIdentifierOld(pid, result); |
251 } | 251 } |
252 | 252 |
253 bool EnumerateWindows(window_proc_t window_proc) { | 253 bool EnumerateWindows(window_proc_t window_proc) { |
254 if (!window_proc) | 254 if (!window_proc) |
255 return false; | 255 return false; |