Я посылаю нажатия клавиш клавиатуры и нажатия клавиш, которые работают для всех клавиш клавиатуры.Эмуляция/отправка ключа модификатора (Cntrl, Alt, fn, Shift) в OSx
Но ключи-модификаторы работают только тогда, когда ключ, связанный с ключом-модификатором, отправляется из приложения, а не из реального оборудования. То есть, если я отправлю Shift и «a» из приложения, он печатает «A» (капитал A, это то, что ожидается).
Но если я отправил событие «смена» из приложения и введите «a» с физической клавиатуры, он напечатает «a» (клавиша shift не работает на разных устройствах). То же самое относится к другим клавишам-модификаторам, таким как клавиши cmd, alt и fn !.
Есть ли способ отправить ключи-модификаторы в систему, чтобы я мог эмулировать ключи-модификаторы из моего приложения ?. В частности, Я хотел бы активировать ключ-модификатор из приложения и ввести комбинационный ключ с физической клавиатуры.
Вот код, который я использую для отправки ключевых событий нажатия и выпуска.
- (void)setADBKey:(uint32)key value:(int)value
{
if (!eventSource)
{
eventSource = CGEventSourceCreate(kCGEventSourceStatePrivate);
}
CGEventRef event = CGEventCreateKeyboardEvent(eventSource, key, value!=0);
CGEventPost(kCGHIDEventTap, event);
CFRelease(event);
}
Я также попытался создать и отправить системное событие, через следующий код
struct
{
CGKeyCode keyCode;
int flag;
int cgEventFlag;
} modifiers[] = {
{ 56, NX_DEVICELSHIFTKEYMASK, kCGEventFlagMaskShift },
{ 60, NX_DEVICERSHIFTKEYMASK, kCGEventFlagMaskShift },
{ 59, NX_DEVICELCTLKEYMASK, kCGEventFlagMaskControl },
{ 58, NX_DEVICELALTKEYMASK, kCGEventFlagMaskAlternate },
{ 61, NX_DEVICERALTKEYMASK, kCGEventFlagMaskAlternate },
{ 55, NX_DEVICELCMDKEYMASK, kCGEventFlagMaskCommand },
{ 54, NX_DEVICERCMDKEYMASK, kCGEventFlagMaskCommand }
};
- (void)setAdbKey:(uint32)adbkey value:(int)value repeat:(BOOL)repeat
{
//int adbkey = def_usb_2_adb_keymap[hidkey];
int modifier = 0;
for(int i=0; i< ARR_SIZE(modifiers); i++)
{
if (adbkey == modifiers[i].keyCode)
{
modifier = modifiers[i].cgEventFlag;
break;
}
}
if (value)
{
flags |= modifier;
}
else
{
flags &= ~modifier;
}
CGEventRef event = CGEventCreateKeyboardEvent(eventSource, adbkey, value!=0);
if (repeat)
{
CGEventSetIntegerValueField(event, kCGKeyboardEventAutorepeat, (int64_t)1);
}
// don't apply modifier flags to a modifier
if (!modifier)
{
CGEventSetFlags(event, flags);
}
CGEventPost(kCGHIDEventTap, event);
CFRelease(event);
}
Оба метода работают, когда клавиша-модификатор и комбинации клавиш посылаются от приложения, но не тогда, когда клавиша-модификатор в одиночку набор из приложения.
Вместо того чтобы создать источник событий с 'kCGEventSourceStatePrivate', вы пробовали' kCGEventSourceStateCombinedSessionState' или 'kCGEventSourceStateHIDSystemState'? –