Question: I wanted to implement two finger scrolling in tkinter. Here is the result of my own attempt: import tkinter as tk class Scene: def __init__(self, canvas): self.canvas = canvas self.elements = [ { "type": "rect", "x": canvas.winfo_width() / 2, "y": canvas.winfo_height() / 2, "width": 200, "height": 200, "color": (55 / 255, 55 / 255, 10 / 255), }, { "type": "rect", "x": 100, "y": 300, "width": 200, "height": 200, "color": (155 / 255, 200 / 255, 10 / 255), }, ] def update_scene(self, offset): for element in self.elements: element["x"] -= offset[0] element["y"] -= offset[1] self.render_scene() def render_scene(self): self.canvas.delete("all") for element in self.elements: if element["type"] == "rect": self.canvas.create_rectangle( element["x"], element["y"], element["x"] + element["width"], element["y"] + element["height"], fill=f"#{int(element['color'][0] * 255):02x}{int(element['color'][1] * 255):02x}{int(element['color'][2] * 255):02x}", ) else: print(f"Error: type {element['type']} is not supported.") root = tk.Tk() root.geometry("{}x{}".format(800, 600)) canvas = tk.Canvas(root) canvas.pack(fill="both", expand=True) canvas_scroll = [0, 0] scene = Scene(canvas) scene.render_scene() def on_mouse_scroll(event): canvas_scroll[0] = event.delta canvas_scroll[1] = event.delta scene.update_scene(canvas_scroll) canvas.bind("<MouseWheel>", on_mouse_scroll) root.mainloop()  The above only works in one diagonal/direction, instead of any direction (up, down, left, right, and all four diagonals) The above was inspired by a Javascript snippet I found here: https://jsfiddle.net/qmyho24r/ I know using Shift-MouseWheel works, but then I have to also press the shift key, instead of just using the trackpad and two fingers (like in the Javascript example). How can I use two fingers scrolling in Tkinter?

Answer: tkinter does only support horizontal scrolling on windows from patchlevel 8.6.10 <= I've created a small example that works for me with tkinter 8.6.12 on Win11. When using two fingers with a little gap between them I can successfully scroll in both direction and move the View in a circle. I retrieve two different events depending on which direction I swap. This is also mentioned in the documentation. import tkinter as tk import sys #https://stackoverflow.com/a/13874620/13629335 OS = sys.platform def horizontal_scroll(event): if OS in ('win32','darwin'): canvas.xview_scroll(int(event.delta/120), 'units') elif OS == 'linux': if event.num == 5: canvas.xview_scroll(-1, 'units') elif event.num == 4: canvas.xview_scroll(1, 'units') def vertical_scroll(event): if OS in ('win32','darwin'): canvas.yview_scroll(int(event.delta/120), 'units') elif OS == 'linux': if event.num == 5: canvas.yview_scroll(-1, 'units') elif event.num == 4: canvas.yview_scroll(1, 'units') root = tk.Tk('test') if int(root.tk.call("info", "patchlevel").split('.')[-1]) >= 10: #https://docs.activestate.com/activetcl/8.6/get/relnotes/ canvas = tk.Canvas(root,highlightthickness=0,bd=0) #something to show v = viewsize = 150 cw = canvas.winfo_reqwidth()+v ch = canvas.winfo_reqheight()+v/2 s = square = 50 canvas.create_rectangle(0,0, s,s, tags=('NW',)) canvas.create_rectangle(cw-s,0, cw,s, tags=('NE',)) canvas.create_rectangle(cw-s,ch-s, cw,ch, tags=('SE',)) canvas.create_rectangle(0,ch-s, s,ch, tags=('SW',)) canvas.pack(fill='both', expand=True, padx=10) #update scrollregion canvas.configure(scrollregion=canvas.bbox('all')) #bindings #https://stackoverflow.com/a/17457843/13629335 if OS in ('win32','darwin'): #https://apple.stackexchange.com/q/392936 root.bind('<MouseWheel>', vertical_scroll) root.bind('<Shift-MouseWheel>', horizontal_scroll) if OS == 'linux': #https://stackoverflow.com/a/17452217/13629335 root.bind('<Button-4>', vertical_scroll) root.bind('<Button-5>', vertical_scroll) root.bind('<Shift-Button-4>', horizontal_scroll) root.bind('<Shift-Button-5>', horizontal_scroll) root.mainloop() else: print('at least for windows it is supported at patchlevel 8.6.10') root.destroy()