diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | LICENSE | 21 | ||||
| -rw-r--r-- | Makefile | 27 | ||||
| -rw-r--r-- | README.md | 18 | ||||
| -rw-r--r-- | main.c | 45 |
5 files changed, 112 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..66228a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +xhidecursor @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Aleksandrs Stier + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6320366 --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +PREFIX ?= /usr/local/bin + +CFLAGS += -std=c99 -march=native -O3 -pipe +CFLAGS += -Wall +CFLAGS += -Wconversion +CFLAGS += -Wdouble-promotion +CFLAGS += -Wextra +CFLAGS += -Wmissing-prototypes +CFLAGS += -Wold-style-definition +CFLAGS += -Wpedantic +CFLAGS += -Wshadow + +all: xhidecursor + +xhidecursor: main.c Makefile + $(CC) $(CFLAGS) -o $@ $< -lX11 -lXfixes -lXi + +install: all + install -D xhidecursor $(DESTDIR)$(PREFIX)/xhidecursor + +uninstall: + rm -f $(DESTDIR)$(PREFIX)/xhidecursor + +clean: + rm -f xhidecursor + +.PHONY: all install uninstall clean diff --git a/README.md b/README.md new file mode 100644 index 0000000..3c8e0f2 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +## Description + +[xhidecursor](https://github.com/astier/xhidecursor) is a minimal X-application which hides the cursor on key-press and unhides the cursor on mouse-movement. The two main advantages compared to other popular alternatives like [xbanish](https://github.com/jcs/xbanish) are: + +- **Simplicity:** xhidecursor `~40 SLOC` vs. xbanish `~488 SLOC`. This is because xhidecursor only uses the [XFIXES-Extension](https://cgit.freedesktop.org/xorg/proto/fixesproto/plain/fixesproto.txt) to hide the cursor while xbanish implements many different methods. + +- **Performance:** If stress-tested on a i5-8350U CPU by moving the mouse erratically around htop shows a CPU-Utilization of `0%` for xhidecursor and up to `1.3%` for xbanish. This is because xhidecursor only listens to the first mouse-movement to unhide the cursor and ignores all the following mouse-movements. xbanish on the other hand processes every single mouse-movement even if the mouse is already visible. The same goes for key-presses. + +## Dependencies + +- libxi +- libxifixes + +## Installation + +```sh +make install +``` @@ -0,0 +1,45 @@ +#include <X11/extensions/XInput2.h> + +#include <stdio.h> + +static void xi_select_events(int); + +static Display *d; +static Window r; // root-window + +void xi_select_events(const int event) { + unsigned char mask[3] = {None}; + XISetMask(mask, event); + XIEventMask event_mask; + event_mask.deviceid = XIAllMasterDevices; + event_mask.mask_len = sizeof(mask); + event_mask.mask = mask; + XISelectEvents(d, r, &event_mask, 1); +} + +int main(void) { + if (!(d = XOpenDisplay(NULL))) { + printf("Couldn't open Display.\n"); + return 1; + } + r = XDefaultRootWindow(d); + xi_select_events(XI_RawKeyPress); + XEvent e; + XGenericEventCookie *c; + while (!XNextEvent(d, &e)) { + if (!XGetEventData(d, (c = &e.xcookie))) + continue; + switch (c->evtype) { + case XI_RawKeyPress: + xi_select_events(XI_RawMotion); + XFixesHideCursor(d, r); + break; + case XI_RawMotion: + xi_select_events(XI_RawKeyPress); + XFixesShowCursor(d, r); + break; + } + XFreeEventData(d, c); + } + XCloseDisplay(d); +} |
