From 2296b159cdb5a6010eaa0614fb0ad3c122460a8e Mon Sep 17 00:00:00 2001 From: NRK Date: Sun, 21 May 2023 21:39:16 +0600 Subject: [PATCH] scrotGetGeometry: sleep explicitly this patch simply removes the fluff and indirection and shows what's actually going on already. since we never subscribed to visibility event, we're never going to receive it anyways and will end up sleeping the entire duration. also reduce the sleep from ~300ms to ~160ms, which should be enough for local X server. (note: it's fine to call nanosleep in loop, it's just a fuzzy sleep, doesn't have to be exact). ref: https://github.com/resurrecting-open-source-projects/scrot/issues/274 --- src/scrot.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/src/scrot.c b/src/scrot.c index a5a4918..cae6255 100644 --- a/src/scrot.c +++ b/src/scrot.c @@ -73,7 +73,6 @@ static void uninitXAndImlib(void); static size_t scrotHaveFileExtension(const char *, char **); static Imlib_Image scrotGrabFocused(void); static void applyFilterIfRequired(void); -static Bool scrotXEventVisibility(Display *, XEvent *, XPointer); static Imlib_Image scrotGrabAutoselect(void); static void scrotWaitUntil(const struct timespec *); static Imlib_Image scrotGrabShotMulti(void); @@ -382,24 +381,18 @@ int scrotGetGeometry(Window target, int *rx, int *ry, int *rw, int *rh) /* Get windowmanager frame of window */ if (target != root) { if (findWindowManagerFrame(&target, &frames)) { - /* Get client window. */ if (!opt.border) target = scrotGetClientWindow(disp, target); - XRaiseWindow(disp, target); - /* Give the WM time to update the hidden area of the window. - * Some windows never send the event, a time limit is placed. - */ - XSelectInput(disp, target, FocusChangeMask); - - struct timespec delay = {0, 10000000L}; // 10ms + XRaiseWindow(disp, target); + XSync(disp, False); - for (short i = 0; i < 30; ++i) { - if (XCheckIfEvent(disp, &(XEvent){0}, &scrotXEventVisibility, (XPointer)&target)) - break; - nanosleep(&delay, NULL); - } + /* HACK: there doesn't seem to be any way to figure out whether the + * raise request was accepted or rejected. so just sleep a bit to + * give the WM some time to update. */ + struct timespec t = { .tv_nsec = 160 * 1000L * 1000L }; + while (nanosleep(&t, &t) < 0 && errno == EINTR); } } stat = XGetWindowAttributes(disp, target, &attr); @@ -598,13 +591,6 @@ static void scrotExecApp(Imlib_Image image, struct tm *tm, char *filenameIM, free(execStr); } -static Bool scrotXEventVisibility(Display *dpy, XEvent *ev, XPointer arg) -{ - (void)dpy; // unused - Window *win = (Window *)arg; - return (ev->type == VisibilityNotify && ev->xvisibility.window == *win); -} - static char *imPrintf(const char *str, struct tm *tm, const char *filenameIM, const char *filenameThumb, Imlib_Image im) {