From 6ff7f20633bd60e6a4a71170d6837659547ef068 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Sat, 3 Feb 2024 01:12:00 -0500 Subject: Smarter warp direction, allow ctrl plus any mod key to override. --- xdeadzone.c | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/xdeadzone.c b/xdeadzone.c index 3d7bc78..376794f 100644 --- a/xdeadzone.c +++ b/xdeadzone.c @@ -67,16 +67,25 @@ int streq(const char *s1, const char *s2) { return !strcmp(s1, s2); } +/* return true if control + any of the Mod[1-5] are both pressed. */ +int ctrl_and_mod(unsigned int state) { + if(state & ControlMask) + if(state & (Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)) + return 1; + return 0; +} + int main(int argc, char **argv) { Display *d; Window w; XEvent ev; Atom dock_atom; - XWindowAttributes attr; + XWindowAttributes root_attr; XSetWindowAttributes setattr; int x = -1, y = -1, gflags = -1, visible = 0, black = 0, mode = M_UNSET, normal_window = 0; unsigned int width, height; + int new_x, new_y; set_exe_name(argv[0]); @@ -160,17 +169,17 @@ int main(int argc, char **argv) { if(!(d = XOpenDisplay(NULL))) errmsg("can't open X display"); - XGetWindowAttributes(d, DefaultRootWindow(d), &attr); + XGetWindowAttributes(d, DefaultRootWindow(d), &root_attr); if(mode == M_ABS) { - if(gflags & XNegative) x = (attr.width + x) - width; - if(gflags & YNegative) y = (attr.height + y) - height; + if(gflags & XNegative) x = (root_attr.width + x) - width; + if(gflags & YNegative) y = (root_attr.height + y) - height; } else { - if(x < 0) x = (attr.width + x); - if(y < 0) y = (attr.height + y); + if(x < 0) x = (root_attr.width + x); + if(y < 0) y = (root_attr.height + y); } DBG(printf("X size %d x %d, x %d, y %d, width %d, height %d\n", - attr.width, attr.height, x, y, width, height)); + root_attr.width, root_attr.height, x, y, width, height)); /* Create window with override_redirect enabled, to tell the window manager not to decorate it with a titlebar or resize frame. @@ -228,17 +237,39 @@ int main(int argc, char **argv) { DBG(printf("awaiting EnterNotify events...\n")); while(1) { XNextEvent(d, &ev); - if(ev.type == EnterNotify) { - /* warp down if at top of screen */ - int new_y = (y == 0 ? y + height : y - 1); + if(ev.type == EnterNotify && !ctrl_and_mod(ev.xcrossing.state)) { + new_x = ev.xcrossing.x_root; + new_y = ev.xcrossing.y_root; + + /* Where do we warp the pointer to? + It would be better if we had a way to find out + the previous pointer position, so we could know which + direction it's moving. But, in the specific (but usual) case + of deadzones in the corner of the screen, the dumb logic + below is good enough. */ + + if(height < root_attr.height) { + /* window is less than full height of the screen, warp vertically */ + if(y == 0) + new_y = height; /* it's at the top, warp down. */ + else + new_y = y - 1; /* it's not at the top, warp up */ + } else { + /* window *is* full height of the screen, have to warp horizonally */ + if(x == 0) + new_x = width; /* it's at the left edge, warp right */ + else + new_x = x - 1; /* it's not at the left edge, warp left */ + } DBG(printf("Got EnterNotify, coords %d, %d, new Y is %d\n", ev.xcrossing.x_root, ev.xcrossing.y_root, new_y)); + XWarpPointer(d, None, DefaultRootWindow(d), 0, 0, 0, 0, - ev.xcrossing.x_root, + new_x, new_y); } } -- cgit v1.2.3