diff --git a/frame_clock.c b/frame_clock.c index 7447ead..5387e3e 100644 --- a/frame_clock.c +++ b/frame_clock.c @@ -367,7 +367,23 @@ StartFrame (FrameClock *clock, Bool urgent, Bool predict) return False; if (clock->in_frame) - return False; + { + if (clock->end_frame_timer + /* If the end of the frame is still pending but EndFrame has + been called, then treat the frame as if it has just been + started. */ + && clock->end_frame_called) + { + /* In addition, require another EndFrame for the frame to + end. */ + clock->end_frame_called = False; + return True; + } + + /* Otherwise it genuinely is invalid to call StartFrame here, so + return False. */ + return False; + } if (clock->need_configure) { diff --git a/subcompositor.c b/subcompositor.c index a4b0a3e..21d9c7d 100644 --- a/subcompositor.c +++ b/subcompositor.c @@ -3063,8 +3063,8 @@ SubcompositorLookupView (Subcompositor *subcompositor, int x, int y, /* Now see if the input region contains the given coordinates. If it does, return the view. */ - if (pixman_region32_contains_point (&list->view->input, x, y, - &box)) + if (pixman_region32_contains_point (&list->view->input, temp_x, + temp_y, &box)) { *view_x = list->view->abs_x - subcompositor->min_x; *view_y = list->view->abs_y - subcompositor->min_y; diff --git a/xdg_surface.c b/xdg_surface.c index 424259a..18ec0f3 100644 --- a/xdg_surface.c +++ b/xdg_surface.c @@ -1235,9 +1235,11 @@ NoteFrame (FrameMode mode, uint64_t id, void *data) /* Record this frame counter as the pending frame. */ role->pending_frame = id; - if (!(role->state & StateFrameStarted) - && XLFrameClockStartFrame (role->clock, False)) - role->state |= StateFrameStarted; + if (!(role->state & StateFrameStarted)) + { + if (XLFrameClockStartFrame (role->clock, False)) + role->state |= StateFrameStarted; + } /* Also run role "commit inside frame" hook. */ if (role->impl && role->impl->funcs.commit_inside_frame) @@ -1265,26 +1267,16 @@ NoteFrame (FrameMode mode, uint64_t id, void *data) /* End the frame. */ XLFrameClockEndFrame (role->clock); - /* Clear the frame completed flag. */ - role->state &= ~StateFrameStarted; - - /* Clients which commit when a configure event that has not - yet been acked still expect frame callbacks to be called; - however, frame callbacks are not provided by the frame - clock while it is frozen. - - If that happens, just run the frame callback - immediately. */ - if (XLFrameClockIsFrozen (role->clock) - /* If the window is not mapped, then the native frame - clock will not draw frames. Some clients do commit - before the initial configure event and wait for the - frame callback to be called after or before - ack_configure, leading to the mapping commit never - being performed. */ + /* No frame was started clock-side for this frame. That + means programs waiting for frame callbacks will not get + any, so the frame callbacks must be run by hand. */ + if (!(role->state & StateFrameStarted) || !IsRoleMapped (role)) RunFrameCallbacksConditionally (role); + /* Clear the frame completed flag. */ + role->state &= ~StateFrameStarted; + if (mode == ModePresented && renderer_flags & SupportsDirectPresent) {