キーボードのキーを押すイベントとキーを離すイベントを送信しています。これは、すべてのキーボード キーで機能します。
ただし、修飾キーは、修飾キーに関連付けられたキーがアプリケーションから送信された場合にのみ機能し、実際のハードウェアからは送信されません。つまり、アプリケーションから Shift と 'a' を送信すると、'A' (大文字の A、これが期待されます) が出力されます。
しかし、アプリケーションから「シフト」キーダウンイベントを送信し、物理キーボードから「a」を入力すると、「a」が出力されます (シフトキーは異なるデバイス間で機能していないようです)。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);
}
どちらの方法も、アプリケーションから修飾キーと組み合わせキーが送信された場合は機能しますが、アプリケーションから修飾キーのみが設定された場合は機能しません。