diff options
| author | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
|---|---|---|
| committer | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
| commit | 76424950e373d3b04ac3dd13019151bfba3e8423 (patch) | |
| tree | 4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/detection/wm/wm_apple.m | |
Add the files
Diffstat (limited to 'src/detection/wm/wm_apple.m')
| -rw-r--r-- | src/detection/wm/wm_apple.m | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/detection/wm/wm_apple.m b/src/detection/wm/wm_apple.m new file mode 100644 index 0000000..89273e9 --- /dev/null +++ b/src/detection/wm/wm_apple.m @@ -0,0 +1,94 @@ +#include "wm.h" + +#include "common/sysctl.h" +#include "common/mallocHelper.h" +#include "common/strutil.h" +#include "common/apple/version.h" + +#include <ctype.h> +#include <libproc.h> +#import <Foundation/Foundation.h> + +const char* ffDetectWMPlugin(FFstrbuf* pluginName) { + int request[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL }; + u_int requestLength = ARRAY_SIZE(request); + + size_t length = 0; + FF_AUTO_FREE struct kinfo_proc* processes = ffSysctlGetData(request, requestLength, &length); + if (processes == NULL) { + return "sysctl(CTL_KERN, KERN_PROC, KERN_PROC_ALL) failed"; + } + assert(length % sizeof(struct kinfo_proc) == 0); + + for (size_t i = 0; i < length / sizeof(struct kinfo_proc); i++) { + const struct kinfo_proc* proc = &processes[i]; + if (proc->kp_eproc.e_ppid != 1) { + continue; + } + + const char* comm = proc->kp_proc.p_comm; + + if ( + !ffStrEqualsIgnCase(comm, "rectangle") && // 28.6k + !ffStrEqualsIgnCase(comm, "yabai") && // 28.4k + !ffStrEqualsIgnCase(comm, "aerospace") && // 19.6k + !ffStrEqualsIgnCase(comm, "amethyst") && // 16k + !ffStrEqualsIgnCase(comm, "glazewm") && // 11.6k + +#if 0 + // Unmaintained + !ffStrEqualsIgnCase(comm, "spectacle") && // 13.6k + !ffStrEqualsIgnCase(comm, "chunkwm") && // repo deleted; was https://github.com/koekeishiya/chunkwm + !ffStrEqualsIgnCase(comm, "kwm") && // repo deleted; was https://github.com/koekeishiya/kwm +#endif + true) + continue; + + if (instance.config.general.detectVersion) { + char buf[PROC_PIDPATHINFO_MAXSIZE]; + int length = proc_pidpath(proc->kp_proc.p_pid, buf, ARRAY_SIZE(buf) - strlen("Info.plist")); + if (length > 0) { + buf[length] = '\0'; + FF_STRBUF_AUTO_DESTROY pluginVersion = ffStrbufCreate(); + if (ffGetAppNameAndVersion(buf, pluginName, &pluginVersion)) { + if (pluginName->length == 0) { + ffStrbufSetS(pluginName, comm); + } + if (pluginVersion.length > 0) { + ffStrbufAppendC(pluginName, ' '); + ffStrbufAppend(pluginName, &pluginVersion); + } + break; + } + } + } + + ffStrbufAppendS(pluginName, comm); + pluginName->chars[0] = (char) toupper(pluginName->chars[0]); + break; + } + + return NULL; +} + +const char* ffDetectWMVersion(const FFstrbuf* wmName, FFstrbuf* result, FF_A_UNUSED FFWMOptions* options) { + if (!wmName) { + return "No WM detected"; + } + + if (ffStrbufEqualS(wmName, "WindowServer")) { + NSError* error; + NSDictionary* dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL fileURLWithPath:@"/System/Library/PrivateFrameworks/SkyLight.framework/Resources/version.plist" isDirectory:NO] + error:&error]; + if (!dict) { + dict = [NSDictionary dictionaryWithContentsOfURL:[NSURL fileURLWithPath:@"/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/version.plist" isDirectory:NO] + error:&error]; + } + + if (dict) { + ffStrbufSetS(result, ((NSString*) dict[@"CFBundleShortVersionString"]).UTF8String); + } + } + + return NULL; +} |