Search code examples
pythontkintertkinter-text

Why does the Text widget event <<Modified>> get triggered when specifically using <Control-o>?


I've come across a bug that I can't seem to understand. I have a tkinter Text widget that has a bind that triggers on text modification. For some reason this event gets triggered when I use the key combination even though it shouldn't, as it doesn't modify the contents of the Text widget.

Here comes the weird part: this only occurs with <Control-o>. I have made a simple program to demonstrate the problem. Other than special preassigned key combinations such as <Control-i> that actually modify the content, no other combination behaves like this.

Why does this occur for <Control-o> specifically? And how do I prevent it?

import tkinter as tk
root = tk.Tk()
txt = tk.Text(root)
txt.pack()
root.bind("<Control-u>", lambda e: print("doesn't trigger"))
root.bind("<Control-o>", lambda e: print("somehow triggers"))
txt.bind("<<Modified>>", lambda e: print("text got modified!")) # (keep in mind that this will only get triggered once)

Solution

  • The default binding on the text widget for <Control-o> adds a newline. This is from the section bindings in the official Tcl/Tk documentation for the text widget:

    Control-o opens a new line by inserting a newline character in front of the insertion cursor without moving the insertion cursor.

    Returning the string "break" from any binding prevents any further processing of the event. So, you can add a binding on the text widget for control-o that returns the string "break". Since your binding is handled before the default bindings for the widget, this will effectively prevent the default binding from modifying the widget.

    txt.bind("<Control-o>", lambda e: "break")