diff --git a/glfw/x11_platform.h b/glfw/x11_platform.h index eb5e576c1..806e125e5 100644 --- a/glfw/x11_platform.h +++ b/glfw/x11_platform.h @@ -180,6 +180,7 @@ typedef struct _GLFWwindowX11 { Colormap colormap; Window handle; + Window parent; bool iconified; bool maximized; diff --git a/glfw/x11_window.c b/glfw/x11_window.c index b3c0cd785..b0e408ff7 100644 --- a/glfw/x11_window.c +++ b/glfw/x11_window.c @@ -1184,6 +1184,18 @@ static void processEvent(XEvent *event) switch (event->type) { + case CreateNotify: + { + window->x11.parent = event->xcreatewindow.parent; + return; + } + + case ReparentNotify: + { + window->x11.parent = event->xreparent.parent; + return; + } + case KeyPress: { UPDATE_KEYMAP_IF_NEEDED; @@ -1377,18 +1389,28 @@ static void processEvent(XEvent *event) window->x11.height = event->xconfigure.height; } - if (event->xconfigure.x != window->x11.xpos || - event->xconfigure.y != window->x11.ypos) - { - if (event->xany.send_event) - { - _glfwInputWindowPos(window, - event->xconfigure.x, - event->xconfigure.y); + int xpos = event->xconfigure.x; + int ypos = event->xconfigure.y; - window->x11.xpos = event->xconfigure.x; - window->x11.ypos = event->xconfigure.y; - } + // NOTE: ConfigureNotify events from the server are in local + // coordinates, so if we are reparented we need to translate + // the position into root (screen) coordinates + if (!event->xany.send_event && window->x11.parent != _glfw.x11.root) + { + Window dummy; + XTranslateCoordinates(_glfw.x11.display, + window->x11.parent, + _glfw.x11.root, + xpos, ypos, + &xpos, &ypos, + &dummy); + } + + if (xpos != window->x11.xpos || ypos != window->x11.ypos) + { + _glfwInputWindowPos(window, xpos, ypos); + window->x11.xpos = xpos; + window->x11.ypos = ypos; } return;