aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2024-02-03 01:12:00 -0500
committerB. Watson <urchlay@slackware.uk>2024-02-03 01:12:00 -0500
commit6ff7f20633bd60e6a4a71170d6837659547ef068 (patch)
treee3ce91e8433ad46d7e54364361f011b7ccd72157
parent9416fb792b4c0f5e71f90a632c4eebaf2c06a368 (diff)
downloadxdeadzone-6ff7f20633bd60e6a4a71170d6837659547ef068.tar.gz
Smarter warp direction, allow ctrl plus any mod key to override.
-rw-r--r--xdeadzone.c53
1 files 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);
}
}