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 |
