Почему перемещение `CFRunLoopRun ()` в метод приводит к тому, что обратный вызов tap не срабатывает? - PullRequest
0 голосов
/ 06 июля 2019

Следующий код (причудливо) завершается неудачно, когда я пытаюсь переместить CFRunLoopRun(); обратно в main.m:

// main.m
int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Remapper* remapper = [Remapper new];
        [remapper run];

        // CFRunLoopRun(); // <-- (1) If this is HERE ...
    }

    return 0;
}


@implementation Remapper
- (void) run {
    Intercept* intercept = [Intercept new];
    [intercept setup];

    CFRunLoopRun(); // (3) but if I put it here, tap_callback now DOES hit.
}


@implementation Intercept
- (void) setup {
    [self tapEvents];
    [self listen];
}

- (bool) tapEvents {
    modifiers = [NSEvent modifierFlags];

    if ( ! eventTap )
        eventTap = CGEventTapCreate( kCGHIDEventTap, ..., tap_callback, ... );

    CGEventTapEnable( eventTap, true );

    return CGEventTapIsEnabled( eventTap ); // (4) Note return value is always `true`
}

- (void) listen {
    if( ! runLoopSource ) {
        runLoopSource = CFMachPortCreateRunLoopSource( kCFAllocatorDefault, eventTap, 0 );

        CFRunLoopAddSource( CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes );
    }
}

CGEventRef tap_callback(...)
{
    // (2) This now won't hit! 
}

Пожалуйста, изучите (1) - (4).

Теперь, как это может иметь какое-то значение, выполняется ли CFRunLoopRun() в конце метода [remapper run] или на следующей строке на сайте вызова? Я не вижу возможности решить проблему с потоками.

Я просто не могу обдумать это.

...