以编程方式模拟 Home 之后的粘性 Fn,MacOS

问题描述 投票:0回答:1

当我尝试在 MacOS 上以编程方式模拟按键时。 我发现有些按键会导致“Fn”粘滞。

以下代码结果为“Fn”+“h”。 谁能帮忙解释一下这是否是故意的?

#include <stdio.h>
#include <Carbon/Carbon.h>

void simulate_key(CGEventSourceRef source, CGKeyCode key, bool key_down)
{
    CGEventRef event = CGEventCreateKeyboardEvent(source, key, key_down);
    CGEventPost(kCGSessionEventTap, event);
    CFRelease(event);
    sleep(1);
}

void print33(void) {
    CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStatePrivate);
    
    printf("simulate #: ");
    fflush(stdout);
    simulate_key(source, kVK_Shift, true);
    simulate_key(source, kVK_ANSI_3, true);
    simulate_key(source, kVK_ANSI_3, false);
    simulate_key(source, kVK_Shift, false);
    
    // sticky Fn, after clicking Home.
    simulate_key(source, kVK_Home, true);
    simulate_key(source, kVK_Home, false);
    
    printf("\nSimulate h after Home.\n");
    fflush(stdout);
    
    // Simulate h. The behavior seems Fn + h.
    simulate_key(source, kVK_ANSI_H, true);
    simulate_key(source, kVK_ANSI_H, false);
    
    // So as simulating e and d...
    
    CFRelease(source);
}

int main(int argc, const char * argv[]) {
    print33();
    return 0;
}

我也尝试过打印

CGEventFlags
。显示
kCGEventFlagMaskSecondaryFn
已设置。但不知道是不是有副作用。当我只是模拟
Fn
键时,如何防止设置
Home
标志。

#include <stdio.h>
#include <Carbon/Carbon.h>

void simulate_key(CGEventSourceRef source, CGKeyCode key, bool key_down)
{
    CGEventRef event = CGEventCreateKeyboardEvent(source, key, key_down);
    // CGEventSetFlags(event, 0);
    CGEventFlags flags = CGEventGetFlags(event);
    printf("event flags: %llX\n", (int64_t)flags);
    CGEventPost(kCGSessionEventTap, event);
    CFRelease(event);
    sleep(1);
}

void print33(void) {
    CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStatePrivate);
    
//    printf("simulate #: ");
//    fflush(stdout);
//    simulate_key(source, kVK_Shift, true);
//    simulate_key(source, kVK_ANSI_3, true);
//    simulate_key(source, kVK_ANSI_3, false);
//    simulate_key(source, kVK_Shift, false);
    
    printf("kCGEventFlagMaskAlphaShift: %llX\n", (int64_t)kCGEventFlagMaskAlphaShift);
    printf("kCGEventFlagMaskShift: %llX\n", (int64_t)kCGEventFlagMaskShift);
    printf("kCGEventFlagMaskControl: %llX\n", (int64_t)kCGEventFlagMaskControl);
    printf("kCGEventFlagMaskAlternate: %llX\n", (int64_t)kCGEventFlagMaskAlternate);
    printf("kCGEventFlagMaskCommand: %llX\n", (int64_t)kCGEventFlagMaskCommand);
    printf("kCGEventFlagMaskHelp: %llX\n", (int64_t)kCGEventFlagMaskHelp);
    printf("kCGEventFlagMaskSecondaryFn: %llX\n", (int64_t)kCGEventFlagMaskSecondaryFn);
    printf("kCGEventFlagMaskNumericPad: %llX\n", (int64_t)kCGEventFlagMaskNumericPad);
    printf("kCGEventFlagMaskNonCoalesced: %llX\n", (int64_t)kCGEventFlagMaskNonCoalesced);
    
    // sticky Fn, after clicking Home.
    simulate_key(source, kVK_Home, true);
    simulate_key(source, kVK_Home, false);
    
    printf("\n\nSimulate h after Home.\n");
    fflush(stdout);
    
    // simulate_key(source, kVK_Shift, true);
    
    // Simulate h. The behavior seems Fn + h.
    simulate_key(source, kVK_ANSI_H, true);
    simulate_key(source, kVK_ANSI_H, false);
    
    // simulate_key(source, kVK_Shift, false);
    
    // So as simulating e and d...
    
    CFRelease(source);
}

int main(int argc, const char * argv[]) {
//    UInt8 keyboard_type = LMGetKbdType();
//    unsigned int layout_type = KBGetLayoutType(keyboard_type);
//    printf("LMGetKbdType(): %d, KBGetLayoutType(): %d\n", keyboard_type, layout_type);
    
    print33();
    return 0;
}
c macos keyboard simulation sticky
1个回答
0
投票

我也遇到了同样的问题。并且您在研究过程中走向了正确的方向(检查是否设置了

kCGEventFlagMaskSecondaryFn
标志)。 所以解决方案是确保在调用之前没有设置任何标志
CGEventPost(kCGSessionEventTap, event);

只需在

CGEventPost
调用之前添加一行:
CGEventSetFlags(event, 0);
之后它会按预期工作。

CGEventRef event = CGEventCreateKeyboardEvent(source, key, key_down);
CGEventSetFlags(event, 0);
CGEventPost(kCGSessionEventTap, event);
CFRelease(event);
© www.soinside.com 2019 - 2024. All rights reserved.