diff --git a/src/carbon.c b/src/carbon.c index 687820c..821a07d 100644 --- a/src/carbon.c +++ b/src/carbon.c @@ -30,6 +30,58 @@ find_active_process_name(void) GetFrontProcess(&psn); return find_process_name_for_psn(&psn); } + +static inline char * +find_process_bundle_id_for_psn(ProcessSerialNumber *psn) +{ + CFDictionaryRef process_info_ref = ProcessInformationCopyDictionary(psn, kProcessDictionaryIncludeAllInformationMask); + if (!process_info_ref) { + return NULL; + } + CFStringRef process_bundle_id_ref = CFDictionaryGetValue(process_info_ref, kCFBundleIdentifierKey); + CFRelease(process_info_ref); + if (!process_bundle_id_ref) { + return NULL; + } + char *process_bundle_id = copy_cfstring(process_bundle_id_ref); + CFRelease(process_bundle_id_ref); + for (char *s = process_bundle_id; *s; ++s) *s = tolower(*s); + return process_bundle_id; +} + +static inline char * +find_active_process_bundle_id(void) +{ + ProcessSerialNumber psn; + GetFrontProcess(&psn); + return find_process_bundle_id_for_psn(&psn); +} + +static inline char * +find_process_bundle_name_for_psn(ProcessSerialNumber *psn) +{ + CFDictionaryRef process_info_ref = ProcessInformationCopyDictionary(psn, kProcessDictionaryIncludeAllInformationMask); + if (!process_info_ref) { + return NULL; + } + CFStringRef process_bundle_name_ref = CFDictionaryGetValue(process_info_ref, kCFBundleNameKey); + CFRelease(process_info_ref); + if (process_bundle_name_ref) { + return NULL; + } + char *process_bundle_name = copy_cfstring(process_bundle_name_ref); + CFRelease(process_bundle_name_ref); + for (char *s = process_bundle_name; *s; ++s) *s = tolower(*s); + return process_bundle_name; +} + +static inline char * +find_active_process_bundle_name(void) +{ + ProcessSerialNumber psn; + GetFrontProcess(&psn); + return find_process_bundle_name_for_psn(&psn); +} #pragma clang diagnostic pop static OSStatus @@ -55,6 +107,20 @@ carbon_event_handler(EventHandlerCallRef ref, EventRef event, void *context) carbon->process_name = find_process_name_for_psn(&psn); + if (carbon->process_bundle_id) { + free(carbon->process_bundle_id); + carbon->process_bundle_id = NULL; + } + + carbon->process_bundle_id = find_process_bundle_id_for_psn(&psn); + + if (carbon->process_bundle_name) { + free(carbon->process_bundle_name); + carbon->process_bundle_name = NULL; + } + + carbon->process_bundle_name = find_process_bundle_name_for_psn(&psn); + return noErr; } @@ -65,6 +131,8 @@ bool carbon_event_init(struct carbon_event *carbon) carbon->type.eventClass = kEventClassApplication; carbon->type.eventKind = kEventAppFrontSwitched; carbon->process_name = find_active_process_name(); + carbon->process_bundle_id = find_active_process_bundle_id(); + carbon->process_bundle_name = find_active_process_bundle_name(); return InstallEventHandler(carbon->target, carbon->handler, diff --git a/src/carbon.h b/src/carbon.h index 8ef9ed4..7569764 100644 --- a/src/carbon.h +++ b/src/carbon.h @@ -10,6 +10,8 @@ struct carbon_event EventTypeSpec type; EventHandlerRef handler_ref; char * volatile process_name; + char * volatile process_bundle_id; + char * volatile process_bundle_name; }; char *find_process_name_for_pid(pid_t pid); diff --git a/src/hotkey.c b/src/hotkey.c index 6ed79f5..a274e65 100644 --- a/src/hotkey.c +++ b/src/hotkey.c @@ -147,7 +147,9 @@ find_process_command_mapping(struct hotkey *hotkey, uint32_t *capture, struct ca bool found = false; for (int i = 0; i < buf_len(hotkey->process_name); ++i) { - if (same_string(carbon->process_name, hotkey->process_name[i])) { + if (same_string(carbon->process_name, hotkey->process_name[i]) + || same_string(carbon->process_bundle_id, hotkey->process_name[i]) + || same_string(carbon->process_bundle_name, hotkey->process_name[i])) { result = hotkey->command[i]; found = true; break; diff --git a/src/skhd.c b/src/skhd.c index 0cea25b..53312c7 100644 --- a/src/skhd.c +++ b/src/skhd.c @@ -170,6 +170,8 @@ static EVENT_TAP_CALLBACK(key_handler) } break; case kCGEventKeyDown: { if (table_find(&blacklst, carbon.process_name)) return event; + if (table_find(&blacklst, carbon.process_bundle_id)) return event; + if (table_find(&blacklst, carbon.process_bundle_name)) return event; if (!current_mode) return event; BEGIN_TIMED_BLOCK("handle_keypress"); @@ -181,6 +183,8 @@ static EVENT_TAP_CALLBACK(key_handler) } break; case NX_SYSDEFINED: { if (table_find(&blacklst, carbon.process_name)) return event; + if (table_find(&blacklst, carbon.process_bundle_id)) return event; + if (table_find(&blacklst, carbon.process_bundle_name)) return event; if (!current_mode) return event; struct hotkey eventkey;