8000 Only set the wait cursor if the last draw was >1s ago. · matplotlib/matplotlib@a520fa3 · GitHub
[go: up one dir, main page]

Skip to content

Commit a520fa3

Browse files
committed
Only set the wait cursor if the last draw was >1s ago.
This avoids setting the wait cursor when panning or zooming (that behavior was somewhat annoying), or during an animation that renders at least one frame per second. Rename `_set_cursor` to `_update_cursor` as it is fairly different from `set_cursor` and the previous name could cause confusion. Move the defintion of cursor-related methods to a single place.
1 parent 35b875c commit a520fa3

File tree

3 files changed

+48
-19
lines changed

3 files changed

+48
-19
lines changed

lib/matplotlib/backend_bases.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,11 +2342,11 @@ def key_press_handler(event, canvas, toolbar=None):
23422342
# pan mnemonic (default key 'p')
23432343
elif event.key in pan_keys:
23442344
toolbar.pan()
2345-
toolbar._set_cursor(event)
2345+
toolbar._update_cursor(event)
23462346
# zoom mnemonic (default key 'o')
23472347
elif event.key in zoom_keys:
23482348
toolbar.zoom()
2349-
toolbar._set_cursor(event)
2349+
toolbar._update_cursor(event)
23502350
# saving current figure (default key 's')
23512351
elif event.key in save_keys:
23522352
toolbar.save_figure()
@@ -2702,7 +2702,10 @@ class implementation.
27022702
"""
27032703
raise NotImplementedError
27042704

2705-
def _set_cursor(self, event):
2705+
def _update_cursor(self, event):
2706+
"""
2707+
Update the cursor after a mouse move event or a tool (de)activation.
2708+
"""
27062709
if not event.inaxes or not self._active:
27072710
if self._lastCursor != cursors.POINTER:
27082711
self.set_cursor(cursors.POINTER)
@@ -2717,8 +2720,30 @@ def _set_cursor(self, event):
27172720
self.set_cursor(cursors.MOVE)
27182721
self._lastCursor = cursors.MOVE
27192722

2723+
@contextmanager
2724+
def _wait_cursor_for_draw_cm(self):
2725+
"""
2726+
Set the cursor to a wait cursor when drawing the canvas.
2727+
2728+
In order to avoid constantly changing the cursor when the canvas
2729+
changes frequently, do nothing if this context was triggered during the
2730+
last second. (Optimally we'd prefer only setting the wait cursor if
2731+
the *current* draw takes too long, but the current draw blocks the GUI
2732+
thread).
2733+
"""
2734+
self._draw_time, last_draw_time = (
2735+
time.time(), getattr(self, "_draw_time", -np.inf))
2736+
if self._draw_time - last_draw_time > 1:
2737+
try:
2738+
self.set_cursor(cursors.WAIT)
2739+
yield
2740+
finally:
2741+
self.set_cursor(self._lastCursor)
2742+
else:
2743+
yield
2744+
27202745
def mouse_move(self, event):
2721-
self._set_cursor(event)
2746+
self._update_cursor(event)
27222747

27232748
if event.inaxes and event.inaxes.get_navigate():
27242749

lib/matplotlib/backends/backend_agg.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@
2323
import threading
2424
except ImportError:
2525
import dummy_threading as threading
26-
import numpy as np
2726
from collections import OrderedDict
27+
from contextlib import ExitStack
2828
from math import radians, cos, sin
29+
30+
import numpy as np
31+
2932
from matplotlib import cbook, rcParams, __version__
3033
from matplotlib.backend_bases import (
3134
_Backend, FigureCanvasBase, FigureManagerBase, RendererBase)
@@ -384,8 +387,10 @@ def draw(self):
384387
Draw the figure using the renderer.
385388
"""
386389
self.renderer = self.get_renderer(cleared=True)
387-
with RendererAgg.lock:
388-
self.figure.draw(self.renderer)
390+
# Acquire a lock on the shared font cache.
391+
with RendererAgg.lock, (
392+
self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
393+
else ExitStack()):
389394
# A GUI class may be need to update a window using this draw, so
390395
# don't forget to call the superclass.
391396
super().draw()

lib/matplotlib/backends/backend_gtk3cairo.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from contextlib import ExitStack
2+
13
from . import backend_cairo, backend_gtk3
24
from .backend_gtk3 import Gtk, _BackendGTK3
35
from matplotlib import cbook
@@ -22,18 +24,15 @@ def _render_figure(self, width, height):
2224

2325
def on_draw_event(self, widget, ctx):
2426
"""GtkDrawable draw event."""
25-
# toolbar = self.toolbar
26-
# if toolbar:
27-
# toolbar.set_cursor(cursors.WAIT)
28-
self._renderer.set_context(ctx)
29-
allocation = self.get_allocation()
30-
Gtk.render_background(
31-
self.get_style_context(), ctx,
32-
allocation.x, allocation.y, allocation.width, allocation.height)
33-
self._render_figure(allocation.width, allocation.height)
34-
# if toolbar:
35-
# toolbar.set_cursor(toolbar._lastCursor)
36-
return False # finish event propagation?
27+
with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
28+
else ExitStack()):
29+
self._renderer.set_context(ctx)
30+
allocation = self.get_allocation()
31+
Gtk.render_background(
32+
self.get_style_context(), ctx,
33+
allocation.x, allocation.y,
34+
allocation.width, allocation.height)
35+
self._render_figure(allocation.width, allocation.height)
3736

3837

3938
@cbook.deprecated("3.1", alternative="backend_gtk3.FigureManagerGTK3")

0 commit comments

Comments
 (0)
0