#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"
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;
priv->window = XCreateWindow(dpy,
- DefaultRootWindow(dpy),
- 0, 0,
+ display.get_private().root_window,
+ 0, 0, // User position is set when the window is mapped
options.width, options.height,
0,
CopyFromParent,
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);
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)
+ XMoveWindow(dpy, priv->window, options.x, options.y);
}
void Window::platform_hide()
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))
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;
}