4 Replies
      Latest reply on Sep 14, 2019 2:14 PM by nemike
      alvarof Level 1 Level 1 (0 points)

        On MacOSX 10.14 (Mojave) the behavior changed, the following code runs on 10.13 but fail on 10.14.

        The creation of "CGEventTapCreate" is failing (returning null) on Mojave but works before.

         

        Any thoughts? Thanks in advance!

         

        // alterkeys.c
        // http://osxbook.com
        //
        // Complile using the following command line:
        //     clang -Wall -o alterkeys alterkeys.c -framework ApplicationServices
        //
        
        
        #include <ApplicationServices/ApplicationServices.h>
        
        
        // This callback will be invoked every time there is a keystroke.
        //
        CGEventRef
        myCGEventCallback(CGEventTapProxy proxy, CGEventType type,
                          CGEventRef event, void *refcon)
        {
            // Paranoid sanity check.
            if ((type != kCGEventKeyDown) && (type != kCGEventKeyUp))
                return event;
        
        
            // The incoming keycode.
            CGKeyCode keycode = (CGKeyCode)CGEventGetIntegerValueField(
                                               event, kCGKeyboardEventKeycode);
        
        
            // Swap 'a' (keycode=0) and 'z' (keycode=6).
            if (keycode == (CGKeyCode)0)
                keycode = (CGKeyCode)6;
            else if (keycode == (CGKeyCode)6)
                keycode = (CGKeyCode)0;
        
        
            // Set the modified keycode field in the event.
            CGEventSetIntegerValueField(
                event, kCGKeyboardEventKeycode, (int64_t)keycode);
        
        
            // We must return the event for it to be useful.
            return event;
        }
        
        
        int
        main(void)
        {
            CGEventMask eventMask = CGEventMaskBit(kCGEventLeftMouseDown) |
                           CGEventMaskBit(kCGEventLeftMouseUp);
            CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, 0,
                                        eventMask, myCGEventCallback, NULL);
            if (!eventTap) {
                fprintf(stderr, "failed to create event tap\n");
                exit(1);
            }
        
        
            // Create a run loop source.
            CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(
                                kCFAllocatorDefault, eventTap, 0);
        
        
            // Add to the current run loop.
            CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
                               kCFRunLoopCommonModes);
        
        
            // Enable the event tap.
            CGEventTapEnable(eventTap, true);
        
        
            // Set it all running.
            CFRunLoopRun();
        
        
            // In a real program, one would have arranged for cleaning up.
        
        
            exit(0);
        }
        
        • Re: CGEventTapCreate fail on Mojave (10.14)
          tsts123 Level 1 Level 1 (0 points)

          Got this working after some fighting. Add this to your info.plist:

           

            <key>NSAppleEventsUsageDescription</key>

            <string></string>

           

          Then go to your system preferences -> security -> privacy -> accessibility, and ensure your app is there and checked. If it's already there and this keeps happening, remove it and add it again. I have to do this every time I rebuild my app

            • Re: CGEventTapCreate fail on Mojave (10.14)
              alvarof Level 1 Level 1 (0 points)

              Thanks tsts123!

               

              Do you know if there is a way to automatically add to the accessibility? Something like the first run, or during installation?

              • Re: CGEventTapCreate fail on Mojave (10.14)
                nemike Level 1 Level 1 (0 points)

                I just upgraded to Mojave (many reasons why it took this long but I'm there now)  And I'm struggling with the same kind of problem, I've tried your workaround of editing my Info.plist but that hasn't worked for me.  Does your application require running as root?  In the past (like high sierra etc) the only way I could get CGEventTapCreate to succeed was to run my application as root.  If your app doesn't require root how are you working around that???

                 

                Here is my Info.plist

                 

                <?xml version="1.0" encoding="UTF-8"?>

                <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

                <plist version="1.0">

                <dict>

                    <key>CFBundleDevelopmentRegion</key>

                    <string>English</string>

                    <key>CFBundleExecutable</key>

                    <string>MacPwdMgr</string>

                    <key>CFBundleIconFile</key>

                    <string>padlock</string>

                    <key>CFBundleIdentifier</key>

                    <string>com.xxxx.MacPwdMgr</string>

                    <key>CFBundleInfoDictionaryVersion</key>

                    <string>6.0</string>

                    <key>CFBundlePackageType</key>

                    <string>APPL</string>

                    <key>CFBundleSignature</key>

                    <string>????</string>

                    <key>NSAppleEventsUsageDescription</key>

                    <string></string>

                    <key>CFBundleURLTypes</key>

                    <array>

                        <dict>

                            <key>CFBundleURLSchemes</key>

                            <array>

                                <string>tel</string>

                                <string>sip</string>

                            </array>

                        </dict>

                    </array>

                    <key>CFBundleVersion</key>

                    <string>1.0</string>

                    <key>NSAppTransportSecurity</key>

                    <dict>

                        <key>NSAllowsArbitraryLoads</key>

                        <true/>

                        <key>NSExceptionDomains</key>

                        <dict>

                            <key>xxxx.com</key>

                            <dict>

                                <key>NSExceptionAllowsInsecureHTTPLoads</key>

                                <true/>

                                <key>NSIncludesSubdomains</key>

                                <true/>

                            </dict>

                        </dict>

                    </dict>

                    <key>NSAppleScriptEnabled</key>

                    <string>YES</string>

                    <key>NSMainNibFile</key>

                    <string>MainMenu</string>

                    <key>NSPrincipalClass</key>

                    <string>NSApplication</string>

                    <key>NSUIElement</key>

                    <string>1</string>

                </dict>

                </plist>

                  • Re: CGEventTapCreate fail on Mojave (10.14)
                    nemike Level 1 Level 1 (0 points)

                    In the past I had to run as root (high sierra), but I guess I failed to try to run as myself once I made the above changes.  Can't say if I needed the plist.info change or not but it does work now if I run it as myself and it's in the accessibility app list.

                     

                    Thanks everyone!