Skip to content

Commit 20252e1

Browse files
authored
Merge pull request #1003 from gtk-rs/bilelmoussaoui/objectimpl
glib: add missing ObjectImpl vfuncs overrides
2 parents feb2a38 + bb69386 commit 20252e1

File tree

1 file changed

+74
-2
lines changed

1 file changed

+74
-2
lines changed

glib/src/subclass/object.rs

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
use std::{mem, ptr};
88

99
use super::{prelude::*, Signal};
10-
use crate::{prelude::*, translate::*, Cast, Object, ParamSpec, Value};
10+
use crate::{prelude::*, translate::*, Cast, Object, ParamSpec, Slice, Value};
1111

1212
// rustdoc-stripper-ignore-next
1313
/// Trait for implementors of `glib::Object` subclasses.
1414
///
15-
/// This allows overriding the virtual methods of `glib::Object`.
15+
/// This allows overriding the virtual methods of `glib::Object`. Except for
16+
/// `finalize` as implementing `Drop` would allow the same behavior.
1617
pub trait ObjectImpl: ObjectSubclass + ObjectImplExt {
1718
// rustdoc-stripper-ignore-next
1819
/// Properties installed for this type.
@@ -67,6 +68,17 @@ pub trait ObjectImpl: ObjectSubclass + ObjectImplExt {
6768
/// error code but no memory violation) until it is dropped. `dispose()` can be executed more
6869
/// than once.
6970
fn dispose(&self) {}
71+
72+
// rustdoc-stripper-ignore-next
73+
/// Function to be called when property change is notified for with
74+
/// `self.notify("property")`.
75+
fn notify(&self, pspec: &ParamSpec) {
76+
self.parent_notify(pspec)
77+
}
78+
79+
fn dispatch_properties_changed(&self, pspecs: &[ParamSpec]) {
80+
self.parent_dispatch_properties_changed(pspecs)
81+
}
7082
}
7183

7284
#[doc(alias = "get_property")]
@@ -116,6 +128,25 @@ unsafe extern "C" fn constructed<T: ObjectImpl>(obj: *mut gobject_ffi::GObject)
116128
imp.constructed();
117129
}
118130

131+
unsafe extern "C" fn notify<T: ObjectImpl>(
132+
obj: *mut gobject_ffi::GObject,
133+
pspec: *mut gobject_ffi::GParamSpec,
134+
) {
135+
let instance = &*(obj as *mut T::Instance);
136+
let imp = instance.imp();
137+
imp.notify(&from_glib_borrow(pspec));
138+
}
139+
140+
unsafe extern "C" fn dispatch_properties_changed<T: ObjectImpl>(
141+
obj: *mut gobject_ffi::GObject,
142+
n_pspecs: u32,
143+
pspecs: *mut *mut gobject_ffi::GParamSpec,
144+
) {
145+
let instance = &*(obj as *mut T::Instance);
146+
let imp = instance.imp();
147+
imp.dispatch_properties_changed(Slice::from_glib_borrow_num(pspecs, n_pspecs as _));
148+
}
149+
119150
unsafe extern "C" fn dispose<T: ObjectImpl>(obj: *mut gobject_ffi::GObject) {
120151
let instance = &*(obj as *mut T::Instance);
121152
let imp = instance.imp();
@@ -183,6 +214,8 @@ unsafe impl<T: ObjectImpl> IsSubclassable<T> for Object {
183214
klass.set_property = Some(set_property::<T>);
184215
klass.get_property = Some(property::<T>);
185216
klass.constructed = Some(constructed::<T>);
217+
klass.notify = Some(notify::<T>);
218+
klass.dispatch_properties_changed = Some(dispatch_properties_changed::<T>);
186219
klass.dispose = Some(dispose::<T>);
187220

188221
let pspecs = <T as ObjectImpl>::properties();
@@ -220,6 +253,14 @@ pub trait ObjectImplExt: ObjectSubclass {
220253
/// Chain up to the parent class' implementation of `glib::Object::constructed()`.
221254
fn parent_constructed(&self);
222255

256+
// rustdoc-stripper-ignore-next
257+
/// Chain up to the parent class' implementation of `glib::Object::notify()`.
258+
fn parent_notify(&self, pspec: &ParamSpec);
259+
260+
// rustdoc-stripper-ignore-next
261+
/// Chain up to the parent class' implementation of `glib::Object::dispatch_properties_changed()`.
262+
fn parent_dispatch_properties_changed(&self, pspecs: &[ParamSpec]);
263+
223264
// rustdoc-stripper-ignore-next
224265
/// Chain up to parent class signal handler.
225266
fn signal_chain_from_overridden(
@@ -242,6 +283,37 @@ impl<T: ObjectImpl> ObjectImplExt for T {
242283
}
243284
}
244285

286+
#[inline]
287+
fn parent_notify(&self, pspec: &ParamSpec) {
288+
unsafe {
289+
let data = T::type_data();
290+
let parent_class = data.as_ref().parent_class() as *mut gobject_ffi::GObjectClass;
291+
292+
if let Some(ref func) = (*parent_class).notify {
293+
func(
294+
self.obj().unsafe_cast_ref::<Object>().to_glib_none().0,
295+
pspec.to_glib_none().0,
296+
);
297+
}
298+
}
299+
}
300+
301+
#[inline]
302+
fn parent_dispatch_properties_changed(&self, pspecs: &[ParamSpec]) {
303+
unsafe {
304+
let data = T::type_data();
305+
let parent_class = data.as_ref().parent_class() as *mut gobject_ffi::GObjectClass;
306+
307+
if let Some(ref func) = (*parent_class).dispatch_properties_changed {
308+
func(
309+
self.obj().unsafe_cast_ref::<Object>().to_glib_none().0,
310+
pspecs.len() as _,
311+
pspecs.as_ptr() as *mut _,
312+
);
313+
}
314+
}
315+
}
316+
245317
fn signal_chain_from_overridden(
246318
&self,
247319
token: &super::SignalClassHandlerToken,

0 commit comments

Comments
 (0)