Какао Виртуальная боль при нажатии клавиш - PullRequest
1 голос
/ 19 апреля 2010

Я пишу приложение для ответа на горячую клавишу, копируя выделенный текст в общую панель NSPasteboard. Посмотрев здесь решение для отправки виртуальных нажатий клавиш, я обнаружил следующее: Как отправить нажатие клавиши "Cmd-C" в активное приложение в target-c или указать приложению выполнить операцию копирования? *

Я попробовал яблочный скрипт, предложенный с NSAppleScript:

NSLog(@"Hotkey Pressed");
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; 

NSAppleScript *playScript;
playScript = [[NSAppleScript alloc] initWithSource:@"tell application \"System Events\" to keystroke \"c\" using command down"];

if([playScript isCompiled] == NO){
[playScript compileAndReturnError:nil];
}

id exerror = [playScript executeAndReturnError:nil];

if(exerror == nil){
 NSLog(@"Script Failed");
}

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

 Pastify[16929:a0b] woooooooo! I'm being CALLED
 Pastify[16929:a0b] Hotkey Pressed
 Pastify[16929:a0b] Error loading /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types:  dlopen(/Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types, 262): no suitable image found.  Did find:
    /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types: no matching architecture in universal wrapper
 Pastify: OpenScripting.framework - scripting addition "/Library/ScriptingAdditions/Adobe Unit Types.osax" declares no loadable handlers.
 Pastify[16929:a0b] Size of copiedItems: 1
 Pastify[16929:a0b] Content of paste: 2010-04-19 03:41:04.355 Pastify[16929:a0b] woooooooo! I'm being CALLED
 Pastify[16929:a0b] Hotkey Pressed
 Pastify[16929:a0b] Size of copiedItems: 1
 Pastify[16929:a0b] Content of paste: 2010-04-19 03:41:04.355 Pastify[16929:a0b] woooooooo! I'm being CALLED
 Pastify[16929:a0b] Hotkey Pressed
 Pastify[16929:a0b] Size of copiedItems: 1
 Pastify[16929:a0b] Content of paste: 2010-04-19 03:41:04.355 Pastify[16929:a0b] woooooooo! I'm being CALLED

Итак, я попробовал следующее предлагаемое решение:

 CFRelease(CGEventCreate(NULL));

 CGEventRef event1, event2, event3, event4;
 event1 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)50, true);
 event2 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)8, true);
 event3 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)8, false);
 event4 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)50, false);

 CGEventPost(kCGHIDEventTap, event1);
 CGEventPost(kCGHIDEventTap, event2);
 CGEventPost(kCGHIDEventTap, event3);
 CGEventPost(kCGHIDEventTap, event4);

Вышеприведенное должно послать нажатия клавиш Command + c, но все, что я получаю, это звуковой сигнал, и содержимое картона остается неизменным.

Я в конце концов - может кто-нибудь просветить меня о том, что я скучаю, или указать мне на то, что я упускаю из виду что-то такое простое?

Ответы [ 3 ]

1 голос
/ 19 апреля 2010

Есть ли причина, по которой вы не можете использовать услугу для этого?

Если вы действительно хотите сделать это путем синтеза событий, лучше всего публиковать измененное событие клавиатуры, а не вниз / вверх - см. Этот вопрос для получения дополнительной информации.

Имитация событий нажатия клавиш в Mac OS X

Если это не сработает, вы знаете, где меня найти: -)

1 голос
/ 19 апреля 2010

Просто мысль ... трюк cmd-c работает на самом переднем приложении. Я подозреваю, что в первый раз, когда вы запускаете горячую клавишу, чтобы вызвать это, что надлежащее приложение находится на переднем крае, cmd-c работает, тогда ваше приложение что-то делает с монтажным столом. При втором запуске горячая клавиша активируется, но предыдущее приложение больше не является передним, поэтому cmd-c не работает. По сути, вы отправляете cmd-c в другое приложение. Возможно, ваша заявка поступила на фронт или какой-то другой.

Чтобы избежать этой проблемы, вы должны убедиться, что приложение, на которое вы нацеливаетесь, находится впереди. Итак, сначала вам нужно каким-то образом выяснить, какое приложение является передним, а затем непосредственно перед тем, как выполнить cmd-c, активировать это приложение. Например, в appleScript, если бы я хотел запустить cmd-c в Safari, я бы использовал:

tell application "Safari" to activate
tell application "System Events" to keystroke "c" using command down
0 голосов
/ 19 апреля 2010

Я действительно не понимаю, зачем вы это делаете, но если вы хотите, чтобы ваши события перешли к определенному процессу, используйте вариант «ToPSN» CGEventPost.

...