From: Mikko Rasa Date: Sun, 20 Dec 2015 13:43:35 +0000 (+0200) Subject: Track window positions X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=f6ca714e2258f4cad433801c88264947d4c2d14c;p=libs%2Fgui.git Track window positions --- diff --git a/source/graphics/window.cpp b/source/graphics/window.cpp index d2fb37f..5bc9a35 100644 --- a/source/graphics/window.cpp +++ b/source/graphics/window.cpp @@ -9,6 +9,8 @@ namespace Msp { namespace Graphics { WindowOptions::WindowOptions(): + x(0), + y(0), width(640), height(480), fullscreen(false), diff --git a/source/graphics/window.h b/source/graphics/window.h index b2c7833..8065762 100644 --- a/source/graphics/window.h +++ b/source/graphics/window.h @@ -11,6 +11,8 @@ class Display; struct WindowOptions { + int x; + int y; unsigned width; unsigned height; bool fullscreen; @@ -30,6 +32,7 @@ public: objects instead. */ sigc::signal signal_input_event; + sigc::signal signal_move; sigc::signal signal_resize; sigc::signal signal_expose; sigc::signal signal_close; diff --git a/source/graphics/windows/window.cpp b/source/graphics/windows/window.cpp index 68baea7..b148915 100644 --- a/source/graphics/windows/window.cpp +++ b/source/graphics/windows/window.cpp @@ -180,6 +180,11 @@ bool Window::event(const Event &evnt) resizing = false; signal_resize.emit(options.width, options.height); break; + case WM_MOVE: + options.x = static_cast(LOWORD(evnt.lparam)); + options.y = static_cast(HIWORD(evnt.lparam)); + signal_move.emit(options.x, options.y); + break; case WM_CLOSE: signal_close.emit(); break; diff --git a/source/graphics/x11/window.cpp b/source/graphics/x11/window.cpp index 2c03bf7..9b46e4e 100644 --- a/source/graphics/x11/window.cpp +++ b/source/graphics/x11/window.cpp @@ -26,6 +26,9 @@ void Window::platform_init() priv->wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", true); priv->invisible_cursor = 0; + priv->reparented = false; + priv->rel_x = 0; + priv->rel_y = 0; XSetWindowAttributes attr; attr.override_redirect = options.fullscreen; @@ -185,6 +188,46 @@ bool Window::event(const Event &evnt) resizing = false; signal_resize.emit(options.width, options.height); } + + { + int x = ev.xconfigure.x; + int y = ev.xconfigure.y; + + if(priv->reparented) + { + if(!ev.xconfigure.send_event) + { + /* If the window manager reparented us, the coordinates of a + real event are in the parent window's space. */ + priv->rel_x = ev.xconfigure.x; + priv->rel_y = ev.xconfigure.y; + + const Display::Private &dpy_priv = display.get_private(); + WindowHandle dummy; + XTranslateCoordinates(dpy_priv.display, priv->window, dpy_priv.root_window, 0, 0, &x, &y, &dummy); + } + + // Use the coordinates of the window manager frame + x -= priv->rel_x; + y -= priv->rel_y; + } + + if(x!=options.x || y!=options.y) + { + options.x = x; + options.y = y; + signal_move.emit(options.x, options.y); + } + } + + break; + case ReparentNotify: + priv->reparented = (ev.xreparent.parent!=display.get_private().root_window); + if(!priv->reparented) + { + priv->rel_x = 0; + priv->rel_y = 0; + } break; case ClientMessage: if(ev.xclient.data.l[0]==static_cast(priv->wm_delete_window)) diff --git a/source/graphics/x11/window_platform.h b/source/graphics/x11/window_platform.h index 3c81a6e..41cdec8 100644 --- a/source/graphics/x11/window_platform.h +++ b/source/graphics/x11/window_platform.h @@ -12,6 +12,9 @@ struct PlatformWindowPrivate { Atom wm_delete_window; Cursor invisible_cursor; + bool reparented; + int rel_x; + int rel_y; }; struct PlatformEvent