New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
multiple canvas support for Windows #4236
Conversation
@mdboom Who knows enough about tk to review this? |
@ffteja If it's not too much trouble, could you provide some steps for reproducing the problem this fixes? |
Here is a test script. #!/usr/bin/env python
import matplotlib
matplotlib.use('TkAgg')
from numpy import arange, sin, pi
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
import sys
if sys.version_info[0] < 3:
import Tkinter as Tk
else:
import tkinter as Tk
root = Tk.Tk()
root.wm_title("Embedding in TK")
f = Figure(figsize=(2,2), dpi=100)
a = f.add_subplot(111)
t = arange(0.0,3.0,0.01)
s = sin(2*pi*t)
a.plot(t,s)
canvas = FigureCanvasTkAgg(f, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
def on_key_event(event):
print("on_key_event1")
def on_wheel_event(event):
print("on_wheel_event1")
canvas.mpl_connect('key_press_event', on_key_event)
canvas.mpl_connect('scroll_event', on_wheel_event)
canvas2 = FigureCanvasTkAgg(f, master=root)
canvas2.show()
canvas2.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
def on_key_event2(event):
print("on_key_event2")
def on_wheel_event2(event):
print("on_wheel_event2")
canvas2.mpl_connect('key_press_event', on_key_event2)
canvas2.mpl_connect('scroll_event', on_wheel_event2)
def _quit():
root.quit() # stops mainloop
root.destroy() # this is necessary on Windows to prevent
button = Tk.Button(master=root, text='Focus on canvas 2', command=canvas2.get_tk_widget().focus_set)
button.pack(side=Tk.BOTTOM)
button = Tk.Button(master=root, text='Focus on canvas 1', command=canvas.get_tk_widget().focus_set)
button.pack(side=Tk.BOTTOM)
button = Tk.Button(master=root, text='Quit', command=_quit)
button.pack(side=Tk.BOTTOM)
Tk.mainloop() [TAC edited to add markup] |
@ffteja Would you mind editing your last comment to put the code sample in code blocks (see https://help.github.com/articles/github-flavored-markdown/#fenced-code-blocks)? Then the indentation can be fixed up as well. |
I've confirmed the issue on Windows, and that this patch fixes it. Though it's totally not obvious to me why this worked on Linux when it didn't work on Windows. 🤷 |
Furthermore, this seems to be specifically an issue for mouse scroll events--it isn't a problem for other events. For example mouse motion events are handled by the correct canvas regardless of focus. Key events go to whichever canvas has focus, which makes sense. Same with others I tried. |
Event launched are different in windows and linux for the mouse wheel: As you can see in the source code, the binding are different for each platform so. |
Is this patch harmful on linux? Do we need to platform wrap this? |
No, I don't think so. It's superfluous on Linux but not at all harmful that I can tell (I tested it there too, and I don't think there's anything it would break). |
FIX : multiple canvas support for Windows Correctly dispatch scroll wheel events in Tk on MS/windows
Thank you! |
On Windows platform the bind of the mousewheel event is made on the main application window rather than the canvas. As a side effect, if you have multiple canvas in the same application, only the last one created answers to mousewheeel events.
This patch makes the bindings chain rather than replacing each other. In the callbacks (scroll_event_windows, filter_destroy), event filtering is done to check if the canvas should answer.