mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-06 16:05:05 +02:00
Framework for Apple's default global shortcuts
This commit is contained in:
@@ -265,6 +265,7 @@ display_reconfigured(CGDirectDisplayID display UNUSED, CGDisplayChangeSummaryFla
|
||||
}
|
||||
|
||||
static NSDictionary<NSString*,NSNumber*> *global_shortcuts = nil;
|
||||
static NSDictionary<NSString*,NSNumber*> *disabled_global_shortcuts = nil;
|
||||
|
||||
@interface GLFWHelper : NSObject
|
||||
@end
|
||||
@@ -290,6 +291,10 @@ static NSDictionary<NSString*,NSNumber*> *global_shortcuts = nil;
|
||||
[global_shortcuts release];
|
||||
global_shortcuts = nil;
|
||||
}
|
||||
if (disabled_global_shortcuts != nil) {
|
||||
[disabled_global_shortcuts release];
|
||||
disabled_global_shortcuts = nil;
|
||||
}
|
||||
}
|
||||
|
||||
@end // GLFWHelper
|
||||
@@ -581,6 +586,7 @@ static void
|
||||
build_global_shortcuts_lookup(void) {
|
||||
// dump these in a terminal with: defaults read com.apple.symbolichotkeys
|
||||
NSMutableDictionary<NSString*, NSNumber*> *temp = [NSMutableDictionary dictionaryWithCapacity:128]; // will be autoreleased
|
||||
NSMutableDictionary<NSString*, NSNumber*> *temp_disabled = [NSMutableDictionary dictionaryWithCapacity:128]; // will be autoreleased
|
||||
NSDictionary *apple_settings = [[NSUserDefaults standardUserDefaults] persistentDomainForName:@"com.apple.symbolichotkeys"];
|
||||
if (apple_settings) {
|
||||
NSDictionary<NSString*, id> *symbolic_hotkeys = [apple_settings objectForKey:@"AppleSymbolicHotKeys"];
|
||||
@@ -591,7 +597,8 @@ build_global_shortcuts_lookup(void) {
|
||||
NSInteger sc = [key integerValue];
|
||||
NSDictionary *sc_value = obj;
|
||||
id enabled = [sc_value objectForKey:@"enabled"];
|
||||
if (!enabled || ![enabled isKindOfClass:[NSNumber class]] || ![(NSNumber*)enabled boolValue]) continue;
|
||||
if (!enabled || ![enabled isKindOfClass:[NSNumber class]] ) continue;
|
||||
|
||||
id v = [sc_value objectForKey:@"value"];
|
||||
if (!v || ![v isKindOfClass:[NSDictionary class]]) continue;
|
||||
NSDictionary *value = v;
|
||||
@@ -607,31 +614,32 @@ build_global_shortcuts_lookup(void) {
|
||||
static char buf[64];
|
||||
#define S(x, k) snprintf(buf, sizeof(buf) - 1, #x":%lx:%ld", (unsigned long)mods, (long)k)
|
||||
if (ch == 0xffff) { if (vk == 0xffff) continue; S(v, vk); } else S(c, ch);
|
||||
temp[@(buf)] = @(sc);
|
||||
NSMutableDictionary<NSString*, NSNumber*> *dest = ([(NSNumber*)enabled boolValue]) ? temp : temp_disabled;
|
||||
dest[@(buf)] = @(sc);
|
||||
// the move to next window shortcuts also respond to the same shortcut + shift
|
||||
if (is_shiftable_shortcut([key intValue]) && !(mods & NSEventModifierFlagShift)) {
|
||||
mods |= NSEventModifierFlagShift;
|
||||
if (ch == 0xffff) S(v, vk); else S(c, ch);
|
||||
temp[@(buf)] = @(sc);
|
||||
dest[@(buf)] = @(sc);
|
||||
}
|
||||
#undef S
|
||||
}
|
||||
}
|
||||
}
|
||||
global_shortcuts = [[NSDictionary dictionaryWithDictionary:temp] retain];
|
||||
disabled_global_shortcuts = [[NSDictionary dictionaryWithDictionary:temp_disabled] retain];
|
||||
/* NSLog(@"global_shortcuts: %@", global_shortcuts); */
|
||||
/* NSLog(@"disabled_global_shortcuts: %@", disabled_global_shortcuts); */
|
||||
}
|
||||
|
||||
static int
|
||||
is_active_apple_global_shortcut(NSEvent *event) {
|
||||
if (global_shortcuts == nil) build_global_shortcuts_lookup();
|
||||
lookup_global_shortcut(NSEvent *event, NSDictionary<NSString*,NSNumber*> *global_shortcuts) {
|
||||
NSEventModifierFlags modifierFlags = USEFUL_MODS([event modifierFlags]);
|
||||
static char lookup_key[64];
|
||||
|
||||
#define LOOKUP(t, k) \
|
||||
snprintf(lookup_key, sizeof(lookup_key) - 1, #t":%lx:%ld", (unsigned long)modifierFlags, (long)k); \
|
||||
NSNumber *sc = global_shortcuts[@(lookup_key)]; \
|
||||
if (sc != nil) return [sc intValue];
|
||||
if (sc != nil) return [sc intValue]; \
|
||||
|
||||
if ([event.charactersIgnoringModifiers length] == 1) {
|
||||
if (modifierFlags & NSEventModifierFlagShift) {
|
||||
@@ -651,6 +659,44 @@ is_active_apple_global_shortcut(NSEvent *event) {
|
||||
return kSHKUnknown;
|
||||
}
|
||||
|
||||
static int
|
||||
default_global_character_shortcut(uint32_t ch, NSEventModifierFlags mods) {
|
||||
(void)ch; (void)mods;
|
||||
return kSHKUnknown;
|
||||
}
|
||||
|
||||
static int
|
||||
default_global_vk_shortcut(unsigned short vk, NSEventModifierFlags mods) {
|
||||
(void)vk; (void)mods;
|
||||
return kSHKUnknown;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
is_active_apple_global_shortcut(NSEvent *event) {
|
||||
if (global_shortcuts == nil) build_global_shortcuts_lookup();
|
||||
int ans = lookup_global_shortcut(event, global_shortcuts);
|
||||
if (ans != kSHKUnknown) return ans;
|
||||
ans = lookup_global_shortcut(event, disabled_global_shortcuts);
|
||||
if (ans != kSHKUnknown) return kSHKUnknown; // disabled shortcut
|
||||
// look for known global shortcuts
|
||||
NSEventModifierFlags modifierFlags = USEFUL_MODS([event modifierFlags]);
|
||||
if ([event.charactersIgnoringModifiers length] == 1) {
|
||||
if (modifierFlags & NSEventModifierFlagShift) {
|
||||
const uint32_t ch_without_shift = vk_to_unicode_key_with_current_layout([event keyCode]);
|
||||
if (ch_without_shift < GLFW_FKEY_FIRST || ch_without_shift > GLFW_FKEY_LAST) {
|
||||
ans = default_global_character_shortcut(ch_without_shift, modifierFlags);
|
||||
if (ans != kSHKUnknown) return ans;
|
||||
}
|
||||
const unichar ch = [event.charactersIgnoringModifiers characterAtIndex:0];
|
||||
ans = default_global_character_shortcut(ch, modifierFlags);
|
||||
if (ans != kSHKUnknown) return ans;
|
||||
}
|
||||
}
|
||||
unsigned short vk = [event keyCode];
|
||||
return default_global_vk_shortcut(vk, modifierFlags);
|
||||
}
|
||||
|
||||
static bool
|
||||
is_useful_apple_global_shortcut(int sc) {
|
||||
switch(sc) {
|
||||
@@ -944,6 +990,7 @@ void _glfwPlatformTerminate(void)
|
||||
|
||||
_glfwTerminateNSGL();
|
||||
if (global_shortcuts != nil) { [global_shortcuts release]; global_shortcuts = nil; }
|
||||
if (disabled_global_shortcuts != nil) { [disabled_global_shortcuts release]; disabled_global_shortcuts = nil; }
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user