diff --git a/find-cursor.1 b/find-cursor.1 index f336a97..808f2b7 100644 --- a/find-cursor.1 +++ b/find-cursor.1 @@ -50,11 +50,11 @@ Maximum size the circle will grow to. .TP \fB-t\fR, \fB--transparent\fR Make the window truly 'transparent'. This helps with some display issues when -following the cursor position, but it doesn't work well with all WMs, which is -why it's disabled by default. +following the cursor position, but it doesn't work well with all window +managers, which is why it's disabled by default. .TP -\fB-w\fR, \fB--wait\fR \fI\,MICROSECONDS\/\fR -Time to wait before drawing the next circle. +\fB-w\fR, \fB--wait\fR \fI\,TIME\/\fR +Time to wait before drawing the next circle, in tenths of milliseconds. .TP \fB-r\fR, \fB--repeat\fR \fI\,N\/\fR Number of times to repeat the animation. Use 0 to repeat indefinitely. @@ -78,7 +78,7 @@ find-cursor --repeat 0 --follow --distance 1 --wait 1 --line-width 16 --size 16 .PP You will want to map a key in your window manager to run \fIfind-cursor\fR. You -can also use \fIxbindkeys\fR, which should work with $any window manager. +can also use \fIxbindkeys\fR, which should work with any window manager. .PP I run it with \fIxcape\fR: .RS diff --git a/find-cursor.c b/find-cursor.c index 195879a..5dcdee8 100644 --- a/find-cursor.c +++ b/find-cursor.c @@ -1,6 +1,6 @@ /* * http://code.arp242.net/find-cursor - * Copyright © 2015-2017 Martin Tournoij + * Copyright © 2015-2020 Martin Tournoij * See below for full copyright */ @@ -22,8 +22,7 @@ void usage(char *name); int parse_num(int ch, char *opt, char *name); -void draw( - char *name, Display *display, int screen, +void draw(char *name, Display *display, int screen, int size, int distance, int wait, int line_width, char *color_name, int follow, int transparent, int grow, int outline, int repeat); @@ -43,7 +42,9 @@ static struct option longopts[] = { }; void usage(char *name) { - printf("Usage: %s [-stplcftgr]\n\n", name); + printf("Usage: %s [-stplcftgr]\n", name); + printf("\n"); + printf("Flags:\n"); printf(" -h, --help Show this help.\n"); printf("\n"); printf("Shape options:\n"); @@ -51,8 +52,8 @@ void usage(char *name) { printf(" -d, --distance Distance between the circles in pixels.\n"); printf(" -l, --line-width Width of the lines in pixels.\n"); printf(" -w, --wait Time to wait before drawing the next circle in\n"); - printf(" microseconds.\n"); - printf(" -c, --color Color; can either be an X11 color name or RGB as hex.\n"); + printf(" tenths of milliseconds.\n"); + printf(" -c, --color Color as X11 color name or RGB (e.g. #ff0000)\n"); printf(" -g, --grow Grow the animation in size, rather than shrinking it.\n"); printf("\n"); printf("Extra options:\n"); @@ -68,12 +69,11 @@ void usage(char *name) { printf("\n"); printf("Examples:\n"); printf(" The defaults:\n"); - printf(" %s --size 320 --distance 40 --wait 400 --line-width 4 --color black\n\n", name); + printf(" %s --size 320 --distance 40 --wait 400 --line-width 4 --color black\n\n", name); printf(" Draw a solid circle:\n"); - printf(" %s --size 100 --distance 1 --wait 20 --line-width 1\n\n", name); + printf(" %s --size 100 --distance 1 --wait 20 --line-width 1\n\n", name); printf(" Always draw a full circle on top of the cursor:\n"); - printf(" %s --repeat 0 --follow --distance 1 --wait 1 --line-width 16 --size 16", name); - printf("\n"); + printf(" %s --repeat 0 --follow --distance 1 --wait 1 --line-width 16 --size 16\n", name); } // Parse number from commandline, or show error and exit if it's not a number. @@ -88,7 +88,6 @@ int parse_num(int ch, char *opt, char *name) { return result; } - int main(int argc, char* argv[]) { // Parse options int size = 320; @@ -166,22 +165,29 @@ int main(int argc, char* argv[]) { } // Actually draw. - do { + do draw(argv[0], display, screen, size, distance, wait, line_width, color_name, follow, transparent, grow, outline, repeat); - } while (repeat == -1 || repeat--); + while (repeat == -1 || repeat--); XCloseDisplay(display); } -void draw( - char *name, Display *display, int screen, +// Try to get the centre of the cursor. +void cursor_center(Display *display, int size, int *x, int *y) { + XFixesCursorImage *c = XFixesGetCursorImage(display); + *x = c->x - size/2 - c->width/2 + c->xhot; + *y = c->y - size/2 - c->height/2 + c->yhot; +} + +void draw(char *name, Display *display, int screen, int size, int distance, int wait, int line_width, char *color_name, int follow, int transparent, int grow, int outline, int repeat ) { // Get the mouse cursor position and size. - XFixesCursorImage *cursor = XFixesGetCursorImage(display); + int center_x, center_y; + cursor_center(display, size, ¢er_x, ¢er_y); // Create a window at the mouse position Window window; @@ -194,8 +200,8 @@ void draw( window_attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone); window_attr.background_pixel = 0; window = XCreateWindow(display, XRootWindow(display, screen), - cursor->x - size/2 - cursor->width/2, // x position - cursor->y - size/2 - cursor->height/2, // y position + center_x, // x position + center_y, // y position size, size, // width, height 4, // border width vinfo.depth, // depth @@ -204,10 +210,10 @@ void draw( CWColormap | CWBorderPixel | CWBackPixel | CWOverrideRedirect, // valuemask &window_attr); // attributes } - else { + else window = XCreateWindow(display, XRootWindow(display, screen), - cursor->x - size/2 - cursor->width/2, // x position - cursor->y - size/2 - cursor->height/2, // y position + center_x, // x position + center_y, // y position size, size, // width, height 4, // border width DefaultDepth(display, screen), // depth @@ -215,7 +221,6 @@ void draw( DefaultVisual(display, screen), // visual CWOverrideRedirect, // valuemask &window_attr); // attributes - } // Make round shaped window. XGCValues xgcv; @@ -229,8 +234,8 @@ void draw( size, size, // Size 0, 360 * 64); // Make it a full circle - XShapeCombineMask(display, window, ShapeBounding, 0,0, shape_mask, ShapeSet); - XShapeCombineMask(display, window, ShapeClip, 0,0, shape_mask, ShapeSet); + XShapeCombineMask(display, window, ShapeBounding, 0, 0, shape_mask, ShapeSet); + XShapeCombineMask(display, window, ShapeClip, 0, 0, shape_mask, ShapeSet); XFreePixmap(display, shape_mask); // Input region is small so we can pass input events. @@ -288,9 +293,10 @@ void draw( color2.red = 65535 - color.red; color2.green = 65535 - color.green; color2.blue = 65535 - color.blue; - sprintf(color2_name,"#%04X%04X%04X", color2.red,color2.green, color2.blue); + sprintf(color2_name, "#%04X%04X%04X", color2.red, color2.green, color2.blue); XAllocNamedColor(display, colormap, color2_name, &color2, &color2); - } else { + } + else { // Set colour only once if not outline. XSetLineAttributes(display, gc, line_width, LineSolid, CapButt, JoinBevel); XSetForeground(display, gc, color.pixel); @@ -299,15 +305,10 @@ void draw( // Draw the circles int i = 1; for (i=1; i<=size; i+=distance) { - if (follow) { + if (follow) XClearWindow(display, window); - } - int cs; - if (grow) - cs = i; - else - cs = size - i; + int cs = grow ? i : size - i; if (outline) { XSetLineAttributes(display, gc, line_width+2, LineSolid, CapButt, JoinBevel); @@ -328,10 +329,8 @@ void draw( 0, 360 * 64); // Make it a full circle if (follow) { - XFixesCursorImage *cursor = XFixesGetCursorImage(display); - XMoveWindow(display, window, - cursor->x - size/2 - cursor->width/2, - cursor->y - size/2 - cursor->height/2); + cursor_center(display, size, ¢er_x, ¢er_y); + XMoveWindow(display, window, center_x, center_y); } XSync(display, False); @@ -346,7 +345,7 @@ void draw( /* * The MIT License (MIT) * - * Copyright © 2015-2017 Martin Tournoij + * Copyright © 2015-2020 Martin Tournoij * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to