Emulate / send Modifier Key (Cntrl, Alt, fn, Shift) in OSx

梦想的初衷 提交于 2019-12-06 04:28:28

All you have to do is create an event tap and set the mask.

Sample:

@interface AppDelegate ()

@property (assign) CFMachPortRef myEventTap;
@property (assign) CFRunLoopSourceRef myRunLoopSource;

@end

@implementation AppDelegate

CGEventRef MyEventTapCallBack(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
    CGEventSetFlags(event, kCGEventFlagMaskShift);
    return event;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    self.myEventTap = CGEventTapCreate(kCGHIDEventTap,
                                            kCGHeadInsertEventTap,
                                            kCGEventTapOptionDefault,
                                            CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventKeyUp) | CGEventMaskBit(kCGEventFlagsChanged),
                                            MyEventTapCallBack,
                                            (__bridge void *)self);
    if (self.myEventTap) {
        self.myRunLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, self.myEventTap, 0);
        if (self.myRunLoopSource)
            CFRunLoopAddSource(CFRunLoopGetMain(), self.myRunLoopSource, kCFRunLoopCommonModes);
    }
}

- (void)applicationWillTerminate:(NSNotification *)aNotification {
    if (self.myRunLoopSource) {
        CFRunLoopSourceInvalidate(self.myRunLoopSource);
        CFRelease(self.myRunLoopSource);
    }
    if (self.myEventTap)
        CFRelease(self.myEventTap);
}

@end

This is my appDelegate and how I got it working.

import Cocoa
import CoreGraphics
import Foundation

var shift = false;
var cntrl = false;
var option = false;
var command = false;

func myCGEventCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, refcon: UnsafeMutableRawPointer?) -> Unmanaged<CGEvent>? {

    var mask: CGEventFlags = []
    if(shift) {
        mask.insert(CGEventFlags.maskShift)
     }
    if(cntrl) {
        mask.insert(CGEventFlags.maskControl)
     }
     if(option) {
         mask.insert(CGEventFlags.maskAlternate)
     }
    if(command) {
        mask.insert(CGEventFlags.maskCommand)
    }
    if(mask.rawValue != 0) {
        event.flags = mask;
    }

    return Unmanaged.passRetained(event)
}

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

func applicationDidFinishLaunching(_ aNotification: Notification) {

    // Insert code here to initialize your application
    let mask: CGEventMask = 1 << CGEventType.keyDown.rawValue
    let eventTap:CFMachPort = CGEvent.tapCreate(tap: .cghidEventTap, place: .headInsertEventTap, options: .defaultTap, eventsOfInterest: mask, callback: myCGEventCallback, userInfo: nil)!

    let runLoopSource:CFRunLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);

    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, CFRunLoopMode.commonModes);
    CGEvent.tapEnable(tap: eventTap, enable: true);

    CFRunLoopRun();
}

func applicationWillTerminate(_ aNotification: Notification) {
    // Insert code here to tear down your application
}

public func SetShift() {
    shift = !shift;
}
public func SetCtrl() {
    cntrl = !cntrl;
}
public func SetCommand() {
    command = !command;
}
public func SetOption() {
    option = !option;
}
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!