diff options
-rw-r--r-- | xdeadzone.1 | 8 | ||||
-rw-r--r-- | xdeadzone.c | 53 | ||||
-rw-r--r-- | xdeadzone.rst | 6 |
3 files changed, 52 insertions, 15 deletions
diff --git a/xdeadzone.1 b/xdeadzone.1 index c6cc0d6..74505d4 100644 --- a/xdeadzone.1 +++ b/xdeadzone.1 @@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. -.TH "XDEADZONE" 1 "2024-02-01" "0.1" "Urchlay's Misc Stuff" +.TH "XDEADZONE" 1 "2024-02-03" "0.1" "Urchlay's Misc Stuff" .SH NAME xdeadzone \- keep the mouse pointer out of the dead zone, on mismatched multihead displays. .\" RST source for xdeadzone(1) man page. Convert with: @@ -63,6 +63,12 @@ it anyway. If you want a titlebar (and a movable window), run with \fB\-n\fP\&. \fBxdeadzone\fP has been tested with various window managers and desktop environments, and works properly with at least: KDE (Plasma 5), XFCE 4, Fmwv2, WindowMaker, BlackBox, and FluxBox. +.sp +As a safety measure, \fBxdeadzone\fP will allow the mouse pointer into +its window if the control key and at least one modifier (left/right +alt, "win" keys) are held down while the mouse is moving. This +prevents e.g. an error in the geometry argument from locking out the +mouse from the wrong part of the screen. .SH OPTIONS .sp Options can appear in any order on the command line. diff --git a/xdeadzone.c b/xdeadzone.c index 35fece6..be0ab92 100644 --- a/xdeadzone.c +++ b/xdeadzone.c @@ -80,8 +80,9 @@ int main(int argc, char **argv) { Window w; XEvent ev; Atom dock_atom; - XWindowAttributes root_attr; + XWindowAttributes w_attr, root_attr; XSetWindowAttributes setattr; + XSizeHints hints; int x = -1, y = -1, gflags = -1, visible = 0, black = 0, mode = M_UNSET, normal_window = 0; unsigned int width, height; @@ -194,7 +195,7 @@ int main(int argc, char **argv) { BlackPixel(d, DefaultScreen(d)) : WhitePixel(d, DefaultScreen(d)); } - setattr.event_mask = EnterWindowMask; + setattr.event_mask = EnterWindowMask | VisibilityChangeMask | StructureNotifyMask; w = XCreateWindow(d, DefaultRootWindow(d), @@ -207,6 +208,13 @@ int main(int argc, char **argv) { DBG(printf("window created\n")); + if(!normal_window) { + hints.min_width = hints.max_width = hints.width = width; + hints.min_height = hints.max_height = hints.height = height; + hints.flags = PSize | PMinSize | PMaxSize; + XSetWMNormalHints(d, w, &hints); + } + XStoreName(d, w, NAME); /* On most window managers, this makes the window stay on top and @@ -234,12 +242,26 @@ int main(int argc, char **argv) { ignored the x and y in the XCreateWindow(). */ XMoveWindow(d, w, x, y); - DBG(printf("awaiting EnterNotify events...\n")); + DBG(printf("awaiting events...\n")); while(1) { XNextEvent(d, &ev); + if(ev.type == VisibilityNotify) { + XRaiseWindow(d, w); + XFlush(d); + } + + if(!normal_window && ev.type == ConfigureNotify) { + XMoveResizeWindow(d, w, x, y, width, height); + XFlush(d); + } + if(ev.type == EnterNotify && !ctrl_and_mod(ev.xcrossing.state)) { - new_x = ev.xcrossing.x_root; - new_y = ev.xcrossing.y_root; + Window dummy; + int real_x, real_y; + XGetWindowAttributes(d, w, &w_attr); + XTranslateCoordinates(d, w, DefaultRootWindow(d), 0, 0, &real_x, &real_y, &dummy); + + DBG(printf("Got EnterNotify, real_x %d, real_y %d, height %d, width %d\n", real_x, real_y, w_attr.height, w_attr.width)); /* Where do we warp the pointer to? It would be better if we had a way to find out @@ -248,22 +270,25 @@ int main(int argc, char **argv) { of deadzones in the corner of the screen, the dumb logic below is good enough. */ - if(height < root_attr.height) { + new_x = ev.xcrossing.x_root; + new_y = ev.xcrossing.y_root; + + if(w_attr.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. */ + if(w_attr.y == 0) + new_y = real_y + w_attr.height; /* it's at the top, warp down. */ else - new_y = y - 1; /* it's not at the top, warp up */ + new_y = real_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 */ + if(w_attr.x == 0) + new_x = real_x + w_attr.width; /* it's at the left edge, warp right */ else - new_x = x - 1; /* it's not at the left edge, warp left */ + new_x = real_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)); + DBG(printf(" old X/Y were %d, %d, new X/Y are %d, %d\n", + ev.xcrossing.x_root, ev.xcrossing.y_root, new_x, new_y)); XWarpPointer(d, None, diff --git a/xdeadzone.rst b/xdeadzone.rst index 1226907..5b77573 100644 --- a/xdeadzone.rst +++ b/xdeadzone.rst @@ -50,6 +50,12 @@ it anyway. If you want a titlebar (and a movable window), run with **-n**. environments, and works properly with at least: KDE (Plasma 5), XFCE 4, Fmwv2, WindowMaker, BlackBox, and FluxBox. +As a safety measure, **xdeadzone** will allow the mouse pointer into +its window if the control key and at least one modifier (left/right +alt, "win" keys) are held down while the mouse is moving. This +prevents e.g. an error in the geometry argument from locking out the +mouse from the wrong part of the screen. + OPTIONS ======= |