Mercurial > minori
view 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 |
line wrap: on
line source
#include "animia/win/quartz.h" #include "animia/util/osx.h" #include "animia.h" #include <objc/runtime.h> #include <objc/message.h> #include <CoreFoundation/CoreFoundation.h> #include <CoreGraphics/CoreGraphics.h> #include <iostream> namespace animia::internal::quartz { typedef id (*object_message_send)(id, SEL, ...); typedef id (*class_message_send)(Class, SEL, ...); static const object_message_send obj_send = reinterpret_cast<object_message_send>(objc_msgSend); static const class_message_send cls_send = reinterpret_cast<class_message_send>(objc_msgSend); static bool GetWindowTitle(unsigned int wid, std::string& result) { // NSApplication* app = [NSApplication sharedApplication]; id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication")); // NSWindow* window = [app windowWithWindowNumber: wid]; id window = obj_send(app, sel_getUid("windowWithWindowNumber:"), wid); if (!window) return false; // NSString* title = [window title]; // does this have to be freed? CFStringRef title = reinterpret_cast<CFStringRef>(obj_send(window, sel_getUid("title"))); if (!title) return false; // return [title UTF8String]; return osx::util::StringFromCFString(title, result); } bool QuartzWinTools::EnumerateWindows(window_proc_t window_proc) { if (!window_proc) return false; const CFArrayRef windows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID); if (!windows) return false; const CFIndex count = CFArrayGetCount(windows); for (CFIndex i = 0; i < count; i++) { CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(windows, i)); if (!window) continue; Process proc; { { CFNumberRef num = nullptr; if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowOwnerPID"), reinterpret_cast<const void**>(&num)) && num) osx::util::GetCFNumber(num, proc.pid); } { CFStringRef str = nullptr; if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowOwnerName"), reinterpret_cast<const void**>(&str)) && str) osx::util::StringFromCFString(str, proc.name); } if (proc.name.empty()) osx::util::GetProcessName(proc.pid, proc.name); } Window win; { { CFNumberRef num = nullptr; if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowNumber"), reinterpret_cast<const void**>(&num)) && num) osx::util::GetCFNumber(num, win.id); } { CFStringRef str = nullptr; if (CFDictionaryGetValueIfPresent(window, CFSTR("kCGWindowName"), reinterpret_cast<const void**>(&str)) && str) osx::util::StringFromCFString(str, win.class_name); } GetWindowTitle(win.id, win.text); } if (!window_proc(proc, win)) { CFRelease(windows); return false; } } CFRelease(windows); return true; } } // namespace animia::win::detail