Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 53 additions & 27 deletions src/platform/macos/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <ApplicationServices/ApplicationServices.h>
#import <Carbon/Carbon.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/hidsystem/IOLLEvent.h>
#include <mach/mach.h>

// local includes
Expand All @@ -36,6 +37,7 @@ namespace platf {
CGEventSourceRef source {};

// keyboard related stuff
CGEventSourceRef keyboard_source {};
CGEventFlags kb_flags {};

// mouse related stuff
Expand Down Expand Up @@ -245,6 +247,43 @@ const KeyCodeMap kKeyCodesMap[] = {
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) {
auto key = keysym(modcode);

Expand All @@ -256,43 +295,28 @@ const KeyCodeMap kKeyCodesMap[] = {

auto macos_input = ((macos_input_t *) input.get());
CGEventRef event = nullptr;
modifier_flags_t modifier_flags;

if (key == kVK_Shift || key == kVK_RightShift ||
key == kVK_Command || key == kVK_RightCommand ||
key == kVK_Option || key == kVK_RightOption ||
key == kVK_Control || key == kVK_RightControl) {
event = CGEventCreate(macos_input->source);
if (modifier_flags_for_key(key, modifier_flags)) {
event = CGEventCreateKeyboardEvent(macos_input->keyboard_source, key, !release);
if (!event) {
return;
}

CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, key);

CGEventFlags mask;

switch (key) {
case kVK_Shift:
case kVK_RightShift:
mask = kCGEventFlagMaskShift;
break;
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;
if (release) {
macos_input->kb_flags &= ~modifier_flags.device;
if ((macos_input->kb_flags & modifier_flags.all_devices) == 0) {
macos_input->kb_flags &= ~modifier_flags.generic;
}
} else {
macos_input->kb_flags |= modifier_flags.generic | modifier_flags.device;
}

macos_input->kb_flags = release ? macos_input->kb_flags & ~mask : macos_input->kb_flags | mask;
CGEventSetType(event, kCGEventFlagsChanged);
} else {
event = CGEventCreateKeyboardEvent(macos_input->source, key, !release);
event = CGEventCreateKeyboardEvent(macos_input->keyboard_source, key, !release);
if (!event) {
return;
}
Expand All @@ -301,7 +325,7 @@ const KeyCodeMap kKeyCodesMap[] = {
}

CGEventSetFlags(event, macos_input->kb_flags);
CGEventPost(kCGHIDEventTap, event);
CGEventPost(kCGSessionEventTap, event);
CFRelease(event);
}

Expand Down Expand Up @@ -567,6 +591,7 @@ const KeyCodeMap kKeyCodesMap[] = {
CFRelease(mode);

macos_input->source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
macos_input->keyboard_source = CGEventSourceCreate(kCGEventSourceStatePrivate);

macos_input->kb_flags = 0;

Expand All @@ -584,6 +609,7 @@ const KeyCodeMap kKeyCodesMap[] = {
const auto *input = static_cast<macos_input_t *>(p);

CFRelease(input->source);
CFRelease(input->keyboard_source);
CFRelease(input->mouse_event);

delete input;
Expand Down
Loading