Merge pull request #35536 from shroudedcode/keep-screen-on-linux
Make "Keep screen on" work on Linux
This commit is contained in:
commit
a738ddb9a4
7 changed files with 230 additions and 3 deletions
6
.github/workflows/linux_builds.yml
vendored
6
.github/workflows/linux_builds.yml
vendored
|
@ -26,7 +26,7 @@ jobs:
|
|||
- name: Configure dependencies
|
||||
run: |
|
||||
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
|
||||
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
|
||||
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libdbus-1-dev libudev-dev libxi-dev libxrandr-dev yasm
|
||||
|
||||
# Upload cache on completion and check it out now
|
||||
- name: Load .scons_cache directory
|
||||
|
@ -111,7 +111,7 @@ jobs:
|
|||
- name: Configure dependencies
|
||||
run: |
|
||||
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
|
||||
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm \
|
||||
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libdbus-1-dev libudev-dev libxi-dev libxrandr-dev yasm \
|
||||
xvfb wget unzip
|
||||
|
||||
# Upload cache on completion and check it out now
|
||||
|
@ -204,7 +204,7 @@ jobs:
|
|||
- name: Configure dependencies
|
||||
run: |
|
||||
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
|
||||
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
|
||||
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libdbus-1-dev libudev-dev libxi-dev libxrandr-dev yasm
|
||||
|
||||
# Upload cache on completion and check it out now
|
||||
- name: Load .scons_cache directory
|
||||
|
|
|
@ -9,6 +9,7 @@ common_linuxbsd = [
|
|||
"crash_handler_linuxbsd.cpp",
|
||||
"os_linuxbsd.cpp",
|
||||
"joypad_linux.cpp",
|
||||
"freedesktop_screensaver.cpp",
|
||||
]
|
||||
|
||||
if "x11" in env and env["x11"]:
|
||||
|
|
|
@ -72,6 +72,7 @@ def get_opts():
|
|||
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN)", False),
|
||||
BoolVariable("use_msan", "Use LLVM compiler memory sanitizer (MSAN)", False),
|
||||
BoolVariable("pulseaudio", "Detect and use PulseAudio", True),
|
||||
BoolVariable("dbus", "Detect and use D-Bus to handle screensaver", True),
|
||||
BoolVariable("udev", "Use udev for gamepad connection callbacks", True),
|
||||
BoolVariable("x11", "Enable X11 display", True),
|
||||
BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
|
||||
|
@ -347,6 +348,14 @@ def configure(env):
|
|||
else:
|
||||
print("PulseAudio development libraries not found, disabling driver")
|
||||
|
||||
if env["dbus"]:
|
||||
if os.system("pkg-config --exists dbus-1") == 0: # 0 means found
|
||||
print("Enabling D-Bus")
|
||||
env.Append(CPPDEFINES=["DBUS_ENABLED"])
|
||||
env.ParseConfig("pkg-config --cflags --libs dbus-1")
|
||||
else:
|
||||
print("D-Bus development libraries not found, disabling dependent features")
|
||||
|
||||
if platform.system() == "Linux":
|
||||
env.Append(CPPDEFINES=["JOYDEV_ENABLED"])
|
||||
if env["udev"]:
|
||||
|
|
|
@ -121,6 +121,9 @@ bool DisplayServerX11::has_feature(Feature p_feature) const {
|
|||
case FEATURE_ICON:
|
||||
case FEATURE_NATIVE_ICON:
|
||||
case FEATURE_SWAP_BUFFERS:
|
||||
#ifdef DBUS_ENABLED
|
||||
case FEATURE_KEEP_SCREEN_ON:
|
||||
#endif
|
||||
return true;
|
||||
default: {
|
||||
}
|
||||
|
@ -822,6 +825,26 @@ bool DisplayServerX11::screen_is_touchscreen(int p_screen) const {
|
|||
return DisplayServer::screen_is_touchscreen(p_screen);
|
||||
}
|
||||
|
||||
#ifdef DBUS_ENABLED
|
||||
void DisplayServerX11::screen_set_keep_on(bool p_enable) {
|
||||
if (screen_is_kept_on() == p_enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_enable) {
|
||||
screensaver->inhibit();
|
||||
} else {
|
||||
screensaver->uninhibit();
|
||||
}
|
||||
|
||||
keep_screen_on = p_enable;
|
||||
}
|
||||
|
||||
bool DisplayServerX11::screen_is_kept_on() const {
|
||||
return keep_screen_on;
|
||||
}
|
||||
#endif
|
||||
|
||||
Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
@ -4270,6 +4293,11 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
|||
|
||||
_update_real_mouse_position(windows[MAIN_WINDOW_ID]);
|
||||
|
||||
#ifdef DBUS_ENABLED
|
||||
screensaver = memnew(FreeDesktopScreenSaver);
|
||||
screen_set_keep_on(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true));
|
||||
#endif
|
||||
|
||||
r_error = OK;
|
||||
}
|
||||
|
||||
|
@ -4334,6 +4362,10 @@ DisplayServerX11::~DisplayServerX11() {
|
|||
if (xmbstring) {
|
||||
memfree(xmbstring);
|
||||
}
|
||||
|
||||
#ifdef DBUS_ENABLED
|
||||
memdelete(screensaver);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DisplayServerX11::register_x11_driver() {
|
||||
|
|
|
@ -55,6 +55,10 @@
|
|||
#include "platform/linuxbsd/vulkan_context_x11.h"
|
||||
#endif
|
||||
|
||||
#if defined(DBUS_ENABLED)
|
||||
#include "freedesktop_screensaver.h"
|
||||
#endif
|
||||
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
@ -103,6 +107,11 @@ class DisplayServerX11 : public DisplayServer {
|
|||
RenderingDeviceVulkan *rendering_device_vulkan;
|
||||
#endif
|
||||
|
||||
#if defined(DBUS_ENABLED)
|
||||
FreeDesktopScreenSaver *screensaver;
|
||||
bool keep_screen_on = false;
|
||||
#endif
|
||||
|
||||
struct WindowData {
|
||||
Window x11_window;
|
||||
::XIC xic;
|
||||
|
@ -291,6 +300,11 @@ public:
|
|||
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
|
||||
virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
|
||||
|
||||
#if defined(DBUS_ENABLED)
|
||||
virtual void screen_set_keep_on(bool p_enable);
|
||||
virtual bool screen_is_kept_on() const;
|
||||
#endif
|
||||
|
||||
virtual Vector<DisplayServer::WindowID> get_window_list() const;
|
||||
|
||||
virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
|
||||
|
|
124
platform/linuxbsd/freedesktop_screensaver.cpp
Normal file
124
platform/linuxbsd/freedesktop_screensaver.cpp
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*************************************************************************/
|
||||
/* freedesktop_screensaver.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "freedesktop_screensaver.h"
|
||||
|
||||
#ifdef DBUS_ENABLED
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#define BUS_OBJECT_NAME "org.freedesktop.ScreenSaver"
|
||||
#define BUS_OBJECT_PATH "/org/freedesktop/ScreenSaver"
|
||||
#define BUS_INTERFACE "org.freedesktop.ScreenSaver"
|
||||
|
||||
void FreeDesktopScreenSaver::inhibit() {
|
||||
if (unsupported) {
|
||||
return;
|
||||
}
|
||||
|
||||
DBusError error;
|
||||
dbus_error_init(&error);
|
||||
|
||||
DBusConnection *bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
|
||||
if (dbus_error_is_set(&error)) {
|
||||
unsupported = true;
|
||||
return;
|
||||
}
|
||||
|
||||
String app_name_string = ProjectSettings::get_singleton()->get("application/config/name");
|
||||
const char *app_name = app_name_string.is_empty() ? "Godot Engine" : app_name_string.utf8().get_data();
|
||||
|
||||
const char *reason = "Running Godot Engine project";
|
||||
|
||||
DBusMessage *message = dbus_message_new_method_call(
|
||||
BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE,
|
||||
"Inhibit");
|
||||
dbus_message_append_args(
|
||||
message,
|
||||
DBUS_TYPE_STRING, &app_name,
|
||||
DBUS_TYPE_STRING, &reason,
|
||||
DBUS_TYPE_INVALID);
|
||||
|
||||
DBusMessage *reply = dbus_connection_send_with_reply_and_block(bus, message, 50, &error);
|
||||
dbus_message_unref(message);
|
||||
if (dbus_error_is_set(&error)) {
|
||||
dbus_connection_unref(bus);
|
||||
unsupported = false;
|
||||
return;
|
||||
}
|
||||
|
||||
DBusMessageIter reply_iter;
|
||||
dbus_message_iter_init(reply, &reply_iter);
|
||||
dbus_message_iter_get_basic(&reply_iter, &cookie);
|
||||
print_verbose("FreeDesktopScreenSaver: Acquired screensaver inhibition cookie: " + uitos(cookie));
|
||||
|
||||
dbus_message_unref(reply);
|
||||
dbus_connection_unref(bus);
|
||||
}
|
||||
|
||||
void FreeDesktopScreenSaver::uninhibit() {
|
||||
if (unsupported) {
|
||||
return;
|
||||
}
|
||||
|
||||
DBusError error;
|
||||
dbus_error_init(&error);
|
||||
|
||||
DBusConnection *bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
|
||||
if (dbus_error_is_set(&error)) {
|
||||
unsupported = true;
|
||||
return;
|
||||
}
|
||||
|
||||
DBusMessage *message = dbus_message_new_method_call(
|
||||
BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE,
|
||||
"UnInhibit");
|
||||
dbus_message_append_args(
|
||||
message,
|
||||
DBUS_TYPE_UINT32, &cookie,
|
||||
DBUS_TYPE_INVALID);
|
||||
|
||||
DBusMessage *reply = dbus_connection_send_with_reply_and_block(bus, message, 50, &error);
|
||||
if (dbus_error_is_set(&error)) {
|
||||
dbus_connection_unref(bus);
|
||||
unsupported = true;
|
||||
return;
|
||||
}
|
||||
|
||||
print_verbose("FreeDesktopScreenSaver: Released screensaver inhibition cookie: " + uitos(cookie));
|
||||
|
||||
dbus_message_unref(message);
|
||||
dbus_message_unref(reply);
|
||||
dbus_connection_unref(bus);
|
||||
}
|
||||
|
||||
#endif // DBUS_ENABLED
|
47
platform/linuxbsd/freedesktop_screensaver.h
Normal file
47
platform/linuxbsd/freedesktop_screensaver.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*************************************************************************/
|
||||
/* freedesktop_screensaver.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef DBUS_ENABLED
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include <stdint.h>
|
||||
|
||||
class FreeDesktopScreenSaver {
|
||||
private:
|
||||
uint32_t cookie = 0;
|
||||
bool unsupported = false;
|
||||
|
||||
public:
|
||||
FreeDesktopScreenSaver() {}
|
||||
void inhibit();
|
||||
void uninhibit();
|
||||
};
|
||||
|
||||
#endif // DBUS_ENABLED
|
Loading…
Reference in a new issue