]> git.tdb.fi Git - libs/gui.git/commitdiff
Track window positions
authorMikko Rasa <tdb@tdb.fi>
Sun, 20 Dec 2015 13:43:35 +0000 (15:43 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 20 Dec 2015 13:43:35 +0000 (15:43 +0200)
source/graphics/window.cpp
source/graphics/window.h
source/graphics/windows/window.cpp
source/graphics/x11/window.cpp
source/graphics/x11/window_platform.h

index d2fb37f893d23379a1df46914b175f3a7312bdc5..5bc9a358e2786d99e7ba7e4be1c63b6dce20afa8 100644 (file)
@@ -9,6 +9,8 @@ namespace Msp {
 namespace Graphics {
 
 WindowOptions::WindowOptions():
+       x(0),
+       y(0),
        width(640),
        height(480),
        fullscreen(false),
index b2c7833c1db844957b09d39df9b1cbe6876dbdb5..8065762a4b2cc57d826db9f904f594de17365b96 100644 (file)
@@ -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<void, const Event &> signal_input_event;
 
+       sigc::signal<void, int, int> signal_move;
        sigc::signal<void, unsigned, unsigned> signal_resize;
        sigc::signal<void, unsigned, unsigned, unsigned, unsigned, const Event &> signal_expose;
        sigc::signal<void> signal_close;
index 68baea71ed2d9c91a05d99ef42fd1fe844e3a8c8..b148915d9bc94b6581037a682c3982c0bf78212f 100644 (file)
@@ -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<short>(LOWORD(evnt.lparam));
+               options.y = static_cast<short>(HIWORD(evnt.lparam));
+               signal_move.emit(options.x, options.y);
+               break;
        case WM_CLOSE:
                signal_close.emit();
                break;
index 2c03bf745570f7d2680257e30491e4fd56af2403..9b46e4e16593cfe4abe1e760d2cdf832a4593d26 100644 (file)
@@ -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<long>(priv->wm_delete_window))
index 3c81a6e76559c99c22eaf5ad9dc8471f2d9efacc..41cdec8f2f32dc08931d20d00bc332c003d91a01 100644 (file)
@@ -12,6 +12,9 @@ struct PlatformWindowPrivate
 {
        Atom wm_delete_window;
        Cursor invisible_cursor;
+       bool reparented;
+       int rel_x;
+       int rel_y;
 };
 
 struct PlatformEvent