windows-rs icon indicating copy to clipboard operation
windows-rs copied to clipboard

Array is not IIterable

Open Corallus-Caninus opened this issue 4 years ago • 3 comments

the following code does not compile since Array is not IIterable. Yet this is how this function should be called in the window documentation.

let mouse_injection = InjectedInputMouseInfo::new().unwrap();
mouse_injection.SetDeltaY(y as i32).unwrap();
mouse_injection.SetDeltaX(x as i32).unwrap();
let injector = InputInjector::TryCreate().unwrap();
let mouse_injection_array: Array<InjectedInputMouseInfo> = Array::from_slice(&[Some(mouse_injection)]);
injector.InjectMouseInput(mouse_injection_array).unwrap();

This (and intuition) leads me to believe Array in windows::core should also be IIterable.

Corallus-Caninus avatar Nov 19 '21 03:11 Corallus-Caninus

This is a duplicate of #91 that I hope to get to soon.

kennykerr avatar Nov 19 '21 16:11 kennykerr

Although In the windows documentation injection uses an array of mouseinfo classes as the parameter that rust declares must be IIterable, I cannot find anywhere in the documentation that says array should actually be IIterable whereas IVector explicitly states it's IIterable in windows api documentation.

It seems there's a missing polymorphism since IEnumerable can be passed to injector for #1326 instead which array should impl natively:

https://docs.microsoft.com/en-us/uwp/api/windows.ui.input.preview.injection.inputinjector.injectmouseinput?view=winrt-22000#Windows_UI_Input_Preview_Injection_InputInjector_InjectMouseInput_Windows_Foundation_Collections_IIterable_Windows_UI_Input_Preview_Injection_InjectedInputMouseInfo__

Corallus-Caninus avatar Nov 20 '21 17:11 Corallus-Caninus

It doesn't have to be but it is common practice by language projections (e.g. C# and C++) to make arrays iterable. That is part of #91, both providing stock implementations and stock parameter bindings.

kennykerr avatar Nov 22 '21 18:11 kennykerr

Thanks to https://github.com/microsoft/windows-rs/pull/2346 you should now be able to call InjectMouseInput.

kennykerr avatar Mar 02 '23 17:03 kennykerr

it still doesn't work

    let mouse_injection = InjectedInputMouseInfo::new().unwrap();
    mouse_injection.SetDeltaY(0).unwrap();
    mouse_injection.SetDeltaX(0).unwrap();
    let injector = InputInjector::TryCreate().unwrap();
    let mouse_injection_array: Array<InjectedInputMouseInfo> =
        Array::from_slice(&[Some(mouse_injection)]);
    injector.InjectMouseInput(mouse_injection_array).unwrap();
the trait bound `Array<InjectedInputMouseInfo>: TryIntoParam<IIterable<InjectedInputMouseInfo>>` is not satisfied
the following other types implement trait `TryIntoParam<T>`:
  Option<&T>
  &U

NiiightmareXD avatar Oct 02 '23 14:10 NiiightmareXD

To be clear, a WinRT array is not iterable. To be iterable in WinRT means to be a COM object that implements the IIterable<T> interface, but that would require an extra heap allocation. When other language projections let you treat arrays as iterable, they silently create a heap-allocated COM object to model the array.

What #2346 (#91) did was make it easy to create an IIterable<T> implementation around a collection using try_from. Today that collection has to be a Vec or BTreeMap but it would be nice to be able to create a scoped IIterable<T> from a slice, as I implemented for cppwinrt.

kennykerr avatar Oct 06 '23 13:10 kennykerr