Skip to content

frame-clock: Don't stop paint idle from flush idle

Sebastian Keller requested to merge skeller/gtk:fix-frame-clock-freeze into main

If one of the pointer motions handled in the flush idle after the toplevel surface has been frozen (awaiting a frame event) ends up calling maybe_stop_idle() via gdk_frame_clock_idle_freeze(), such as when opening a new popup surface or hiding an existing one, this can lead to the frame clock getting stuck.

Calling maybe_stop_idle() in this situation will cancel any scheduled paint idle and no new one will be scheduled either until any surface is thawed again due to some event, such as the requested frame event from the main surface. If no such event is triggered during the flush idle, the frame clock will remain frozen forever, because gdk_surface_flush_events() pauses the display event handler, blocking any future events until "resume-events" is emitted by the paint idle. This leaves us with a situation in which no paint idle is scheduled until there is a frame event to thaw the surface and no frame event is handled until a paint idle emits "resume-events".

This situation became much more likely after 4bf07aee, especially when quickly showing/hiding tooltips, such as during browse mode. Prior to that commit when hiding the tooltip surface, it was not immediately frozen, but only at its delayed (via another idle) destruction. After that commit queued motion events can now lead to tooltip surfaces being frozen immediately, which then could trigger maybe_stop_idle() from the flush idle.

Avoid this by not allowing the paint idle to be canceled from the flush idle.

Closes: #4941 (closed)

Merge request reports