annotate dep/animia/src/win/quartz.cc @ 192:50108040d792

dep/animia/quartz: GetWindowBundleIdentifier -> GetProcessBundleIdentifier
author Paper <mrpapersonic@gmail.com>
date Thu, 07 Dec 2023 01:50:29 -0500
parents 0fc126d52de4
children c4ca035c565d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
191
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
1 /*
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
2 * win/quartz.cc: support for macOS (the Quartz Compositor)
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
3 *
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
4 * This file does not require an Objective-C++ compiler,
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
5 * but it *does* require an Objective-C runtime and linking
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
6 * with AppKit in order to receive proper window titles.
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
7 */
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
8 #include "animia/win/quartz.h"
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
9 #include "animia/util/osx.h"
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
10 #include "animia.h"
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
11
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
12 #include <objc/runtime.h>
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
13 #include <objc/message.h>
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
14
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
15 #include <CoreFoundation/CoreFoundation.h>
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
16 #include <CoreGraphics/CoreGraphics.h>
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
17
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
18 namespace animia::internal::quartz {
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
19
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
20 typedef id (*object_message_send)(id, SEL, ...);
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
21 typedef id (*class_message_send)(Class, SEL, ...);
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
22
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
23 static const object_message_send obj_send = reinterpret_cast<object_message_send>(objc_msgSend);
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
24 static const class_message_send cls_send = reinterpret_cast<class_message_send>(objc_msgSend);
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
25
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
26 static bool GetWindowTitle(unsigned int wid, std::string& result) {
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
27 // NSApplication* app = [NSApplication sharedApplication];
191
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
28 const id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication"));
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
29
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
30 // NSWindow* window = [app windowWithWindowNumber: wid];
191
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
31 const id window = obj_send(app, sel_getUid("windowWithWindowNumber:"), wid);
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
32 if (!window)
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
33 return false;
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
34
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
35 // NSString* title = [window title];
191
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
36 const CFStringRef title = reinterpret_cast<CFStringRef>(obj_send(window, sel_getUid("title")));
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
37 if (!title)
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
38 return false;
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
39
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
40 // return [title UTF8String];
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
41 return osx::util::StringFromCFString(title, result);
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
42 }
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
43
192
50108040d792 dep/animia/quartz: GetWindowBundleIdentifier -> GetProcessBundleIdentifier
Paper <mrpapersonic@gmail.com>
parents: 191
diff changeset
44 static bool GetProcessBundleIdentifier(pid_t pid, std::string& result) {
191
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
45 /* The Bundle ID is essentially OS X's solution to Windows'
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
46 * "class name"; theoretically, it should be different for
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
47 * each program, although it requires an app bundle.
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
48 */
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
49
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
50 // NSRunningApplication* app = [NSRunningApplication runningApplicationWithProcessIdentifier: pid];
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
51 const id app = cls_send(objc_getClass("NSRunningApplication"), sel_getUid("runningApplicationWithProcessIdentifier:"), pid);
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
52 if (!app)
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
53 return false;
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
54
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
55 // NSString* bundle_id = [app bundleIdentifier];
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
56 const CFStringRef bundle_id = reinterpret_cast<CFStringRef>(obj_send(app, sel_getUid("bundleIdentifier")));
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
57 if (!bundle_id)
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
58 return false;
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
59
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
60 // return [bundle_id UTF8String];
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
61 return osx::util::StringFromCFString(bundle_id, result);
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
62 }
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
63
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
64 bool QuartzWinTools::EnumerateWindows(window_proc_t window_proc) {
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
65 if (!window_proc)
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
66 return false;
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
67
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
68 const CFArrayRef windows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
69 if (!windows)
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
70 return false;
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
71
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
72 const CFIndex count = CFArrayGetCount(windows);
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
73 for (CFIndex i = 0; i < count; i++) {
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
74 CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(windows, i));
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
75 if (!window)
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
76 continue;
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
77
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
78 Process proc;
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
79 {
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
80 {
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
81 CFNumberRef num = nullptr;
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
82 if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowOwnerPID"), reinterpret_cast<const void**>(&num)) && num)
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
83 osx::util::GetCFNumber(num, proc.pid);
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
84 }
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
85 {
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
86 CFStringRef str = nullptr;
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
87 if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowOwnerName"), reinterpret_cast<const void**>(&str)) && str)
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
88 osx::util::StringFromCFString(str, proc.name);
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
89 }
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
90 if (proc.name.empty())
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
91 osx::util::GetProcessName(proc.pid, proc.name);
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
92 }
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
93
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
94 Window win;
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
95 {
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
96 {
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
97 CFNumberRef num = nullptr;
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
98 if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowNumber"), reinterpret_cast<const void**>(&num)) && num)
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
99 osx::util::GetCFNumber(num, win.id);
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
100 }
192
50108040d792 dep/animia/quartz: GetWindowBundleIdentifier -> GetProcessBundleIdentifier
Paper <mrpapersonic@gmail.com>
parents: 191
diff changeset
101 if (!GetProcessBundleIdentifier(proc.pid, win.class_name)) {
191
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
102 // Fallback to the Quartz window name, which is unlikely to be filled, but it
0fc126d52de4 animia: multiple stylistic choices
Paper <mrpapersonic@gmail.com>
parents: 190
diff changeset
103 // *could* be.
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
104 CFStringRef str = nullptr;
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
105 if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowName"), reinterpret_cast<const void**>(&str)) && str)
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
106 osx::util::StringFromCFString(str, win.class_name);
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
107 }
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
108 GetWindowTitle(win.id, win.text);
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
109 }
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
110
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
111 if (!window_proc(proc, win)) {
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
112 CFRelease(windows);
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
113 return false;
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
114 }
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
115 }
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
116
190
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
117 CFRelease(windows);
2d5823df870f dep/animia: finalize de-objc-ifying quartz
Paper <mrpapersonic@gmail.com>
parents: 189
diff changeset
118
189
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
119 return true;
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
120 }
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
121
649786bae914 *: etc. code cleanup
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
122 } // namespace animia::win::detail