Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manually add typed & with_type methods #1415

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions gdk4/Gir.toml
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ generate_builder = false
name = "read_async"
manual = true # mime_types are cloned instead of converting them to a Vec<String>
[[object.function]]
name = "read_value_async"
manual = true # To add a with_type variant
[[object.function]]
name = "set_content"
[object.function.return]
bool_return_is_error = "Can't set new clipboard content"
Expand Down Expand Up @@ -282,9 +285,11 @@ status = "generate"
[[object.function]]
name = "new_for_gtype"
rename = "for_type"
manual = true # To add a with_type variant
[[object.function]]
name = "contain_gtype"
rename = "contains_type"
manual = true # To add a with_type variant
[[object.function]]
name = "match_gtype"
rename = "match_type"
Expand Down Expand Up @@ -448,6 +453,9 @@ status = "generate"
[[object.function]]
name = "read_async"
manual = true # mime_types are cloned instead of converting them to a Vec<String>
[[object.function]]
name = "read_value_async"
manual = true # To add a with_type variant

[[object]]
name = "Gdk.EventType"
Expand Down
66 changes: 0 additions & 66 deletions gdk4/src/auto/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,72 +166,6 @@ impl Clipboard {
}))
}

#[doc(alias = "gdk_clipboard_read_value_async")]
pub fn read_value_async<P: FnOnce(Result<glib::Value, glib::Error>) + 'static>(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
cancellable: Option<&impl IsA<gio::Cancellable>>,
callback: P,
) {
let main_context = glib::MainContext::ref_thread_default();
let is_main_context_owner = main_context.is_owner();
let has_acquired_main_context = (!is_main_context_owner)
.then(|| main_context.acquire().ok())
.flatten();
assert!(
is_main_context_owner || has_acquired_main_context.is_some(),
"Async operations only allowed if the thread is owning the MainContext"
);

let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::new(glib::thread_guard::ThreadGuard::new(callback));
unsafe extern "C" fn read_value_async_trampoline<
P: FnOnce(Result<glib::Value, glib::Error>) + 'static,
>(
_source_object: *mut glib::gobject_ffi::GObject,
res: *mut gio::ffi::GAsyncResult,
user_data: glib::ffi::gpointer,
) {
let mut error = ptr::null_mut();
let ret =
ffi::gdk_clipboard_read_value_finish(_source_object as *mut _, res, &mut error);
let result = if error.is_null() {
Ok(from_glib_none(ret))
} else {
Err(from_glib_full(error))
};
let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::from_raw(user_data as *mut _);
let callback: P = callback.into_inner();
callback(result);
}
let callback = read_value_async_trampoline::<P>;
unsafe {
ffi::gdk_clipboard_read_value_async(
self.to_glib_none().0,
type_.into_glib(),
io_priority.into_glib(),
cancellable.map(|p| p.as_ref()).to_glib_none().0,
Some(callback),
Box_::into_raw(user_data) as *mut _,
);
}
}

pub fn read_value_future(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Value, glib::Error>> + 'static>>
{
Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
obj.read_value_async(type_, io_priority, Some(cancellable), move |res| {
send.resolve(res);
});
}))
}

#[doc(alias = "gdk_clipboard_set_content")]
pub fn set_content(
&self,
Expand Down
18 changes: 0 additions & 18 deletions gdk4/src/auto/content_formats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,6 @@ impl ContentFormats {
}
}

#[doc(alias = "gdk_content_formats_new_for_gtype")]
#[doc(alias = "new_for_gtype")]
pub fn for_type(type_: glib::types::Type) -> ContentFormats {
assert_initialized_main_thread!();
unsafe { from_glib_full(ffi::gdk_content_formats_new_for_gtype(type_.into_glib())) }
}

#[doc(alias = "gdk_content_formats_contain_gtype")]
#[doc(alias = "contain_gtype")]
pub fn contains_type(&self, type_: glib::types::Type) -> bool {
unsafe {
from_glib(ffi::gdk_content_formats_contain_gtype(
self.to_glib_none().0,
type_.into_glib(),
))
}
}

