diff --git a/src/GLib/GLib.jl b/src/GLib/GLib.jl index 9ba33cac..1751fd60 100644 --- a/src/GLib/GLib.jl +++ b/src/GLib/GLib.jl @@ -72,7 +72,7 @@ function find_leaf_type_if_not_null(o,owns) if o == C_NULL nothing else - leaftype = GLib.find_leaf_type(o) + leaftype = find_leaf_type(o) convert(leaftype, o, owns) end end diff --git a/src/GLib/gobject.jl b/src/GLib/gobject.jl index 401440f7..1f9f9563 100644 --- a/src/GLib/gobject.jl +++ b/src/GLib/gobject.jl @@ -6,7 +6,7 @@ end # converts the string output by `g_value_get_string` to Julia equivalent function gvalue_string_convert(str) - value = (str == C_NULL ? "nothing" : GLib.bytestring(str)) + value = (str == C_NULL ? "nothing" : bytestring(str)) if value == "TRUE" value = "true" elseif value == "FALSE" @@ -34,7 +34,7 @@ function show(io::IO, w::GObject) else first = false end - print(io, GLib.bytestring(param.name)) + print(io, bytestring(param.name)) if (ParamFlags(param.flags) & ParamFlags_READABLE) != 0 && (param.flags & DEPRECATED) == 0 && (ccall((:g_value_type_transformable, libgobject), Cint, diff --git a/src/GLib/gtype.jl b/src/GLib/gtype.jl index cdec7ccc..2321a262 100644 --- a/src/GLib/gtype.jl +++ b/src/GLib/gtype.jl @@ -91,6 +91,7 @@ mutable struct GObjectLeaf <: GObject if handle == C_NULL error("Cannot construct $gname with a NULL pointer") end + gobject_maybe_sink(handle, owns) return gobject_ref(new(handle)) end end @@ -127,16 +128,14 @@ cconvert(::Type{Ptr{GObject}}, @nospecialize(x::GObject)) = x # or to override this method (e.g. GtkNullContainer, AbstractString) unsafe_convert(::Type{Ptr{GObject}}, w::GObject) = getfield(w, :handle) -# this method should be used by gtk methods returning widgets of unknown type -# and/or that might have been wrapped by julia before, -# instead of a direct call to the constructor -convert(::Type{T}, w::Ptr{Y}, owns=false) where {T <: GObject, Y <: GObject} = convert_(T, convert(Ptr{T}, w), owns) # this definition must be first due to a 0.2 dispatch bug +# This method should be used by gtk methods returning widgets of unknown type and/or that +# might have been wrapped by julia before, instead of a direct call to the constructor. +# The argument `owns` should be set to true when the method that produced the Ptr{GObject} +# transfers ownership to the callee. +convert(::Type{T}, w::Ptr{Y}, owns=false) where {T <: GObject, Y <: GObject} = convert_(T, convert(Ptr{T}, w), owns) convert(::Type{T}, ptr::Ptr{T}, owns=false) where T <: GObject = convert_(T, ptr, owns) # need to introduce convert_ since otherwise there was a StackOverFlow error - -# The argument owns should be set to true when the method that produced the Ptr{GObject} -# transfers ownership to the callee. function convert_(::Type{T}, ptr::Ptr{T}, owns=false) where T <: GObject hnd = convert(Ptr{GObject}, ptr) if hnd == C_NULL @@ -149,8 +148,7 @@ function convert_(::Type{T}, ptr::Ptr{T}, owns=false) where T <: GObject if owns # we already had a reference so we should get rid of the one we just received gc_unref(hnd) end - else - # create a wrapper + else # new GObject, create a wrapper ret = wrap_gobject(hnd)::T end ret @@ -167,9 +165,10 @@ function find_leaf_type(hnd::Ptr{T}) where T <: GObject gtype_wrappers[typname] end +# Finds the best leaf type and calls the constructor function wrap_gobject(hnd::Ptr{GObject},owns=false) T = find_leaf_type(hnd) - return T(hnd,owns) + return T(hnd,owns) # these are defined in xlib_structs end ### GList support for GObject @@ -207,14 +206,15 @@ _gc_unref(@nospecialize(x), ::Ptr{Nothing}) = gc_unref(x) gc_ref_closure(@nospecialize(cb::Function)) = (invoke(gc_ref, Tuple{Any}, cb), @cfunction(_gc_unref, Nothing, (Any, Ptr{Nothing}))) gc_ref_closure(x::T) where {T} = (gc_ref(x), @cfunction(_gc_unref, Nothing, (Any, Ptr{Nothing}))) -# generally, you shouldn't be calling gc_ref(::Ptr{GObject}) -function gc_ref(x::Ptr{GObject}) +# GLib ref/unref functions -- generally, you shouldn't be calling these +function glib_ref(x::Ptr{GObject}) ccall((:g_object_ref, libgobject), Nothing, (Ptr{GObject},), x) end -function gc_unref(x::Ptr{GObject}) +gc_unref(p::Ptr{GObject}) = glib_unref(p) +function glib_unref(x::Ptr{GObject}) ccall((:g_object_unref, libgobject), Nothing, (Ptr{GObject},), x) end -function gc_ref_sink(x::Ptr{GObject}) +function glib_ref_sink(x::Ptr{GObject}) ccall((:g_object_ref_sink, libgobject), Nothing, (Ptr{GObject},), x) end const gc_preserve_glib = Dict{Union{WeakRef, GObject}, Bool}() # glib objects @@ -263,7 +263,7 @@ end function gobject_maybe_sink(handle,owns::Bool) is_floating = (ccall(("g_object_is_floating", libgobject), Cint, (Ptr{GObject},), handle)!=0) if !owns || is_floating # if owns is true then we already have a reference, but if it's floating we should sink it - GLib.gc_ref_sink(handle) + glib_ref_sink(handle) end end function gobject_ref(x::T) where T <: GObject @@ -286,7 +286,7 @@ function gobject_ref(x::T) where T <: GObject end elseif strong # oops, we previously deleted the link, but now it's back - gc_ref(getfield(x,:handle)) + glib_ref(getfield(x,:handle)) addref(Ref{GObject}(x)[]) else # already gc-protected, nothing to do @@ -305,6 +305,10 @@ function run_delayed_finalizers() x = pop!(await_finalize) finalize_gc_unref(x) end + # prevents empty WeakRefs from filling gc_preserve_glib + gc_preserve_glib_lock[] = true + filter!(x->!(isa(x.first,WeakRef) && x.first.value === nothing),gc_preserve_glib) + gc_preserve_glib_lock[] = false topfinalizer[] = true end @@ -341,9 +345,9 @@ gc_ref_closure(x::GObject) = (gc_ref(x), C_NULL) function gobject_move_ref(new::GObject, old::GObject) h = unsafe_convert(Ptr{GObject}, new) @assert h == unsafe_convert(Ptr{GObject}, old) != C_NULL - gc_ref(h) + glib_ref(h) gc_unref(old) gc_ref(new) - gc_unref(h) + glib_unref(h) new end diff --git a/src/GLib/gvalues.jl b/src/GLib/gvalues.jl index 2686e191..494db65e 100644 --- a/src/GLib/gvalues.jl +++ b/src/GLib/gvalues.jl @@ -48,7 +48,7 @@ function settype!(gv::Ref{GValue}, ::Type{T}) where T <: CEnum.Cenum end function setindex!(v::Base.Ref{GValue}, x, ::Type{T}) where T <: CEnum.Cenum - ccall((:g_value_set_enum, libgobject), Nothing, (Ptr{GLib.GValue}, Cint), v, x) + ccall((:g_value_set_enum, libgobject), Nothing, (Ptr{GValue}, Cint), v, x) end function settype!(gv::Ref{GValue}, ::Type{T}) where T <: BitFlag @@ -58,7 +58,7 @@ function settype!(gv::Ref{GValue}, ::Type{T}) where T <: BitFlag end function setindex!(v::Base.Ref{GValue}, x, ::Type{T}) where T <: BitFlag - ccall((:g_value_set_flags, libgobject), Nothing, (Ptr{GLib.GValue}, Cint), v, Int32(x)) + ccall((:g_value_set_flags, libgobject), Nothing, (Ptr{GValue}, Cint), v, Int32(x)) end function setindex!(dest::Base.RefValue{GValue}, src::Ref{GValue}) @@ -205,7 +205,7 @@ const fundamental_fns = tuple(Function[ make_gvalue_from_fundamental_type(i, @__ g_type(::Type{GValue}) = ccall(("g_value_get_type", libgobject), GType, ()) push!(gboxed_types, GValue) function getindex(v::Base.RefValue{GValue}, ::Type{GValue}) - x = ccall(("g_value_get_boxed", GLib.libgobject), Ptr{GValue}, (Ptr{GValue},), v) + x = ccall(("g_value_get_boxed", libgobject), Ptr{GValue}, (Ptr{GValue},), v) if x == C_NULL return nothing end diff --git a/src/GLib/loop.jl b/src/GLib/loop.jl index c1174551..2e4e2018 100644 --- a/src/GLib/loop.jl +++ b/src/GLib/loop.jl @@ -77,7 +77,7 @@ g_source_remove(id) = G_.source_remove(id) const g_main_running = Ref{Bool}(true) -glib_main() = GLib.g_sigatom() do +glib_main() = g_sigatom() do # gtk_main() was deprecated in GTK 4.0, hence we iterate the loop ourselves while g_main_running[] ccall((:g_main_context_iteration, libglib), Cint, (Ptr{Cvoid}, Cint), C_NULL, true) @@ -157,7 +157,7 @@ See also [`set_uv_loop_integration`](@ref). """ is_uv_loop_integration_enabled() = uv_int_enabled[] -GApplication(id = nothing, flags = GLib.ApplicationFlags_FLAGS_NONE) = G_.Application_new(id,flags) +GApplication(id = nothing, flags = ApplicationFlags_FLAGS_NONE) = G_.Application_new(id,flags) function run(app::GApplication) ccall(("g_application_run", libgio), Int32, (Ptr{GObject}, Int32, Ptr{Cstring}), app, 0, C_NULL)