diff --git a/src/lib/platform/OSXKeyState.cpp b/src/lib/platform/OSXKeyState.cpp index 270ed854..7bf258c9 100644 --- a/src/lib/platform/OSXKeyState.cpp +++ b/src/lib/platform/OSXKeyState.cpp @@ -181,15 +181,13 @@ static const CKeyEntry s_controlKeys[] = { // COSXKeyState::COSXKeyState(IEventQueue* events) : - CKeyState(events), - m_deadKeyState(0) + CKeyState(events) { init(); } COSXKeyState::COSXKeyState(IEventQueue* events, CKeyMap& keyMap) : - CKeyState(events, keyMap), - m_deadKeyState(0) + CKeyState(events, keyMap) { init(); } @@ -201,16 +199,17 @@ COSXKeyState::~COSXKeyState() void COSXKeyState::init() { - // initialize modifier key values - shiftPressed = false; - controlPressed = false; - altPressed = false; - superPressed = false; - capsPressed = false; + m_deadKeyState = 0; + m_shiftPressed = false; + m_controlPressed = false; + m_altPressed = false; + m_superPressed = false; + m_capsPressed = false; // build virtual key map - for (size_t i = 0; i < sizeof(s_controlKeys) / - sizeof(s_controlKeys[0]); ++i) { + for (size_t i = 0; i < sizeof(s_controlKeys) / sizeof(s_controlKeys[0]); + ++i) { + m_virtualKeyMap[s_controlKeys[i].m_virtualKey] = s_controlKeys[i].m_keyID; } @@ -483,63 +482,97 @@ COSXKeyState::getKeyMap(CKeyMap& keyMap) void COSXKeyState::fakeKey(const Keystroke& keystroke) { - CGEventRef ref; - switch (keystroke.m_type) { - case Keystroke::kButton: - { - LOG((CLOG_DEBUG1 " %03x (%08x) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up")); + case Keystroke::kButton: { + + KeyButton button = keystroke.m_data.m_button.m_button; + bool keyDown = keystroke.m_data.m_button.m_press; + UInt32 client = keystroke.m_data.m_button.m_client; + CGEventSourceRef source = 0; + CGKeyCode virtualKey = mapKeyButtonToVirtualKey(button); + + LOG((CLOG_DEBUG1 + " button=0x%04x virtualKey=0x%04x keyDown=%s client=0x%04x", + button, virtualKey, keyDown ? "down" : "up", client)); - // let system figure out character for us - ref = CGEventCreateKeyboardEvent(0, mapKeyButtonToVirtualKey( - keystroke.m_data.m_button.m_button), - keystroke.m_data.m_button.m_press); + CGEventRef ref = CGEventCreateKeyboardEvent( + source, virtualKey, keyDown); + if (ref == NULL) { LOG((CLOG_CRIT "unable to create keyboard event for keystroke")); + return; } - UInt32 vk = mapKeyButtonToVirtualKey(keystroke.m_data.m_button.m_button); - UInt32 modifierDown = keystroke.m_data.m_button.m_press; + // persist modifier state. + if (virtualKey == s_shiftVK) { + m_shiftPressed = keyDown; + } + + if (virtualKey == s_controlVK) { + m_controlPressed = keyDown; + } + + if (virtualKey == s_altVK) { + m_altPressed = keyDown; + } + + if (virtualKey == s_superVK) { + m_superPressed = keyDown; + } + + if (virtualKey == s_capsLockVK) { + m_capsPressed = keyDown; + } - // check the key for specials and store the value (persistent until changed) - if (vk == s_shiftVK) shiftPressed=modifierDown; - if (vk == s_controlVK) controlPressed=modifierDown; - if (vk == s_altVK) altPressed=modifierDown; - if (vk == s_superVK) superPressed=modifierDown; - if (vk == s_capsLockVK) capsPressed=modifierDown; + // set the event flags for special keys + // http://tinyurl.com/pxl742y + CGEventFlags modifiers = 0; + + if (m_shiftPressed) { + modifiers |= kCGEventFlagMaskShift; + } + + if (m_controlPressed) { + modifiers |= kCGEventFlagMaskControl; + } + + if (m_altPressed) { + modifiers |= kCGEventFlagMaskAlternate; + } + + if (m_superPressed) { + modifiers |= kCGEventFlagMaskCommand; + } + + if (m_capsPressed) { + modifiers |= kCGEventFlagMaskAlphaShift; + } + + CGEventSetFlags(ref, modifiers); + CGEventPost(kCGHIDEventTap, ref); + CFRelease(ref); - //Set the event flags for special keys - see following link: - //http://stackoverflow.com/questions/2008126/cgeventpost-possible-bug-when-simulating-keyboard-events - CGEventFlags modifiers = 0; - if (shiftPressed) modifiers |= kCGEventFlagMaskShift; - if (controlPressed) modifiers |= kCGEventFlagMaskControl; - if (altPressed) modifiers |= kCGEventFlagMaskAlternate; - if (superPressed) modifiers |= kCGEventFlagMaskCommand; - if (capsPressed) modifiers |= kCGEventFlagMaskAlphaShift; - - CGEventSetFlags(ref, modifiers); - - CGEventPost(kCGHIDEventTap, ref); - - // add a delay if client data isn't zero - if (keystroke.m_data.m_button.m_client) { - ARCH->sleep(0.01); - } + // add a delay if client data isn't zero + // FIXME -- why? + if (client != 0) { + ARCH->sleep(0.01); } break; + } - case Keystroke::kGroup: + case Keystroke::kGroup: { + SInt32 group = keystroke.m_data.m_group.m_group; if (keystroke.m_data.m_group.m_absolute) { - LOG((CLOG_DEBUG1 " group %d", keystroke.m_data.m_group.m_group)); - setGroup(keystroke.m_data.m_group.m_group); + LOG((CLOG_DEBUG1 " group %d", group)); + setGroup(group); } else { - LOG((CLOG_DEBUG1 " group %+d", keystroke.m_data.m_group.m_group)); - setGroup(getEffectiveGroup(pollActiveGroup(), - keystroke.m_data.m_group.m_group)); + LOG((CLOG_DEBUG1 " group %+d", group)); + setGroup(getEffectiveGroup(pollActiveGroup(), group)); } break; } + } } void diff --git a/src/lib/platform/OSXKeyState.h b/src/lib/platform/OSXKeyState.h index c10833fd..fad80701 100644 --- a/src/lib/platform/OSXKeyState.h +++ b/src/lib/platform/OSXKeyState.h @@ -214,11 +214,9 @@ private: mutable UInt32 m_deadKeyState; GroupList m_groups; GroupMap m_groupMap; - - // Hold the current state of modifier keys - bool shiftPressed; - bool controlPressed; - bool altPressed; - bool superPressed; - bool capsPressed; + bool m_shiftPressed; + bool m_controlPressed; + bool m_altPressed; + bool m_superPressed; + bool m_capsPressed; };