X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgraphics%2Fx11%2Fwindow.cpp;h=0b9eacb41187f138153b71674b26b7ebdd0daa41;hb=1d0d0b91c1df8b563d1f8817e042ebdc06762236;hp=577f1d42d65f41af62b08d10c9d57f23167dbc12;hpb=1aca77b93853ee127ac3bbf6886f7f04920542ef;p=libs%2Fgui.git diff --git a/source/graphics/x11/window.cpp b/source/graphics/x11/window.cpp index 577f1d4..0b9eacb 100644 --- a/source/graphics/x11/window.cpp +++ b/source/graphics/x11/window.cpp @@ -1,9 +1,6 @@ #include #include #include -#ifdef WITH_XF86VIDMODE -#include -#endif #include #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(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; }