indianakernick / The-Fat-Controller

A library for simulating mouse and keyboard events
Apache License 2.0
39 stars 17 forks source link

Cannot press a key on Linux Wayland #6

Closed ValouBambou closed 1 year ago

ValouBambou commented 2 years ago

I'm trying to simply press a key with a minimal example :

use std::thread::sleep;
use std::time::Duration;
use tfc::{traits::KeyboardContext, Context, Key};

fn main() {
    println!("Hello, world!");
    let mut ctx = Context::new().unwrap();
    loop {
        sleep(Duration::from_secs(1));
        ctx.key_click(Key::A).unwrap();
        println!("A pressed");
    }
}

It runs without any error but the A key isn't pressed in practice when I open a text editor for example. I did the chmod +0666 /dev/uinput command but it still seems to do nothing. Any idea of what could be wrong ?

indianakernick commented 2 years ago

I'm really not sure about this one. This worked fine for me. /dev/uinput should work on any Linux distro because it's a part of the kernel. Does anything work or is it all broken? Are there any errors or warnings anywhere? Did following the other permission steps in the README have any effect?

ValouBambou commented 2 years ago

Ok I've tried the permanent solution and the line with udevadm control --reload-rules && udevadm trigger as root, but it's still doing nothing.

notewio commented 1 year ago

The minimal example only works within XWayland applications for me. I think it's because I'm using swaywm, and it sets $DISPLAY if XWayland is enabled, which looks like it's causing tfc to build the X11 version instead of the Wayland version.

That being said, even when forcing tfc to build the Wayland version it still doesn't work, I get this output & error:

Hello, world!
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Platform(XOpenDisplay)', src/main.rs:7:34
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
indianakernick commented 1 year ago

Ah. This is starting to make a bit more sense now. It seems that the code that checks for X11 doesn't work in all cases.

@notewio From the error message, it looks like you're still running the X11 code path. To force it one way or the other, update build.rs and then do a clean build. At some point I'll update that file to do more robust platform detection. Any further insights on the differences between the two would be appreciated!

notewio commented 1 year ago

Deleting the platform detection in build.rs gives a couple of compile errors:

error[E0308]: mismatched types
  --> The-Fat-Controller/src/command/execute.rs:62:23
   |
62 |             return Ok(true);
   |                       ^^^^ expected `()`, found `bool`

error[E0308]: mismatched types
  --> The-Fat-Controller/src/command/execute.rs:71:28
   |
71 |             _ => return Ok(false)
   |                            ^^^^^ expected `()`, found `bool`

warning: unreachable call
  --> The-Fat-Controller/src/command/execute.rs:66:9
   |
66 |            match self {
   |   _________^
   |  |_________|
   | ||
67 | ||             UnicodeCharDown(_) => panic!("UnicodeKeyboardContext is not implemented"),
68 | ||             UnicodeCharUp(_) => panic!("UnicodeKeyboardContext is not implemented"),
69 | ||             UnicodeChar(_) => panic!("UnicodeKeyboardContext is not implemented"),
70 | ||             UnicodeString(_) => panic!("UnicodeKeyboardContext is not implemented"),
71 | ||             _ => return Ok(false)
72 | ||         }?;
   | ||_________-^ unreachable call
   | |__________|
   |            any code following this `match` expression is unreachable, as all arms diverge
   |
   = note: `#[warn(unreachable_code)]` on by default

error[E0308]: mismatched types
  --> The-Fat-Controller/src/command/execute.rs:74:12
   |
74 |         Ok(true)
   |            ^^^^ expected `()`, found `bool`

error[E0308]: `?` operator has incompatible types
   --> The-Fat-Controller/src/command/execute.rs:141:12
    |
141 |         if self.execute_unicode(ctx)? {
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
    |
    = note: `?` operator cannot convert from `()` to `bool`

error[E0599]: no variant or associated item named `COUNT` found for enum `key::Key` in the current scope
   --> The-Fat-Controller/src/linux_wayland/mod.rs:40:33
    |
40  |         for k in 0..crate::Key::COUNT {
    |                                 ^^^^^ variant or associated item not found in `key::Key`
    |
   ::: The-Fat-Controller/src/enum.rs:110:9
    |
110 |         pub enum $name {
    |         -------------- variant or associated item `COUNT` not found here
    |
    = help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
    |
1   | use crate::r#enum::Enum;
    |

Some errors have detailed explanations: E0308, E0599.
For more information about an error, try `rustc --explain E0308`.
warning: `tfc` (lib) generated 1 warning
error: could not compile `tfc` due to 5 previous errors; 1 warning emitted

Not sure if the fixes I did for these were actually correct or not but the minimal example works now. I put my fixes in a fork here https://github.com/notewio/The-Fat-Controller

indianakernick commented 1 year ago

@notewio I had a look at your fork and tested it myself. Would you like to open a PR? There are some minor things I'd want you to change (primarily addressing the Clippy warnings). I have noticed that there are Clippy warnings in code that you didn't touch but don't worry about that.

indianakernick commented 1 year ago

Thanks to @notewio's contribution, this has been fixed in version 0.6.2.