On Fri Sep 30 21:37:03 2022 +0000, Esme Povirk wrote:
I don't feel like this name is any more intuitive. Maybe something like client_is_remote? Fundamentally, I think my confusion stems from not having enough terms to describe all the possible kinds of nodes. We have nodes where the element provider is in the same thread that uses it, client nodes that wrap an element provider on another thread, and nodes being wrapped by a client node. I'm not sure which of those three categories is a "nested" node, or what the others are called.
From a clients point of view, there is one `HUIANODE`. It acts as a container for one (or later multiple) `IWineUiaProvider` interfaces.
An `IWineUiaProvider` can get its values from one of the following interfaces: - An `IRawElementProviderSimple` interface. - An `IWineUiaNode` interface.
If the provider gets its values directly from an `IRawElementProviderSimple` interface, it's a normal, non-nested node provider. These are created from the function `UiaNodeFromProvider()`, and also created when you call `UiaNodeFromHandle()` on a same-thread HWND.
If the provider gets its values from an `IWineUiaNode` interface, it's a "nested node" provider. I.e, a node within a node. These are created when calling `UiaNodeFromHandle()` on an HWND from another thread or process. The node it represents contains its own `IWineUiaProvider` which gets its values from an `IRawElementProviderSimple` interface. This is the "nested node". Nested nodes are an HUIANODE, but they're never meant to be touched directly by a client. They're tracked by the provider thread and able to be disconnected with `UiaDisconnectProvider()` and `UiaDisconnectAllProviders()`. Any properties that return a new HUIANODE to a client (i.e `UIAutomationType_Element` properties) need to return a new "nested node", that gets turned into an `IWineUiaProvider` on the client end that gets its properties from an `IWineUiaNode`.
This is why I thought `is_nested_node_elprov` made more sense, because that's the distinction. An `IWineUiaProvider` that gets its values from an `IRawElementProviderSimple` inside of a nested node behaves the same way as an `IWineUiaProvider` that gets its values from an `IRawElementProviderSimple` inside of a non-nested node, the only difference is that we need to return a different kind of `HUIANODE` for `UIAutomationType_Element` properties. We need to pass them to the provider thread to be tracked, and we need to return a value that the client can use to unmarshal an `IWineUiaNode` interface and create an `IWineUiaProvider` that gets its values from an `IWineUiaNode` interface. For a non-nested node, we just return an `HUIANODE` pointer directly to the client containing an `IWineUiaProvider` that gets its values directly from an `IRawElementProviderSimple`.
It's kind of complicated, and I hope that has cleared things up a bit. :/ A more simplified way of thinking about it might be:
- A nested node provider calls: `IWineUiaProvider->IWineUiaNode->IWineUiaProvider->IRawElementProviderSimple` - A normal provider calls: `IWineUiaProvider->IRawElementProviderSimple`