diff --git a/lib/matplotlib/backends/_backend_tk.py b/lib/matplotlib/backends/_backend_tk.py index cf5d983a26a9..529f71c446c8 100644 --- a/lib/matplotlib/backends/_backend_tk.py +++ b/lib/matplotlib/backends/_backend_tk.py @@ -279,6 +279,9 @@ def enter_notify_event(self, event): guiEvent=event, xy=self._event_mpl_coords(event)) def button_press_event(self, event, dblclick=False): + # set focus to the canvas so that it can receive keyboard events + self._tkcanvas.focus_set() + num = getattr(event, 'num', None) if sys.platform == 'darwin': # 2 and 3 are reversed. num = {2: 3, 3: 2}.get(num, num) @@ -473,6 +476,7 @@ def destroy(*args): Gcf.destroy(self) self.window.protocol("WM_DELETE_WINDOW", destroy) self.window.deiconify() + self.canvas._tkcanvas.focus_set() else: self.canvas.draw_idle() if mpl.rcParams['figure.raise_window']: diff --git a/lib/matplotlib/tests/test_backend_tk.py b/lib/matplotlib/tests/test_backend_tk.py index 3e3251d64a17..c3dac0556087 100644 --- a/lib/matplotlib/tests/test_backend_tk.py +++ b/lib/matplotlib/tests/test_backend_tk.py @@ -185,3 +185,33 @@ class Toolbar(NavigationToolbar2Tk): print("success") Toolbar(fig.canvas, fig.canvas.manager.window) # This should not raise. print("success") + + +@pytest.mark.backend('TkAgg', skip_on_importerror=True) +@_isolated_tk_test(success_count=1) +def test_canvas_focus(): # pragma: no cover + import tkinter as tk + import matplotlib.pyplot as plt + success = [] + + def check_focus(): + tkcanvas = fig.canvas.get_tk_widget() + # Give the plot window time to appear + if not tkcanvas.winfo_viewable(): + tkcanvas.wait_visibility() + # Make sure the canvas has the focus, so that it's able to receive + # keyboard events. + if tkcanvas.focus_lastfor() == tkcanvas: + success.append(True) + plt.close() + root.destroy() + + root = tk.Tk() + fig = plt.figure() + plt.plot([1, 2, 3]) + root.after(0, plt.show) + root.after(100, check_focus) + root.mainloop() + + if success: + print("success")