macOS: Fix global shortcuts with shift modifier key not working

This commit is contained in:
pagedown 2022-01-17 02:23:00 +08:00
parent 71106bcd39
commit 5182f79152
No known key found for this signature in database
GPG Key ID: E921CF18AC8FF6EB

View File

@ -554,6 +554,11 @@ typedef enum AppleShortcutNames {
kSHKUnknown = 0, // kSHKUnknown = 0, //
} AppleShortcutNames; } AppleShortcutNames;
static bool
is_shiftable_shortcut(int scv) {
return scv == kSHKMoveFocusToActiveOrNextWindow || scv == kSHKMoveFocusToNextWindow;
}
#define USEFUL_MODS(x) (x & (NSEventModifierFlagShift | NSEventModifierFlagOption | NSEventModifierFlagCommand | NSEventModifierFlagControl)) #define USEFUL_MODS(x) (x & (NSEventModifierFlagShift | NSEventModifierFlagOption | NSEventModifierFlagCommand | NSEventModifierFlagControl))
static void static void
@ -583,11 +588,16 @@ build_global_shortcuts_lookup(void) {
NSEventModifierFlags mods = ([parameters count] > 2 && [parameters[2] isKindOfClass:[NSNumber class]]) ? [parameters[2] unsignedIntegerValue] : 0; NSEventModifierFlags mods = ([parameters count] > 2 && [parameters[2] isKindOfClass:[NSNumber class]]) ? [parameters[2] unsignedIntegerValue] : 0;
mods = USEFUL_MODS(mods); mods = USEFUL_MODS(mods);
static char buf[64]; static char buf[64];
if (ch == 0xffff) { #define S(x, k) snprintf(buf, sizeof(buf) - 1, #x":%lx:%ld", (unsigned long)mods, (long)k)
if (vk == 0xffff) continue; if (ch == 0xffff) { if (vk == 0xffff) continue; S(v, vk); } else S(c, ch);
snprintf(buf, sizeof(buf) - 1, "v:%lx:%ld", (unsigned long)mods, (long)vk);
} else snprintf(buf, sizeof(buf) - 1, "c:%lx:%ld", (unsigned long)mods, (long)ch);
temp[@(buf)] = @(sc); temp[@(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);
}
#undef S
} }
} }
} }
@ -595,47 +605,32 @@ build_global_shortcuts_lookup(void) {
/* NSLog(@"global_shortcuts: %@", global_shortcuts); */ /* NSLog(@"global_shortcuts: %@", global_shortcuts); */
} }
static bool
is_shiftable_shortcut(int scv) {
return scv == kSHKMoveFocusToActiveOrNextWindow || scv == kSHKMoveFocusToNextWindow;
}
static int static int
is_active_apple_global_shortcut(NSEvent *event) { is_active_apple_global_shortcut(NSEvent *event) {
if (global_shortcuts == nil) build_global_shortcuts_lookup(); if (global_shortcuts == nil) build_global_shortcuts_lookup();
NSEventModifierFlags modifierFlags = USEFUL_MODS([event modifierFlags]); NSEventModifierFlags modifierFlags = USEFUL_MODS([event modifierFlags]);
static char lookup_key[64]; static char lookup_key[64];
if ([event.charactersIgnoringModifiers length] == 1) {
const unichar ch = [event.charactersIgnoringModifiers characterAtIndex:0]; #define LOOKUP(t, k) \
snprintf(lookup_key, sizeof(lookup_key) - 1, "c:%lx:%ld", (unsigned long)modifierFlags, (long)ch); snprintf(lookup_key, sizeof(lookup_key) - 1, #t":%lx:%ld", (unsigned long)modifierFlags, (long)k); \
NSNumber *sc = global_shortcuts[@(lookup_key)]; 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) { if (modifierFlags & NSEventModifierFlagShift) {
// the move to next window shortcuts also respond to the same shortcut + shift so check for that
const uint32_t ch_without_shift = vk_to_unicode_key_with_current_layout([event keyCode]); 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) { if (ch_without_shift < GLFW_FKEY_FIRST || ch_without_shift > GLFW_FKEY_LAST) {
snprintf(lookup_key, sizeof(lookup_key) - 1, "c:%lx:%ld", (unsigned long)(modifierFlags & ~NSEventModifierFlagShift), (long)ch_without_shift); LOOKUP(c, ch_without_shift);
NSNumber *sc = global_shortcuts[@(lookup_key)];
if (sc != nil) {
int scv = [sc intValue];
if (is_shiftable_shortcut(scv)) return scv;
}
} }
} }
const unichar ch = [event.charactersIgnoringModifiers characterAtIndex:0];
LOOKUP(c, ch);
} }
unsigned short vk = [event keyCode]; unsigned short vk = [event keyCode];
if (vk != 0xffff) { if (vk != 0xffff) {
snprintf(lookup_key, sizeof(lookup_key) - 1, "v:%lx:%ld", (unsigned long)modifierFlags, (long)vk); LOOKUP(v, vk);
NSNumber *sc = global_shortcuts[@(lookup_key)];
if (sc != nil) return [sc intValue];
// the move to next window shortcuts also respond to the same shortcut + shift so check for that
snprintf(lookup_key, sizeof(lookup_key) - 1, "v:%lx:%ld", (unsigned long)(modifierFlags & ~NSEventModifierFlagShift), (long)vk);
sc = global_shortcuts[@(lookup_key)];
if (sc != nil) {
int scv = [sc intValue];
if (is_shiftable_shortcut(scv)) return scv;
}
} }
#undef LOOKUP
return kSHKUnknown; return kSHKUnknown;
} }