Commit edcd55ba authored by Connor McAdams's avatar Connor McAdams Committed by Alexandre Julliard

uiautomationcore: Add support for multiple providers on a single HUIANODE.

parent e9ff761d
...@@ -4328,14 +4328,14 @@ static const struct prov_method_sequence get_elem_arr_prop_seq[] = { ...@@ -4328,14 +4328,14 @@ static const struct prov_method_sequence get_elem_arr_prop_seq[] = {
{ &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider_child, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */ { &Provider_child, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider_child, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider_child, PROV_GET_PROVIDER_OPTIONS },
{ &Provider_child2, PROV_GET_PROVIDER_OPTIONS }, { &Provider_child2, PROV_GET_PROVIDER_OPTIONS },
/* Win10v1507 and below call this. */ /* Win10v1507 and below call this. */
{ &Provider_child2, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */ { &Provider_child2, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider_child2, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider_child2, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider_child2, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */ { &Provider_child2, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider_child2, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider_child2, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider_child2, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider_child2, PROV_GET_PROVIDER_OPTIONS },
{ &Provider_child, PROV_GET_PROPERTY_VALUE }, { &Provider_child, PROV_GET_PROPERTY_VALUE },
{ &Provider_child2, PROV_GET_PROPERTY_VALUE }, { &Provider_child2, PROV_GET_PROPERTY_VALUE },
{ 0 } { 0 }
...@@ -4972,8 +4972,8 @@ static const struct prov_method_sequence node_from_hwnd2[] = { ...@@ -4972,8 +4972,8 @@ static const struct prov_method_sequence node_from_hwnd2[] = {
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
{ &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
/* Windows 10+ calls this. */ /* Windows 10+ calls this. */
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_OPTIONAL }, { &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_OPTIONAL },
...@@ -4987,7 +4987,7 @@ static const struct prov_method_sequence node_from_hwnd3[] = { ...@@ -4987,7 +4987,7 @@ static const struct prov_method_sequence node_from_hwnd3[] = {
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_TODO }, /* UIA_ProviderDescriptionPropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE, METHOD_TODO }, /* UIA_ProviderDescriptionPropertyId */
{ 0 } { 0 }
...@@ -5016,7 +5016,7 @@ static const struct prov_method_sequence node_from_hwnd5[] = { ...@@ -5016,7 +5016,7 @@ static const struct prov_method_sequence node_from_hwnd5[] = {
{ &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider_child, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */ { &Provider_child, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider_child, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider_child, PROV_GET_PROVIDER_OPTIONS },
/* Only done in Windows 8+. */ /* Only done in Windows 8+. */
{ &Provider_child, FRAG_GET_RUNTIME_ID, METHOD_OPTIONAL }, { &Provider_child, FRAG_GET_RUNTIME_ID, METHOD_OPTIONAL },
{ &Provider_child, FRAG_GET_FRAGMENT_ROOT, METHOD_OPTIONAL }, { &Provider_child, FRAG_GET_FRAGMENT_ROOT, METHOD_OPTIONAL },
...@@ -5034,7 +5034,7 @@ static const struct prov_method_sequence node_from_hwnd6[] = { ...@@ -5034,7 +5034,7 @@ static const struct prov_method_sequence node_from_hwnd6[] = {
{ &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider_child, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */ { &Provider_child, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider_child, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider_child, PROV_GET_PROVIDER_OPTIONS },
/* Next 4 are only done in Windows 8+. */ /* Next 4 are only done in Windows 8+. */
{ &Provider_child, FRAG_GET_RUNTIME_ID, METHOD_OPTIONAL }, { &Provider_child, FRAG_GET_RUNTIME_ID, METHOD_OPTIONAL },
{ &Provider_child, FRAG_GET_FRAGMENT_ROOT, METHOD_OPTIONAL }, { &Provider_child, FRAG_GET_FRAGMENT_ROOT, METHOD_OPTIONAL },
...@@ -5059,7 +5059,7 @@ static const struct prov_method_sequence node_from_hwnd7[] = { ...@@ -5059,7 +5059,7 @@ static const struct prov_method_sequence node_from_hwnd7[] = {
{ &Provider_child, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */ { &Provider_child, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider_child, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider_child, PROV_GET_PROVIDER_OPTIONS },
{ &Provider_child, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider_child, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
...@@ -5077,7 +5077,7 @@ static const struct prov_method_sequence node_from_hwnd8[] = { ...@@ -5077,7 +5077,7 @@ static const struct prov_method_sequence node_from_hwnd8[] = {
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider, PROV_GET_PROPERTY_VALUE }, /* UIA_ProviderDescriptionPropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE }, /* UIA_ProviderDescriptionPropertyId */
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_TODO }, /* UIA_ControlTypePropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE, METHOD_TODO }, /* UIA_ControlTypePropertyId */
...@@ -5091,7 +5091,7 @@ static const struct prov_method_sequence node_from_hwnd9[] = { ...@@ -5091,7 +5091,7 @@ static const struct prov_method_sequence node_from_hwnd9[] = {
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
/* Only done in Windows 8+. */ /* Only done in Windows 8+. */
{ &Provider, FRAG_GET_RUNTIME_ID, METHOD_OPTIONAL }, { &Provider, FRAG_GET_RUNTIME_ID, METHOD_OPTIONAL },
{ &Provider, FRAG_GET_FRAGMENT_ROOT, METHOD_OPTIONAL }, { &Provider, FRAG_GET_FRAGMENT_ROOT, METHOD_OPTIONAL },
...@@ -5109,7 +5109,7 @@ static const struct prov_method_sequence disconnect_prov1[] = { ...@@ -5109,7 +5109,7 @@ static const struct prov_method_sequence disconnect_prov1[] = {
{ &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider_child, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */ { &Provider_child, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider_child, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider_child, PROV_GET_PROVIDER_OPTIONS },
{ &Provider_child, FRAG_GET_RUNTIME_ID }, { &Provider_child, FRAG_GET_RUNTIME_ID },
{ &Provider_child, FRAG_GET_FRAGMENT_ROOT }, { &Provider_child, FRAG_GET_FRAGMENT_ROOT },
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
...@@ -5124,7 +5124,7 @@ static const struct prov_method_sequence disconnect_prov2[] = { ...@@ -5124,7 +5124,7 @@ static const struct prov_method_sequence disconnect_prov2[] = {
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
{ &Provider, FRAG_GET_RUNTIME_ID }, { &Provider, FRAG_GET_RUNTIME_ID },
{ &Provider, FRAG_GET_FRAGMENT_ROOT }, { &Provider, FRAG_GET_FRAGMENT_ROOT },
{ 0 } { 0 }
...@@ -5137,7 +5137,7 @@ static const struct prov_method_sequence disconnect_prov3[] = { ...@@ -5137,7 +5137,7 @@ static const struct prov_method_sequence disconnect_prov3[] = {
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
{ &Provider, FRAG_GET_RUNTIME_ID }, { &Provider, FRAG_GET_RUNTIME_ID },
{ 0 } { 0 }
}; };
...@@ -5148,7 +5148,7 @@ static const struct prov_method_sequence disconnect_prov4[] = { ...@@ -5148,7 +5148,7 @@ static const struct prov_method_sequence disconnect_prov4[] = {
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
{ 0 } { 0 }
}; };
......
...@@ -54,7 +54,7 @@ library UIA_wine_private ...@@ -54,7 +54,7 @@ library UIA_wine_private
] ]
interface IWineUiaNode : IUnknown interface IWineUiaNode : IUnknown
{ {
HRESULT get_provider([out, retval]IWineUiaProvider **out_prov); HRESULT get_provider([in]int idx, [out, retval]IWineUiaProvider **out_prov);
HRESULT get_prop_val([in]const GUID *prop_guid, [out, retval]VARIANT *ret_val); HRESULT get_prop_val([in]const GUID *prop_guid, [out, retval]VARIANT *ret_val);
HRESULT disconnect(); HRESULT disconnect();
} }
......
...@@ -30,12 +30,35 @@ enum uia_prop_type { ...@@ -30,12 +30,35 @@ enum uia_prop_type {
PROP_TYPE_SPECIAL, PROP_TYPE_SPECIAL,
}; };
/*
* HUIANODEs that have an associated HWND are able to pull data from up to 4
* different providers:
*
* - Override providers are used to override values from all other providers.
* - Main providers are the base provider for an HUIANODE.
* - Nonclient providers are used to represent the nonclient area of the HWND.
* - HWND providers are used to represent data from the HWND as a whole, such
* as the bounding box.
*
* When a property is requested from the node, each provider is queried in
* descending order starting with the override provider until either one
* returns a property or there are no more providers to query.
*/
enum uia_node_prov_type {
PROV_TYPE_OVERRIDE,
PROV_TYPE_MAIN,
PROV_TYPE_NONCLIENT,
PROV_TYPE_HWND,
PROV_TYPE_COUNT,
};
struct uia_node { struct uia_node {
IWineUiaNode IWineUiaNode_iface; IWineUiaNode IWineUiaNode_iface;
LONG ref; LONG ref;
IWineUiaProvider *prov; IWineUiaProvider *prov[PROV_TYPE_COUNT];
DWORD git_cookie; DWORD git_cookie[PROV_TYPE_COUNT];
int prov_count;
HWND hwnd; HWND hwnd;
BOOL nested_node; BOOL nested_node;
...@@ -65,6 +88,7 @@ static inline struct uia_provider *impl_from_IWineUiaProvider(IWineUiaProvider * ...@@ -65,6 +88,7 @@ static inline struct uia_provider *impl_from_IWineUiaProvider(IWineUiaProvider *
/* uia_client.c */ /* uia_client.c */
int uia_compare_runtime_ids(SAFEARRAY *sa1, SAFEARRAY *sa2) DECLSPEC_HIDDEN; int uia_compare_runtime_ids(SAFEARRAY *sa1, SAFEARRAY *sa2) DECLSPEC_HIDDEN;
int get_node_provider_type_at_idx(struct uia_node *node, int idx) DECLSPEC_HIDDEN;
/* uia_ids.c */ /* uia_ids.c */
const struct uia_prop_info *uia_prop_info_from_id(PROPERTYID prop_id) DECLSPEC_HIDDEN; const struct uia_prop_info *uia_prop_info_from_id(PROPERTYID prop_id) DECLSPEC_HIDDEN;
......
...@@ -1231,10 +1231,12 @@ exit: ...@@ -1231,10 +1231,12 @@ exit:
static HRESULT uia_provider_thread_add_node(HUIANODE node) static HRESULT uia_provider_thread_add_node(HUIANODE node)
{ {
struct uia_node *node_data = impl_from_IWineUiaNode((IWineUiaNode *)node); struct uia_node *node_data = impl_from_IWineUiaNode((IWineUiaNode *)node);
struct uia_provider *prov_data = impl_from_IWineUiaProvider(node_data->prov); int prov_type = get_node_provider_type_at_idx(node_data, 0);
struct uia_provider *prov_data;
SAFEARRAY *sa; SAFEARRAY *sa;
HRESULT hr; HRESULT hr;
prov_data = impl_from_IWineUiaProvider(node_data->prov[prov_type]);
node_data->nested_node = prov_data->return_nested_node = TRUE; node_data->nested_node = prov_data->return_nested_node = TRUE;
hr = UiaGetRuntimeId(node, &sa); hr = UiaGetRuntimeId(node, &sa);
if (FAILED(hr)) if (FAILED(hr))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment