diff --git a/gtk4-macros/tests/templates.rs b/gtk4-macros/tests/templates.rs
index c581d190c79d..75a78f006ab3 100644
--- a/gtk4-macros/tests/templates.rs
+++ b/gtk4-macros/tests/templates.rs
@@ -303,3 +303,50 @@ glib::wrapper! {
fn blueprint_file() {
let _: MyWidget5 = glib::Object::new();
}
+
+mod imp6 {
+ use super::*;
+
+ #[derive(Default, glib::Properties, gtk::CompositeTemplate)]
+ #[template(string = r#"
+
+
+
+
+
+
+
+
+"#)]
+ #[properties(wrapper_type = super::TestWidget)]
+ pub struct TestWidget {
+ #[property(get)]
+ #[template_child]
+ widget: gtk::TemplateChild,
+ }
+
+ #[glib::object_subclass]
+ impl ObjectSubclass for TestWidget {
+ const NAME: &'static str = "TestWidget";
+ type Type = super::TestWidget;
+ type ParentType = gtk::Widget;
+
+ fn class_init(klass: &mut Self::Class) {
+ klass.bind_template();
+ }
+
+ fn instance_init(obj: &glib::subclass::InitializingObject) {
+ obj.init_template();
+ }
+ }
+
+ #[glib::derived_properties]
+ impl ObjectImpl for TestWidget {}
+ impl WidgetImpl for TestWidget {}
+ impl TestWidget {}
+}
+
+glib::wrapper! {
+ pub struct TestWidget(ObjectSubclass)
+ @extends gtk::Widget;
+}
diff --git a/gtk4/src/subclass/widget.rs b/gtk4/src/subclass/widget.rs
index 2e8e6dd29d78..4fe0dc2bb129 100644
--- a/gtk4/src/subclass/widget.rs
+++ b/gtk4/src/subclass/widget.rs
@@ -1211,12 +1211,13 @@ pub unsafe trait WidgetClassExt: ClassStruct {
unsafe impl WidgetClassExt for T where T::Type: WidgetImpl {}
#[derive(Debug, PartialEq, Eq)]
-#[repr(transparent)]
+#[repr(C)]
pub struct TemplateChild
where
T: ObjectType + FromGlibPtrNone<*mut ::GlibType>,
{
ptr: *mut ::GlibType,
+ should_drop: bool,
}
impl Default for TemplateChild
@@ -1228,6 +1229,7 @@ where
Self {
ptr: std::ptr::null_mut(),
+ should_drop: false,
}
}
}
@@ -1245,6 +1247,44 @@ where
}
}
+impl ToValue for TemplateChild
+where
+ T: ToValue + ObjectType + FromGlibPtrNone<*mut ::GlibType>,
+{
+ #[inline]
+ fn to_value(&self) -> glib::Value {
+ T::to_value(&self.get())
+ }
+
+ #[inline]
+ fn value_type(&self) -> glib::Type {
+ T::static_type()
+ }
+}
+
+impl glib::value::ValueType for TemplateChild
+where
+ T: glib::value::ValueType + ObjectType + FromGlibPtrNone<*mut ::GlibType>,
+{
+ type Type = ::Type;
+}
+
+unsafe impl<'a, T> glib::value::FromValue<'a> for TemplateChild
+where
+ T: ObjectType + FromGlibPtrNone<*mut ::GlibType>,
+{
+ type Checker = glib::value::GenericValueTypeChecker;
+
+ #[inline]
+ unsafe fn from_value(value: &'a glib::Value) -> Self {
+ skip_assert_initialized!();
+ TemplateChild {
+ ptr: T::from_value(value).into_glib_ptr(),
+ should_drop: true,
+ }
+ }
+}
+
impl std::ops::Deref for TemplateChild
where
T: ObjectType + FromGlibPtrNone<*mut ::GlibType>,
@@ -1274,6 +1314,19 @@ where
}
}
+impl Drop for TemplateChild
+where
+ T: ObjectType + FromGlibPtrNone<*mut ::GlibType>,
+{
+ fn drop(&mut self) {
+ if self.should_drop {
+ unsafe {
+ crate::glib::gobject_ffi::g_object_unref(self.ptr as *mut _);
+ }
+ }
+ }
+}
+
impl TemplateChild
where
T: ObjectType + FromGlibPtrNone<*mut ::GlibType>,