enigo icon indicating copy to clipboard operation
enigo copied to clipboard

In some games, special keys can't be triggered

Open FurryWolfX opened this issue 2 years ago • 13 comments

Describe the bug A clear and concise description of what the bug is.

In some games, special keys can't be triggered.

To Reproduce Steps or a minimal code example to reproduce the behavior.

for example:

enigo.key_click(Key::LShift); 

But letters work fine:

enigo.key_click(Key::Layout('r')); 

Expected behavior A clear and concise description of what you expected to happen.

The game I tested was Guild Wars 2. LeftShift button bound to the skill, but it won't trigger. I want to be able to trigger skills properly.

Environment (please complete the following information):

  • OS: Windows 10 - Rust 1.73 - enigo 0.1.3

Additional context Add any other context about the problem here.

FurryWolfX avatar Oct 14 '23 14:10 FurryWolfX

Thank you for the report. You wrote "in some games" does that mean that in general it works? Also Windows makes a difference between Key::Shift, Key::LShift and Key::RShift. All these are different keys. The game might expect one of the other keys.

pentamassiv avatar Oct 14 '23 14:10 pentamassiv

Thank you for the report. You wrote "in some games" does that mean that in general it works? Also Windows makes a difference between Key::Shift, Key::LShift and Key::RShift. All these are different keys. The game might expect one of the other keys.

When I use the physical keyboard in the game, it all triggers the skills properly. But using enigo doesn't trigger it. F1-F12 can't be triggered either.

FurryWolfX avatar Oct 14 '23 14:10 FurryWolfX

Can you please open Notepad and then run this slightly changed example

use enigo::{Enigo, Key, KeyboardControllable};
use std::thread;
use std::time::Duration;

fn main() {
    thread::sleep(Duration::from_secs(2));
    let mut enigo = Enigo::new();

    // select all
    enigo.key_down(Key::LShift);
    println!("Press key");
    thread::sleep(Duration::from_secs(5));
    enigo.key_up(Key::LShift);
}

Please try to press a letter key on your physical keyboard during the 5 seconds the example sleeps. If the letter is capitalized, we know that the Shift key works in general. Then we know that there must be some special case with the game

pentamassiv avatar Oct 14 '23 14:10 pentamassiv

Can you please open Notepad and then run this slightly changed example

use enigo::{Enigo, Key, KeyboardControllable};
use std::thread;
use std::time::Duration;

fn main() {
    thread::sleep(Duration::from_secs(2));
    let mut enigo = Enigo::new();

    // select all
    enigo.key_down(Key::LShift);
    println!("Press key");
    thread::sleep(Duration::from_secs(5));
    enigo.key_up(Key::LShift);
}

Please try to press a letter key on your physical keyboard during the 5 seconds the example sleeps. If the letter is capitalized, we know that the Shift key works in general. Then we know that there must be some special case with the game

It works fine in Notepad and other editors. But not in Guild Wars 2, I don't know why.

FurryWolfX avatar Oct 14 '23 14:10 FurryWolfX

Okay, thank you. That helps already to narrow it down. I probably need some time for this to investigate the issue.

pentamassiv avatar Oct 14 '23 14:10 pentamassiv

And in-game chatting also works, just not when binding skills.

FurryWolfX avatar Oct 14 '23 14:10 FurryWolfX

Maybe the old API to simulate input will work. Could you please try this changed example:

use enigo::{Enigo, Key, KeyboardControllable};
use std::thread;
use std::time::Duration;
use windows::Win32::UI::Input::KeyboardAndMouse::{KEYBD_EVENT_FLAGS, KEYEVENTF_KEYUP, VK_LSHIFT};

fn main() {
    thread::sleep(Duration::from_secs(2));
    let mut enigo = Enigo::new();

    // Simulate a key press
    unsafe {
        windows::Win32::UI::Input::KeyboardAndMouse::keybd_event(
            VK_LSHIFT.0 as u8,
            0,
            KEYBD_EVENT_FLAGS::default(),
            0,
        )
    };
    thread::sleep(Duration::from_millis(20));

    // Press other key (Change this if you'd like)
    enigo.key_click(Key::Layout('a'));

    // Simulate a key release
    thread::sleep(Duration::from_millis(20));
    unsafe {
        windows::Win32::UI::Input::KeyboardAndMouse::keybd_event(
            VK_LSHIFT.0 as u8,
            0,
            KEYEVENTF_KEYUP,
            0,
        )
    };
}

I don't know which other keys you want to press in order to see if Key::LShift works. Feel free to change this part of the example:

   // Press other key (Change this if you'd like)
   enigo.key_click(Key::Layout('a'));

pentamassiv avatar Oct 14 '23 15:10 pentamassiv

Maybe the old API to simulate input will work. Could you please try this changed example:

use enigo::{Enigo, Key, KeyboardControllable};
use std::thread;
use std::time::Duration;
use windows::Win32::UI::Input::KeyboardAndMouse::{KEYBD_EVENT_FLAGS, KEYEVENTF_KEYUP, VK_LSHIFT};

fn main() {
    thread::sleep(Duration::from_secs(2));
    let mut enigo = Enigo::new();

    // Simulate a key press
    unsafe {
        windows::Win32::UI::Input::KeyboardAndMouse::keybd_event(
            VK_LSHIFT.0 as u8,
            0,
            KEYBD_EVENT_FLAGS::default(),
            0,
        )
    };
    thread::sleep(Duration::from_millis(20));

    // Press other key (Change this if you'd like)
    enigo.key_click(Key::Layout('a'));

    // Simulate a key release
    thread::sleep(Duration::from_millis(20));
    unsafe {
        windows::Win32::UI::Input::KeyboardAndMouse::keybd_event(
            VK_LSHIFT.0 as u8,
            0,
            KEYEVENTF_KEYUP,
            0,
        )
    };
}

I don't know which other keys you want to press in order to see if Key::LShift works. Feel free to change this part of the example:

   // Press other key (Change this if you'd like)
   enigo.key_click(Key::Layout('a'));

This example also does not trigger any skills that are tied to special keys (Shift and F1-F12 etc...)

I tried to simulate it using Python's Keyboard module and it works fine.

FurryWolfX avatar Oct 15 '23 08:10 FurryWolfX

Okay, thank you for trying it out. Back to the drawing board :/

pentamassiv avatar Oct 15 '23 17:10 pentamassiv

The same issue occurs with the game "Star Citizen"

pentamassiv avatar Nov 25 '23 11:11 pentamassiv

Apparently it is best to send both, the scan code and the virtual key, in order for all programs to register the key input properly (e.g something like this https://github.com/Narsil/rdev/pull/113/files). Maybe that would solve this issue as well

pentamassiv avatar Apr 18 '24 17:04 pentamassiv

I created https://github.com/enigo-rs/enigo/pull/280, which might address this issue. It would be great if you could test it to see if it fixes it.

pentamassiv avatar Apr 19 '24 10:04 pentamassiv

Same issue with Ctrl F1

Aunmag avatar May 29 '24 21:05 Aunmag

I also was having issues with controlling games on Windows 10 as well with enigo v0.2.1. Certain keys such as Space and Shift were not working, but others were working such as WASD.

I tried out your PR @pentamassiv in my Cargo.toml using enigo = { git = "https://github.com/enigo-rs/enigo.git", rev = "a204717" } and for my use case it solves all the problems. I haven't found any regressions in my case.

Thank you for the fix! I am looking forward to its release.

zardini123 avatar Jul 27 '24 04:07 zardini123

That's great to hear, thank you for testing it. I will merge it within the next week and publish a new version :-)

pentamassiv avatar Aug 01 '24 16:08 pentamassiv