8000 Merge pull request #25101 from anntzer/le · matplotlib/matplotlib@2b938cd · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2b938cd

Browse files
authored
Merge pull request #25101 from anntzer/le
Deprecate LocationEvent.lastevent.
2 parents 79570ab + 6bd6238 commit 2b938cd

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-17
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Event objects emitted for ``axes_leave_event``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
``axes_leave_event`` now emits a synthetic `.LocationEvent`, instead of reusing
4+
the last event object associated with a ``motion_notify_event``.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
``LocationEvent.lastevent``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
... is deprecated with no replacement.

lib/matplotlib/backend_bases.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import os
3838
import sys
3939
import time
40+
import weakref
4041
from weakref import WeakKeyDictionary
4142

4243
import numpy as np
@@ -1331,7 +1332,11 @@ class LocationEvent(Event):
13311332
The keyboard modifiers currently being pressed (except for KeyEvent).
13321333
"""
13331334

1334-
lastevent = None # The last event processed so far.
1335+
# Fully delete all occurrences of lastevent after deprecation elapses.
1336+
_lastevent = None
1337+
lastevent = _api.deprecated("3.8")(
1338+
_api.classproperty(lambda cls: cls._lastevent))
1339+
_last_axes_ref = None
13351340

13361341
def __init__(self, name, canvas, x, y, guiEvent=None, *, modifiers=None):
13371342
super().__init__(name, canvas, guiEvent=guiEvent)
@@ -1348,20 +1353,25 @@ def __init__(self, name, canvas, x, y, guiEvent=None, *, modifiers=None):
13481353
# cannot check if event was in Axes if no (x, y) info
13491354
return
13501355

1351-
if self.canvas.mouse_grabber is None:
1352-
self.inaxes = self.canvas.inaxes((x, y))
1353-
else:
1354-
self.inaxes = self.canvas.mouse_grabber
1356+
self._set_inaxes(self.canvas.inaxes((x, y))
1357+
if self.canvas.mouse_grabber is None else
1358+
self.canvas.mouse_grabber,
1359+
(x, y))
1360+
1361+
# Splitting _set_inaxes out is useful for the axes_leave_event handler: it
1362+
# needs to generate synthetic LocationEvents with manually-set inaxes. In
1363+
# that latter case, xy has already been cast to int so it can directly be
1364+
# read from self.x, self.y; in the normal case, however, it is more
1365+
# accurate to pass the untruncated float x, y values passed to the ctor.
13551366

1356-
if self.inaxes is not None:
1367+
def _set_inaxes(self, inaxes, xy=None):
1368+
self.inaxes = inaxes
1369+
if inaxes is not None:
13571370
try:
1358-
trans = self.inaxes.transData.inverted()
1359-
xdata, ydata = trans.transform((x, y))
1371+
self.xdata, self.ydata = inaxes.transData.inverted().transform(
1372+
xy if xy is not None else (self.x, self.y))
13601373
except ValueError:
13611374
pass
1362-
else:
1363-
self.xdata = xdata
1364-
self.ydata = ydata
13651375

13661376

13671377
class MouseButton(IntEnum):
@@ -1555,17 +1565,30 @@ def _mouse_handler(event):
15551565
event.key = event.canvas._key
15561566
# Emit axes_enter/axes_leave.
15571567
if event.name == "motion_notify_event":
1558-
last = LocationEvent.lastevent
1559-
last_axes = last.inaxes if last is not None else None
1568+
last_ref = LocationEvent._last_axes_ref
1569+
last_axes = last_ref() if last_ref else None
15601570
if last_axes != event.inaxes:
15611571
if last_axes is not None:
1572+
# Create a synthetic LocationEvent for the axes_leave_event.
1573+
# Its inaxes attribute needs to be manually set (because the
1574+
# cursor is actually *out* of that axes at that point); this is
1575+
# done with the internal _set_inaxes method which ensures that
1576+
# the xdata and ydata attributes are also correct.
15621577
try:
1563-
last.canvas.callbacks.process("axes_leave_event", last)
1578+
leave_event = LocationEvent(
1579+
"axes_leave_event", last_axes.figure.canvas,
1580+
event.x, event.y, event.guiEvent,
1581+
modifiers=event.modifiers)
1582+
leave_event._set_inaxes(last_axes)
1583+
last_axes.figure.canvas.callbacks.process(
1584+
"axes_leave_event", leave_event)
15641585
except Exception:
15651586
pass # The last canvas may already have been torn down.
15661587
if event.inaxes is not None:
15671588
event.canvas.callbacks.process("axes_enter_event", event)
1568-
LocationEvent.lastevent = (
1589+
LocationEvent._last_axes_ref = (
1590+
weakref.ref(event.inaxes) if event.inaxes else None)
1591+
LocationEvent._lastevent = (
15691592
None if event.name == "figure_leave_event" else event)
15701593

15711594

@@ -1964,8 +1987,8 @@ def leave_notify_event(self, guiEvent=None):
19641987
guiEvent
19651988
The native UI event that generated the Matplotlib event.
19661989
"""
1967-
self.callbacks.process('figure_leave_event', LocationEvent.lastevent)
1968-
LocationEvent.lastevent = None
1990+
self.callbacks.process('figure_leave_event', LocationEvent._lastevent)
1991+
LocationEvent._lastevent = None
19691992
self._lastx, self._lasty = None, None
19701993

19711994
@_api.deprecated("3.6", alternative=(

0 commit comments

Comments
 (0)
0