Get Window Number from Keyboard Event Using addGlobalMonitorForEventsMatchingMask and addLocalMonitorForEventsMatchingMask (Objective-C)

I am using addGlobalMonitorForEventsMatchingMask and addLocalMonitorForEventsMatchingMask to monitor the global as well as local keyboard events by providing a mask as NSEventMaskKeyDown. As global event monitoring requires accessibility permission, I am providing that as well, but the window number I am getting from the NSEvent* passed to the monitor as an argument as 0 always. Also, the window object in the event object is null (0x0). I also tried to get the window number from the CGEvent object in the NSEvent object, and the window number is still 0. Please help me with where I am wrong.

This is my main file for a headless application: main.m

#import <Foundation/Foundation.h>
#include "keylogger.h"

int main(int argc, const char * argv[]) {
  @autoreleasepool {
    AppDelegate *delegate = [[AppDelegate alloc] init];

    NSApplication * application = [NSApplication sharedApplication];
    [application setDelegate:delegate];
    [NSApp run];
  }
}

Header file: keylogger.h

#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;

@end

File in which I am adding the monitors: keylogger.m

#import "keylogger.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
  [NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
                     handler:^(NSEvent *event) {
    NSLog(@"%lld", (long long)event.windowNumber);
  }];
  [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:^NSEvent * _Nullable(NSEvent *event) {
    NSLog(@"%lld", (long long)event.windowNumber);
    return event;
  }];
}

@end

Note: In order to run it, please create a command line tool application in Xcode.

I'm not sure why you would assume that a keyboard event has a window number. When you create a keyboard event with CGEventCreateKeyboardEvent, you don't specify a window or a mouse location. And the global event monitor may see events before applications have begun to dispatch them.

But according to the docs, it should have that. I am attaching the link for the same.

NSEvent windowNumber

If you do this using CGEventTap you can to specify where to place tap, which might give you more of the metadata you need. This has the added benefit that you can get off the Accessibility privilege and on to the much-easier-to-manage Input Monitoring privilege.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Get Window Number from Keyboard Event Using addGlobalMonitorForEventsMatchingMask and addLocalMonitorForEventsMatchingMask (Objective-C)
 
 
Q