|
@@ -369,6 +369,26 @@ static void UpdateKeymap(SDL_CocoaVideoData *data, bool send_event)
|
|
|
SDL_SetKeymap(keymap, send_event);
|
|
|
}
|
|
|
|
|
|
+static void SDLCALL SDL_MacOptionAsAltChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
|
|
+{
|
|
|
+ SDL_VideoDevice *_this = (SDL_VideoDevice *)userdata;
|
|
|
+ SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->internal;
|
|
|
+
|
|
|
+ if (hint && *hint) {
|
|
|
+ if (SDL_strcmp(hint, "none") == 0) {
|
|
|
+ data.option_as_alt = OptionAsAltNone;
|
|
|
+ } else if (SDL_strcmp(hint, "only_left") == 0) {
|
|
|
+ data.option_as_alt = OptionAsAltOnlyLeft;
|
|
|
+ } else if (SDL_strcmp(hint, "only_right") == 0) {
|
|
|
+ data.option_as_alt = OptionAsAltOnlyRight;
|
|
|
+ } else if (SDL_strcmp(hint, "both") == 0) {
|
|
|
+ data.option_as_alt = OptionAsAltBoth;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ data.option_as_alt = OptionAsAltNone;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void Cocoa_InitKeyboard(SDL_VideoDevice *_this)
|
|
|
{
|
|
|
SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->internal;
|
|
@@ -385,6 +405,8 @@ void Cocoa_InitKeyboard(SDL_VideoDevice *_this)
|
|
|
|
|
|
data.modifierFlags = (unsigned int)[NSEvent modifierFlags];
|
|
|
SDL_ToggleModState(SDL_KMOD_CAPS, (data.modifierFlags & NSEventModifierFlagCapsLock) ? true : false);
|
|
|
+
|
|
|
+ SDL_AddHintCallback(SDL_HINT_MAC_OPTION_AS_ALT, SDL_MacOptionAsAltChanged, _this);
|
|
|
}
|
|
|
|
|
|
bool Cocoa_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props)
|
|
@@ -437,6 +459,51 @@ bool Cocoa_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+static NSEvent *ReplaceEvent(NSEvent *event, OptionAsAlt option_as_alt)
|
|
|
+{
|
|
|
+ if (option_as_alt == OptionAsAltNone) {
|
|
|
+ return event;
|
|
|
+ }
|
|
|
+
|
|
|
+ const unsigned int modflags = (unsigned int)[event modifierFlags];
|
|
|
+
|
|
|
+ bool ignore_alt_characters = false;
|
|
|
+
|
|
|
+ bool lalt_pressed = IsModifierKeyPressed(modflags, NX_DEVICELALTKEYMASK,
|
|
|
+ NX_DEVICERALTKEYMASK, NX_ALTERNATEMASK);
|
|
|
+ bool ralt_pressed = IsModifierKeyPressed(modflags, NX_DEVICERALTKEYMASK,
|
|
|
+ NX_DEVICELALTKEYMASK, NX_ALTERNATEMASK);
|
|
|
+
|
|
|
+ if (option_as_alt == OptionAsAltOnlyLeft && lalt_pressed) {
|
|
|
+ ignore_alt_characters = true;
|
|
|
+ } else if (option_as_alt == OptionAsAltOnlyRight && ralt_pressed) {
|
|
|
+ ignore_alt_characters = true;
|
|
|
+ } else if (option_as_alt == OptionAsAltBoth && (lalt_pressed || ralt_pressed)) {
|
|
|
+ ignore_alt_characters = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool cmd_pressed = modflags & NX_COMMANDMASK;
|
|
|
+ bool ctrl_pressed = modflags & NX_CONTROLMASK;
|
|
|
+
|
|
|
+ ignore_alt_characters = ignore_alt_characters && !cmd_pressed && !ctrl_pressed;
|
|
|
+
|
|
|
+ if (ignore_alt_characters) {
|
|
|
+ NSString *charactersIgnoringModifiers = [event charactersIgnoringModifiers];
|
|
|
+ return [NSEvent keyEventWithType:[event type]
|
|
|
+ location:[event locationInWindow]
|
|
|
+ modifierFlags:modflags
|
|
|
+ timestamp:[event timestamp]
|
|
|
+ windowNumber:[event windowNumber]
|
|
|
+ context:nil
|
|
|
+ characters:charactersIgnoringModifiers
|
|
|
+ charactersIgnoringModifiers:charactersIgnoringModifiers
|
|
|
+ isARepeat:[event isARepeat]
|
|
|
+ keyCode:[event keyCode]];
|
|
|
+ }
|
|
|
+
|
|
|
+ return event;
|
|
|
+}
|
|
|
+
|
|
|
void Cocoa_HandleKeyEvent(SDL_VideoDevice *_this, NSEvent *event)
|
|
|
{
|
|
|
unsigned short scancode;
|
|
@@ -446,6 +513,10 @@ void Cocoa_HandleKeyEvent(SDL_VideoDevice *_this, NSEvent *event)
|
|
|
return; // can happen when returning from fullscreen Space on shutdown
|
|
|
}
|
|
|
|
|
|
+ if ([event type] == NSEventTypeKeyDown || [event type] == NSEventTypeKeyUp) {
|
|
|
+ event = ReplaceEvent(event, data.option_as_alt);
|
|
|
+ }
|
|
|
+
|
|
|
scancode = [event keyCode];
|
|
|
|
|
|
if ((scancode == 10 || scancode == 50) && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO) {
|