Add "Keep screen on" feature to DisplayServerX11
This commit is contained in:
parent
953de68cfc
commit
0c83a23ab5
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
|
- name: Configure dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
|
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
|
# Upload cache on completion and check it out now
|
||||||
- name: Load .scons_cache directory
|
- name: Load .scons_cache directory
|
||||||
|
@ -111,7 +111,7 @@ jobs:
|
||||||
- name: Configure dependencies
|
- name: Configure dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
|
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
|
xvfb wget unzip
|
||||||
|
|
||||||
# Upload cache on completion and check it out now
|
# Upload cache on completion and check it out now
|
||||||
|
@ -204,7 +204,7 @@ jobs:
|
||||||
- name: Configure dependencies
|
- name: Configure dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
|
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
|
# Upload cache on completion and check it out now
|
||||||
- name: Load .scons_cache directory
|
- name: Load .scons_cache directory
|
||||||
|
|
|
@ -9,6 +9,7 @@ common_linuxbsd = [
|
||||||
"crash_handler_linuxbsd.cpp",
|
"crash_handler_linuxbsd.cpp",
|
||||||
"os_linuxbsd.cpp",
|
"os_linuxbsd.cpp",
|
||||||
"joypad_linux.cpp",
|
"joypad_linux.cpp",
|
||||||
|
"freedesktop_screensaver.cpp",
|
||||||
]
|
]
|
||||||
|
|
||||||
if "x11" in env and env["x11"]:
|
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_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN)", False),
|
||||||
BoolVariable("use_msan", "Use LLVM compiler memory sanitizer (MSAN)", False),
|
BoolVariable("use_msan", "Use LLVM compiler memory sanitizer (MSAN)", False),
|
||||||
BoolVariable("pulseaudio", "Detect and use PulseAudio", True),
|
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("udev", "Use udev for gamepad connection callbacks", True),
|
||||||
BoolVariable("x11", "Enable X11 display", True),
|
BoolVariable("x11", "Enable X11 display", True),
|
||||||
BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
|
BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
|
||||||
|
@ -347,6 +348,14 @@ def configure(env):
|
||||||
else:
|
else:
|
||||||
print("PulseAudio development libraries not found, disabling driver")
|
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":
|
if platform.system() == "Linux":
|
||||||
env.Append(CPPDEFINES=["JOYDEV_ENABLED"])
|
env.Append(CPPDEFINES=["JOYDEV_ENABLED"])
|
||||||
if env["udev"]:
|
if env["udev"]:
|
||||||
|
|
|
@ -121,6 +121,9 @@ bool DisplayServerX11::has_feature(Feature p_feature) const {
|
||||||
case FEATURE_ICON:
|
case FEATURE_ICON:
|
||||||
case FEATURE_NATIVE_ICON:
|
case FEATURE_NATIVE_ICON:
|
||||||
case FEATURE_SWAP_BUFFERS:
|
case FEATURE_SWAP_BUFFERS:
|
||||||
|
#ifdef DBUS_ENABLED
|
||||||
|
case FEATURE_KEEP_SCREEN_ON:
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
default: {
|
default: {
|
||||||
}
|
}
|
||||||
|
@ -822,6 +825,26 @@ bool DisplayServerX11::screen_is_touchscreen(int p_screen) const {
|
||||||
return DisplayServer::screen_is_touchscreen(p_screen);
|
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 {
|
Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
@ -4270,6 +4293,11 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
|
||||||
|
|
||||||
_update_real_mouse_position(windows[MAIN_WINDOW_ID]);
|
_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;
|
r_error = OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4334,6 +4362,10 @@ DisplayServerX11::~DisplayServerX11() {
|
||||||
if (xmbstring) {
|
if (xmbstring) {
|
||||||
memfree(xmbstring);
|
memfree(xmbstring);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DBUS_ENABLED
|
||||||
|
memdelete(screensaver);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayServerX11::register_x11_driver() {
|
void DisplayServerX11::register_x11_driver() {
|
||||||
|
|
|
@ -55,6 +55,10 @@
|
||||||
#include "platform/linuxbsd/vulkan_context_x11.h"
|
#include "platform/linuxbsd/vulkan_context_x11.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(DBUS_ENABLED)
|
||||||
|
#include "freedesktop_screensaver.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <X11/Xcursor/Xcursor.h>
|
#include <X11/Xcursor/Xcursor.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/extensions/XInput2.h>
|
#include <X11/extensions/XInput2.h>
|
||||||
|
@ -103,6 +107,11 @@ class DisplayServerX11 : public DisplayServer {
|
||||||
RenderingDeviceVulkan *rendering_device_vulkan;
|
RenderingDeviceVulkan *rendering_device_vulkan;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(DBUS_ENABLED)
|
||||||
|
FreeDesktopScreenSaver *screensaver;
|
||||||
|
bool keep_screen_on = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct WindowData {
|
struct WindowData {
|
||||||
Window x11_window;
|
Window x11_window;
|
||||||
::XIC xic;
|
::XIC xic;
|
||||||
|
@ -291,6 +300,11 @@ public:
|
||||||
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
|
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;
|
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 Vector<DisplayServer::WindowID> get_window_list() const;
|
||||||
|
|
||||||
virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
|
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…
Add table
Reference in a new issue