aboutsummaryrefslogtreecommitdiff
path: root/1
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2024-01-31 01:07:09 -0500
committerB. Watson <urchlay@slackware.uk>2024-01-31 01:07:09 -0500
commitd20d7a88902659b28369b56ab5d1447b775fb7a1 (patch)
tree97d3c76b7193e40215afc4b423943f3eca1ea029 /1
downloadxdeadzone-d20d7a88902659b28369b56ab5d1447b775fb7a1.tar.gz
Initial commit.
Diffstat (limited to '1')
-rw-r--r--1166
1 files changed, 166 insertions, 0 deletions
diff --git a/1 b/1
new file mode 100644
index 0000000..d0725da
--- /dev/null
+++ b/1
@@ -0,0 +1,166 @@
+/*
+ xdeadzone - create a window and don't allow the mouse pointer to enter it.
+
+ compile me with:
+
+ gcc -Wall -o xdeadzone xdeadzone.c -lX11
+
+ run me with ./xdeadzone, and be prepared to hit ^C or use kill to exit,
+ since it doesn't have any other way to exit (currently).
+*/
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifndef VERSION
+# define VERSION "UnknownVersion"
+#endif
+
+#define NAME "XDeadZone"
+
+const char *exename;
+
+void set_exename(const char *p) {
+ exename = p;
+ while(*p) {
+ if(*p == '/') exename = p + 1;
+ p++;
+ }
+ printf("exename: %s\n", exename);
+}
+
+void usage(char *name, int ret) {
+ printf(
+ NAME " " VERSION "\n"
+ "Usage:\n %s "
+ "[-nw | -ne | -sw | -se | -abs xpos ypos] [width] [height]"
+ "\n",
+ name);
+ exit(ret);
+}
+
+void errmsg(char *name, char *msg) {
+ fprintf(stderr, "%s: %s\n", name, msg);
+ usage(name, 1);
+}
+
+int main(int argc, char **argv) {
+ Display *d;
+ Window w;
+ XEvent ev;
+ Atom dock_atom;
+ XWindowAttributes attr;
+ XSetWindowAttributes setattr;
+ int screen;
+
+ int done = 0;
+ int x = 0, y = 0, width = 0, height = 0;
+
+ if(argc == 2 && strcmp(argv[1], "--help") == 0)
+ usage(argv[0], 0);
+
+ if(strcmp(argv[1], "-abs") == 0) {
+ if(argc != 6)
+ errmsg(argv[0], "wrong number of arguments for -abs");
+ x = atoi(argv[2]);
+ y = atoi(argv[3]);
+ width = atoi(argv[4]);
+ height = atoi(argv[5]);
+ } else {
+ if(argc != 4)
+ errmsg(argv[0], "wrong number of arguments for -nw/-ne/-sw/-se");
+ width = atoi(argv[2]);
+ height = atoi(argv[3]);
+ if(strcmp(argv[1], "-nw") == 0) {
+ x = 0; y = 0;
+ } else if(strcmp(argv[1], "-ne") == 0) {
+ x = -width; y = 0;
+ } else if(strcmp(argv[1], "-sw") == 0) {
+ x = 0; y = -height;
+ } else if(strcmp(argv[1], "-se") == 0) {
+ x = -width; y = -height;
+ } else {
+ errmsg(argv[0], "invalid 1st argument (not -abs/-nw/-ne/-sw/-se)");
+ }
+ }
+
+ if(width <= 0 || height <= 0)
+ errmsg(argv[0], "width and height must be positive and non-zero");
+
+ if(!(d = XOpenDisplay(NULL)))
+ errmsg(argv[0], "can't open X display");
+
+ XGetWindowAttributes(d, DefaultRootWindow(d), &attr);
+ if(x < 0) x = attr.width + x;
+ if(y < 0) y = attr.height + y;
+
+ printf("X size %d x %d, x %d, y %d, width %d, height %d\n", attr.width, 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.
+ Also, we really only care about EnterNotify events.
+ Set the window to solid white, to make it easy to see during testing.
+ In actual use, the window won't be visible, it'll be in the dead zone,
+ right?
+ */
+ screen = DefaultScreen(d);
+ setattr.override_redirect = True;
+ setattr.background_pixel = WhitePixel(d, screen);
+ setattr.event_mask = EnterWindowMask;
+
+ w = XCreateWindow(d,
+ RootWindow(d, screen),
+ x, y, width, height, 0,
+ DefaultDepth(d, screen),
+ InputOutput,
+ DefaultVisual(d, screen),
+ CWBackPixel | CWOverrideRedirect | CWEventMask,
+ &setattr);
+
+ XStoreName(d, w, NAME);
+
+ /* On most window managers, this makes the window stay on top and
+ be present on all virtual desktops. Tested, works with WindowMaker, Fvwm2,
+ KDE5, XFCE4, BlackBox, and FluxBox. On all but Fvwm2, it also
+ disappears the titlebar and resize frame... but we already took
+ care of that with override_redirect, above.
+ ref: http://standards.freedesktop.org/wm-spec/wm-spec-latest.html
+ */
+ dock_atom = XInternAtom(d, "_NET_WM_WINDOW_TYPE_DOCK", False);
+ XChangeProperty(d,
+ w,
+ XInternAtom(d, "_NET_WM_WINDOW_TYPE", False),
+ XA_ATOM,
+ 32,
+ PropModeReplace,
+ (unsigned char *) &dock_atom,
+ 1);
+
+ XMapWindow(d, w);
+
+ /* have to do this after it's mapped, since the window manager might have
+ ignored the x and y in the XCreateWindow(). */
+ XMoveWindow(d, w, x, y);
+
+ while(!done) {
+ XNextEvent(d, &ev);
+ if(ev.type == EnterNotify) {
+ // printf("entered at %d, %d\n", ev.xcrossing.x_root, ev.xcrossing.y_root);
+ XWarpPointer(d,
+ None,
+ DefaultRootWindow(d),
+ 0, 0, 0, 0,
+ ev.xcrossing.x_root,
+ (y == 0 ? y + height : y - 1));
+ }
+ }
+
+ XUnmapWindow(d, w);
+ XDestroyWindow(d, w);
+ XCloseDisplay(d);
+
+ return 0;
+}