I have an application that is designed to send keystrokes to Lightroom. It assumes Lightroom is the foreground application. It works correctly in Windows for any keystroke/modifier key combination (code not included below) but, in OSX, it doesn't work if a Command modifier key is included. The Command key is ignored. Shift works, Option works, but not Command.
For example, shift+command+c (copy) does not work in OS X. Shift+l (lights out) does.
The full code (including Windows and OS X) is at https://github.com/rsjaffe/MIDI2LR/blob/master/Source/SendKeys.cpp. Below is a version that focuses on the issue at hand. Even though this is an abbreviated version of the code, I included all the "includes", just in case that helps you understand the issue. Also, I hardcoded a letter in this example and assumed an English keyboard to simplify things.
Note that I am doing this in C++, not Objective C. I've been trying to avoid using another language, as my app already uses two languages by necessity (C++ and Lua), and my brain is nearly full.
Question: Am I missing something here regarding handling of modifier keys, is this an issue with using C++ for these OS X functions, or is this a Lightroom bug in its key handling?
#include <mutex>
#include <unordered_map>
#include <cctype>
#include <vector>
#include <string>
#import <CoreFoundation/CoreFoundation.h>
#import <CoreGraphics/CoreGraphics.h>
void SendKeys::SendKeyDownUp(bool Option, bool Command, bool Shift) const
{
auto vk = 0x08; //for this example, just use 'c' key, assuming ANSI keyboard
const CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
CGEventRef d;
CGEventRef u;
uint64_t flags = 0;
d = CGEventCreateKeyboardEvent(source, vk, true);
u = CGEventCreateKeyboardEvent(source, vk, false);
if (Command) flags |= kCGEventFlagMaskCommand;
if (Option) flags |= kCGEventFlagMaskAlternate;
if (Shift) flags |= kCGEventFlagMaskShift;
if (flags != UINT64_C(0))
{
CGEventSetFlags(d, static_cast<CGEventFlags>(flags));
CGEventSetFlags(u, static_cast<CGEventFlags>(flags));
}
CGEventPost(kCGHIDEventTap, d);
CGEventPost(kCGHIDEventTap, u);
CFRelease(d);
CFRelease(u);
CFRelease(source);
}