diff --git a/README.md b/README.md index d367308c..ee6f3395 100644 --- a/README.md +++ b/README.md @@ -220,6 +220,7 @@ information on what to include when reporting a bug. - [Win32] Bugfix: `glfwCreateWindow` activated window even with `GLFW_FOCUSED` hint set to false (#1179,#1180) - [X11] Added support for `org.freedesktop.ScreenSaver` (#854) +- [X11] Added support for the MIT screensaver extension (#854) - [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125) - [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading - [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X diff --git a/src/x11_init.c b/src/x11_init.c index f3a5c3b7..2951c393 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -623,6 +623,23 @@ static GLFWbool initExtensions(void) } } + _glfw.x11.xss.handle = _glfw_dlopen("libXss.so.1"); + if (_glfw.x11.xss.handle) + { + _glfw.x11.xss.QueryExtension = (PFN_XScreenSaverQueryExtension) + dlsym(_glfw.x11.xss.handle, "XScreenSaverQueryExtension"); + _glfw.x11.xss.Suspend = (PFN_XScreenSaverSuspend) + dlsym(_glfw.x11.xss.handle, "XScreenSaverSuspend"); + + if (XScreenSaverQueryExtension(_glfw.x11.display, + &_glfw.x11.xss.eventBase, + &_glfw.x11.xss.errorBase)) + { + _glfw.x11.xss.available = GLFW_TRUE; + } + } + + // Check if Xkb is supported on this display _glfw.x11.xkb.major = 1; _glfw.x11.xkb.minor = 0; _glfw.x11.xkb.available = diff --git a/src/x11_platform.h b/src/x11_platform.h index 7acbf575..fea68a23 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -126,6 +126,11 @@ typedef XRenderPictFormat* (* PFN_XRenderFindVisualFormat)(Display*,Visual const #define XRenderQueryVersion _glfw.x11.xrender.QueryVersion #define XRenderFindVisualFormat _glfw.x11.xrender.FindVisualFormat +typedef Bool (* PFN_XScreenSaverQueryExtension)(Display*,int*,int*); +typedef void (* PFN_XScreenSaverSuspend)(Display*,Bool); +#define XScreenSaverQueryExtension _glfw.x11.xss.QueryExtension +#define XScreenSaverSuspend _glfw.x11.xss.Suspend + typedef void (*PFN_dbus_error_init)(DBusError*); typedef dbus_bool_t (*PFN_dbus_error_is_set)(const DBusError*); typedef DBusConnection* (*PFN_dbus_bus_get_private)(DBusBusType,DBusError*); @@ -263,6 +268,8 @@ typedef struct _GLFWlibraryX11 double restoreCursorPosX, restoreCursorPosY; // The window whose disabled cursor mode is active _GLFWwindow* disabledCursorWindow; + // The number of full screen windows active on their monitors + int acquiredMonitorCount; // Window manager atoms Atom WM_PROTOCOLS; @@ -355,7 +362,6 @@ typedef struct _GLFWlibraryX11 } xkb; struct { - int count; int timeout; int interval; int blanking; @@ -385,6 +391,15 @@ typedef struct _GLFWlibraryX11 PFN_XineramaQueryScreens QueryScreens; } xinerama; + struct { + GLFWbool available; + void* handle; + int eventBase; + int errorBase; + PFN_XScreenSaverQueryExtension QueryExtension; + PFN_XScreenSaverSuspend Suspend; + } xss; + struct { void* handle; PFN_XGetXCBConnection GetXCBConnection; diff --git a/src/x11_window.c b/src/x11_window.c index 95b5837a..30b16122 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1078,18 +1078,20 @@ static const char* getSelectionString(Atom selection) // static void acquireMonitor(_GLFWwindow* window) { - if (_glfw.x11.saver.count == 0) + if (_glfw.x11.acquiredMonitorCount == 0) { - // Remember old screen saver settings - XGetScreenSaver(_glfw.x11.display, - &_glfw.x11.saver.timeout, - &_glfw.x11.saver.interval, - &_glfw.x11.saver.blanking, - &_glfw.x11.saver.exposure); - - // Disable screen saver - XSetScreenSaver(_glfw.x11.display, 0, 0, DontPreferBlanking, - DefaultExposures); + if (_glfw.x11.xss.available) + XScreenSaverSuspend(_glfw.x11.display, True); + else + { + XGetScreenSaver(_glfw.x11.display, + &_glfw.x11.saver.timeout, + &_glfw.x11.saver.interval, + &_glfw.x11.saver.blanking, + &_glfw.x11.saver.exposure); + XSetScreenSaver(_glfw.x11.display, 0, 0, DontPreferBlanking, + DefaultExposures); + } if (_glfw.x11.dbus.session) { @@ -1124,7 +1126,7 @@ static void acquireMonitor(_GLFWwindow* window) } if (!window->monitor->window) - _glfw.x11.saver.count++; + _glfw.x11.acquiredMonitorCount++; _glfwSetVideoModeX11(window->monitor, &window->videoMode); @@ -1154,16 +1156,19 @@ static void releaseMonitor(_GLFWwindow* window) _glfwInputMonitorWindow(window->monitor, NULL); _glfwRestoreVideoModeX11(window->monitor); - _glfw.x11.saver.count--; - - if (_glfw.x11.saver.count == 0) + _glfw.x11.acquiredMonitorCount--; + if (_glfw.x11.acquiredMonitorCount == 0) { - // Restore old screen saver settings - XSetScreenSaver(_glfw.x11.display, - _glfw.x11.saver.timeout, - _glfw.x11.saver.interval, - _glfw.x11.saver.blanking, - _glfw.x11.saver.exposure); + if (_glfw.x11.xss.available) + XScreenSaverSuspend(_glfw.x11.display, False); + else + { + XSetScreenSaver(_glfw.x11.display, + _glfw.x11.saver.timeout, + _glfw.x11.saver.interval, + _glfw.x11.saver.blanking, + _glfw.x11.saver.exposure); + } if (_glfw.x11.dbus.session) {