Mercurial > minori
changeset 269:3efac0541151
chore: merge
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Fri, 12 Apr 2024 05:23:45 -0400 |
parents | 382b50754fe4 (diff) 09c5bd74fe93 (current diff) |
children | 0718f538c5f9 |
files | |
diffstat | 3 files changed, 77 insertions(+), 199 deletions(-) [+] |
line wrap: on
line diff
--- a/dep/animone/include/animone/util/osx.h Thu Apr 11 23:39:18 2024 -0400 +++ b/dep/animone/include/animone/util/osx.h Fri Apr 12 05:23:45 2024 -0400 @@ -4,35 +4,12 @@ #include "animone/types.h" #include <cstdint> #include <string> +#include <memory> #include <CoreFoundation/CoreFoundation.h> namespace animone::internal::osx::util { -template<typename T> -bool GetCFNumber(CFNumberRef num, T& result) { - if (!num) - return false; - - int64_t res; - if (!CFNumberGetValue(num, static_cast<CFNumberType>(4), &res)) - return false; - - result = static_cast<T>(res); - return true; -} - -template<typename T> -struct CFDeconstructor { - using pointer = T; - void operator()(pointer t) const { ::CFRelease(t); }; -}; - -template<typename T> -using CFPtr = vector<T, CFDecontructor<T>>; // type-id is vector<T, Alloc<T>> - -bool StringFromCFString(CFStringRef string, std::string& result); - bool GetProcessName(pid_t pid, std::string& result); } // namespace animone::internal::osx::util
--- a/dep/animone/src/util/osx.cc Thu Apr 11 23:39:18 2024 -0400 +++ b/dep/animone/src/util/osx.cc Fri Apr 12 05:23:45 2024 -0400 @@ -8,167 +8,30 @@ namespace animone::internal::osx::util { -typedef CFTypeRef (*LSASNCreateWithPidSpec)(CFAllocatorRef, pid_t); -typedef CFDictionaryRef (*LSCopyApplicationInformationSpec)(int, CFTypeRef, CFArrayRef); - -/* retrieved dynamically from launchservices */ -static LSCopyApplicationInformationSpec LSCopyApplicationInformation = nullptr; -static LSASNCreateWithPidSpec LSASNCreateWithPid = nullptr; - -static CFStringRef kLSDisplayNameKey = nullptr; -static CFStringRef kLSPIDKey = nullptr; - -/* retrieved from LaunchServicesSPI.h in WebKit */ -static constexpr int kLSDefaultSessionID = -2; +static bool GetProcessNameFromProcPidPath(pid_t pid, std::string& result) { + result.assign(PROC_PIDPATHINFO_MAXSIZE, '\0'); -static const CFStringRef kLaunchServicesBundleID = CFSTR("com.apple.LaunchServices"); - -static bool GetLaunchServicesPrivateSymbols() { - CFBundleRef launch_services_bundle = CFBundleGetBundleWithIdentifier(kLaunchServicesBundleID); - if (!launch_services_bundle) - return false; - - LSCopyApplicationInformation = reinterpret_cast<LSCopyApplicationInformationSpec>( - CFBundleGetFunctionPointerForName(launch_services_bundle, CFSTR("_LSCopyApplicationInformation"))); - if (!LSCopyApplicationInformation) - return false; - - LSASNCreateWithPid = reinterpret_cast<LSASNCreateWithPidSpec>( - CFBundleGetFunctionPointerForName(launch_services_bundle, CFSTR("_LSASNCreateWithPid"))); - if (!LSASNCreateWithPid) + int ret = proc_pidpath(pid, result.data(), result.size() * sizeof(char)); + if (ret <= 0) return false; - CFStringRef* ptr_kLSDisplayNameKey = reinterpret_cast<CFStringRef*>( - CFBundleGetDataPointerForName(launch_services_bundle, CFSTR("_kLSDisplayNameKey"))); - if (!ptr_kLSDisplayNameKey) - return false; - kLSDisplayNameKey = *ptr_kLSDisplayNameKey; - - CFStringRef* ptr_kLSPIDKey = - reinterpret_cast<CFStringRef*>(CFBundleGetDataPointerForName(launch_services_bundle, CFSTR("_kLSPIDKey"))); - if (!ptr_kLSPIDKey) - return false; - kLSPIDKey = *ptr_kLSPIDKey; - - return true; -} - -static bool LaunchServicesGetProcessName(pid_t pid, std::string& result) { - if (!LSCopyApplicationInformation || !LSASNCreateWithPid || !kLSDisplayNameKey || !kLSPIDKey) - if (!GetLaunchServicesPrivateSymbols()) - return false; + /* find the last slash, if there's none, we're done here */ + size_t last_slash = result.rfind('/'); + if (last_slash == std::string::npos) + return true; - /* what the hell is an `asn`? */ - CFPtr<CFTypeRef> asn = LSASNCreateWithPid(kCFAllocatorDefault, pid); - if (!asn) - return false; - - CFPtr<CFArrayRef> request_array = CFArrayCreate(NULL, (const void**)kLSDisplayNameKey, 1, NULL); - if (!request_array) - return false; - - CFPtr<CFDictionaryRef> dictionary = - LSCopyApplicationInformation(kLSDefaultSessionID, asn.get(), request_array.get()); - if (!dictionary) - return false; - - { - /* this doesn't need to be free'd */ - CFStringRef rstr; - - if (!CFDictionaryGetValueIfPresent(dictionary, kLSDisplayNameKey, (CFTypeRef*)&rstr) || !rstr) - return false; - - if (!StringFromCFString(rstr, result)) - return false; - } - - result.resize(result.find('\0')); - + result.erase(0, last_slash + 1); return true; } -bool StringFromCFString(CFStringRef string, std::string& result) { - if (!string) - return false; - - result.resize(CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), kCFStringEncodingUTF8) + 1); - if (!CFStringGetCString(string, &result.front(), result.length(), kCFStringEncodingUTF8)) - return false; - - return true; -} - -static bool GetProcessArgs(pid_t pid, std::string& args) { - /* sysctl shouldn't touch these, so we define them as const */ - int mib[3] = {CTL_KERN, KERN_PROCARGS2, static_cast<int>(pid)}; - const size_t mib_size = sizeof(mib) / sizeof(*mib); - - /* Get the initial size of the array - * - * NOTE: it IS possible for this value to change inbetween calls to sysctl(). - * Unfortunately, I couldn't care less about handling this. :) - * - * is that really true, though? these should be constant values. but are - * argc and argv *really* constant? - */ - size_t size; - { - int ret = sysctl((int*)mib, mib_size, nullptr, &size, nullptr, 0); - if (ret) - return false; - } - - /* Reserve the space for it in args */ - args.resize(size); - - /* Get the contents of argc and argv */ - { - int ret = sysctl((int*)mib, mib_size, &args.front(), &size, NULL, 0); - if (ret) - return false; - } - - /* Is the size big enough to hold at least argc? */ - if (size < sizeof(int)) - return false; - - args.resize(size); - return true; -} - -static bool GetProcessNameFromArgs(pid_t pid, std::string& result) { - if (!GetProcessArgs(pid, result)) - return false; - - /* Get argc using memcpy */ - int argc = 0; - memcpy(&argc, &result.front(), sizeof(argc)); - - /* Do we even have argv[0]? */ - if (argc < 1) - return false; - - /* Find the first null character */ - size_t null_pos = result.find('\0', sizeof(argc)); - if (null_pos == std::string::npos) - return false; - - /* Find the last slash */ - size_t last_slash = result.rfind('/', null_pos); - if (last_slash == std::string::npos) - return false; - - /* Return our result */ - result = result.substr(last_slash + 1, null_pos - last_slash - 1); - return true; -} - -static bool GetProcessNameFromKernel(pid_t pid, std::string& result) { - result.resize(2 * MAXCOMLEN); +static bool GetProcessNameFromProcName(pid_t pid, std::string& result) { + result.assign(2 * MAXCOMLEN, '\0'); int size = proc_name(pid, &result.front(), result.length()); - if (!size) + + /* if size is MAXCOMLEN or 2 * MAXCOMLEN, assume + * this method won't work and our result is truncated */ + if (size <= 0 || size == MAXCOMLEN || size == 2 * MAXCOMLEN) return false; result.resize(size); @@ -176,18 +39,10 @@ } bool GetProcessName(pid_t pid, std::string& result) { - if (LaunchServicesGetProcessName(pid, result)) + if (GetProcessNameFromProcName(pid, result)) return true; - /* Try parsing the arguments, this prevents the process name being - * cut off to 2*MAXCOMLEN (32 chars) */ - if (GetProcessNameFromArgs(pid, result)) - return true; - - /* Then attempt getting it from the kernel, which results in the - * process name being cut to 32 chars (worse, 16 chars if p_name is - * unavailable) */ - if (GetProcessNameFromKernel(pid, result)) + if (GetProcessNameFromProcPidPath(pid, result)) return true; return false;
--- a/dep/animone/src/win/quartz.cc Thu Apr 11 23:39:18 2024 -0400 +++ b/dep/animone/src/win/quartz.cc Fri Apr 12 05:23:45 2024 -0400 @@ -17,6 +17,9 @@ namespace animone::internal::quartz { +template<typename T> +using CFPtr = std::unique_ptr<T, CFDecontructor<T>>; + #if __LP64__ typedef long NSInteger; #else @@ -58,21 +61,51 @@ } template<typename T> +static bool GetCFNumber(CFNumberRef num, T& result) { + if (!num) + return false; + + int64_t res; + if (!CFNumberGetValue(num, static_cast<CFNumberType>(4), &res)) + return false; + + result = static_cast<T>(res); + return true; +} + +static bool StringFromCFString(CFStringRef string, std::string& result) { + if (!string) + return false; + + result.resize(CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), kCFStringEncodingUTF8) + 1); + if (!CFStringGetCString(string, &result.front(), result.length(), kCFStringEncodingUTF8)) + return false; + + return true; +} + +template<typename T> static bool CFDictionaryGetValue(CFDictionaryRef thedict, CFStringRef key, T& out) { CFTypeRef data = nullptr; if (!CFDictionaryGetValueIfPresent(thedict, key, reinterpret_cast<const void**>(&data)) || !data) return false; if constexpr (std::is_arithmetic<T>::value) - osx::util::GetCFNumber(reinterpret_cast<CFNumberRef>(data), out); + GetCFNumber(reinterpret_cast<CFNumberRef>(data), out); else if constexpr (std::is_same<T, std::string>::value) - osx::util::StringFromCFString(reinterpret_cast<CFStringRef>(data), out); + StringFromCFString(reinterpret_cast<CFStringRef>(data), out); else return false; return true; } +template<typename T> +struct CFDeconstructor { + using pointer = T; + void operator()(pointer t) const { ::CFRelease(t); }; +}; + static bool GetWindowTitleAccessibility(unsigned int wid, pid_t pid, std::string& result) { CGRect bounds = {0}; { @@ -119,24 +152,39 @@ kAXErrorSuccess) { CGPoint point; if (!AXValueGetValue(val, kAXValueTypeCGPoint, reinterpret_cast<CFTypeRef>(&point)) || - (point.x != bounds.origin.x || point.y != bounds.origin.y)) + (point.x != bounds.origin.x || point.y != bounds.origin.y)) { + CFRelease(val); continue; - } else + } + } else { + CFRelease(val); continue; + } + + CFRelease(val); if (AXUIElementCopyAttributeValue(window, kAXSizeAttribute, reinterpret_cast<CFTypeRef*>(&val)) == kAXErrorSuccess) { CGSize size; if (!AXValueGetValue(val, kAXValueTypeCGSize, reinterpret_cast<CFTypeRef>(&size)) || - (size.width != bounds.size.width || size.height != bounds.size.height)) + (size.width != bounds.size.width || size.height != bounds.size.height)) { + CFRelease(val); continue; - } else + } + } else { + CFRelease(val); continue; + } + + CFRelease(val); CFStringRef title; if (AXUIElementCopyAttributeValue(window, kAXTitleAttribute, reinterpret_cast<CFTypeRef*>(&title)) == - kAXErrorSuccess) - return osx::util::StringFromCFString(title, result); + kAXErrorSuccess) { + bool success = StringFromCFString(title, result); + CFRelease(title); + return success; + } } return false; @@ -152,7 +200,7 @@ title.reset(t); } - if (title && CFStringGetLength(title.get()) && osx::util::StringFromCFString(title.get(), result)) + if (title && CFStringGetLength(title.get()) && StringFromCFString(title.get(), result)) return true; } @@ -171,8 +219,7 @@ if (!bundle_id) return false; - result = osx::util::StringFromCFString(bundle_id, result); - return true; + return StringFromCFString(bundle_id, result); } static bool GetProcessBundleIdentifierOld(pid_t pid, std::string& result) { @@ -189,8 +236,7 @@ if (!value) return false; - result = osx::util::StringFromCFString(value, result); - return true; + return StringFromCFString(value, result); } static bool GetProcessBundleIdentifier(pid_t pid, std::string& result) {