Gtk.jl
Gtk.jl copied to clipboard
Inserting text in GtkTextBuffer crashes v1.6 in some conditions
I came across this strange crash in v1.6 (works just fine in prior versions). The example is a bit long but I think all these ingredients are necessary to trigger the issue. In short I have a custom widget v
that holds a GtkTextBuffer and a callback that modifies it using insert!
. It seems I have to do at least two edits to cause a problem :
function insert_text(str, v)
it = GtkTextIter(v.buffer, 1)
insert!(v.buffer, it, str)
it = GtkTextIter(v.buffer, 2)
insert!(v.buffer, it, str)
end
Which gives a :
(<unknown>:15129): Gtk-WARNING **: 15:04:25.871: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a position across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset)
will invalidate all outstanding iterators
(<unknown>:15129): Gtk-CRITICAL **: 15:04:25.871: gtk_text_buffer_insert: assertion 'gtk_text_iter_get_buffer (iter) == buffer' failed
Interestingly passing the buffer directly to the function "solves" the problem :
function insert_text(str, buffer)
it = GtkTextIter(buffer, 1)
insert!(buffer, it, str)
it = GtkTextIter(buffer, 2)
insert!(buffer, it, str)
end
Not sure what the issue is, looks like some kind of memory problem. Full example :
using Gtk
import Gtk: GtkTextIter, mutable
mutable struct Widget{B<:GtkTextBuffer} <: GtkScrolledWindow
handle::Ptr{Gtk.GObject}
buffer::B
view::GtkTextView
function Widget{B}() where {B<:GtkTextBuffer}
b = B()
b.text[String] = "test"
v = GtkTextView(b)
sc = GtkScrolledWindow()
push!(sc, v)
n = new(sc.handle, b, v)
Gtk.gobject_move_ref(n, sc)
end
end
PROPAGATE = convert(Cint, false)
INTERRUPT = convert(Cint, true)
get_text_left_of_iter(it::GtkTextIter) = ((mutable(it)-1):mutable(it)).text[String]
@guarded (PROPAGATE) function key_press_cb(widgetptr::Ptr, eventptr::Ptr, user_data)
textview = convert(GtkTextView, widgetptr)
event = convert(Gtk.GdkEvent, eventptr)
v = user_data
if event.keyval == Gtk.GdkKeySyms.Tab
@info "trying to insert"
insert_text("test", v)
return INTERRUPT
end
PROPAGATE
end
function insert_text(str, v)
it = GtkTextIter(v.buffer, 1)
insert!(v.buffer, it, str)
it = GtkTextIter(v.buffer, 2)
insert!(v.buffer, it, str)
end
#= function insert_text(str, buffer)
it = GtkTextIter(buffer, 1)
insert!(buffer, it, str)
it = GtkTextIter(buffer, 2)
insert!(buffer, it, str)
end =#
w = GtkWindow()
v = Widget{GtkTextBuffer}()
push!(w, v)
it = GtkTextIter(v.buffer, 1)
insert!(v.buffer, it, "test insert")
signal_connect(key_press_cb, v.view, "key-press-event", Cint, (Ptr{Gtk.GdkEvent}, ), false, v)
showall(w)
I'd note that tests are failing on Julia nightly (Julia v1.6 isn't tested at the moment)
On my machine it's the test of GtkRadioButtonGroup that fails, which is also a custom widget, so maybe it's related to my issue :
https://github.com/JuliaGraphics/Gtk.jl/blob/7c8802a6fa5ce0002b529d5017ffe72365ea4b4a/src/buttons.jl#L56
I have a crash on 1.6 on internal code, which I also need to track down. Don't have time for that right now.