fix(macos): provide left/right identity for modifiers (#5115)
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
#import <Carbon/Carbon.h>
|
#import <Carbon/Carbon.h>
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#include <IOKit/hidsystem/IOLLEvent.h>
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
|
|
||||||
// local includes
|
// local includes
|
||||||
@@ -36,6 +37,7 @@ namespace platf {
|
|||||||
CGEventSourceRef source {};
|
CGEventSourceRef source {};
|
||||||
|
|
||||||
// keyboard related stuff
|
// keyboard related stuff
|
||||||
|
CGEventSourceRef keyboard_source {};
|
||||||
CGEventFlags kb_flags {};
|
CGEventFlags kb_flags {};
|
||||||
|
|
||||||
// mouse related stuff
|
// mouse related stuff
|
||||||
@@ -245,6 +247,43 @@ const KeyCodeMap kKeyCodesMap[] = {
|
|||||||
return temp_map->mac_keycode;
|
return temp_map->mac_keycode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct modifier_flags_t {
|
||||||
|
CGEventFlags generic {};
|
||||||
|
CGEventFlags device {};
|
||||||
|
CGEventFlags all_devices {};
|
||||||
|
};
|
||||||
|
|
||||||
|
bool modifier_flags_for_key(int key, modifier_flags_t &flags) {
|
||||||
|
switch (key) {
|
||||||
|
case kVK_Shift:
|
||||||
|
flags = {kCGEventFlagMaskShift, NX_DEVICELSHIFTKEYMASK, NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK};
|
||||||
|
return true;
|
||||||
|
case kVK_RightShift:
|
||||||
|
flags = {kCGEventFlagMaskShift, NX_DEVICERSHIFTKEYMASK, NX_DEVICELSHIFTKEYMASK | NX_DEVICERSHIFTKEYMASK};
|
||||||
|
return true;
|
||||||
|
case kVK_Command:
|
||||||
|
flags = {kCGEventFlagMaskCommand, NX_DEVICELCMDKEYMASK, NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK};
|
||||||
|
return true;
|
||||||
|
case kVK_RightCommand:
|
||||||
|
flags = {kCGEventFlagMaskCommand, NX_DEVICERCMDKEYMASK, NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK};
|
||||||
|
return true;
|
||||||
|
case kVK_Option:
|
||||||
|
flags = {kCGEventFlagMaskAlternate, NX_DEVICELALTKEYMASK, NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK};
|
||||||
|
return true;
|
||||||
|
case kVK_RightOption:
|
||||||
|
flags = {kCGEventFlagMaskAlternate, NX_DEVICERALTKEYMASK, NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK};
|
||||||
|
return true;
|
||||||
|
case kVK_Control:
|
||||||
|
flags = {kCGEventFlagMaskControl, NX_DEVICELCTLKEYMASK, NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK};
|
||||||
|
return true;
|
||||||
|
case kVK_RightControl:
|
||||||
|
flags = {kCGEventFlagMaskControl, NX_DEVICERCTLKEYMASK, NX_DEVICELCTLKEYMASK | NX_DEVICERCTLKEYMASK};
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void keyboard_update(input_t &input, uint16_t modcode, bool release, uint8_t flags) {
|
void keyboard_update(input_t &input, uint16_t modcode, bool release, uint8_t flags) {
|
||||||
auto key = keysym(modcode);
|
auto key = keysym(modcode);
|
||||||
|
|
||||||
@@ -256,43 +295,28 @@ const KeyCodeMap kKeyCodesMap[] = {
|
|||||||
|
|
||||||
auto macos_input = ((macos_input_t *) input.get());
|
auto macos_input = ((macos_input_t *) input.get());
|
||||||
CGEventRef event = nullptr;
|
CGEventRef event = nullptr;
|
||||||
|
modifier_flags_t modifier_flags;
|
||||||
|
|
||||||
if (key == kVK_Shift || key == kVK_RightShift ||
|
if (modifier_flags_for_key(key, modifier_flags)) {
|
||||||
key == kVK_Command || key == kVK_RightCommand ||
|
event = CGEventCreateKeyboardEvent(macos_input->keyboard_source, key, !release);
|
||||||
key == kVK_Option || key == kVK_RightOption ||
|
|
||||||
key == kVK_Control || key == kVK_RightControl) {
|
|
||||||
event = CGEventCreate(macos_input->source);
|
|
||||||
if (!event) {
|
if (!event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, key);
|
CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, key);
|
||||||
|
|
||||||
CGEventFlags mask;
|
if (release) {
|
||||||
|
macos_input->kb_flags &= ~modifier_flags.device;
|
||||||
switch (key) {
|
if ((macos_input->kb_flags & modifier_flags.all_devices) == 0) {
|
||||||
case kVK_Shift:
|
macos_input->kb_flags &= ~modifier_flags.generic;
|
||||||
case kVK_RightShift:
|
}
|
||||||
mask = kCGEventFlagMaskShift;
|
} else {
|
||||||
break;
|
macos_input->kb_flags |= modifier_flags.generic | modifier_flags.device;
|
||||||
case kVK_Command:
|
|
||||||
case kVK_RightCommand:
|
|
||||||
mask = kCGEventFlagMaskCommand;
|
|
||||||
break;
|
|
||||||
case kVK_Option:
|
|
||||||
case kVK_RightOption:
|
|
||||||
mask = kCGEventFlagMaskAlternate;
|
|
||||||
break;
|
|
||||||
case kVK_Control:
|
|
||||||
case kVK_RightControl:
|
|
||||||
mask = kCGEventFlagMaskControl;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macos_input->kb_flags = release ? macos_input->kb_flags & ~mask : macos_input->kb_flags | mask;
|
|
||||||
CGEventSetType(event, kCGEventFlagsChanged);
|
CGEventSetType(event, kCGEventFlagsChanged);
|
||||||
} else {
|
} else {
|
||||||
event = CGEventCreateKeyboardEvent(macos_input->source, key, !release);
|
event = CGEventCreateKeyboardEvent(macos_input->keyboard_source, key, !release);
|
||||||
if (!event) {
|
if (!event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -301,7 +325,7 @@ const KeyCodeMap kKeyCodesMap[] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CGEventSetFlags(event, macos_input->kb_flags);
|
CGEventSetFlags(event, macos_input->kb_flags);
|
||||||
CGEventPost(kCGHIDEventTap, event);
|
CGEventPost(kCGSessionEventTap, event);
|
||||||
CFRelease(event);
|
CFRelease(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,6 +591,7 @@ const KeyCodeMap kKeyCodesMap[] = {
|
|||||||
CFRelease(mode);
|
CFRelease(mode);
|
||||||
|
|
||||||
macos_input->source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
macos_input->source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||||
|
macos_input->keyboard_source = CGEventSourceCreate(kCGEventSourceStatePrivate);
|
||||||
|
|
||||||
macos_input->kb_flags = 0;
|
macos_input->kb_flags = 0;
|
||||||
|
|
||||||
@@ -584,6 +609,7 @@ const KeyCodeMap kKeyCodesMap[] = {
|
|||||||
const auto *input = static_cast<macos_input_t *>(p);
|
const auto *input = static_cast<macos_input_t *>(p);
|
||||||
|
|
||||||
CFRelease(input->source);
|
CFRelease(input->source);
|
||||||
|
CFRelease(input->keyboard_source);
|
||||||
CFRelease(input->mouse_event);
|
CFRelease(input->mouse_event);
|
||||||
|
|
||||||
delete input;
|
delete input;
|
||||||
|
|||||||
Reference in New Issue
Block a user