Title says it all.
The code works with the XPeekEvent
right before the while XCheckTypedEvent
but without that the conditional evaluates to false and I have no idea why that might be.
#include <X11/Xlib.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define false 0
#define true 1
int main(void)
{
Display* dpy;
XWindowAttributes attr;
// state of cursor at the start of move/resize
XButtonEvent cur_start;
// return failure status if we can't connect
if (!(dpy = XOpenDisplay(0x0))) return 1;
char* keys_to_grab[] = {"F1"};
for (size_t i = 0; i < sizeof(keys_to_grab) / sizeof(keys_to_grab[0]); i++)
{
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym(keys_to_grab[i])), Mod1Mask,
DefaultRootWindow(dpy), True, GrabModeAsync, GrabModeAsync);
}
XGrabButton(dpy, 1, Mod1Mask, DefaultRootWindow(dpy), True,
ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(dpy, 3, Mod1Mask, DefaultRootWindow(dpy), True,
ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
cur_start.subwindow = None;
for(;;)
{
XNextEvent(dpy, &ev);
switch(ev.type)
{
case KeyPress:
if (ev.xkey.subwindow != None)
XRaiseWindow(dpy, ev.xkey.subwindow);
break;
case ButtonPress:
if (ev.xbutton.subwindow != None)
cur_start = ev.xbutton;
break;
case MotionNotify:
if (cur_start.subwindow != None)
{
XPeekEvent(dpy, &ev);
while(XCheckTypedEvent(dpy, MotionNotify, &ev))
{
int xdiff = ev.xbutton.x_root - cur_start.x_root;
int ydiff = ev.xbutton.y_root - cur_start.y_root;
XMoveWindow(dpy, cur_start.subwindow,
attr.x + (cur_start.button==1 ? xdiff : 0),
attr.y + (cur_start.button==1 ? ydiff : 0));
}
}
break;
case ButtonRelease:
cur_start.subwindow = None;
break;
default:
break;
}
}
}
This is how I run the code: xinit ./xinitrc -- /usr/bin/Xephyr :100 -ac -screen 500x500 -host-cursor
With this as the xinitrc:
xclock &
xeyes &
sleep 2 && xterm &
exec ./a.out
and by “works”, I mean I can drag the windows around.