fix(canvas): paint the committed shape before the label dialog opens - #2429
Merged
Conversation
_reset_after_shape_creation emitted new_shape, whose handler blocks on the modal label dialog, before invalidating the canvas, so the canvas was only repainted once the dialog closed. Whether the new shape was visible behind the dialog came down to whether a paint request happened to still be pending when the shape was committed: if one was, the dialog's own event loop flushed it and the shape appeared; if not, the dialog opened over the previous frame. AI-Box is where this is most visible because its last painted frame is the drag bbox rather than the segmentation result. Point mode can also finalize before any matching preview is painted. Other create modes leave a preview that already matches the committed geometry. Repaint synchronously before emitting so the shape is on screen regardless of the pending-paint state.
wkentaro
force-pushed
the
fix/canvas-paint-shape-before-label-dialog
branch
from
July 29, 2026 22:56
881ee7b to
3155734
Compare
Owner
Author
|
confirmed this only happens on linux (not on macOS) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An AI-Box annotation opens the label dialog over a canvas that still shows the
drag bbox, not the segmentation it is asking you to name.
_reset_after_shape_creationemitsnew_shape, whose handler blocks in_label_dialog.popup()->exec(), before invalidating the canvas, so thecommitted shape is only scheduled for repaint after the dialog closes.
Three non-obvious bits:
It presents as intermittent rather than always broken. If a paint request
from the drag is still pending when the second click lands, the dialog's own
nested event loop flushes it, and because
self.shapeswas already extendedit happens to render the new shape. When nothing is pending, which is the
normal case once the drag repaints have drained, the dialog opens over the
previous frame. Stack traces confirmed both paths, and this is why the
existing GUI tests never caught it.
AI-Box is where this is most visible. Its last painted frame is the drag bbox
because
_build_preview_shapereturnsNone, so the segmentation result ismissing entirely. Point mode can also finalize before any matching preview is
painted. Other create modes leave a preview that already matches the
committed geometry.
repaint()is required rather than hoisting the existingupdate()abovethe emit.
update()only posts an event, so it would still depend on themodal loop delivering it, which is the same mechanism that masks the bug
today. The trailing
update()stays because the handler mutates shapesafterwards by applying labels on accept or calling
undo_last_line()oncancel.
Test plan
tests/unit/widgets/canvas_test.py::test_finalize_paints_new_shape_before_notifyingasserts that the shape is painted by the time
new_shapefires; verifiedfor point mode and both AI create modes
bbox only before, segmentation polygon after
make lint