Mercurial > minori
comparison dep/animia/src/win/quartz.cc @ 190:2d5823df870f
dep/animia: finalize de-objc-ifying quartz
this also fixes up some... rather dumb mistakes in window.cc :)
HG Enter commit message. Lines beginning with 'HG:' are removed.
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Wed, 06 Dec 2023 21:26:13 -0500 |
parents | 649786bae914 |
children | 0fc126d52de4 |
comparison
equal
deleted
inserted
replaced
189:649786bae914 | 190:2d5823df870f |
---|---|
1 /* We actually DON'T need Objective-C for most of this file. | |
2 * GetWindowTitle() is the only function that really needs it. | |
3 * (and even then, we can use the C bindings for it...) | |
4 * | |
5 * However, being able to use the Foundation classes makes things | |
6 * so, so, so much easier, and so I've decided to make this file | |
7 * in Objective-C++. | |
8 */ | |
9 #include "animia/win/quartz.h" | 1 #include "animia/win/quartz.h" |
2 #include "animia/util/osx.h" | |
10 #include "animia.h" | 3 #include "animia.h" |
11 | 4 |
12 #include <objc/runtime.h> | 5 #include <objc/runtime.h> |
13 #include <objc/message.h> | 6 #include <objc/message.h> |
14 | 7 |
15 #include <CoreFoundation/CoreFoundation.h> | 8 #include <CoreFoundation/CoreFoundation.h> |
16 #include <CoreGraphics/CoreGraphics.h> | 9 #include <CoreGraphics/CoreGraphics.h> |
17 #include <Carbon/Carbon.h> | 10 |
11 #include <iostream> | |
18 | 12 |
19 namespace animia::internal::quartz { | 13 namespace animia::internal::quartz { |
20 | 14 |
15 typedef id (*object_message_send)(id, SEL, ...); | |
16 typedef id (*class_message_send)(Class, SEL, ...); | |
17 | |
18 static const object_message_send obj_send = reinterpret_cast<object_message_send>(objc_msgSend); | |
19 static const class_message_send cls_send = reinterpret_cast<class_message_send>(objc_msgSend); | |
20 | |
21 static bool GetWindowTitle(unsigned int wid, std::string& result) { | 21 static bool GetWindowTitle(unsigned int wid, std::string& result) { |
22 // id app = [NSApplication sharedApplication]; | 22 // NSApplication* app = [NSApplication sharedApplication]; |
23 id app = cls_msg(cls("NSApplication"), sel("sharedApplication")); | 23 id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication")); |
24 | 24 |
25 // id window = [app windowWithWindowNumber: wid]; | 25 // NSWindow* window = [app windowWithWindowNumber: wid]; |
26 id window = msg(app, sel("windowWithWindowNumber:"), wid); | 26 id window = obj_send(app, sel_getUid("windowWithWindowNumber:"), wid); |
27 if (!window) | |
28 return false; | |
27 | 29 |
28 // return [[window title] UTF8String]; | 30 // NSString* title = [window title]; |
29 return StringFromCFString(reinterpret_cast<CFStringRef>(msg(window, "title")), result); | 31 // does this have to be freed? |
32 CFStringRef title = reinterpret_cast<CFStringRef>(obj_send(window, sel_getUid("title"))); | |
33 if (!title) | |
34 return false; | |
35 | |
36 // return [title UTF8String]; | |
37 return osx::util::StringFromCFString(title, result); | |
30 } | 38 } |
31 | 39 |
32 bool QuartzWinTools::EnumerateWindows(window_proc_t window_proc) { | 40 bool QuartzWinTools::EnumerateWindows(window_proc_t window_proc) { |
33 if (!window_proc) | 41 if (!window_proc) |
34 return false; | 42 return false; |
35 | 43 |
36 CFArrayRef windows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID); | 44 const CFArrayRef windows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID); |
37 if (!windows) | 45 if (!windows) |
38 return false; | 46 return false; |
39 | 47 |
40 CFIndex i = 0; count = CFArrayGetCount(windows); | 48 const CFIndex count = CFArrayGetCount(windows); |
41 for (; i < count; i++) { | 49 for (CFIndex i = 0; i < count; i++) { |
42 CFDictionaryRef window = CFArrayGetValueAtIndex(windows, i); | 50 CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(windows, i)); |
43 if (!window) | 51 if (!window) |
44 continue; | 52 continue; |
45 | 53 |
46 Process proc; | 54 Process proc; |
47 { | 55 { |
48 { | 56 { |
49 CFNumber num; | 57 CFNumberRef num = nullptr; |
50 CFDictionaryGetValueIfPresent(window, "kCGWindowOwnerPID", &num); | 58 if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowOwnerPID"), reinterpret_cast<const void**>(&num)) && num) |
51 osx::util::GetCFNumber(num, proc.pid); | 59 osx::util::GetCFNumber(num, proc.pid); |
52 } | 60 } |
53 { | 61 { |
54 CFStringRef str; | 62 CFStringRef str = nullptr; |
55 CFDictionaryGetValueIfPresent(window, "kCGWindowOwnerName", &str); | 63 if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowOwnerName"), reinterpret_cast<const void**>(&str)) && str) |
56 osx::util::StringFromCFString(str, proc.name); | 64 osx::util::StringFromCFString(str, proc.name); |
57 } | 65 } |
58 if (proc.name.empty()) | 66 if (proc.name.empty()) |
59 osx::util::GetProcessName(proc.pid, proc.name); | 67 osx::util::GetProcessName(proc.pid, proc.name); |
60 } | 68 } |
61 | 69 |
62 Window win; | 70 Window win; |
63 { | 71 { |
64 { | 72 { |
65 CFNumber num; | 73 CFNumberRef num = nullptr; |
66 CFDictionaryGetValueIfPresent(window, "kCGWindowNumber", &num); | 74 if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowNumber"), reinterpret_cast<const void**>(&num)) && num) |
67 osx::util::GetCFNumber(num, win.id); | 75 osx::util::GetCFNumber(num, win.id); |
68 } | 76 } |
69 { | 77 { |
70 CFStringRef str; | 78 CFStringRef str = nullptr; |
71 CFDictionaryGetValueIfPresent(window, "kCGWindowName", &str); | 79 if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowName"), reinterpret_cast<const void**>(&str)) && str) |
72 osx::util::GetCFNumber(str, win.class_name); | 80 osx::util::StringFromCFString(str, win.class_name); |
73 } | 81 } |
74 GetWindowTitle(win.id, win.text); | 82 GetWindowTitle(win.id, win.text); |
75 } | 83 } |
76 | 84 |
77 if (!window_proc(proc, win)) | 85 if (!window_proc(proc, win)) { |
86 CFRelease(windows); | |
78 return false; | 87 return false; |
88 } | |
79 } | 89 } |
90 | |
91 CFRelease(windows); | |
80 | 92 |
81 return true; | 93 return true; |
82 } | 94 } |
83 | 95 |
84 } // namespace animia::win::detail | 96 } // namespace animia::win::detail |