Skip to content

Instantly share code, notes, and snippets.

@sailist

sailist/main.m Secret

Created February 20, 2022 11:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sailist/02c2b1fa323dd406107b944f24c2062d to your computer and use it in GitHub Desktop.
Save sailist/02c2b1fa323dd406107b944f24c2062d to your computer and use it in GitHub Desktop.
Get Active Window Dynamic By Objective-C
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#include <unistd.h> // getopt
int
GetFrontMostAppPid(void) {
NSRunningApplication *app = [[NSWorkspace sharedWorkspace]
frontmostApplication];
pid_t pid = [app processIdentifier];
return pid;
}
CFStringRef
getAppTitle(pid_t pid) {
CFStringRef title = NULL;
// Get the process ID of the frontmost application.
// NSRunningApplication* app = [[NSWorkspace sharedWorkspace]
// frontmostApplication];
// pid_t pid = [app processIdentifier];
// See if we have accessibility permissions, and if not, prompt the user to
// visit System Preferences.
NSDictionary *options = @{(__bridge id) kAXTrustedCheckOptionPrompt: @YES};
Boolean appHasPermission = AXIsProcessTrustedWithOptions(
(__bridge CFDictionaryRef) options);
if (!appHasPermission) {
return title; // we don't have accessibility permissions
}
// Get the accessibility element corresponding to the frontmost application.
AXUIElementRef appElem = AXUIElementCreateApplication(pid);
if (!appElem) {
return title;
}
// Get the accessibility element corresponding to the frontmost window
// of the frontmost application.
AXUIElementRef window = NULL;
if (AXUIElementCopyAttributeValue(appElem,
kAXFocusedWindowAttribute, (CFTypeRef *) &window) != kAXErrorSuccess) {
CFRelease(appElem);
return title;
}
// Finally, get the title of the frontmost window.
AXError result = AXUIElementCopyAttributeValue(window, kAXTitleAttribute,
(CFTypeRef *) &title);
// At this point, we don't need window and appElem anymore.
CFRelease(window);
CFRelease(appElem);
if (result != kAXErrorSuccess) {
// Failed to get the window title.
return title;
}
// Success! Now, do something with the title, e.g. copy it somewhere.
// Once we're done with the title, release it.
// CFRelease(title);
return title;
}
@interface AppFocus : NSObject
@end
@implementation AppFocus
- (id)init {
self = [super init];
if (!self)
return self;
NSNotificationCenter *center = NSWorkspace.sharedWorkspace.notificationCenter;
[center addObserver:self
selector:@selector(didActivateApp:)
name:NSWorkspaceDidActivateApplicationNotification
object:nil];
return self;
}
- (void)didActivateApp:(NSNotification *)d {
NSRunningApplication *app = d.userInfo[NSWorkspaceApplicationKey];
// getAppTitle(app.processIdentifier);
NSString *title = (__bridge NSString *) getAppTitle(app.processIdentifier);
NSLog(@"%s\n", app.localizedName.UTF8String);
NSLog(title);
// fflush(stdout);
}
@end
void print_usage(FILE *stream) {
fprintf(stream, "usage: app-focus\n");
fprintf(stream, "\n");
fprintf(stream, "print notifications to the console when different apps take focus on OS X\n");
fprintf(stream, "\n");
fprintf(stream, "options\n");
fprintf(stream, " -h print this message and exit\n");
}
int main(int argc, char **argv) {
int c;
while ((c = getopt(argc, argv, "h")) != EOF) {
switch (c) {
case 'h':
print_usage(stdout);
return 0;
case '?':
print_usage(stderr);
return 1;
}
}
@autoreleasepool {
NSRunLoop *runLoop = NSRunLoop.currentRunLoop;
AppFocus *af = [[AppFocus alloc] init];
while ([runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:2]]);
};
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment