RetroPie / RetroPie-Setup

Shell script to set up a Raspberry Pi/Odroid/PC with RetroArch emulator and various cores
Other
10.06k stars 1.39k forks source link

Unable to enter runcommand menu in Ubuntu 22.04 LTS (since uinput changes in commit d417e069) #3991

Open carlosefr opened 1 week ago

carlosefr commented 1 week ago

Since the uinput changes to joy2key in commit d417e069, it is no longer possible to enter the runcommand menu in Ubuntu 22.04 (x86_64+X11). I confirmed this by checking out the commit immediately prior to that and reinstalling joy2key, which works.

Also, in Ubuntu 22.04 uinput is builtin and not a module, thus the group change that should be triggered by /etc/udev/rules.d/80-rpi-uinput.rules does not work. I ran chmod 0660 /dev/uinput and chgrp input /dev/uinput manually, but this had no effect. I also tried using my user's own group, which also didn't work.

I also confirmed that python-uinput is able to generate keyboard events successfully, with the following script:

import uinput
import time

d = uinput.Device([uinput.KEY_LEFT, uinput.KEY_RIGHT])
time.sleep(2)
d.emit_click(uinput.KEY_LEFT)
time.sleep(2)
d.emit_click(uinput.KEY_RIGHT)

I'm not sure what the problem is. If you have any suggestions, I can help debug this.

Edit: After a couple of reboots, /etc/udev/rules.d/80-rpi-uinput.rules is being honored and /dev/input gets the proper permissions. Perhaps I hadn't rebooted after that rule was installed, so this bit at least is not an issue.

carlosefr commented 1 week ago

Testing this a bit more, and there's a difference in behavior between the current joy2key_sdl.py and the one prior to d417e06 that I find suspicious...

I'm running this command via SSH, while EmulationStation is visible in the RetroPie (Ubuntu) machine:

python3 /opt/retropie/admin/joy2key/joy2key_sdl.py /dev/input/jsX kcub1 kcuf1 kcuu1 kcud1 0x0a 0x20 0x1b 0x09 kpp knp

So, maybe runcommand isn't getting the keyboard event because it's being sent somewhere else?

Edit: The keyboard events are indeed going somewhere else. If I remove /opt/retropie/configs/all/launching.png, then I can trigger the runcommand menu. Otherwise, the events are probably being captured by feh while the launching image is being displayed in the foreground.

cmitu commented 1 week ago

This was already reported in the forums and it could be caused by the delay in the joy2key initialization (see here).

Using a launching image would have 'swallowed' the events in the previous version also, but with a faster joy2key start-up, you'd have been able to enter the menu before feh was starting. Can you run a standalone joy2key with debug mode (--debug) and post the output ?

cmitu commented 1 week ago

Edit: After a couple of reboots, /etc/udev/rules.d/80-rpi-uinput.rules is being honored and /dev/input gets the proper permissions. Perhaps I hadn't rebooted after that rule was installed, so this bit at least is not an issue.

It's /dev/uinput that needs the proper permissions and yes, on Ubuntu it needs a reboot since the udev rule is no applied unless modprobe is run, even though the uinput support is built-in the kernel. If there's a way to change the permissions I'd be happy to add it, but since Ubuntu also doesn't put the user into the input group, a re-login is required anyway.

cmitu commented 1 week ago

I've found the issue, but not a full solution at the moment.

The problem stems from https://github.com/libsdl-org/SDL/issues/9092 (fixed in SDL2 2.30.3), which affects the SDL2 2.30.0 version included in Ubuntu 24.04. Due to the fact that now the RetroPie installation user is part of the input group, it can stat all input related inodes under /dev/input (which it couldn't do before) and then the delay reported in the SDL issue occurs. The previous joy2key_sdl2.py version was not working at all on Ubuntu 24.04 (out-of-the-box) due to the reasons mentioned in the update commit.

As a workaround, you can install the RetroPie's SDL2 package, which contains minor modifications meant for the KMSDRM video drivers. Running sudo ./retropie_setup.sh sdl2 should build and install the 2.30.8 version of SDL2 and fix the timeout in the runcommand menu.

carlosefr commented 1 week ago

on Ubuntu it needs a reboot since the udev rule is no applied unless modprobe is run

With the module builtin, modprobe does not trigger the rule either. But that can be done without rebooting with udevadm trigger -s misc.

Using a launching image would have 'swallowed' the events in the previous version also, but with a faster joy2key start-up, you'd have been able to enter the menu before feh was starting.

