CGEventCreateKeyboardEvent на рабочем столе против MacBook - PullRequest
0 голосов
/ 27 сентября 2010

Ола Фолкс,

Еще раз хочу выпить из пула знаний, которыми делятся люди, использующие SO.

Я написал небольшое приложение для OSX, которое отправляет ключевые события в приложение. Я ориентируюсь на OSX 10.5.x и новее. Однако проблема существует и при сборке 10.6.x. Все работает отлично, за исключением случаев, когда я посылаю только ключи-модификаторы; Alt, Command, Control и Shift.

Проблема в том, что на двух MacBook события для клавиш-модификаторов очищаются, как только тестеры перемещают курсор с помощью мыши или касаются сенсорной панели.

На рабочем столе с установленным XCode все работает нормально. Как и должно быть. На двух разных MacBook возникает проблема. К рабочему столу подключена стандартная клавиатура из 101 клавиши и многокнопочная мышь.
Когда мышь подключена к MacBook, используется двухкнопочная мышь с колесом прокрутки. Однако проблема существует, когда не подключены периферийные устройства и используется тачпад.

Я ожидаю, что событие Key Modifier будет отправлено целевому приложению, пользователь перемещает курсор с помощью мыши / сенсорной панели, нажимает кнопки на мыши / сенсорной панели и / или нажимает клавиши на клавиатуре с модификатором. событие нажатия клавиши «активно». Затем, когда они заканчивают, отправляется событие key up для клавиши-модификатора.

Вот как я посылаю события нажатия клавиш, клавиша Shift для этого примера:

case ModKeyShiftDown:
    xEventSource = CGEventSourceCreate(kCGEventSourceStatePrivate);
    xTheCommand = CGEventCreateKeyboardEvent(xEventSource, kVK_Shift, true);
    CGEventSetFlags(xTheCommand, kCGEventFlagMaskAlternate);
    CGEventPost(kCGHIDEventTap, xTheCommand);
    //CGEventPost(kCGSessionEventTap, xTheCommand);
    //CGEventPost(kCGAnnotatedSessionEventTap, xTheCommand);
    CFRelease(xTheCommand);
    CFRelease(xEventSource);
break;

Я использовал все три флага для создания источника события (kCGEventSourceStatePrivate, kCGEventSourceStateCombinedSessionState и kCGEventSourceStateHIDSystemState).

Я пытался создать событие клавиатуры с источником события, а также нулем в качестве первого параметра.

Я пробовал с и без соответствующих флажков на событии.

Я пробовал разные комбинации размещения события; kCGHIDEventTap, kCGSessionEventTap и kCGAnnotatedSessionEventTap.

Для полноты вот как я отправляю событие up для клавиши Shift:

case ModKeyShiftUp:
    xEventSource = CGEventSourceCreate(kCGEventSourceStatePrivate);
    xTheCommand = CGEventCreateKeyboardEvent(xEventSource, kVK_Shift, false);
    CGEventSetFlags(xTheCommand, 0);
    CGEventPost(kCGHIDEventTap, xTheCommand);
    //CGEventPost(kCGSessionEventTap, xTheCommand);
    //CGEventPost(kCGAnnotatedSessionEventTap, xTheCommand);
    CFRelease(xTheCommand);
    CFRelease(xEventSource);
break;

Когда тестеры запускают событие нажатия клавиши-модификатора, они могут видеть изменение курсора, как и ожидалось. Это позволяет мне знать, что событие обрабатывается целевым приложением. Однако, как только они касаются мыши или сенсорной панели, курсор возвращается к стандартному курсору, и события мыши обрабатываются так, как если бы не было активных событий клавиши-модификатора.

Я хотел бы знать, есть ли проблема с тем, как я отправляю события. Я также хотел бы знать, есть ли альтернативный способ отправки событий клавиши-модификатора, который собирается работать.

Извините, если я перебрал это. Я извиняюсь за то, что проспал только пару часов. : P

Thanx

-isdi-

1 Ответ

0 голосов
/ 28 сентября 2010

Ola,

Интересно, что использование AXUIElementRef и AXUIElementPostKeyboardEvent, похоже, работает.

По любой причине отправка ключевых событий с использованием объекта и метода Accessibility выше решает проблему для тестировщиков.

...