]> git.tdb.fi Git - libs/gui.git/blobdiff - source/graphics/x11/window.cpp
Don't apply user position in fullscreen mode
[libs/gui.git] / source / graphics / x11 / window.cpp
index 577f1d42d65f41af62b08d10c9d57f23167dbc12..0b9eacb41187f138153b71674b26b7ebdd0daa41 100644 (file)
@@ -1,9 +1,6 @@
 #include <vector>
 #include <X11/Xatom.h>
 #include <X11/Xutil.h>
-#ifdef WITH_XF86VIDMODE
-#include <X11/extensions/xf86vmode.h>
-#endif
 #include <msp/core/systemerror.h>
 #include "display_private.h"
 #include "window.h"
@@ -29,14 +26,27 @@ 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;
-       attr.event_mask = ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask|EnterWindowMask;
+       attr.event_mask = ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask|EnterWindowMask|ExposureMask|FocusChangeMask;
+
+       // User position is set when the window is mapped
+       int x = 0;
+       int y = 0;
+       if(options.fullscreen && !options.fullscreen_exclusive)
+       {
+               const Monitor::Settings &ms = options.fullscreen_monitor->current_settings;
+               x = ms.x;
+               y = ms.y;
+       }
 
        priv->window = XCreateWindow(dpy,
-               DefaultRootWindow(dpy),
-               0, 0,
+               display.get_private().root_window,
+               x, y,
                options.width, options.height,
                0,
                CopyFromParent,
@@ -111,7 +121,17 @@ void Window::platform_reconfigure(bool fullscreen_changed)
        XSetWMNormalHints(dpy, priv->window, &hints);
 
        if(options.fullscreen)
-               XMoveResizeWindow(dpy, priv->window, 0, 0, options.width, options.height);
+       {
+               if(options.fullscreen_exclusive)
+                       XMoveResizeWindow(dpy, priv->window, 0, 0, options.width, options.height);
+               else
+               {
+                       const Monitor::Settings &ms = options.fullscreen_monitor->current_settings;
+                       XMoveResizeWindow(dpy, priv->window, ms.x, ms.y, options.width, options.height);
+               }
+       }
+       else if(options.user_position)
+               XMoveResizeWindow(dpy, priv->window, options.x, options.y, options.width, options.height);
        else
                XResizeWindow(dpy, priv->window, options.width, options.height);
 
@@ -154,9 +174,16 @@ void Window::warp_pointer(int x, int y)
        XWarpPointer(display.get_private().display, None, priv->window, 0, 0, 0, 0, x, y);
 }
 
+void Window::platform_set_touch_input()
+{
+}
+
 void Window::platform_show()
 {
-       XMapRaised(display.get_private().display, priv->window);
+       DisplayHandle dpy = display.get_private().display;
+       XMapRaised(dpy, priv->window);
+       if(options.user_position && !options.fullscreen)
+               XMoveWindow(dpy, priv->window, options.x, options.y);
 }
 
 void Window::platform_hide()
@@ -184,14 +211,47 @@ bool Window::event(const Event &evnt)
                        resizing = false;
                        signal_resize.emit(options.width, options.height);
                }
-#ifdef WITH_XF86VIDMODE
-               if(options.fullscreen)
+
                {
-                       DisplayHandle dpy = display.get_private().display;
-                       int screen = DefaultScreen(dpy);
-                       XF86VidModeSetViewPort(dpy, screen, ev.xconfigure.x, ev.xconfigure.y);
+                       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) == moving)
+                       {
+                               options.x = x;
+                               options.y = y;
+                               moving = false;
+                               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;
                }
-#endif
                break;
        case ClientMessage:
                if(ev.xclient.data.l[0]==static_cast<long>(priv->wm_delete_window))
@@ -202,9 +262,18 @@ bool Window::event(const Event &evnt)
                        XSetInputFocus(display.get_private().display, priv->window, RevertToParent, CurrentTime);
                break;
        case MapNotify:
-               if(options.fullscreen)
+               if(options.fullscreen && options.fullscreen_exclusive)
                        XGrabPointer(display.get_private().display, priv->window, true, None, GrabModeAsync, GrabModeAsync, priv->window, None, CurrentTime);
                break;
+       case Expose:
+               signal_expose.emit(ev.xexpose.x, ev.xexpose.y, ev.xexpose.width, ev.xexpose.height, evnt);
+               break;
+       case FocusIn:
+               signal_got_focus.emit();
+               break;
+       case FocusOut:
+               signal_lost_focus.emit();
+               break;
        default:
                return false;
        }