Skip to content
38 changes: 25 additions & 13 deletions lib/matplotlib/tests/test_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1819,17 +1819,29 @@ def test_parent_axes_removal():
checks._clear(evt)


def test_cursor_overlapping_axes_blitting_warning():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove this test?

"""Test that a warning is raised and useblit is disabled for overlapping axes."""
fig = plt.figure()
ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax2 = fig.add_axes([0.2, 0.2, 0.6, 0.6]) # Explicitly overlaps ax1

Comment on lines -1826 to -1827

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't change!

match_text = (
"Cursor blitting is currently not supported on "
"overlapping axes"
)
with pytest.warns(UserWarning, match=match_text):
cursor = widgets.Cursor(ax1, useblit=True)
def test_cursor_clear_on_move_outside():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not clear that the test is very useful as is. It relies on and tests some internal state.

At the very minimum, do not hack into the event system, but use MouseEvent._process() to simulate mouse move and place the cursor inside or outside the Axes. See how other examples solve this.

"""Test that moving the mouse outside the axes clears the cursor safely."""
import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor

assert cursor.useblit is False
fig, ax = plt.subplots()
cursor = Cursor(ax, useblit=True)

# Simulate the cursor lines being visible
cursor.linev.set_visible(True)
cursor.lineh.set_visible(True)
cursor.needclear = True

# Create a mock mouse event where 'inaxes' is None (meaning outside)
class MockEvent:
inaxes = None
x = 0
y = 0

# Trigger the movement cleanup
cursor.onmove(MockEvent())

# Verify the lines were hidden and the flag reset
assert not cursor.linev.get_visible()
assert not cursor.lineh.get_visible()
assert not cursor.needclear
13 changes: 11 additions & 2 deletions lib/matplotlib/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -2119,7 +2119,16 @@ def onmove(self, event):
self.linev.set_visible(False)
self.lineh.set_visible(False)
if self.needclear:
self.canvas.draw()
if self.useblit:
background = self._load_blit_background()
if background is not None:
self.canvas.restore_region(background)
background = self._load_blit_background()
if self.useblit and background is not None:
self.canvas.restore_region(background)
self.canvas.blit(self.ax.bbox)
else:
self.canvas.draw()
Comment thread
timhoffm marked this conversation as resolved.
Resolved
self.needclear = False
return
self.needclear = True
Expand All @@ -2138,7 +2147,7 @@ def onmove(self, event):
self.ax.draw_artist(self.lineh)
self.canvas.blit(self.ax.bbox)
else:
self.canvas.draw_idle()
self.canvas.draw()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please explain why switching to draw() is the right thing to do.



class MultiCursor(Widget):
Expand Down
Loading