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>,