With the previous version I can enter the menu by pressing a button at any point after feh started, and joy2key seems to be starting pretty fast to me (see below). If I understand it correctly, uinput works as if it were a real keyboard from X11's point of view, so it makes sense that events are sent to whatever window is active (and only that window). The terminal from where EmulationStation was started (and where runcommand runs) is always in the background in my setup, except when there's no launch image (because then it's the only window open at that point).

Can you run a standalone joy2key with debug mode (--debug) and post the output ?

$ python3 /opt/retropie/admin/joy2key/joy2key_sdl.py -d /dev/input/jsX kcub1 kcuf1 kcuu1 kcud1 0x0a 0x20 0x1b 0x09 kpp knp
2024-10-20 10:26:48,184 DEBUG  Debugging enabled, running in foreground
2024-10-20 10:26:48,185 DEBUG  Joy map:
 {'left': 105, 'right': 106, 'up': 103, 'down': 108, 'a': 28, 'b': 57, 'x': 1, 'y': 15, 'pageup': 104, 'pagedown': 109}
2024-10-20 10:26:48,301 DEBUG  Using SDL Version 2.0.20, PySDL2 version 0.9.7.
2024-10-20 10:26:48,301 DEBUG  Creating uinput keyboard devices with events: [(1, 105), (1, 106), (1, 103), (1, 108), (1, 28), (1, 57), (1, 1), (1, 15), (1, 104), (1, 109)]
2024-10-20 10:26:48,302 DEBUG  Joystick #0 360 Wireless Receiver (XBOX) added
2024-10-20 10:26:48,302 DEBUG  Added configuration for known device 360 Wireless Receiver (XBOX), hats: {}, buttons: {13: 'left', 14: 'right', 5: 'pagedown', 16: 'down', 4: 'pageup', 3: 'y', 2: 'x', 1: 'b', 0: 'a', 15: 'up'}, axis: {3: [(1, 'down'), (-1, 'up')], 2: [(-1, 'left'), (1, 'right')], 0: [(1, 'right'), (-1, 'left')], 1: [(-1, 'up'), (1, 'down')]}
2024-10-20 10:26:48,303 DEBUG  Joystick #1 Logitech Gamepad F310 added
2024-10-20 10:26:48,303 DEBUG  Added configuration for known device Logitech Gamepad F310, hats: {0: [(8, 'left'), (2, 'right'), (4, 'down'), (1, 'up')]}, buttons: {5: 'pagedown', 4: 'pageup', 3: 'y', 2: 'x', 1: 'b', 0: 'a'}, axis: {3: [(1, 'down'), (-1, 'up')], 2: [(-1, 'left'), (1, 'right')], 0: [(1, 'right'), (-1, 'left')], 1: [(-1, 'up'), (1, 'down')]}
2024-10-20 10:26:48,303 DEBUG  Joystick #2 Logitech Gamepad F310 added
2024-10-20 10:26:48,303 DEBUG  Added configuration for known device Logitech Gamepad F310, hats: {0: [(8, 'left'), (2, 'right'), (4, 'down'), (1, 'up')]}, buttons: {5: 'pagedown', 4: 'pageup', 3: 'y', 2: 'x', 1: 'b', 0: 'a'}, axis: {3: [(1, 'down'), (-1, 'up')], 2: [(-1, 'left'), (1, 'right')], 0: [(1, 'right'), (-1, 'left')], 1: [(-1, 'up'), (1, 'down')]}
2024-10-20 10:26:53,278 DEBUG  Events to emit: ['right']
2024-10-20 10:26:53,278 DEBUG  Emitting input code 106
^C2024-10-20 10:26:56,698 DEBUG  /opt/retropie/admin/joy2key/joy2key_sdl.py exiting cleanly

The problem stems from https://github.com/libsdl-org/SDL/issues/9092 (fixed in SDL2 2.30.3), which affects the SDL2 2.30.0 version included in Ubuntu 24.04.

I'm using SDL2 2.0.20 in Ubuntu 22.04. From that report, it seems my setup is not affected by that issue.

cmitu commented 1 week ago

OK, so in this case you have basically the behavior that's happening on a Pi system - you'll need to press a button to activate the menu before the image launching utility (feh in this case) is starting. How it was working before for you, since feh was obscuring the runcommand menu window/terminal and the terminal was in the background ?

carlosefr commented 1 week ago

As I've observed above, the previous joy2key sent the synthetic events to the terminal from which it was run. It doesn't matter that that terminal is in the background in X11. Once feh terminates, the terminal becomes visible and the runcommand menu is there waiting for me.

cmitu commented 1 week ago

The previous behavior (i.e. runcommand menu triggered in the background) was a side effect of how keyboard events were sent and it only happened on desktop platforms - where the launching image app was running. Unfortunately starting with Ubuntu 24.04 this method is no longer available and had to be replaced with the current uinput methid.

The behavior you notice is already present on non-desktop platform and it's noted in the documentation (https://retropie.org.uk/docs/Runcommand/#adding-custom-launching-images). I don't think this is a bug per-se, but a side-effect feature that's no longer present.

carlosefr commented 6 days ago

Once these images are installed, the timing to activate the runcommand menu differs, in that pressing a button will not register successfully until just after the image has disappeared.

Yes, this matches the previous behavior. But now it doesn't register even after the image has disappeared.

I understand that if TIOCSTI is disabled in the kernel, this is just the way things are. But if TIOCSTI is available, we should be able to continue using it. The code gets a bit more complicated (not by much), but I think it's worth it.

I've created PR #3992 with my suggestion on how the keep the legacy method around. I'm using it in my setup now, and seems to work.

PS: This is how I'm doing it in my setup, from ~/.xsession:

# Start EmulationStation in windowed mode, so desktop notifications work properly...
cat > ~/.config/openbox/autostart <<EOF
xterm -T 'RetroPie Terminal' -e sh -c 'setterm -cursor off ; export JOY2KEY_USE_LEGACY_TIOCSTI=1 ; emulationstation --no-splash --windowed ; openbox --exit' &
EOF
cmitu commented 6 days ago

Yes, this matches the previous behavior. But now it doesn't register even after the image has disappeared.

Does it register before ? If the runcommand's menu doesn't work at all with launching images, with the new code, then that's a bug.

I understand that if TIOCSTI is disabled in the kernel, this is just the way things are. But if TIOCSTI is available, we should be able to continue using it. The code gets a bit more complicated (not by much), but I think it's worth it.

IMHO it's not. As the sole maintainer of the utility, I'd not want to keep 2 codepaths for the same functionality, when 1 codepath should work.

carlosefr commented 6 days ago

Does it register before ? If the runcommand's menu doesn't work at all with launching images, with the new code, then that's a bug.

No, it does not register keypresses before. Or, putting it another way, the launch image appears almost instantaneously (within milliseconds of pressing "A" in EmulationStation). Even if runcommand registers keypresses before feh starts, it isn't humanly possible to press any button fast enough. And my setup is running in an old x86 iMac from 2008 — not a fast machine by today's standards.

I've tried to press "A" and "up" in quick sequence, or press "A" and "up" simultaneously, and the only thing I get is feh zooming the image in (proving that it's the one receiving the events).

