From af9e3e2b3f05bff471681acbd2388ea149fbf070 Mon Sep 17 00:00:00 2001 From: richardsheridan Date: Wed, 14 Apr 2021 09:39:13 -0400 Subject: [PATCH 1/5] handle timeouts less than 1 millisecond --- lib/matplotlib/backends/_backend_tk.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/backends/_backend_tk.py b/lib/matplotlib/backends/_backend_tk.py index ffb3b17d33cb..2c376291e131 100644 --- a/lib/matplotlib/backends/_backend_tk.py +++ b/lib/matplotlib/backends/_backend_tk.py @@ -358,8 +358,11 @@ def flush_events(self): def start_event_loop(self, timeout=0): # docstring inherited - if timeout > 0: - self._master.after(int(1000*timeout), self.stop_event_loop) + milliseconds = int(1000 * timeout) + if milliseconds > 0: + self._master.after(milliseconds, self.stop_event_loop) + elif milliseconds == 0: + self._master.after_idle(self.stop_event_loop) self._master.mainloop() def stop_event_loop(self): From dc093a569b7b7cf14d1240905906cc97d64fc7ce Mon Sep 17 00:00:00 2001 From: richardsheridan Date: Wed, 14 Apr 2021 09:40:14 -0400 Subject: [PATCH 2/5] cancel timeout if manually stopped --- lib/matplotlib/backends/_backend_tk.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/backends/_backend_tk.py b/lib/matplotlib/backends/_backend_tk.py index 2c376291e131..1d927c7f5e0d 100644 --- a/lib/matplotlib/backends/_backend_tk.py +++ b/lib/matplotlib/backends/_backend_tk.py @@ -166,6 +166,7 @@ def __init__(self, figure=None, master=None, resize_callback=None): super().__init__(figure) self._idle = True self._idle_callback = None + self._event_loop_id = None w, h = self.figure.bbox.size.astype(int) self._tkcanvas = tk.Canvas( master=master, background="white", @@ -360,13 +361,16 @@ def start_event_loop(self, timeout=0): # docstring inherited milliseconds = int(1000 * timeout) if milliseconds > 0: - self._master.after(milliseconds, self.stop_event_loop) - elif milliseconds == 0: - self._master.after_idle(self.stop_event_loop) + self._event_loop_id = self._tkcanvas.after(milliseconds, self.stop_event_loop) + else: + self._event_loop_id = self._tkcanvas.after_idle(self.stop_event_loop) self._master.mainloop() def stop_event_loop(self): # docstring inherited + if self._event_loop_id: + self._master.after_cancel(self._event_loop_id) + self._event_loop_id = None self._master.quit() @@ -442,6 +446,8 @@ def destroy(*args): def destroy(self, *args): if self.canvas._idle_callback: self.canvas._tkcanvas.after_cancel(self.canvas._idle_callback) + if self.canvas._event_loop_id: + self.canvas._tkcanvas.after_cancel(self.canvas._event_loop_id) # NOTE: events need to be flushed before issuing destroy (GH #9956), # however, self.window.update() can break user code. This is the From b92ecda9b3945589042fdb2c9be900ad1c4fab58 Mon Sep 17 00:00:00 2001 From: richardsheridan Date: Wed, 14 Apr 2021 12:37:34 -0400 Subject: [PATCH 3/5] respect timeout==0 -> no timeout --- lib/matplotlib/backends/_backend_tk.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/backends/_backend_tk.py b/lib/matplotlib/backends/_backend_tk.py index 1d927c7f5e0d..620162395e7f 100644 --- a/lib/matplotlib/backends/_backend_tk.py +++ b/lib/matplotlib/backends/_backend_tk.py @@ -359,11 +359,12 @@ def flush_events(self): def start_event_loop(self, timeout=0): # docstring inherited - milliseconds = int(1000 * timeout) - if milliseconds > 0: - self._event_loop_id = self._tkcanvas.after(milliseconds, self.stop_event_loop) - else: - self._event_loop_id = self._tkcanvas.after_idle(self.stop_event_loop) + if timeout > 0: + milliseconds = int(1000 * timeout) + if milliseconds > 0: + self._event_loop_id = self._tkcanvas.after(milliseconds, self.stop_event_loop) + else: + self._event_loop_id = self._tkcanvas.after_idle(self.stop_event_loop) self._master.mainloop() def stop_event_loop(self): From 41bb1d45f11fcfe3de0a5c3ac97b694bb05daba9 Mon Sep 17 00:00:00 2001 From: richardsheridan Date: Wed, 14 Apr 2021 14:29:35 -0400 Subject: [PATCH 4/5] extra defensive delay to prevent race with draw_idle --- lib/matplotlib/backends/_backend_tk.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/_backend_tk.py b/lib/matplotlib/backends/_backend_tk.py index 620162395e7f..539025b7c39b 100644 --- a/lib/matplotlib/backends/_backend_tk.py +++ b/lib/matplotlib/backends/_backend_tk.py @@ -461,7 +461,8 @@ def delayed_destroy(): if self._owns_mainloop and not Gcf.get_num_fig_managers(): self.window.quit() - self.window.after_idle(delayed_destroy) + # "after idle after 0" avoids Tcl error/race (GH #19940) + self.window.after_idle(self.window.after, 0, delayed_destroy) def get_window_title(self): return self.window.wm_title() From 9418774423c291411c76dc41ef6b9d1ade8c95a7 Mon Sep 17 00:00:00 2001 From: richardsheridan Date: Wed, 14 Apr 2021 14:39:24 -0400 Subject: [PATCH 5/5] linting --- lib/matplotlib/backends/_backend_tk.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/backends/_backend_tk.py b/lib/matplotlib/backends/_backend_tk.py index 539025b7c39b..bc69e08aa396 100644 --- a/lib/matplotlib/backends/_backend_tk.py +++ b/lib/matplotlib/backends/_backend_tk.py @@ -362,9 +362,11 @@ def start_event_loop(self, timeout=0): if timeout > 0: milliseconds = int(1000 * timeout) if milliseconds > 0: - self._event_loop_id = self._tkcanvas.after(milliseconds, self.stop_event_loop) + self._event_loop_id = self._tkcanvas.after( + milliseconds, self.stop_event_loop) else: - self._event_loop_id = self._tkcanvas.after_idle(self.stop_event_loop) + self._event_loop_id = self._tkcanvas.after_idle( + self.stop_event_loop) self._master.mainloop() def stop_event_loop(self): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy