Skip to content

Commit

Permalink
Merge pull request #1116 from sdroege/0.17-backports
Browse files Browse the repository at this point in the history
0.17 backports
  • Loading branch information
sdroege committed Jun 6, 2023
2 parents 3ad562c + 840a2eb commit d71c4a8
Show file tree
Hide file tree
Showing 19 changed files with 159 additions and 53 deletions.
3 changes: 2 additions & 1 deletion cairo/src/svg.rs
Expand Up @@ -146,10 +146,11 @@ mod test {
*surface.finish_output_stream().unwrap().downcast().unwrap()
}

#[track_caller]
fn assert_len_close_enough(len_a: usize, len_b: usize) {
// It seems cairo randomizes some element IDs which might make one svg slightly
// larger than the other. Here we make sure the difference is within ~10%.
let len_diff = (len_a as isize - len_b as isize).abs() as usize;
let len_diff = usize::abs_diff(len_a, len_b);
assert!(len_diff < len_b / 10);
}

Expand Down
2 changes: 1 addition & 1 deletion gdk-pixbuf/sys/Cargo.toml
Expand Up @@ -35,7 +35,7 @@ name = "gdk_pixbuf_sys"
authors = ["The gtk-rs Project Developers"]
build = "build.rs"
description = "FFI bindings to libgdk_pixbuf-2.0"
homepage = "http://gtk-rs.org/"
homepage = "https://gtk-rs.org/"
keywords = ["gdk-pixbuf", "ffi", "gtk-rs", "gnome"]
license = "MIT"
name = "gdk-pixbuf-sys"
Expand Down
3 changes: 3 additions & 0 deletions gio/Gir.toml
Expand Up @@ -665,6 +665,7 @@ manual_traits = ["DebugControllerDBusExtManual"]
[[object]]
name = "Gio.DesktopAppInfo"
status = "generate"
manual_traits = ["DesktopAppInfoExtManual"]
cfg_condition = "all(not(windows),not(target_os = \"macos\"))"
[[object.function]]
name = "get_boolean"
Expand Down Expand Up @@ -845,6 +846,7 @@ concurrency = "send+sync"
[[object]]
name = "Gio.InetAddress"
status = "generate"
manual_traits = ["InetAddressExtManual"]
concurrency = "send+sync"
[[object.function]]
name = "new_from_bytes"
Expand Down Expand Up @@ -1121,6 +1123,7 @@ status = "generate"
[[object]]
name = "Gio.Settings"
status = "generate"
manual_traits = ["SettingsExtManual"]
[[object.signal]]
name = "writable-change-event"
inhibit = true
Expand Down
2 changes: 1 addition & 1 deletion gio/sys/Cargo.toml
Expand Up @@ -42,7 +42,7 @@ name = "gio_sys"
authors = ["The gtk-rs Project Developers"]
build = "build.rs"
description = "FFI bindings to libgio-2.0"
homepage = "http://gtk-rs.org/"
homepage = "https://gtk-rs.org/"
keywords = ["gio", "ffi", "gtk-rs", "gnome"]
license = "MIT"
name = "gio-sys"
Expand Down
7 changes: 4 additions & 3 deletions glib-macros/src/lib.rs
Expand Up @@ -851,7 +851,7 @@ pub fn cstr_bytes(item: TokenStream) -> TokenStream {

/// This macro enables you to derive object properties in a quick way.
///
/// # Supported #[property] attributes
/// # Supported `#[property]` attributes
/// | Attribute | Description | Default | Example |
/// | --- | --- | --- | --- |
/// | `name = "literal"` | The name of the property | field ident where `_` (leading and trailing `_` are trimmed) is replaced into `-` | `#[property(name = "prop-name")]` |
Expand All @@ -862,7 +862,8 @@ pub fn cstr_bytes(item: TokenStream) -> TokenStream {
/// | `override_interface = expr` | The type of interface of which to override the property from | | `#[property(override_interface = SomeInterface)]` |
/// | `nullable` | Whether to use `Option<T>` in the wrapper's generated setter | | `#[property(nullable)]` |
/// | `member = ident` | Field of the nested type where property is retrieved and set | | `#[property(member = author)]` |
/// | `builder(<required-params>)[.ident]*` | Used to input required params or add optional Param Spec builder fields | | `#[property(builder(SomeEnum::default()))]`, `#[builder().default_value(1).construct_only()]`, etc. |
/// | `construct_only` | Specify that the property is construct only. This will not generate a public setter and only allow the property to be set during object construction. The use of a custom internal setter is supported. | | `#[property(get, construct_only)]` or `#[property(get, set = set_prop, construct_only)]` |
/// | `builder(<required-params>)[.ident]*` | Used to input required params or add optional Param Spec builder fields | | `#[property(builder(SomeEnum::default()))]`, `#[builder().default_value(1).minimum(0).maximum(5)]`, etc. |
/// | `default` | Sets the `default_value` field of the Param Spec builder | | `#[property(default = 1)]` |
/// | `<optional-pspec-builder-fields> = expr` | Used to add optional Param Spec builder fields | | `#[property(minimum = 0)` , `#[property(minimum = 0, maximum = 1)]`, etc. |
/// | `<optional-pspec-builder-fields>` | Used to add optional Param Spec builder fields | | `#[property(explicit_notify)]` , `#[property(construct_only)]`, etc. |
Expand All @@ -883,7 +884,7 @@ pub fn cstr_bytes(item: TokenStream) -> TokenStream {
///
/// # Internal getters and setters
/// By default, they are generated for you. However, you can use a custom getter/setter
/// by assigning an expression to `get`/`set` #[property] attributes: `#[property(get = |_| 2, set)]` or `#[property(get, set = custom_setter_func)]`.
/// by assigning an expression to `get`/`set` `#[property]` attributes: `#[property(get = |_| 2, set)]` or `#[property(get, set = custom_setter_func)]`.
///
/// # Supported types
/// Every type implementing the trait `Property` is supported.
Expand Down
14 changes: 11 additions & 3 deletions glib-macros/src/properties.rs
Expand Up @@ -236,6 +236,7 @@ struct PropDesc {
member: Option<syn::Ident>,
builder: Option<(Punctuated<syn::Expr, Token![,]>, TokenStream2)>,
builder_fields: HashMap<syn::Ident, Option<syn::Expr>>,
is_construct_only: bool,
}

impl PropDesc {
Expand All @@ -248,7 +249,7 @@ impl PropDesc {
let ReceivedAttrs {
nullable,
get,
set,
mut set,
override_class,
override_interface,
ty,
Expand All @@ -258,6 +259,12 @@ impl PropDesc {
builder_fields,
} = attrs;

let is_construct_only = builder_fields.iter().any(|(k, _)| *k == "construct_only");
if is_construct_only && set.is_none() {
// Insert a default internal setter automatically
set = Some(MaybeCustomFn::Default);
}

if get.is_none() && set.is_none() {
return Err(syn::Error::new(
attrs_span,
Expand Down Expand Up @@ -295,6 +302,7 @@ impl PropDesc {
member,
builder,
builder_fields,
is_construct_only,
})
}
}
Expand Down Expand Up @@ -534,8 +542,8 @@ fn expand_wrapper_getset_properties(props: &[PropDesc]) -> TokenStream2 {
self.property::<<#ty as #crate_ident::Property>::Value>(#stripped_name)
})
});
let is_construct_only = p.builder_fields.iter().any(|(k, _)| *k == "construct_only");
let setter = (p.set.is_some() && !is_construct_only).then(|| {

let setter = (p.set.is_some() && !p.is_construct_only).then(|| {
let ident = format_ident!("set_{}", ident);
let target_ty = quote!(<<#ty as #crate_ident::Property>::Value as #crate_ident::HasParamSpec>::SetValue);
let set_ty = if p.nullable {
Expand Down
26 changes: 25 additions & 1 deletion glib-macros/tests/properties.rs
Expand Up @@ -160,6 +160,10 @@ mod foo {
weak_ref_prop: glib::WeakRef<glib::Object>,
#[property(get, set)]
send_weak_ref_prop: glib::SendWeakRef<glib::Object>,
#[property(get, default_value = 0, construct_only)]
construct_only_cell: OnceCell<u32>,
#[property(get, set = Self::set_construct_only_custom, construct_only)]
construct_only_custom_setter: OnceCell<Option<String>>,
}

impl ObjectImpl for Foo {
Expand Down Expand Up @@ -194,6 +198,11 @@ mod foo {
fn overridden(&self) -> u32 {
43
}
fn set_construct_only_custom(&self, value: Option<String>) {
self.construct_only_custom_setter
.set(value.map(|v| format!("custom set: {}", v)))
.expect("Setter to be only called once");
}
}
}

Expand Down Expand Up @@ -382,7 +391,22 @@ fn props() {
// object subclass
let myobj = glib::BoxedAnyObject::new("");
myfoo.set_object(Some(myobj.upcast_ref()));
assert_eq!(myfoo.object(), Some(myobj.upcast()))
assert_eq!(myfoo.object(), Some(myobj.upcast()));

// construct_only
let myfoo: foo::Foo = glib::object::Object::builder()
.property("construct-only-cell", 1u32)
.build();
assert_eq!(myfoo.construct_only_cell(), 1u32);

// construct_only with custom setter
let myfoo: foo::Foo = glib::object::Object::builder()
.property("construct-only-custom-setter", "foo")
.build();
assert_eq!(
myfoo.construct_only_custom_setter(),
Some("custom set: foo".to_owned())
);
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion glib/gobject-sys/Cargo.toml
Expand Up @@ -31,7 +31,7 @@ name = "gobject_sys"
authors = ["The gtk-rs Project Developers"]
build = "build.rs"
description = "FFI bindings to libgobject-2.0"
homepage = "http://gtk-rs.org/"
homepage = "https://gtk-rs.org/"
keywords = ["gobject", "ffi", "gtk-rs", "gnome"]
license = "MIT"
name = "gobject-sys"
Expand Down
3 changes: 2 additions & 1 deletion glib/src/collections/list.rs
Expand Up @@ -385,7 +385,8 @@ impl<T: TransparentPtrType> List<T> {
/// Consumes the list and returns the underlying pointer.
#[inline]
pub fn into_raw(mut self) -> *mut ffi::GList {
mem::replace(&mut self.ptr, None)
self.ptr
.take()
.map(|p| p.as_ptr())
.unwrap_or(ptr::null_mut())
}
Expand Down
3 changes: 2 additions & 1 deletion glib/src/collections/slist.rs
Expand Up @@ -380,7 +380,8 @@ impl<T: TransparentPtrType> SList<T> {
/// Consumes the list and returns the underlying pointer.
#[inline]
pub fn into_raw(mut self) -> *mut ffi::GSList {
mem::replace(&mut self.ptr, None)
self.ptr
.take()
.map(|p| p.as_ptr())
.unwrap_or(ptr::null_mut())
}
Expand Down
33 changes: 32 additions & 1 deletion glib/src/collections/strv.rs
Expand Up @@ -358,6 +358,21 @@ impl<'a, const N: usize> From<[&'a str; N]> for StrV {
}
}

impl<'a, const N: usize> From<[&'a GStr; N]> for StrV {
#[inline]
fn from(value: [&'a GStr; N]) -> Self {
unsafe {
let mut s = Self::with_capacity(value.len());
for (i, item) in value.iter().enumerate() {
*s.ptr.as_ptr().add(i) = GString::from(*item).into_glib_ptr();
}
s.len = value.len();
*s.ptr.as_ptr().add(s.len) = ptr::null_mut();
s
}
}
}

impl<'a> From<&'a [&'a str]> for StrV {
#[inline]
fn from(value: &'a [&'a str]) -> Self {
Expand Down Expand Up @@ -446,8 +461,10 @@ impl StrV {
if len == 0 {
StrV::default()
} else {
// Allocate space for len + 1 pointers, one pointer for each string and a trailing
// null pointer.
let new_ptr =
ffi::g_malloc(mem::size_of::<*mut c_char>() * len + 1) as *mut *mut c_char;
ffi::g_malloc(mem::size_of::<*mut c_char>() * (len + 1)) as *mut *mut c_char;

// Need to clone every item because we don't own it here
for i in 0..len {
Expand Down Expand Up @@ -1396,6 +1413,20 @@ mod test {
}
}

#[test]
fn test_from_slice() {
let items = [
crate::gstr!("str1"),
crate::gstr!("str2"),
crate::gstr!("str3"),
];

let slice1 = StrV::from(&items[..]);
let slice2 = StrV::from(items);
assert_eq!(slice1.len(), 3);
assert_eq!(slice1, slice2);
}

#[test]
fn test_safe_api() {
let items = [
Expand Down
3 changes: 1 addition & 2 deletions glib/src/main_context_futures.rs
Expand Up @@ -620,11 +620,10 @@ impl MainContext {
pub fn block_on<F: Future>(&self, f: F) -> F::Output {
let mut res = None;
let l = MainLoop::new(Some(self), false);
let l_clone = l.clone();

let f = async {
res = Some(panic::AssertUnwindSafe(f).catch_unwind().await);
l_clone.quit();
l.quit();
};

let f = unsafe {
Expand Down

0 comments on commit d71c4a8

Please sign in to comment.