Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Issues using signal_connect #542

Open
coloursofnoise opened this issue Dec 19, 2020 · 1 comment
Open

Issues using signal_connect #542

coloursofnoise opened this issue Dec 19, 2020 · 1 comment

Comments

@coloursofnoise
Copy link
Contributor

Trying to add a match-selected signal handler to a GtkEntryCompletion, I've had issues getting signal_connect to work, however I have found a working solution.

Issues:

  • Using the "simple" function (signal_connect(func, widget, signal)) doesn't throw any errors, but func never gets called.
  • The "verbose" version of signal_connect does connect, but any attempt to use the arguments passed in beyond printing their values results in an EXCEPTION_ACCESS_VIOLATION.

Fix:

  • Repurposed the "verbose" signal_connect to instead take in a @cfunction argument, skipping the intermediate cfunction_ call

Somehow the @cfunction macro and cfunction_ function are different, possibly related to #358
It may be worth adding this extra signal_connect function temporarily, assuming it works reliably, as a last resort for issues with signals.
Below is a code snippet demonstrating each setup, any further input is appreciated.

@coloursofnoise
Copy link
Contributor Author

using Gtk

# Set-up: Opens a window with an entry, begin typing "test" to open a drop-down auto-complete menu
entry = GtkEntry()
completion = GtkEntryCompletion()
listStore = GtkListStore(String)
push!(listStore, ("test",))
GAccessor.model(completion, GtkTreeModel(listStore))
GAccessor.text_column(completion, 0) # 0-based index
GAccessor.completion(entry, completion)
w = GtkWindow()
push!(w, entry)
showall(w)

# Does not seem to get connected at all, never called
@guarded Int32(false) signal_connect(completion, "match-selected") do args...
	println("match-selected SIMPLE do-block")
	return Int32(false)
end
# Neither does this one
@guarded Int32(false) function match_selected_simple(args...)
	println("match-selected SIMPLE")
	return Int32(false)
end
signal_connect(match_selected_simple, completion, "match-selected")

# Using the verbose function connects properly, 
# however any attempt to do anything at all with `model` or `iter` crashes with an EXCEPTION_ACCESS_VIOLATION
@guarded Int32(false) signal_connect(completion, "match-selected", Cint, (Ptr{GtkEntryCompletion}, Ptr{GtkTreeModel}, Ptr{GtkTreeIter}, Ptr{Cvoid}), false) do widget, completion, model, iter, user_data...
	println("match-selected VERBOSE do-block")
	println(model)
	#convert(GtkTreeModel, model) # EXCEPTION_ACCESS_VIOLATION
	return Int32(false)
end

# This one is as far as I know the same as the previous, however it never gets called
@guarded Int32(false) function match_selected_verbose(widget, completion, model, iter, user_data...)
	println("match-selected VERBOSE")
	return Int32(false)
end
signal_connect(match_selected_verbose, completion, "match-selected")



# Repurposed from https://github.com/JuliaGraphics/Gtk.jl/blob/master/src/GLib/signals.jl
function signal_connect_c(cb, w::GObject, sig::AbstractString, after::Bool = false, user_data::CT = w) where {CT}
	ref, deref = Gtk.GLib.gc_ref_closure(user_data)
	return ccall((:g_signal_connect_data, Gtk.libgobject), Culong,
      (Ptr{GObject}, Ptr{UInt8}, Ptr{Nothing}, Ptr{Nothing}, Ptr{Nothing}, Gtk.GEnum),
      w, Gtk.bytestring(sig), cb, ref, deref, after * Gtk.GLib.GConnectFlags.AFTER)
end

# Works
const match_selected_do_block_c = @cfunction(Cint, (Ptr{GtkEntryCompletion}, Ptr{GtkListStore}, Ptr{GtkTreeIter})) do completion, model, iter
	println("match-selected CFUNCTION do-block")
	treeModel = GtkTreeModel(convert(GtkListStore, model))
	val = Gtk.mutable(Gtk.GValue())
   ccall((:gtk_tree_model_get_value, Gtk.libgtk), Nothing, (Ptr{GObject}, Ref{GtkTreeIter}, Cint, Ptr{Gtk.GValue}), treeModel, iter, 0, val)
	item = val[Any]
	println(item)
	return Int32(false)
end
signal_connect_c(match_selected_do_block_c, completion, "match-selected")

# Works
@guarded Int32(false) function match_selected(completion, model, iter)::Cint
	println("match-selected CFUNCTION")
	treeModel = GtkTreeModel(convert(GtkListStore, model))
	val = Gtk.mutable(Gtk.GValue())
   ccall((:gtk_tree_model_get_value, Gtk.libgtk), Nothing, (Ptr{GObject}, Ref{GtkTreeIter}, Cint, Ptr{Gtk.GValue}), treeModel, iter, 0, val)
	item = val[Any]
	println(item)
	return Int32(false)
end
const match_selected_c = @cfunction(match_selected, Cint, (Ptr{GtkEntryCompletion}, Ptr{GtkListStore}, Ptr{GtkTreeIter}))
signal_connect_c(match_selected_c, completion, "match-selected")

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant