FIX: Prevent Cursor lag on move by using draw_idle instead of draw#31426
FIX: Prevent Cursor lag on move by using draw_idle instead of draw#31426MohitPal2005 wants to merge 6 commits intomatplotlib:mainfrom
Conversation
|
Hi, I have updated the PR based on the CI feedback and restored the correct rendering behavior. Initially, I attempted to use All CI checks are now passing successfully. Kindly review when you have time. Thanks! |
There was a problem hiding this comment.
Do you understand the needclear logic? I don’t, which is why I cannot judge whether using the background is valid here. Or to phrase it differently, the existing implementation uses blit in other places. Are you sure not using blit here was an oversight and we can safely change to it?
|
Hi @timhoffm, thanks for raising this — that’s a very helpful point. From my understanding, Regarding the use of blitting, I initially thought it might be possible to reuse the saved background (as is done in the main drawing path) to clear the cursor more efficiently. However, I’m not fully certain that the background is always valid or up-to-date in this specific case, especially since it depends on prior draw events and backend behavior. So it’s possible that the current use of I’d be happy to investigate this further or try a more careful approach if you think there’s a safe way to extend blitting to this case. |
|
I don’t know. Just saying we nee to think this through carefully. It may well be that blitting is possible. |
|
That makes sense, thanks for the clarification. I’ll take a closer look at how and when the blit background is created and whether it can be reliably reused in this branch. In particular, I want to verify that the background is always valid when I’ll experiment with a small prototype and share findings before proposing any change here. |
|
Thanks for the clarification — I dug deeper into how blitting is used across widgets. From the implementation of Based on this, I agree that we cannot assume blitting is always safe in the A safer approach would be:
This keeps correctness intact while still improving performance when possible. Would you be okay with me updating the PR to follow this pattern? |
|
On a contextual background, since #29855, we can switch the canvas on existing figures. The blur background is canvas-dependent and therefore now stored on the canvas. This means we must assume, a background can vanish at any point in time and guard against that. See also #30503. This however does not resolve the question on needclear. From a quick incomplete look, needclear triggers Note that the event is done after the draw, wich makes sense: The background is updated after each full draw. So if needclear is literally necessary (i.e. implying you need a fresh draw) then you cannot replace it with blitting. In other words, to move forward you must argue why a full draw is not necessary and the background (in it exists) is not invalid. |
|
Hi @timhoffm, thanks again for the detailed explanation — this clarified the draw / background lifecycle a lot. I took a closer look at how From testing (including resize and zoom), restoring the saved background via blitting appears to correctly clear the cursor without visible artifacts in typical scenarios. In particular, since the cursor only draws animated artists ( However, I understand your point that the background is only guaranteed to be valid after a full So the key question seems to be whether My current thinking is:
A possible approach could be to use blitting conditionally (when a valid background is available), and otherwise fall back to Would you be okay with me prototyping this guarded approach to see if it behaves reliably across backends? |
|
Your answer sounds very AI generated. If that is the case, it violates our AI policy. |
|
Hi @timhoffm, thanks for pointing this out. I wrote this myself, but yeah maybe I made it too formal. From what I tested (resize/zoom), blitting seems to clear the cursor fine in most cases. But I also get your point that background might not always be valid after some changes. So I was thinking — maybe we can use blitting when background is valid, and fallback to draw() if not? Not fully sure if this is the right direction. Should I try prototyping this approach, or you suggest something else? |
PR summary
closes #26901
Why is this change necessary & what problem does it solve?
Currently,
widgets.Cursor.onmovecalls a blockingself.canvas.draw()when the mouse leaves the axes and the cursor needs to be cleared. For large or complex figures (e.g., high-res images), this forces a full synchronous re-render, causing massive lag/stuttering (a busy icon that lasts 1-2 seconds per movement).What is the reasoning for this implementation?
This PR optimizes the clear step by:
useblitis enabled. If it is, it cleanly restores the saved background and blits only the specific bounding box (self.ax.bbox).self.canvas.draw_idle()instead ofdraw()if blitting is disabled, preventing the heavy synchronous render lock.AI Disclosure
I used an AI assistant to help review the Git workflow, structure the blitting fallback logic, and format this Pull Request.
PR checklist