From d95b77ebec39207ed694999422bb090a0882da14 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 14 Jun 2015 21:05:42 +0200 Subject: [PATCH] Fix monitor notifications on X11 Fixes #288. --- README.md | 1 + include/GLFW/glfw3.h | 3 --- src/x11_init.c | 35 +++++++++++++++++++---------------- src/x11_window.c | 19 ++++++++++--------- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 28695164..3f05cefa 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ used by the tests and examples and are not required to build the library. - Added `GLFW_TRUE` and `GLFW_FALSE` as client API independent boolean values - Removed dependency on external OpenGL or OpenGL ES headers - [Cocoa] Removed support for OS X 10.6 + - [X11] Bugfix: Monitor connection and disconnection events were not reported - [WGL] Removed dependency on external WGL headers - [GLX] Removed dependency on external GLX headers - [EGL] Removed dependency on external EGL headers diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 641e8714..7b31a7d0 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1374,9 +1374,6 @@ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor); * @return The previously set callback, or `NULL` if no callback was set or the * library had not been [initialized](@ref intro_init). * - * @bug __X11:__ This callback is not yet called on monitor configuration - * changes. - * * @par Thread Safety * This function may only be called from the main thread. * diff --git a/src/x11_init.c b/src/x11_init.c index e962eb3b..19847d70 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -486,29 +486,29 @@ static GLFWbool initExtensions(void) #endif /*_GLFW_HAS_XF86VM*/ // Check for RandR extension - _glfw.x11.randr.available = - XRRQueryExtension(_glfw.x11.display, + if (XRRQueryExtension(_glfw.x11.display, &_glfw.x11.randr.eventBase, - &_glfw.x11.randr.errorBase); - - if (_glfw.x11.randr.available) + &_glfw.x11.randr.errorBase)) { - XRRScreenResources* sr; - - if (!XRRQueryVersion(_glfw.x11.display, - &_glfw.x11.randr.major, - &_glfw.x11.randr.minor)) + if (XRRQueryVersion(_glfw.x11.display, + &_glfw.x11.randr.major, + &_glfw.x11.randr.minor)) + { + // The GLFW RandR path requires at least version 1.3 + if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3) + _glfw.x11.randr.available = GLFW_TRUE; + } + else { _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query RandR version"); - return GLFW_FALSE; } + } - // The GLFW RandR path requires at least version 1.3 - if (_glfw.x11.randr.major == 1 && _glfw.x11.randr.minor < 3) - _glfw.x11.randr.available = GLFW_FALSE; - - sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); + if (_glfw.x11.randr.available) + { + XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display, + _glfw.x11.root); if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0])) { @@ -522,6 +522,9 @@ static GLFWbool initExtensions(void) } XRRFreeScreenResources(sr); + + XRRSelectInput(_glfw.x11.display, _glfw.x11.root, + RROutputChangeNotifyMask); } if (XineramaQueryExtension(_glfw.x11.display, diff --git a/src/x11_window.c b/src/x11_window.c index c08b01ba..309a5f30 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -480,9 +480,6 @@ static GLFWbool createWindow(_GLFWwindow* window, _glfwPlatformSetWindowTitle(window, wndconfig->title); - XRRSelectInput(_glfw.x11.display, window->x11.handle, - RRScreenChangeNotifyMask); - if (_glfw.x11.im) { window->x11.ic = XCreateIC(_glfw.x11.im, @@ -852,6 +849,16 @@ static void processEvent(XEvent *event) if (_glfw.x11.im) filtered = XFilterEvent(event, None); + if (_glfw.x11.randr.available) + { + if (event->type == _glfw.x11.randr.eventBase + RRNotify) + { + XRRUpdateConfiguration(event); + _glfwInputMonitorChange(); + return; + } + } + if (event->type != GenericEvent) { window = findWindowByHandle(event->xany.window); @@ -1412,12 +1419,6 @@ static void processEvent(XEvent *event) } #endif /*_GLFW_HAS_XINPUT*/ } - - if (event->type - _glfw.x11.randr.eventBase == RRScreenChangeNotify) - { - XRRUpdateConfiguration(event); - return; - } }