Skip to content

Commit 3ff2fb6

Browse files
committed
clipmenud: Prevent infinite loop in signal handler
When handling an enable/disable signal, clipmenud could enter an infinite loop if another X event was already in the queue. The function to get the server time would repeatedly read and put back the same event at the head of the queue (er, whoops!). Instead use XIfEvent, which doesn't bodge the event queue. Fixes #255.
1 parent 087cf07 commit 3ff2fb6

File tree

1 file changed

+9
-10
lines changed

1 file changed

+9
-10
lines changed

src/clipmenud.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,23 +64,22 @@ static void free_clip_text(struct clip_text *ct) {
6464
ct->source = CLIP_TEXT_SOURCE_INVALID;
6565
}
6666

67+
// cppcheck-suppress [constParameterCallback,unmatchedSuppression]
68+
static Bool is_timestamp_event(Display *display _unused_, XEvent *event,
69+
XPointer arg) {
70+
return event->type == PropertyNotify &&
71+
event->xproperty.atom == *(Atom *)arg;
72+
}
73+
6774
/**
6875
* Get the current X server time by triggering a PropertyNotify.
6976
*/
7077
static Time get_current_server_time(void) {
7178
XEvent ev;
7279
XChangeProperty(dpy, win, timestamp_atom, XA_INTEGER, 32, PropModeReplace,
7380
NULL, 0);
74-
XSync(dpy, False);
75-
76-
while (1) {
77-
XNextEvent(dpy, &ev);
78-
if (ev.type == PropertyNotify && ev.xproperty.atom == timestamp_atom) {
79-
XDeleteProperty(dpy, win, timestamp_atom);
80-
return ev.xproperty.time;
81-
}
82-
XPutBackEvent(dpy, &ev);
83-
}
81+
XIfEvent(dpy, &ev, is_timestamp_event, (XPointer)&timestamp_atom);
82+
return ev.xproperty.time;
8483
}
8584

8685
/**

0 commit comments

Comments
 (0)