Undo doesn't emit `notified_changed` signal

Hey there. I am trying to develop a PyGObject application but experiencing a strange behavior. I’ve created a demo for you to reproduce it. This is the code:

import gi
gi.require_version("Gtk", "4.0")
from gi.repository import Gtk, Gio

app = Gtk.Application()
window = None
text_view = None
title = "Test"

def on_quit(action, _):
    app.quit()

def on_save_file(action, _):
    text_view.get_buffer().set_modified(False)

def create_action(target, name, handler):
    action = Gio.SimpleAction(name=name)
    action.connect("activate", handler)
    target.add_action(action)

def add_actions(app, window):
    create_action(app, "quit", on_quit)
    create_action(window, "save_file", on_save_file)

def set_accels_for_actions(app):
    app.set_accels_for_action("win.save_file", ["<Ctrl>s"])
    app.set_accels_for_action("app.quit", ["<Ctrl>q"])

def on_modified_changed(buffer):
    modified = buffer.get_modified()
    print("Modified:", modified)
    if modified:
        window.set_title(f"{title}*")
    else:
        window.set_title(title)

def on_activate_app(app):
    global window, text_view
    window = Gtk.ApplicationWindow(application=app)

    text_view = Gtk.TextView()
    text_view.get_buffer().connect("modified_changed", on_modified_changed)

    window.set_child(text_view)
    window.present()
    add_actions(app, window)
    set_accels_for_actions(app)

app.connect("activate", on_activate_app)
app.run()

You can quit from app using “Ctrl+q” and save the content with “Ctrl+s”. Just do this:

  • Write “a”.

  • Delete it with “Backspace”.

  • Write “b”.

  • Press “Ctrl-s” and save it. It is not a real save, just calls buffer.set_modified(False). You can follow the modified flag value in the console.

  • Delete it with “Backspace”.

  • Write “c”.

  • Now it is in modified state. You can follow it from the title. The title is updated whenever the modified_changed signal is triggered.

  • Undo with “Ctrl-z” twice. As expected, it is now in the clean state.

  • Undo one more time with “Ctrl-z”. I think the expected thing is the dirty state again. But it is in the clear state!

Am I missing something or is it weird? BTW, sorry if the code is a mess. Original code follows best practices but this one is simpler.

Hi,

I confirm, it looks like a bug.
I’ll check when I find the time.

Thank you. And I can confirm this happens for GNOME Text Editor as well. I can open a bug in upstream BTW.

I just opened an issue: GTK.TextView undo doesn’t emit `notified_changed` signal as `True` if it moves beyond the save (`Gtk.TextBuffer#set_modified(False)`) point (#740) · Issues · GNOME / pygobject · GitLab

It is probably a GTK issue. So I also opened an issue there: GTK.TextView undo doesn’t emit `notified-changed` signal as `true` if it moves beyond the save (`gtk_text_buffer_set_modified(_, false)`) point (#8018) · Issues · GNOME / gtk · GitLab