annotate src/win/quartz.cc @ 21:973734ebd2be

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