gtk-rs-core
gtk-rs-core copied to clipboard
[FEATURE REQUEST] Properties macro doesn't check for equality
Usually setters for GObject properties check new values for equality and return if the value is equal to the current value. This is to prevent over notifying.
This will have to be opt-in as not every value is comparable in a useful way, and you probably also want to be able to provide a custom equality function to not e.g. compare GInetAddress
es by pointer but by value.
Do you have a suggestion how the API could look like?
How about:
// Uses `Eq/PartialEq`
#[property(get, set, check_eq)]
pub child: RefCell<Option<gtk::Widget>>,
// Uses custom function that takes two of `T`
#[property(get, set, check_eq = compare_address)]
pub ip: RefCell<Option<gio::InetAddress>>
I think having something in the name about notification would be useful. The only difference in behaviour is that it would do a comparison and only notify if the comparison fails.
CC @ranfdev
I agree it's needed, I'm just not convinced about the API. In the meantime it can be implemented by the user using a custom macro set_if_changed!
#[properties(get, set = set_if_changed!(ip), explicit_notify)]
pub ip: RefCell<Option<gio::InetAddress>>
set_if_changed!
can take advantage of the trait PropertySet
to write inside a property. It would wrap PropertySet::set
and check for equality before calling the method.
There you go, it should cover 99% of the gtk use cases.
macro_rules! set_if_changed {
($ident:ident) => {
|this: &&Self, val| {
if glib::PropertyGet::get(&this.$ident, |old_val| old_val == &val) {
return;
}
glib::PropertySet::set(&this.$ident, val);
this.obj().notify(stringify!($ident));
}
}
}
struct MyStruct {
#[properties(get, set = set_if_changed!(ip), explicit_notify)]
pub ip: RefCell<Option<gio::InetAddress>>
}
This unfortunately is problematic on properties with -