bool KwmMainHotkeyTrigger(CGEventRef *Event) { modifiers Mod = {}; CGEventFlags Flags = CGEventGetFlags(*Event); Mod.CmdKey = (Flags & kCGEventFlagMaskCommand) == kCGEventFlagMaskCommand; Mod.AltKey = (Flags & kCGEventFlagMaskAlternate) == kCGEventFlagMaskAlternate; Mod.CtrlKey = (Flags & kCGEventFlagMaskControl) == kCGEventFlagMaskControl; Mod.ShiftKey = (Flags & kCGEventFlagMaskShift) == kCGEventFlagMaskShift; CGKeyCode Keycode = (CGKeyCode)CGEventGetIntegerValueField(*Event, kCGKeyboardEventKeycode); if(KWMHotkeys.Prefix.Enabled && KwmIsPrefixKey(&KWMHotkeys.Prefix.Key, &Mod, Keycode)) { KWMHotkeys.Prefix.Active = true; KWMHotkeys.Prefix.Time = std::chrono::steady_clock::now(); if(PrefixBorder.Enabled) { ClearBorder(&FocusedBorder); UpdateBorder("focused"); } return true; } return KwmExecuteHotkey(Mod, Keycode); }
CGEventRef tapcallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* refcon){ CGEventFlags flags = CGEventGetFlags(event); for(int i = 1; i < DEV_MAX; i++) flags |= keyboard[i].eflags; CGEventSetFlags(event, flags); return event; }
void CreateHotkeyFromCGEvent(CGEventRef Event, hotkey *Hotkey) { CGEventFlags Flags = CGEventGetFlags(Event); Hotkey->Mod.CmdKey = (Flags & kCGEventFlagMaskCommand) == kCGEventFlagMaskCommand; Hotkey->Mod.AltKey = (Flags & kCGEventFlagMaskAlternate) == kCGEventFlagMaskAlternate; Hotkey->Mod.CtrlKey = (Flags & kCGEventFlagMaskControl) == kCGEventFlagMaskControl; Hotkey->Mod.ShiftKey = (Flags & kCGEventFlagMaskShift) == kCGEventFlagMaskShift; Hotkey->Key = (CGKeyCode)CGEventGetIntegerValueField(Event, kCGKeyboardEventKeycode); }
CGEventRef key_configure_callback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { active_keycode = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); active_flags = CGEventGetFlags(event); key_stop(); return event; }
CGEventRef key_event_callback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { int keycode = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); CGEventFlags flags = CGEventGetFlags(event); if (type == kCGEventKeyUp && keycode == active_keycode) cw_keydown = false; if (type == kCGEventKeyDown && keycode == active_keycode && flags == active_flags) cw_keydown = true; return event; }
static Qt::KeyboardModifiers getModifiersFromQuartzEvent(CGEventRef inEvent) { Qt::KeyboardModifiers m; CGEventFlags flags = CGEventGetFlags(inEvent); if (flags & kCGEventFlagMaskShift || flags & kCGEventFlagMaskAlphaShift) m |= Qt::ShiftModifier; if (flags & kCGEventFlagMaskControl) m |= Qt::MetaModifier; if (flags & kCGEventFlagMaskAlternate) m |= Qt::AltModifier; if (flags & kCGEventFlagMaskCommand) m |= Qt::ControlModifier; return m; }
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { // debug //fprintf(stderr, "Caught event!\n"); CGEventFlags modifiers = CGEventGetFlags(event); if ((modifiers & RIGHT_OPT_DOWN) == RIGHT_OPT_DOWN) { //CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); //fprintf(stderr, "\nMINE!\n"); //fprintf(stderr, "Type: %i Modifiers: %i Keycode: %i\n", type, (int)modifiers, keycode); modifiers &= ~RIGHT_OPT_DOWN; //fprintf(stderr, "Type: %i Modifiers: %i Keycode: %i\n", type, (int)modifiers, keycode); modifiers |= RIGHT_CTRL_DOWN; //fprintf(stderr, "Type: %i Modifiers: %i Keycode: %i\n", type, (int)modifiers, keycode); CGEventSetFlags(event, modifiers); // debug //fprintf(stderr, "After swap!\n"); //CGEventFlags modifiers2 = CGEventGetFlags(event); //CGKeyCode keycode2 = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); //fprintf(stderr, "Type: %i Modifiers: %i Keycode: %i\n", type, (int)modifiers2, keycode2); } return event; }
// This callback will be invoked every time the mouse moves. // CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { if (type != kCGEventKeyDown && type != kCGEventFlagsChanged && type != kCGEventKeyUp) return event; CGEventFlags eventFlags = CGEventGetFlags(event); if (type == kCGEventFlagsChanged) { printf("%lld\n", eventFlags); } // Paranoid sanity check. if (type != kCGEventKeyDown && type != kCGEventKeyUp) return event; CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField( event, kCGKeyboardEventKeycode); printf("%d\n", keycode); //Keypress code goes here. // We must return the event for it to be useful. return event; }
bool COSXScreen::onKey(CGEventRef event) { CGEventType eventKind = CGEventGetType(event); // get the key and active modifiers UInt32 virtualKey = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); CGEventFlags macMask = CGEventGetFlags(event); LOG((CLOG_DEBUG1 "event: Key event kind: %d, keycode=%d", eventKind, virtualKey)); // Special handling to track state of modifiers if (eventKind == kCGEventFlagsChanged) { // get old and new modifier state KeyModifierMask oldMask = getActiveModifiers(); KeyModifierMask newMask = m_keyState->mapModifiersFromOSX(macMask); m_keyState->handleModifierKeys(getEventTarget(), oldMask, newMask); // if the current set of modifiers exactly matches a modifiers-only // hot key then generate a hot key down event. if (m_activeModifierHotKey == 0) { if (m_modifierHotKeys.count(newMask) > 0) { m_activeModifierHotKey = m_modifierHotKeys[newMask]; m_activeModifierHotKeyMask = newMask; m_events->addEvent(CEvent(m_events->forIPrimaryScreen().hotKeyDown(), getEventTarget(), CHotKeyInfo::alloc(m_activeModifierHotKey))); } } // if a modifiers-only hot key is active and should no longer be // then generate a hot key up event. else if (m_activeModifierHotKey != 0) { KeyModifierMask mask = (newMask & m_activeModifierHotKeyMask); if (mask != m_activeModifierHotKeyMask) { m_events->addEvent(CEvent(m_events->forIPrimaryScreen().hotKeyUp(), getEventTarget(), CHotKeyInfo::alloc(m_activeModifierHotKey))); m_activeModifierHotKey = 0; m_activeModifierHotKeyMask = 0; } } return true; } // check for hot key. when we're on a secondary screen we disable // all hotkeys so we can capture the OS defined hot keys as regular // keystrokes but that means we don't get our own hot keys either. // so we check for a key/modifier match in our hot key map. if (!m_isOnScreen) { HotKeyToIDMap::const_iterator i = m_hotKeyToIDMap.find(CHotKeyItem(virtualKey, m_keyState->mapModifiersToCarbon(macMask) & 0xff00u)); if (i != m_hotKeyToIDMap.end()) { UInt32 id = i->second; // determine event type CEvent::Type type; //UInt32 eventKind = GetEventKind(event); if (eventKind == kCGEventKeyDown) { type = m_events->forIPrimaryScreen().hotKeyDown(); } else if (eventKind == kCGEventKeyUp) { type = m_events->forIPrimaryScreen().hotKeyUp(); } else { return false; } m_events->addEvent(CEvent(type, getEventTarget(), CHotKeyInfo::alloc(id))); return true; } } // decode event type bool down = (eventKind == kCGEventKeyDown); bool up = (eventKind == kCGEventKeyUp); bool isRepeat = (CGEventGetIntegerValueField(event, kCGKeyboardEventAutorepeat) == 1); // map event to keys KeyModifierMask mask; COSXKeyState::CKeyIDs keys; KeyButton button = m_keyState->mapKeyFromEvent(keys, &mask, event); if (button == 0) { return false; } // check for AltGr in mask. if set we send neither the AltGr nor // the super modifiers to clients then remove AltGr before passing // the modifiers to onKey. KeyModifierMask sendMask = (mask & ~KeyModifierAltGr); if ((mask & KeyModifierAltGr) != 0) { sendMask &= ~KeyModifierSuper; } mask &= ~KeyModifierAltGr; // update button state if (down) { m_keyState->onKey(button, true, mask); } else if (up) { if (!m_keyState->isKeyDown(button)) { // up event for a dead key. throw it away. return false; } m_keyState->onKey(button, false, mask); } // send key events for (COSXKeyState::CKeyIDs::const_iterator i = keys.begin(); i != keys.end(); ++i) { m_keyState->sendKeyEvent(getEventTarget(), down, isRepeat, *i, sendMask, 1, button); } return true; }
// This method must be executed from the main runloop to avoid the seemingly random // Exception detected while handling key input. TSMProcessRawKeyCode failed (-192) errors. // CFEqual(CFRunLoopGetCurrent(), CFRunLoopGetMain()) void keycode_to_string(CGEventRef event_ref, UniCharCount size, UniCharCount *length, UniChar *buffer) { #if defined(USE_CARBON_LEGACY) || defined(USE_COREFOUNDATION) #if defined(USE_CARBON_LEGACY) KeyboardLayoutRef curr_keyboard_layout; void *inputData = NULL; if (KLGetCurrentKeyboardLayout(&curr_keyboard_layout) == noErr) { if (KLGetKeyboardLayoutProperty(curr_keyboard_layout, kKLuchrData, (const void **) &inputData) != noErr) { inputData = NULL; } } #elif defined(USE_COREFOUNDATION) TISInputSourceRef curr_keyboard_layout = TISCopyCurrentKeyboardLayoutInputSource(); CFDataRef inputData = NULL; if (curr_keyboard_layout != NULL && CFGetTypeID(curr_keyboard_layout) == TISInputSourceGetTypeID()) { CFDataRef data = (CFDataRef) TISGetInputSourceProperty(curr_keyboard_layout, kTISPropertyUnicodeKeyLayoutData); if (data != NULL && CFGetTypeID(data) == CFDataGetTypeID() && CFDataGetLength(data) > 0) { inputData = (CFDataRef) data; } } // Check if the keyboard layout has changed to see if the dead key state needs to be discarded. if (prev_keyboard_layout != NULL && curr_keyboard_layout != NULL && CFEqual(curr_keyboard_layout, prev_keyboard_layout) == false) { curr_deadkey_state = 0; } // Release the previous keyboard layout. if (prev_keyboard_layout != NULL) { CFRelease(prev_keyboard_layout); } // Set the previous keyboard layout to the current layout. if (curr_keyboard_layout != NULL) { prev_keyboard_layout = curr_keyboard_layout; } #endif if (inputData != NULL) { #ifdef USE_CARBON_LEGACY const UCKeyboardLayout *keyboard_layout = (const UCKeyboardLayout *) inputData; #else const UCKeyboardLayout *keyboard_layout = (const UCKeyboardLayout*) CFDataGetBytePtr(inputData); #endif if (keyboard_layout != NULL) { //Extract keycode and modifier information. CGKeyCode keycode = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); CGEventFlags modifiers = CGEventGetFlags(event); // Disable all command modifiers for translation. This is required // so UCKeyTranslate will provide a keysym for the separate event. static const CGEventFlags cmd_modifiers = kCGEventFlagMaskCommand | kCGEventFlagMaskControl | kCGEventFlagMaskAlternate; modifiers &= ~cmd_modifiers; // I don't know why but UCKeyTranslate does not process the // kCGEventFlagMaskAlphaShift (A.K.A. Caps Lock Mask) correctly. // We need to basically turn off the mask and process the capital // letters after UCKeyTranslate(). Think Different, not because it // makes sense but because you want to be a hipster. bool is_caps_lock = modifiers & kCGEventFlagMaskAlphaShift; modifiers &= ~kCGEventFlagMaskAlphaShift; OSStatus status = noErr; if (curr_deadkey_state == 0) { // No previous deadkey, attempt a lookup. status = UCKeyTranslate( keyboard_layout, keycode, kUCKeyActionDown, (modifiers >> 16) & 0xFF, //(modifiers >> 16) & 0xFF, || (modifiers >> 8) & 0xFF, LMGetKbdType(), kNilOptions, //kNilOptions, //kUCKeyTranslateNoDeadKeysMask &curr_deadkey_state, size, length, buffer); } else {
// This callback will be invoked every time there is a keystroke. // CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { //printf("called!\n"); // Paranoid sanity check. if ((type != kCGEventKeyDown) && (type != kCGEventKeyUp) && (type != kCGEventFlagsChanged)) return event; // The incoming keycode. CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); //Control if(keycode == (CGKeyCode)59||keycode == (CGKeyCode)62){ if(ctr){ ctr = false; } else{ ctr = true; } } if(ctr){ CGEventSetFlags(event,NX_CONTROLMASK|CGEventGetFlags(event)); } //Shift if(keycode == (CGKeyCode)60||keycode == (CGKeyCode)56){ if(sft){ sft = false; } else{ sft = true; } } if(sft){ CGEventSetFlags(event,NX_SHIFTMASK|CGEventGetFlags(event)); } //Command if(keycode == (CGKeyCode)55||keycode == (CGKeyCode)54){ if(cmd){ cmd = false; } else{ cmd = true; } } if(cmd){ CGEventSetFlags(event,NX_COMMANDMASK|CGEventGetFlags(event)); } //Option if(keycode == (CGKeyCode)58||keycode == (CGKeyCode)61){ if(opt){ opt = false; } else{ opt = true; } } if(opt){ CGEventSetFlags(event,NX_ALTERNATEMASK|CGEventGetFlags(event)); } CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, (int64_t)keycode); if (cmd && sft && keycode == 7) { states = !states; printf("now states is %i\n", states); } //Team T if(keycode == (CGKeyCode)125||keycode == (CGKeyCode)108) { if(dArrow){ dArrow = false; } else{ dArrow = true; } if(dArrow){ playTeam = 2; CGEventSetFlags(event,NX_DOWN_ARROW_KEY|CGEventGetFlags(event)); } } //Team CT if(keycode == (CGKeyCode)126||keycode == (CGKeyCode)103) { if(uArrow){ uArrow = false; } else{ uArrow = true; } if(uArrow){ playTeam = 3; CGEventSetFlags(event,NX_UP_ARROW_KEY|CGEventGetFlags(event)); } } // We must return the event for it to be useful. return event; }
KeyButton OSXKeyState::mapKeyFromEvent(KeyIDs& ids, KeyModifierMask* maskOut, CGEventRef event) const { ids.clear(); // map modifier key if (maskOut != NULL) { KeyModifierMask activeMask = getActiveModifiers(); activeMask &= ~KeyModifierAltGr; *maskOut = activeMask; } // get virtual key UInt32 vkCode = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); // handle up events UInt32 eventKind = CGEventGetType(event); if (eventKind == kCGEventKeyUp) { // the id isn't used. we just need the same button we used on // the key press. note that we don't use or reset the dead key // state; up events should not affect the dead key state. ids.push_back(kKeyNone); return mapVirtualKeyToKeyButton(vkCode); } // check for special keys VirtualKeyMap::const_iterator i = m_virtualKeyMap.find(vkCode); if (i != m_virtualKeyMap.end()) { m_deadKeyState = 0; ids.push_back(i->second); return mapVirtualKeyToKeyButton(vkCode); } // get keyboard info #if defined(MAC_OS_X_VERSION_10_5) TISInputSourceRef currentKeyboardLayout = TISCopyCurrentKeyboardLayoutInputSource(); #else KeyboardLayoutRef currentKeyboardLayout; OSStatus status = KLGetCurrentKeyboardLayout(¤tKeyboardLayout); #endif if (currentKeyboardLayout == NULL) { return kKeyNone; } // get the event modifiers and remove the command and control // keys. note if we used them though. // UCKeyTranslate expects old-style Carbon modifiers, so convert. UInt32 modifiers; modifiers = mapModifiersToCarbon(CGEventGetFlags(event)); static const UInt32 s_commandModifiers = cmdKey | controlKey | rightControlKey; bool isCommand = ((modifiers & s_commandModifiers) != 0); modifiers &= ~s_commandModifiers; // if we've used a command key then we want the glyph produced without // the option key (i.e. the base glyph). //if (isCommand) { modifiers &= ~optionKey; //} // choose action UInt16 action; if(eventKind==kCGEventKeyDown) { action = kUCKeyActionDown; } else if(CGEventGetIntegerValueField(event, kCGKeyboardEventAutorepeat)==1) { action = kUCKeyActionAutoKey; } else { return 0; } // translate via uchr resource #if defined(MAC_OS_X_VERSION_10_5) CFDataRef ref = (CFDataRef) TISGetInputSourceProperty(currentKeyboardLayout, kTISPropertyUnicodeKeyLayoutData); const UCKeyboardLayout* layout = (const UCKeyboardLayout*) CFDataGetBytePtr(ref); const bool layoutValid = (layout != NULL); #else const void* resource; int err = KLGetKeyboardLayoutProperty(currentKeyboardLayout, kKLuchrData, &resource); const bool layoutValid = (err == noErr); const UCKeyboardLayout* layout = (const UCKeyboardLayout*)resource; #endif if (layoutValid) { // translate key UniCharCount count; UniChar chars[2]; LOG((CLOG_DEBUG2 "modifiers: %08x", modifiers & 0xffu)); OSStatus status = UCKeyTranslate(layout, vkCode & 0xffu, action, (modifiers >> 8) & 0xffu, LMGetKbdType(), 0, &m_deadKeyState, sizeof(chars) / sizeof(chars[0]), &count, chars); // get the characters if (status == 0) { if (count != 0 || m_deadKeyState == 0) { m_deadKeyState = 0; for (UniCharCount i = 0; i < count; ++i) { ids.push_back(KeyResource::unicharToKeyID(chars[i])); } adjustAltGrModifier(ids, maskOut, isCommand); return mapVirtualKeyToKeyButton(vkCode); } return 0; } } return 0; }
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { if ((type != kCGEventKeyDown) && (type != kCGEventKeyUp) && (type != kCGEventFlagsChanged)) { return event; } CGEventFlags flags = CGEventGetFlags(event); if ((flags & Modifier_CapsLock) != Modifier_CapsLock) { return event; } CGKeyCode keyCode = (CGKeyCode)CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); if (flags == Modifier_CapsLock) { switch (keyCode) { case kVK_ANSI_A: // Select all, Command+A case kVK_ANSI_C: // Copy, Command+C case kVK_ANSI_F: // Find, Command+F case kVK_ANSI_L: // Location, Command+L case kVK_ANSI_N: // New, Command+N case kVK_ANSI_S: // Save, Command+S case kVK_ANSI_T: // Create Tab, Command+T case kVK_ANSI_V: // Paste, Command+V case kVK_ANSI_X: // Cut, Command+X case kVK_ANSI_Z: // Undo, Command+Z case kVK_ANSI_Grave: // Next Window, Command+` case kVK_Tab: // Next Application, Command+Tab case kVK_Space: // Launcher, Command+Space CGEventSetFlags(event, Modifier_Command); break; case kVK_ANSI_E: // Close Tab, Command+Q CGEventSetFlags(event, Modifier_Command); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_ANSI_W); break; case kVK_Escape: // Abort, Control+C CGEventSetFlags(event, Modifier_Control); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_ANSI_C); break; case kVK_ANSI_Q: // Previous Tab, Shift+Command+LeftBracket CGEventSetFlags(event, Modifier_Shift | Modifier_Command); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_ANSI_LeftBracket); break; case kVK_ANSI_W: // Next Tab, Shift+Command+RightBracket CGEventSetFlags(event, Modifier_Shift | Modifier_Command); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_ANSI_RightBracket); break; case kVK_Delete: // Forward Delete CGEventSetFlags(event, 0); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_ForwardDelete); break; case kVK_ANSI_Comma: // Page Up, PageUp CGEventSetFlags(event, 0); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_PageUp); break; case kVK_ANSI_Period: // Page Down, PageDown CGEventSetFlags(event, 0); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_PageDown); break; case kVK_ANSI_I: // Inspect Page, Shift+Command+Inspect CGEventSetFlags(event, Modifier_Option | Modifier_Command); break; } } else if (flags == Modifier_ShiftCapsLock) { switch (keyCode) { case kVK_ANSI_F: // Replace, Shift+Command+F case kVK_ANSI_Z: // Redo, Shift+Command+Z case kVK_Tab: // Previous Application, Shift+Command+Tab CGEventSetFlags(event, Modifier_Shift | Modifier_Command); break; case kVK_ANSI_Comma: // Select Previous Page, Shift+PageUp CGEventSetFlags(event, Modifier_Shift); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_PageUp); break; case kVK_ANSI_Period: // Select Next Page, Shift+PageDown CGEventSetFlags(event, Modifier_Shift); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_PageDown); break; } } else if (flags == Modifier_DirectionCapsLock) { switch (keyCode) { case kVK_UpArrow: // Beginning of Line, Command+Left CGEventSetFlags(event, Modifier_Direction | Modifier_Command); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_LeftArrow); break; case kVK_DownArrow: // Beginning of Line, Command+Left CGEventSetFlags(event, Modifier_Direction | Modifier_Command); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_RightArrow); break; case kVK_LeftArrow: // Previous Token, Option+Left case kVK_RightArrow: // Next Token, Option+Right CGEventSetFlags(event, Modifier_Direction | Modifier_Option); break; } } else if (flags == Modifier_ShiftDirectionCapsLock) { switch (keyCode) { case kVK_UpArrow: // Select to Beginning of Line, Shift+Command+Left CGEventSetFlags(event, Modifier_Shift | Modifier_Direction | Modifier_Command); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_LeftArrow); break; case kVK_DownArrow: // Select to End of Line, Shift+Command+Left CGEventSetFlags(event, Modifier_Shift | Modifier_Direction | Modifier_Command); CGEventSetIntegerValueField(event, kCGKeyboardEventKeycode, kVK_RightArrow); break; } } return event; }