#[doc(alias = "gdk_content_formats_contain_mime_type")]
pub fn contain_mime_type(&self, mime_type: &str) -> bool {
unsafe {
Expand Down
67 changes: 1 addition & 66 deletions gdk4/src/auto/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use glib::{
signal::{connect_raw, SignalHandlerId},
translate::*,
};
use std::{boxed::Box as Box_, fmt, mem::transmute, pin::Pin, ptr};
use std::{boxed::Box as Box_, fmt, mem::transmute};

glib::wrapper! {
#[doc(alias = "GdkDrop")]
Expand Down Expand Up @@ -63,71 +63,6 @@ impl Drop {
unsafe { from_glib_none(ffi::gdk_drop_get_surface(self.to_glib_none().0)) }
}

#[doc(alias = "gdk_drop_read_value_async")]
pub fn read_value_async<P: FnOnce(Result<glib::Value, glib::Error>) + 'static>(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
cancellable: Option<&impl IsA<gio::Cancellable>>,
callback: P,
) {
let main_context = glib::MainContext::ref_thread_default();
let is_main_context_owner = main_context.is_owner();
let has_acquired_main_context = (!is_main_context_owner)
.then(|| main_context.acquire().ok())
.flatten();
assert!(
is_main_context_owner || has_acquired_main_context.is_some(),
"Async operations only allowed if the thread is owning the MainContext"
);

let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::new(glib::thread_guard::ThreadGuard::new(callback));
unsafe extern "C" fn read_value_async_trampoline<
P: FnOnce(Result<glib::Value, glib::Error>) + 'static,
>(
_source_object: *mut glib::gobject_ffi::GObject,
res: *mut gio::ffi::GAsyncResult,
user_data: glib::ffi::gpointer,
) {
let mut error = ptr::null_mut();
let ret = ffi::gdk_drop_read_value_finish(_source_object as *mut _, res, &mut error);
let result = if error.is_null() {
Ok(from_glib_none(ret))
} else {
Err(from_glib_full(error))
};
let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::from_raw(user_data as *mut _);
let callback: P = callback.into_inner();
callback(result);
}
let callback = read_value_async_trampoline::<P>;
unsafe {
ffi::gdk_drop_read_value_async(
self.to_glib_none().0,
type_.into_glib(),
io_priority.into_glib(),
cancellable.map(|p| p.as_ref()).to_glib_none().0,
Some(callback),
Box_::into_raw(user_data) as *mut _,
);
}
}

pub fn read_value_future(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Value, glib::Error>> + 'static>>
{
Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
obj.read_value_async(type_, io_priority, Some(cancellable), move |res| {
send.resolve(res);
});
}))
}

#[doc(alias = "gdk_drop_status")]
pub fn status(&self, actions: DragAction, preferred: DragAction) {
unsafe {
Expand Down
89 changes: 88 additions & 1 deletion gdk4/src/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::{prelude::*, Clipboard};
use glib::translate::*;
use glib::GString;
use std::{future, pin::Pin, ptr};
use std::{boxed::Box as Box_, future, pin::Pin, ptr};

impl Clipboard {
#[doc(alias = "gdk_clipboard_read_async")]
Expand Down Expand Up @@ -86,4 +86,91 @@ impl Clipboard {
});
}))
}

#[doc(alias = "gdk_clipboard_read_value_async")]
pub fn read_value_async<T: for<'a> glib::value::FromValue<'a> + glib::StaticType>(
&self,
io_priority: glib::Priority,
cancellable: Option<&impl IsA<gio::Cancellable>>,
callback: impl FnOnce(Result<T, glib::Error>) + 'static,
) {
let callback2 =
|t: Result<glib::Value, glib::Error>| callback(t.map(|v| v.get::<T>().unwrap()));
self.read_value_async_with_type(T::static_type(), io_priority, cancellable, callback2)
}

#[doc(alias = "gdk_clipboard_read_value_async")]
pub fn read_value_async_with_type<P: FnOnce(Result<glib::Value, glib::Error>) + 'static>(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
cancellable: Option<&impl IsA<gio::Cancellable>>,
callback: P,
) {
let main_context = glib::MainContext::ref_thread_default();
let is_main_context_owner = main_context.is_owner();
let has_acquired_main_context = (!is_main_context_owner)
.then(|| main_context.acquire().ok())
.flatten();
assert!(
is_main_context_owner || has_acquired_main_context.is_some(),
"Async operations only allowed if the thread is owning the MainContext"
);

let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::new(glib::thread_guard::ThreadGuard::new(callback));
unsafe extern "C" fn read_value_async_trampoline<
P: FnOnce(Result<glib::Value, glib::Error>) + 'static,
>(
_source_object: *mut glib::gobject_ffi::GObject,
res: *mut gio::ffi::GAsyncResult,
user_data: glib::ffi::gpointer,
) {
let mut error = ptr::null_mut();
let ret =
ffi::gdk_clipboard_read_value_finish(_source_object as *mut _, res, &mut error);
let result = if error.is_null() {
Ok(from_glib_none(ret))
} else {
Err(from_glib_full(error))
};
let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::from_raw(user_data as *mut _);
let callback: P = callback.into_inner();
callback(result);
}
let callback = read_value_async_trampoline::<P>;
unsafe {
ffi::gdk_clipboard_read_value_async(
self.to_glib_none().0,
type_.into_glib(),
io_priority.into_glib(),
cancellable.map(|p| p.as_ref()).to_glib_none().0,
Some(callback),
Box_::into_raw(user_data) as *mut _,
);
}
}

pub async fn read_value_future<T: for<'a> glib::value::FromValue<'a> + glib::StaticType>(
&self,
io_priority: glib::Priority,
) -> Result<T, glib::Error> {
self.read_value_future_with_type(T::static_type(), io_priority)
.await
.map(|v| v.get::<T>().unwrap())
}

pub fn read_value_future_with_type(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Value, glib::Error>> + 'static>>
{
Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
obj.read_value_async_with_type(type_, io_priority, Some(cancellable), move |res| {
send.resolve(res);
});
}))
}
}
33 changes: 32 additions & 1 deletion gdk4/src/content_formats.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,40 @@
// Take a look at the license at the top of the repository in the LICENSE file.

use crate::{ContentFormats, ContentFormatsBuilder};
use glib::{translate::*, Slice};
use glib::{translate::*, Slice, StaticType};

impl ContentFormats {
#[doc(alias = "gdk_content_formats_new_for_gtype")]
#[doc(alias = "new_for_gtype")]
pub fn for_type<T: StaticType>() -> Self {
assert_initialized_main_thread!();
Self::for_type_with_type(T::static_type())
}

#[doc(alias = "gdk_content_formats_new_for_gtype")]
#[doc(alias = "new_for_gtype")]
pub fn for_type_with_type(type_: glib::Type) -> Self {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here

assert_initialized_main_thread!();
unsafe { from_glib_full(ffi::gdk_content_formats_new_for_gtype(type_.into_glib())) }
}

#[doc(alias = "gdk_content_formats_contain_gtype")]
#[doc(alias = "contain_gtype")]
pub fn contains_type<T: StaticType>(&self) -> bool {
self.contains_type_with_type(T::static_type())
}

#[doc(alias = "gdk_content_formats_contain_gtype")]
#[doc(alias = "contain_gtype")]
pub fn contains_type_with_type(&self, type_: glib::types::Type) -> bool {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here

unsafe {
from_glib(ffi::gdk_content_formats_contain_gtype(
self.to_glib_none().0,
type_.into_glib(),
))
}
}

#[doc(alias = "gdk_content_formats_get_gtypes")]
#[doc(alias = "get_gtypes")]
pub fn types(&self) -> Slice<glib::Type> {
Expand Down
8 changes: 7 additions & 1 deletion gdk4/src/content_formats_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ impl ContentFormatsBuilder {

#[doc(alias = "gdk_content_formats_builder_add_gtype")]
#[must_use]
pub fn add_type(self, type_: glib::types::Type) -> Self {
pub fn add_type<T: glib::StaticType>(self) -> Self {
self.add_with_type(T::static_type())
}

#[doc(alias = "gdk_content_formats_builder_add_gtype")]
#[must_use]
pub fn add_with_type(self, type_: glib::types::Type) -> Self {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here maybe?

unsafe {
ffi::gdk_content_formats_builder_add_gtype(self.to_glib_none().0, type_.into_glib());
}
Expand Down
9 changes: 8 additions & 1 deletion gdk4/src/content_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@ mod sealed {
// rustdoc-stripper-ignore-next
/// Trait containing manually implemented methods of [`ContentProvider`](crate::ContentProvider).
pub trait ContentProviderExtManual: sealed::Sealed + IsA<ContentProvider> {
fn value<T: for<'a> glib::value::FromValue<'a> + glib::StaticType>(
&self,
) -> Result<T, glib::Error> {
self.value_with_type(T::static_type())
.map(|v| v.get::<T>().unwrap())
}

#[doc(alias = "gdk_content_provider_get_value")]
fn value(&self, type_: glib::Type) -> Result<glib::Value, glib::Error> {
fn value_with_type(&self, type_: glib::Type) -> Result<glib::Value, glib::Error> {
unsafe {
let mut error = std::ptr::null_mut();
let mut value = glib::Value::from_type(type_);
Expand Down
Loading