I am trying to do bi-directional binding of two textboxes which are GtkEntry widgets from Gtk4.jl. The two textboxes should have the same text. I am using signal connect handlers on change events to achieve that. But it crashes the Julia REPL.
Following is my code:
using Gtk4
win = GtkWindow("mirrored text boxes")
hbox = GtkBox(:h)
push!(win, hbox)
textbox1 = GtkEntry()
textbox2 = GtkEntry()
push!(hbox, textbox1)
push!(hbox, textbox2)
## try_1
id1 = signal_connect(textbox1, :changed) do widget
set_gtk_property!(textbox2, :text, get_gtk_property(textbox1, :text))
end
id2 = signal_connect(textbox2, :changed) do widget
#set_gtk_property!(textbox1, :text, get_gtk_property(textbox2, :text))
end
If I uncomment the middle line in id2
signal, and run the code, it crashes the Julia terminal.
I guess that it starts a recursive loop of callbacks. But even if I keep that line commented in id2
, it still crashes the REPL. I do not understand WHY. I was able to capture the screenshot just before the crash, it reads:
GLib-GObject:ERROR:./gobject/gsignal.c:884;emission_pop: code should not be reached
Bail out!
GLib-GObject:ERROR:/gobject/gsignal.c:884:emission_pop: code should not be reached
[392321 signal (6): Abort trap: 6 in expression starting at none:0
I have also tried the following to stop the recursive loop of the callbacks. But it does not work and crashes the REPL.
## try_2
signal_connect(textbox1, :changed) do widget
if get_gtk_property(textbox1, :text) != get_gtk_property(textbox2, :text)
set_gtk_property!(textbox2, :text, get_gtk_property(textbox1, :text))
end
end
signal_connect(textbox2, :changed) do widget
if get_gtk_property(textbox2, :text) != get_gtk_property(textbox1, :text)
set_gtk_property!(textbox1, :text, get_gtk_property(textbox2, :text))
end
end
Finally, I was able to avoid the callbacks loop by using signal_handler_block
and signal_handler_unblock
.
## try_3
id1 = signal_connect(textbox1, :changed) do widget
signal_handler_block(textbox2, id2)
set_gtk_property!(textbox2, :text, get_gtk_property(textbox1, :text))
signal_handler_unblock(textbox2, id2)
end
id2 = signal_connect(textbox2, :changed) do widget
signal_handler_block(textbox1, id1)
set_gtk_property!(textbox1, :text, get_gtk_property(textbox2, :text))
signal_handler_unblock(textbox1, id1)
end
But I am still wondering why the firing of the id2
signal without any action in ## try_1
block crashed the REPL.
Please let me know if something is not clear and you need more information. Thank you in advance! I am using Julia v"1.9.3" in VS Code on a Mac device.