Emulator Issues #10392
closedDolphin should inhibit the screen on Linux systems
Added by eang over 7 years ago. Updated 2 months ago.
0%
Description
On Linux it can happen that joystick keypress are not detected by the desktop environment (due to display server limitations). This causes the screenlocker to kick in while a game is being played, because the system looks idle (if you are playing with a joystick, both mouse and keyboard are idle).
There is a standard dbus api that can be used to inhibit the screen locker 1. This is what browsers and video player use to prevent this issue.
I heard that dolphin is switching to Qt, so it would be trivial to call the inhibit dbus method thanks to qdbus (i.e. something like https://github.com/KDE/kronometer/commit/98bbb8f8ab1b79158f68d29d5b64aee4b6235843).
Updated by leoetlino over 7 years ago
- Operating system Linux added
- Operating system deleted (
N/A)
Dolphin already tries to inhibit the screensaver, but not using dbus. I'm not sure QDBus will ever be used, as we would need this to work in other UIs too -- WX which is still used by most people and nogui.
Does xdg-screensaver (which is supposed to be a freedesktop standard script) work on your system?
Updated by eang over 7 years ago
leoetlino wrote:
Dolphin already tries to inhibit the screensaver, but not using dbus. I'm not sure QDBus will ever be used, as we would need this to work in other UIs too -- WX which is still used by most people and nogui.
Does xdg-screensaver (which is supposed to be a freedesktop standard script) work on your system?
I'm going to do some tests. From the code I see you just call 'xdg-screensaver suspend ', but which window id? the winid of the dolphin window or the window of the game?
Updated by eang over 7 years ago
leoetlino wrote:
I'm not sure QDBus will ever be used, as we would need this to work in other UIs too -- WX which is still used by most people and nogui.
Btw you don't have to use QDBus. Dolphin could just call dbus-send in an external process. The advantage of the dbus api is better integration with the desktop environment. Dolphin would be able to set a translated message as the "reason" of the inhibition, and this information is nicely displayed by modern desktops (e.g. in this example Chromium has set "Playing audio": http://i.imgur.com/pUZFBtn.jpg).
Updated by eang over 7 years ago
eang wrote:
leoetlino wrote:
I'm not sure QDBus will ever be used, as we would need this to work in other UIs too -- WX which is still used by most people and nogui.
Btw you don't have to use QDBus. Dolphin could just call dbus-send in an external process.
Example usage: https://github.com/libretro/RetroArch/issues/2026#issuecomment-244821599
Updated by orbea over 7 years ago
This works perfectly in Slackware with the xdg-screensaver method. I don't think this is an dolphin-emu issue, but rather an issue with the user missing some dependency and/or a bug in the DE used. Dbus is terribly unreliable and probably should not be used by default for this.
Updated by eang over 7 years ago
orbea wrote:
This works perfectly in Slackware with the xdg-screensaver method. I don't think this is an dolphin-emu issue, but rather an issue with the user missing some dependency and/or a bug in the DE used. Dbus is terribly unreliable and probably should not be used by default for this.
I just realized that xdg-screensaver is an ugly bash script of 1400 lines that wraps dbus-send...
I'll try to see if I'm missing some dependencies used by xdg-screensaver.
Updated by orbea over 7 years ago
When this was brought up for RetroArch the missing dependency was xprop. I am not sure if that is also true here or not.
There is also the consideration that dbus is controversial software which not everyone uses or even has installed. It might be useful to let users opt into it, but the xdg-screensaver method should still be default for best compatibility.
Updated by eang over 7 years ago
@orbea do you know how xdg-screenshot is supposed to be used?
I'm trying this (which doesn't work):
xdg-screensaver suspend $(xwininfo -name Konsole | grep ^x | awk '{ print $4 }')
Note that 'xdg-screensaver lock' does work. This is on KDE Plasma as desktop.
By the way, I do have xprop installed.
Updated by eang over 7 years ago
eang wrote:
@orbea do you know how xdg-screenshot is supposed to be used?
(I meant xdg-screensaver, of course...)
Updated by orbea over 7 years ago
Sorry, I don't know exactly. I just know in programs that call it (RetroArch, dolphin-emu, mpv) it works as expected and disables xscreensaver here. I do not use a DE, but rather an minimal tiling wm (Spectrwm) so that might change something.
Does it work for other programs?
You can test retroarch with.
./configure --disable-dbus && make && ./retroarch
I believe mpv should use it by default. If both of these also do not work, I would suggest bringing this up with the KDE5/plasma developers.
Caffeine-ng can be an alternative work around which calls dbus when something full screens itself.
Updated by eang over 7 years ago
Thanks. I can confirm that xdg-screensaver doesn't work either in retroarch (compiled without dbus support). I'll continue to investigate from the KDE side.
Still, it would be nice if dolphin could get optional dbus support. As I said, the dbus api allows nicer integration with desktop applets, something that is not possible with xdg-screenshot.
Updated by eang over 7 years ago
I don't think the bug is in Plasma. The problem is that 'xdg-screensaver suspend' does create an inhibition, but then the inhibition is suddenly released because that's what dbus tells Plasma to do, according to dbus-monitor logs. So the bug is probably in xdg-screensaver itself. Which is probably why most apps (retroarch, vlc, ...) are using xdg-screensaver only as fallback if dbus is not available, as far as I can see.
Updated by eang over 7 years ago
Updated by eang over 7 years ago
eang wrote:
I don't think the bug is in Plasma. The problem is that 'xdg-screensaver suspend' does create an inhibition, but then the inhibition is suddenly released because that's what dbus tells Plasma to do, according to dbus-monitor logs. So the bug is probably in xdg-screensaver itself. Which is probably why most apps (retroarch, vlc, ...) are using xdg-screensaver only as fallback if dbus is not available, as far as I can see.
Updated by nyanpasu64 about 2 years ago
I wonder if there's any progress on this issue. It's annoying for KDE to automatically lock the screen while I'm in the middle of playing with a controller, if I forget to block locking from the system tray during a play session. Now that the Wx GUI is dead, you could use Qt D-Bus, or copy the code found in systemd-inhibit (https://github.com/systemd/systemd/blob/bf1886226724b3db0779d643195d428575cff0be/src/login/inhibit.c), though this depends on libsystemd. (It's suboptimal to shell out to /usr/bin/systemd-inhibit
, since systemd-inhibit blocks sleep and shutdown for the lifetime of a child process, rather than starting and stopping it interactively.)
There's actually multiple D-Bus methods you can use to inhibit sleeping. On KDE, I tried using QDBusViewer to call org.freedesktop.ScreenSaver -> ScreenSaver/ org.freedesktop.ScreenSaver -> Inhibit
. This works (and sleep is blocked until I close QDBusViewer), but you can't call it the way xdg-screensaver does; instead you have to pass a pretty name (not window ID) as the first application_name
argument. Afterwards, if you open KDE's Power Management panel, application_name is the pretty name shown in the panel as doing the suspending. Note that this does not show up in systemd-inhibit.
I think this works, because dbus-monitor
shows that Firefox uses this D-Bus method to block sleeping while a video is playing, and (after I reduce the lock timeout from 5 to 1 minute for testing) the screen sleeps after a 1-minute timeout without this method active, and not with it active.
Alternatively, if you run systemd-inhibit app_name
, this shows up in both KDE and systemd-inhibit
's list of apps blocking sleep. This instead invokes "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "Inhibit".
Updated by nyanpasu64 over 1 year ago
I have a Qt D-Bus implementation of screensaver suppression (not pushed yet), but it might break the build on Dolphin configured to use X11 but not the Qt GUI. Is that unacceptable? Perhaps we could conditionally build screensaver suppression based on whether Qt is enabled (and without Qt, disable the functionality altogether rather than using xdg-screensaver suspend
since that program simply does not work, and likely cannot work without forking off a separate process in the background).
Alternatively, given that we're already using libsystemd systemd/sd-daemon.h for TraversalServer.cpp, we could perhaps use systemd/sd-bus.h to poke the screensaver endpoint (again like https://github.com/systemd/systemd/blob/main/src/login/inhibit.c). I'm not sure if tying this functionality to libsystemd is a problem as well.
Updated by JosJuice over 1 year ago
The nogui build (which doesn't use Qt) needs to continue working, but it would be okay if inhibiting the screensaver doesn't work in the nogui build.
Updated by nyanpasu64 over 1 year ago
Should we invoke the org.freedesktop.ScreenSaver
or org.freedesktop.login1
dbus path?
- Should we use some other non-D-Bus method of screensaver suppression? For what it's worth, Godot uses
org.freedesktop.ScreenSaver
, though it does some sort of so_wrap thing I'm not sure about, and uses SCons as a build system. - Do we need to optionally disable D-Bus at runtime if the bus isn't running? Then again, many apps (Firefox/Telegram/Discord) just hang for 30 seconds waiting on a nonexistent bus, and don't bother handling this case.
Do we build nogui and qt-gui in the same CMake build tree, using the same UICommon library? And nogui cannot link with Qt, so UICommon cannot link with Qt at all (even when used with qt-gui)?
I don't think dbus-based screensaver suppression should belong in X11Utils.cpp at all, and also we should get rid of the unused Window win
argument since the D-Bus endpoints don't use it.
Should we depend on qt or libsystemd for sleep suppression?
- If we depend on Qt, then non-Qt users can't suppress screensaver... but they already don't suppress screensaver, since
InhibitScreenSaver
is only ever called byDolphinQt/MainWindow.cpp
. So we can safely move the logic out from UICommon to DolphinQt.- Or do we want Linux screensaver suppression code to still work if we add a different non-Qt GUI? In which case we can't use QtDbus nor move the code to DolphinQt.
- If we depend on libsystemd, than all 3 non-systemd users don't get it working.
- We could use libdbus directly, though it's a bunch of work to add to CMake.
- Another option is dbus-cxx which natively builds using CMake, though IDK if it's well-maintained. It seems not very popular; it's not packaged in Arch and the AUR package is orphaned.
Updated by nyanpasu64 over 1 year ago
Correction: Core/DolphinNoGUI/PlatformX11.cpp
calls X11Utils::InhibitScreensaver
directly, bypassing UICommon
. So we should ideally keep screensaver inhibition even in non-Qt Linux builds (even though it didn't work before).
I guess we're either using libsystemd, libdbus, or dbus-cxx. Any suggestions?
Updated by Billiard26 9 months ago
- Has duplicate Emulator Issues #11749: XUbuntu Disco Dingo - Dolphin does not prevent monitor standby/screensaver added