Check for pending events after the main loop (#1163)
At the beginning of every main loop iteration, we check for new events from the X11 server. However, it's theoretically possible that during a main loop iteration new events arrive and are read by libxcb into its internal buffer. This would mean that the fd connected to the X11 server is not readable and thus we do not wake up to handle these events. Handle this by checking for pending events before calling poll(). If a new events appears, we set the timeout for poll() to zero and will then handle the new event in the following iteration of the main loop. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
0b17e5dac3
commit
3bd045b57c
19
awesome.c
19
awesome.c
|
@ -295,12 +295,23 @@ acquire_WM_Sn(bool replace)
|
|||
xcb_send_event(globalconf.connection, false, globalconf.screen->root, 0xFFFFFF, (char *) &ev);
|
||||
}
|
||||
|
||||
static xcb_generic_event_t *poll_for_event(void)
|
||||
{
|
||||
if (globalconf.pending_event) {
|
||||
xcb_generic_event_t *event = globalconf.pending_event;
|
||||
globalconf.pending_event = NULL;
|
||||
return event;
|
||||
}
|
||||
|
||||
return xcb_poll_for_event(globalconf.connection);
|
||||
}
|
||||
|
||||
static void
|
||||
a_xcb_check(void)
|
||||
{
|
||||
xcb_generic_event_t *mouse = NULL, *event;
|
||||
|
||||
while((event = xcb_poll_for_event(globalconf.connection)))
|
||||
while((event = poll_for_event()))
|
||||
{
|
||||
/* We will treat mouse events later.
|
||||
* We cannot afford to treat all mouse motion events,
|
||||
|
@ -364,6 +375,12 @@ a_glib_poll(GPollFD *ufds, guint nfsd, gint timeout)
|
|||
lua_settop(L, 0);
|
||||
}
|
||||
|
||||
/* Don't sleep if there is a pending event */
|
||||
assert(globalconf.pending_event == NULL);
|
||||
globalconf.pending_event = xcb_poll_for_event(globalconf.connection);
|
||||
if (globalconf.pending_event != NULL)
|
||||
timeout = 0;
|
||||
|
||||
/* Check how long this main loop iteration took */
|
||||
gettimeofday(&now, NULL);
|
||||
timersub(&now, &last_wakeup, &length_time);
|
||||
|
|
|
@ -192,6 +192,8 @@ typedef struct
|
|||
xcb_void_cookie_t pending_enter_leave_begin;
|
||||
/** List of windows to be destroyed later */
|
||||
window_array_t destroy_later_windows;
|
||||
/** Pending event that still needs to be handled */
|
||||
xcb_generic_event_t *pending_event;
|
||||
} awesome_t;
|
||||
|
||||
extern awesome_t globalconf;
|
||||
|
|
Loading…
Reference in New Issue