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

Held keys do not repeat #98

Open
haata opened this issue Nov 7, 2020 · 1 comment
Open

Held keys do not repeat #98

haata opened this issue Nov 7, 2020 · 1 comment
Labels
bug macOS macOS specific needs investigation Windows windows specific

Comments

@haata
Copy link

haata commented Nov 7, 2020

Describe the bug
examples/key.rs
Holds the a key for 1 second. On Windows and macOS the key only types/prints once.
(I've been looking through the macOS API for a way to do this; haven't found one. Still need to go through winapi. It's definitely possible with X11)

To Reproduce
Run key.rs example, increase timeout to 5 seconds if your OS settings are set for a slow repeat rate start.

Expected behavior
The most recently held key should repeat after an OS (or internal) hold-off time and at a repeat rate interval defined by either the OS (or internal).

Environment (please complete the following information):

Additional context
I think this may be a limitation of the the text input APIs on macOS (and possibly Windows). X11 is composed through fake keypresses (I dynamically assign unicode to unused keycodes and then release them afterwards if the UTF-8 symbol isn't already in the layout).
My goal is a bit different than automation, I'm actually writing a Unicode plugin/driver for a programmable keyboard such that the keyboard can map a specific UTF-8 symbol (or string of text) to a key which is then sent to the host and outputted through a daemon of sorts. Since keys can be held, repeating the keys just like standard keypresses is rather important. Latency is also rather important so I have to make sure there's no notable different between UTF-8 symbols and normal keypresses (how they are handled in things like games will probably be "there be dragons", this is mostly for general text use).

(worst case I can emulate it with some thread scheduling and querying of OS timings)
(I also have to get around to Wayland, so I'll share my findings once I give it a good try).

@indianakernick
Copy link

From what I can tell on the macOS side of things, you'll need to generate multiple key down events if you want the key to repeat. For repeated key downs, you should increment kCGKeyboardEventAutorepeat each time there's a repeat. So 0 for the first key down, then 1, then 2, for each repeated key down. Then finally a single key up.

That might look something like this. If you call key_click_4 with 42, you'll get 4 backslashes. If you call it with 14, you'll get a single e and the accent menu.

use core_graphics::event::{CGEvent, CGEventTapLocation, CGKeyCode, EventField};

impl Enigo {
    fn key_event_repeat(&mut self, key: CGKeyCode, repeat: i64, down: bool) {
        let event = CGEvent::new_keyboard_event(self.event_source.clone(), key, down).unwrap();
        event.set_integer_value_field(EventField::KEYBOARD_EVENT_AUTOREPEAT, repeat);
        event.post(CGEventTapLocation::HID);
    }
    
    // This doesn't work if you create the events too close together, hence the delays.
    pub fn key_click_4(&mut self, key: CGKeyCode) {
        self.key_event_repeat(key, 0, true);
        std::thread::sleep(std::time::Duration::from_millis(20));
        self.key_event_repeat(key, 1, true);
        std::thread::sleep(std::time::Duration::from_millis(20));
        self.key_event_repeat(key, 2, true);
        std::thread::sleep(std::time::Duration::from_millis(20));
        self.key_event_repeat(key, 3, true);
        std::thread::sleep(std::time::Duration::from_millis(20));
        self.key_event_repeat(key, 0, false);
    }
}

This of course means that it's up to you to do the timing logic to work out when a key repeat is necessary. I have no idea what you'll have to do for the other platforms.

Also, for most keys it seems like key repeat is disabled. See this thread. Holding down some letters like A or E will show the accent menu instead of repeating. Even though only a handful of keys have an accent menu, they've disabled key repeat for all letters.

@pentamassiv pentamassiv added Windows windows specific macOS macOS specific labels Feb 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug macOS macOS specific needs investigation Windows windows specific
Projects
None yet
Development

No branches or pull requests

3 participants