AntiMicroX / antimicrox

Graphical program used to map keyboard buttons and mouse controls to a gamepad. Useful for playing games with no gamepad support.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Wayland support for keyboard emulation

gombosg opened this issue · comments

Is your feature request related to a problem? Please describe.
Should support KB emulation in wayland.

Describe the solution you'd like
Dunno yet.

Additional context
GUI works fine, tested in a Wayland Fedora VM.

Got this in a PM on reddit:

It probably runs because of Qt but I don't think mouse and keyboard control would work. I would ask sway developers https://github.com/swaywm/wlroots about what protocols you need to use.
They are very helpful they have even opened MRs for some projects, to port them to wayland. You could just implement it for wlroots and let the community do the rest for you after. For example some wlroots focused tools will work in KDE Plasma soon because of the same protocols being implemented there.
"We hang out in #sway-devel, an IRC channel on irc.freenode.net. Come in and ask questions."

EDIT:
It can be done via switching from xtest to uinput, but uinput requires either root or aditional udev rule
TODO list:

  • switch from xtest to uinput when wayland session is detected #186
  • integrate adding new udev rules into installation process
  • update readme

Maybe in this case XWayland could be used. 🤔

XWayland is always running as a separate (compositor) process in these wayland sessions and it's used automatically.
Let's find where and how the KB/mouse events are being sent to the OS and ask on IRC. 🙂

As I see it uses these to simulate events:

[cmake] XTest support allowed for simulating events.
[cmake] uinput support allowed for simulating events.

So there are two questions that come to my mind:

  • Is there a way to make this into a native wayland QT app?
  • Is there something wrong/wayland-incompatible about I/O?

As I see we have UInputEventHandler::sendKeyboardEvent() and its friends, plus XTestEventHandler::sendKeyboardEvent() and its friends.

My question was which one takes precedence.
When I started: Using Event Handler: XTest, both in VM and local machine.

I tried antimicrox --eventgen uinput, that worked under X11 but not in Wayland (still I saw XTest, guess it fell back to XTest for some reason).

Enabling uinput would be the key here, guessing from this SO.

Oh, let's see this with debug log level.

[gombosg@localhost-live Downloads]$ antimicrox --eventgen uinput --log-level debug
Warning: QObject::connect: No such signal QPlatformNativeInterface::systemTrayWindowChanged(QScreen*) ((null):0, (null))
[01:42:31.481] - Could not open uinput device file
Please check that you have permission to write to the device
/dev/uinput
[01:42:31.481] - Attempting to use fallback option Xtest for event generation.
[01:42:31.481] - Using XTest as the event generator.

There we go! Maybe by running as a native wayland app this could work. Can you somehow compile with the QTWayland module?

With sudo antimicrox --eventgen uinput this is really working 🤣 ... let's go to IRC now to learn more about this permission issue.

Unless they tell me some better solution in IRC, only a workaround works like described here.

(uinput user group, udev rule, systemd service and all that to circumvent sudo)

Just pasting the responses from IRC:

Xtest isn't supported, and uinput should always require root I believe. There are protocols to explictly create virtual inputs though, and the libinput author also has something WIP called "libei", which would possibly be cross-Wayland/X11.

the protocols in question are https://github.com/swaywm/wlr-protocols/blob/master/unstable/wlr-virtual-pointer-unstable-v1.xml and https://github.com/swaywm/wlroots/blob/master/protocol/virtual-keyboard-unstable-v1.xml

An annoying thing is that there's a split between GNOME and the rest of the community, with GNOME wanting to do everything over D-Bus because of their love for flatpak.
and thus, getting some of the protocols standardized is... Cumbersome. That's pretty much why the libei thing got started, as an "equally hated" solution :(

libei is pretty much WIP though promising - not relevant now.

For now to address this, I'll create a section in the README describing some workarounds. (--eventgen uinput parameter, sudo or udev rules etc.)

Please if you can, look into compiling with QTWayland to make the app Wayland-compatible, and let's also look into whether making uinput the default (with XTest fallback) make sense.

With sudo antimicrox --eventgen uinput this is really working rofl ... let's go to IRC now to learn more about this permission issue.

I think we will have to use PolicyKit to somehow gain access to input group. In case if this will appear to be too messy I will check other solutions.

I will investigate it deeper soon.

@pktiuk maybe this will help? flatpak/flatpak#4083

@soredake
It could be useful, but it is not ready yet and it seems to be helpful only in case of flatpak package.

I think the best (and the simplest) solution would be creating a new dedicated group having access to uinput and changing uid of executable.

I think we should create postinstallation script dealing with it. We could also consider making this script optional and offer running it only when Wayland is detected.

Related topics:
https://unix.stackexchange.com/questions/47880/how-debian-package-should-create-user-accounts
https://stackoverflow.com/questions/11939255/writing-to-dev-uinput-on-ubuntu-12-04

Or maybe creating some udev rule would help
https://unix.stackexchange.com/questions/72437/how-to-grant-non-root-user-access-to-device-files

It seems that for classic linux packages we could use setuid, to make it work we should only change bit of executable, but I don't know how it would work with flatpak.

I just tried on Fedora 34 with flatpak, the program starts and detects the joypad, but then doesn't write any input.

Installing the antimicrox from the RPM repos and then running sudo antimicrox --eventgen uinput works

There is already prepared file adding new udev rule allowing users writing to uinput without sudo https://github.com/AntiMicroX/antimicrox/blob/master/other/40-uinput.rules

SUBSYSTEM=="misc", KERNEL=="uinput", MODE="0660", GROUP="uinput"

But this config file is not utilized anywhere.

To work properly, this file should be placed at /etc/udev/rules.d/ and user installing application should be added to uinput group (and create this group if this doesn't exist yet).

I don't know whether this solution will work with flatpak flatpak/flatpak#961

It would be good to check it to be sure.