Вопрос

Я использую кварц CGEVENTTAP в попытке глобально перехватить PAPSLOCK нажимать и блокировать их (чтобы они сделать что-то полезное вместо). Я успешно обнаружил PAPSLOCK PRESSES, но до сих пор не смогли их заблокировать. Мой код (исходящий из это Ответ стойки) - это то вроде этого:

eventTap = CGEventTapCreate(kCGHIDEventTap,
                            kCGTailAppendEventTap, 
                            kCGEventTapOptionDefault, 
                            eventMask,
                            myCGEventCallback,
                            &oldFlags);

runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);

CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);

CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef theEvent, void *refcon)
{
    CGEventFlags *oldFlags = (CGEventFlags *)refcon; 

    switch (type)
    {
        case kCGEventFlagsChanged:
        {
            CGEventFlags newFlags = CGEventGetFlags(theEvent);
            CGEventFlags changedFlags = *oldFlags ^ newFlags; 
            *oldFlags = newFlags;

            if (changedFlags == 65536)
            {
                NSLog(@"Capslock pressed. Let's not return the event");
                return NULL;
            }
            break;
        }
        default:
            break;
    }

    NSLog(@"Different modifier than capslock. Returning the event");
    return theEvent;
}

Если я пойму правильно возвращающуюся нулю, должен эффективно блокировать ключ от распространения. Действительно, это также делает для «нормальных» событий на кейпауп и доставку. Однако Capslock переключается независимо от. Есть идеи почему это? Я делаю неверные предположения? И / или как я могу делать вещи по-разному для достижения моей цели?

Спасибо,

Тора

Это было полезно?

Решение

Вы не можете блокировать так. CapsLock - это условие, которое обрабатывается драйвером клавиатуры, а не на Window Server или отдельные приложения. Событие KeyPress распространяется в OS X, как это:

Драйвер клавиатуры -> Window Server -> Сеанс пользователя -> Активное приложение

При каждом распространении уровня (указано «->»), вы можете поместить коснитесь событий и блокировать и / или изменять ключ событий. Драйвер клавиатуры и Window Server являются привилегированными компонентами, два других - обычные компоненты уровня пользователя.

Самым ранним вы можете поймать событие клавиатуры, это когда событие распространяется от драйвера (пространство ядра) к серверу окна (пользовательское пространство, но все равно привилегировано). Однако, как отмечалось выше, состояние CAPSLOLS обрабатывается внутри водителя, поэтому ловит событие, уже слишком поздно. Водитель уже позволит включить свету CAPSLOCK на клавиатуре (если это необходимо вообще и не выполнять аппаратное обеспечение самостоятельно) и вспомнил состояние CAPSLOCK, которое влияет на все будущие ключевые прессы.

Вы можете автоматически выключить свет CAPSLOCK для устройств HID (Apple имеет даже Пример кода для этого), но это не отключает Capslock, он просто выключает свет.

Единственный способ реализовать, что использование мероприятий - это вручную повторно записать каждое клавишную кнопку с помощью Capslock к ключевому прессу без CAPSLOCK (тот, где флаг Capslock не установлен, а прилагаемая буква, если таковая имеется, является строчным). Кроме того, чтобы не запутать пользователя, вы выключите свет CAPSLOCK, как показано примерным кодом Apple.

Другие альтернативы: напишите свой собственный драйвер клавиатуры, который требует контроля над клавиатурой вместо стандартного драйвера Apple (не так сильно, как вы думаете, но все еще сложно) или взломать путь к водителю (зло, но работает). Например, некоторые комбинации клавиатуры переопределяют только один методы драйвера (драйверы C ++ в OS X, таким образом, они являются OO-объектами, и вы можете динамически переопределять методы C ++ во время выполнения; не совсем переопределяют их, но достаточно манипулировать таблицами метода). Проблемы с этими двумя решениями являются: первое означает, что, если ваш водитель не так хорош, как один из Apple, некоторые клавиатуры USB могут не работать с вашим драйвером, в то время как другие делают, второй означает, что если вы делаете любую ошибку, Система наказывает эту ошибку с паникой ядра.

Я ищу себя на пути к программному переключению Capslock на Mac, без успеха до сих пор. Но я могу заверить вас, мероприятия не так, чтобы пойти.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top