I think it may not be possible to have runcommand register keypresses unless its terminal is in the foreground, at all. At least not under X11 (don't know about Wayland), as it doesn't seem to have a way to declare windows as click-through (only windows using the SHAPE extension allow click-through, and only in transparent areas).

I understand not wanting to maintain two codepaths for the same function but, unless the current way runcommand works is changed, it seems to be needed in practice.

cmitu commented 6 days ago

I'll give it a try to see how the launch images work in conjunction with the runcommand menu on a PC, it should be possible to trigger the menu.

Can you post the contents of your runcommand configuration file, the /opt/retropie/configs/all/runcommand.cfg file ?

carlosefr commented 6 days ago

Sure, here's my runcommand.cfg:

use_art = "0"
disable_joystick = "0"
governor = ""
disable_menu = "0"
image_delay = "2"
cmitu commented 6 days ago

Thank you for the .cfg file.

I haven't had a chance to test, but I think I can see the issue in runcommand. Looks like the 'side effect' of injecting the input chars into the terminal from joy2key was actually used by runcommand when feh was used to launch the image. Whether that was deliberate or not (looking at the commit that handled how feh was stopped, I tend to think it wasn't deliberate).

In the check_menu function, feh was stopped here, after the any read timeout. This obviously fails with the new joy2key_sdl, since the controlling terminal is in the backgroun, behind feh.

The solution would be to stop feh in the same phase as fbi (used on non-X11/non-desktop platform) - in the show_launch function after the sleep delay. @joolswills does that seem okay ?

carlosefr commented 6 days ago

Does that mean the terminal would be visible for a while (in the foreground) after feh terminates, to give the user some time to press a button and trigger the menu?

cmitu commented 6 days ago

@carlosefr yes, the same behavior when fbi is used, on non-desktop systems.

carlosefr commented 6 days ago

On a Raspberry Pi (with the current version of joy2key), the launch image goes away immediately when I press "A", and then the runcommand menu appears.

On X11 that means a black rectangle (the terminal) will be visible on screen for a while, and I can't click any buttons while feh is active because some make it do stuff (e.g. zooming in/out).

This negates the reasons why I'm using a launch image (streamlining the transition from EmulationStation into the game to make things look more polished and console-like)... 😞

I understand that making things work with uinput as default is the way to go. I'm willing to help test that (even if I'll just end up using a patched joy2key for the forseeable future).

But the code to support input with TIOCSTI is so few lines that I don't see why not retain the option to use it. It's useful even outside RetroPie, and it's not like TIOCSTI will be removed from the kernel any time soon, given it can be enabled at runtime on kernels that have it disabled by default.