zadjii-msft / PowerToys

Windows system utilities to maximize productivity
MIT License
2 stars 2 forks source link

Investigate WinRT improvements for updating items, async flow, refiltering items after updates #77

Open joadoumie opened 1 week ago

joadoumie commented 1 week ago

Description of the new feature / enhancement

We need to continue to improve the current state of the world of our WinRT usage. A lot of questions have come up regarding async await patterns + the idea of being able to 'yield' current in PT Run.

This work item includes investigating the Shmueli.WinRT implementation to see what kind of benefits we may be able to get for passing around types.

Scenario when this would be used?

For all things WinRT with extensions.

Supporting information

"Just copying the hacker news http logic, but would be nice to allow extensions to use proper async code... Maybe ties into if we do filtering and are polling extensions less often in the new model, maybe we have a callback pattern for results/updates, so the extension can just spin off a thread to do a search or longer operation, if needed vs. having to just return data right away?"

The discussion revolved around the possibility of extensions returning items with a group string, allowing the UI to handle the grouping instead of extensions having to structure their data. This could be achieved with a public async Task<IEnumberable> Getitems() method, or possibly an IAsyncOperation for WinRT. The extension author could then use yield return to transpose results from another data model to the item.

zadjii commented 1 week ago

This sounds like a combination of a couple different asks:

Should we separate some of this out?

joadoumie commented 1 week ago

Yeah this was the top level item that needed to be broken out -- seems like you've done that above, so I'll go ahead and create the additional items and link them here (there is already one for Shmueli).

Based on feedback from Hackathon and folks building extensions -- it'd be interesting if we could make things a bit better for devs by:

michael-hawker commented 4 days ago

It was about using the newer C# IAsyncEnumerable pattern to help synchronize between the extensions and the app to incrementally return results. But talking to Sergio, there's not equivalent WinRT, so that's probably a non-starter?

joadoumie commented 4 days ago

Probably naive question - is that something we can make better in WinRT if it's an important paradigm?

zadjii-msft commented 4 days ago

is that something we can make better in WinRT if it's an important paradigm?

Probably not, certainly not in the timelines we're thinking about.

FWIW I think the best notes I had on the topic are around here: https://github.com/zadjii-msft/PowerToys/blob/main/src/modules/cmdpal/doc/initial-sdk-spec/initial-sdk-spec.md#updating-the-list

[!WARNING] We chose this API surface for a few reasons:

  • IObservableCollection, which has quite a good mechanism for specifying exactly which parts of the collection changed, isn't exposed through WinRT
  • IObservableVector doesn't work well across process boundaries
  • In general, all the collection WinRT objects are Considered Harmful in cross-proc scenarios

But we want both static and dynamic lists to be able to update the results in real-time. Example: A process list that updates in real-time. We want to be able to add and remove items from the list as they start and stop.


To mitigate how dumb all that is, the plan I came up with Hart was:

That way, the replies to GetItems should remain quick

(this also doesn't look spec'd very well)

zadjii-msft commented 4 days ago

That however does not deal at all with anything "paginated" though. Like, the HN extension just returns the first 24 items, with no way to indicate "I could have more items for you if you want".

That ^^^^ I had mentally punted out of v0, but maybe we shouldn't

michael-hawker commented 4 days ago

I don't know if it's projected in WinRT, but there is the ISupportIncrementalLoading interface too.

I think that's the crux is how much does the UI pre-filter what it has vs. when it goes to the extension and what does that look like and how we minimize the creation of new/duplicate items: