yury / cidre

Apple frameworks bindings for rust
MIT License
49 stars 2 forks source link

A sync API to get SharableContent::current #10

Closed morajabi closed 9 months ago

morajabi commented 9 months ago

Is there a way to have a sync version or add Send to get sharable content? Because I'm getting error of cannot send !Send struct across await points. https://github.com/yury/cidre/blob/main/cidre/src/sc/shareable_content.rs#L113

Other impls I've seen: https://github.com/svtlabs/screencapturekit-rs/blob/main/screencapturekit-sys/src/shareable_content.rs#L175

yury commented 9 months ago

Sorry for late reply.

https://github.com/yury/cidre/blob/9601c0626e4f6f2b716c4f7d4f83bcc14b374c46/cidre/examples/sc-record/main.rs#L274

It is Send on my branch: https://github.com/yury/cidre/blob/9601c0626e4f6f2b716c4f7d4f83bcc14b374c46/cidre/src/sc/shareable_content.rs#L88

morajabi commented 9 months ago

It is Send on my branch:

https://github.com/yury/cidre/blob/9601c0626e4f6f2b716c4f7d4f83bcc14b374c46/cidre/src/sc/shareable_content.rs#L88

My bad — let me try again with latest and will post the exact error if I get any.

morajabi commented 9 months ago

@yury this is the error I get: CleanShot 2024-01-28 at 18 01 39

CleanShot 2024-01-28 at 18 02 44

yury commented 9 months ago

Do you use latest version?

I just double checked with sc-record example. Everything is good.

cargo r --example sc-record

Is it broken for you too?

morajabi commented 9 months ago

Yes I do. In fact, I see this line: unsafe impl Send for ShareableContent {} and it works in one situation but not the other.
This one works in a struct:


  pub async fn start(&mut self) -> (i32) {
    let queue = dispatch::Queue::serial_with_ar_pool();

    // display
    let content = sc::ShareableContent::current().await.expect("content");

But when I use this function in another crate it doesn't work:

pub async fn get_sharable_contents() -> Vec<SharableItem> {
  // display
  let content = cidre::sc::ShareableContent::current()
    .await
    .expect("content");

  let primary_id: u32 = cidre::cg::main_display_id().into();
  let displays: Vec<SharableItem> = content
    .displays()
    .iter()
    .map(|display| {
      let is_primary = display.display_id() == primary_id;

      SharableItem {
        id: display.display_id().into(),
        kind: SharableKind::Display,
        title: format!(
          "{} ({w}x{h})",
          if is_primary {
            "Primary Display"
          } else {
            "Display"
          },
          w = display.width(),
          h = display.height()
        ),
      }
    })
    .collect();

  return displays;
}

probably I'm missing something myself, can't figure it out though.

yury commented 9 months ago

Interesting...

Could it be that you are using different async runtime (not tokio) in another crate?

yury commented 9 months ago

I think, it is ns::Error. Please try latest version

morajabi commented 9 months ago

It works! Thank you