Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remap a keyboard key as a left mouse button unable to register a double click #176

Open
dedisuryadi opened this issue Sep 12, 2023 · 1 comment

Comments

@dedisuryadi
Copy link

Hello,

First, I want to say thank you for this library. I'm currently trying to remap a button (the F20 key in my case) to mimic the behavior of a left mouse button. It's working wonderfully; I can click, block, drag, and drop. However, I'm facing an issue with dispatching double clicks (no text is selected if I try to double click on a text).

Could anyone provide any pointers on how to achieve this? By the way, I'm using an M1 Mac running Monterey, and I'm unable to use Karabiner-Elements due to a specific reason. I've attached the dispatch function for reference.

Thank you very much

void dispatch_proc(uiohook_event * const event) {
    mev = (uiohook_event *) malloc(sizeof(uiohook_event));
    mev->data.mouse.x = x;
    mev->data.mouse.y = y;
    mev->data.mouse.button = MOUSE_BUTTON1;

    // Grab the event timestamp for use later
    uint64_t timestamp = (uint64_t) event->time;

    switch (event->type) {
        case EVENT_KEY_PRESSED:
            if (event->data.keyboard.keycode == VC_F20) {
                event->reserved = 0x1; // stop F20 propagation

                // Track the number of clicks.
                if (ispressed == 0 && (long int) (timestamp - click_time) / 1000000 <= hook_get_multi_click_time()) {
                    if (click_count < USHRT_MAX) {
                        click_count++;
                    }
                } else {
                    // Reset the click count.
                    click_count = 1;
                }

                // Save this events time to calculate the click_count.
                click_time = timestamp;

                if (ispressed == 0) {
                    mev->type = EVENT_MOUSE_PRESSED;
                    fprintf(stdout, "%s - %d\n", "key as pressed", click_count);
                } else {
                    mev->type = EVENT_MOUSE_MOVED;
                    mev->data.mouse.button = MOUSE_NOBUTTON;
                    fprintf(stdout, "%s - %d\n", "key as moved", click_count);
                };

                ispressed = 1;
                hook_post_event(mev);
            }
            break;

        case EVENT_KEY_RELEASED:
            if (event->data.keyboard.keycode == VC_F20) {
                event->reserved = 0x1; // stop F20 propagation

                if ((long int) (timestamp - click_time) / 1000000 > hook_get_multi_click_time()) {
                    if (click_count > 1) {
                        mev->type = EVENT_MOUSE_CLICKED;
                        mev->data.mouse.clicks = click_count;
                        hook_post_event(mev);
                    }

                    // Reset the click count.
                    click_count = 0;

                } else {
                    mev->type = EVENT_MOUSE_RELEASED;
                    fprintf(stdout, "%s - %d\n", "key released", click_count);

                    hook_post_event(mev);
                    ispressed = 0;
                }
            }
            break;

        case EVENT_MOUSE_PRESSED:
        case EVENT_MOUSE_RELEASED:
        case EVENT_MOUSE_CLICKED:
            fprintf(stdout, "%s - %d\n", "got clicked", event->data.mouse.clicks);
        case EVENT_MOUSE_MOVED:
        case EVENT_MOUSE_WHEEL:
        case EVENT_MOUSE_DRAGGED:
                x = event->data.mouse.x;
                y = event->data.mouse.y;
            break;

        default:
            break;
    }

    free(mev);
}
@TolikPylypchuk
Copy link
Contributor

@kwhat This behavior is actually a macOS quirk that's not addressed in libuiohook - macOS requires setting kCGMouseEventClickState on the event that's posted if the click count is more than 1. It doesn't do any timing checks.

libuiohook doesn't take event->data.mouse.clicks into consideration when posting an event on macOS, but it should do something like that:

if (event->data.mouse.clicks != 0) {
    CGEventSetIntegerValueField(cg_event, kCGMouseEventClickState, event->data.mouse.clicks);
}

Whether it should be provided manually when posting an event, or calculating automatically using the OS multi-click time is another question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants