1

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);

}
rsjaffe
  • 5,600
  • 7
  • 27
  • 39

0 Answers0