@@ -1609,9 +1609,32 @@ static void unredirect(session_t *ps) {
1609
1609
log_debug ("Screen unredirected." );
1610
1610
}
1611
1611
1612
- // Handle queued events before we go to sleep
1612
+ /// Handle queued events before we go to sleep.
1613
+ ///
1614
+ /// This function is called by ev_prepare watcher, which is called just before
1615
+ /// the event loop goes to sleep. X damage events are incremental, which means
1616
+ /// if we don't handle the ones X server already sent us, we won't get new ones.
1617
+ /// And if we don't get new ones, we won't render, i.e. we would freeze. libxcb
1618
+ /// keeps an internal queue of events, so we have to be 100% sure no events are
1619
+ /// left in that queue before we go to sleep.
1613
1620
static void handle_queued_x_events (EV_P attr_unused , ev_prepare * w , int revents attr_unused ) {
1614
1621
session_t * ps = session_ptr (w , event_check );
1622
+ // Flush because if we go into sleep when there is still requests in the
1623
+ // outgoing buffer, they will not be sent for an indefinite amount of
1624
+ // time. Use XFlush here too, we might still use some Xlib functions
1625
+ // because OpenGL.
1626
+ //
1627
+ // Also note, after we have flushed here, we won't flush again in this
1628
+ // function before going into sleep. This is because `xcb_flush`/`XFlush`
1629
+ // may _read_ more events from the server (yes, this is ridiculous, I
1630
+ // know). And we can't have that, see the comments above this function.
1631
+ //
1632
+ // This means if functions called ev_handle need to send some events,
1633
+ // they need to carefully make sure those events are flushed, one way or
1634
+ // another.
1635
+ XFlush (ps -> c .dpy );
1636
+ xcb_flush (ps -> c .c );
1637
+
1615
1638
if (ps -> vblank_scheduler ) {
1616
1639
vblank_handle_x_events (ps -> vblank_scheduler );
1617
1640
}
@@ -1621,13 +1644,6 @@ static void handle_queued_x_events(EV_P attr_unused, ev_prepare *w, int revents
1621
1644
ev_handle (ps , ev );
1622
1645
free (ev );
1623
1646
};
1624
- // Flush because if we go into sleep when there is still
1625
- // requests in the outgoing buffer, they will not be sent
1626
- // for an indefinite amount of time.
1627
- // Use XFlush here too, we might still use some Xlib functions
1628
- // because OpenGL.
1629
- XFlush (ps -> c .dpy );
1630
- xcb_flush (ps -> c .c );
1631
1647
int err = xcb_connection_has_error (ps -> c .c );
1632
1648
if (err ) {
1633
1649
log_fatal ("X11 server connection broke (error %d)" , err );
0 commit comments