Module: wine Branch: master Commit: 67dd36095f12baa39f54919ca8fb65f22778242b URL: https://gitlab.winehq.org/wine/wine/-/commit/67dd36095f12baa39f54919ca8fb65f...
Author: Connor McAdams cmcadams@codeweavers.com Date: Fri Nov 11 15:57:40 2022 -0500
uiautomationcore: Add support for ExcludeRoot parameter in UiaFind.
Signed-off-by: Connor McAdams cmcadams@codeweavers.com
---
dlls/uiautomationcore/tests/uiautomation.c | 44 ++++++++++++++---------------- dlls/uiautomationcore/uia_client.c | 43 +++++++++++++++++------------ 2 files changed, 45 insertions(+), 42 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index 3636a0746e4..01f74cb4f3f 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -8800,35 +8800,31 @@ static void test_UiaFind(void) AutomationElementMode_Full); set_find_params(&find_params, 1, TRUE, TRUE, (struct UiaCondition *)&UiaTrueCondition); hr = UiaFind(node, &find_params, &cache_req, &out_req, &offsets, &tree_structs); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(Provider_child.ref == 2, "Unexpected refcnt %ld\n", Provider_child.ref); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(Provider_child.ref == 2, "Unexpected refcnt %ld\n", Provider_child.ref);
- node2 = NULL; - if (SUCCEEDED(hr)) - { - add_provider_desc(&exp_node_desc[0], L"Main", L"Provider_child", TRUE); - exp_lbound[0] = exp_lbound[1] = 0; - exp_elems[0] = exp_elems[1] = 1; + add_provider_desc(&exp_node_desc[0], L"Main", L"Provider_child", TRUE); + exp_lbound[0] = exp_lbound[1] = 0; + exp_elems[0] = exp_elems[1] = 1;
- idx[0] = idx[1] = 0; - hr = SafeArrayGetElement(out_req, idx, &v); - ok(hr == S_OK, "Unexpected hr %#lx\n", hr); + idx[0] = idx[1] = 0; + hr = SafeArrayGetElement(out_req, idx, &v); + ok(hr == S_OK, "Unexpected hr %#lx\n", hr);
- /* node2 is now set as Provider_child. */ - hr = UiaHUiaNodeFromVariant(&v, &node2); - ok(hr == S_OK, "Unexpected hr %#lx\n", hr); - IUnknown_AddRef((IUnknown *)node2); + /* node2 is now set as Provider_child. */ + hr = UiaHUiaNodeFromVariant(&v, &node2); + ok(hr == S_OK, "Unexpected hr %#lx\n", hr); + IUnknown_AddRef((IUnknown *)node2);
- test_cache_req_sa(out_req, exp_lbound, exp_elems, exp_node_desc); + test_cache_req_sa(out_req, exp_lbound, exp_elems, exp_node_desc);
- for (i = 0; i < exp_elems[0]; i++) - { - exp_offset[i] = i; - exp_tree_struct[i] = L"P)"; - } - test_find_sa_results(tree_structs, offsets, exp_elems[0], exp_tree_struct, exp_offset); - ok_method_sequence(find_seq4, "find_seq4"); + for (i = 0; i < exp_elems[0]; i++) + { + exp_offset[i] = i; + exp_tree_struct[i] = L"P)"; } + test_find_sa_results(tree_structs, offsets, exp_elems[0], exp_tree_struct, exp_offset); + ok_method_sequence(find_seq4, "find_seq4");
SafeArrayDestroy(out_req); SafeArrayDestroy(offsets); @@ -8910,7 +8906,7 @@ static void test_UiaFind(void) SafeArrayDestroy(offsets); SafeArrayDestroy(tree_structs);
- todo_wine ok(UiaNodeRelease(node2), "UiaNodeRelease returned FALSE\n"); + ok(UiaNodeRelease(node2), "UiaNodeRelease returned FALSE\n"); ok(Provider_child.ref == 1, "Unexpected refcnt %ld\n", Provider_child.ref);
initialize_provider_tree(FALSE); diff --git a/dlls/uiautomationcore/uia_client.c b/dlls/uiautomationcore/uia_client.c index 49c59f45b34..d2f7ea66414 100644 --- a/dlls/uiautomationcore/uia_client.c +++ b/dlls/uiautomationcore/uia_client.c @@ -967,8 +967,8 @@ static HRESULT traverse_uia_node_tree_siblings(HUIANODE huianode, struct UiaCond */ static HRESULT traverse_uia_node_tree(HUIANODE huianode, struct UiaCondition *view_cond, struct UiaCondition *search_cond, struct UiaCondition *pre_sibling_nav_stop_cond, - struct UiaCondition *ascending_stop_cond, int traversal_opts, BOOL at_root_level, int max_depth, int *cur_depth, - HUIANODE *out_node) + struct UiaCondition *ascending_stop_cond, int traversal_opts, BOOL at_root_level, BOOL *root_found, + int max_depth, int *cur_depth, HUIANODE *out_node) { HUIANODE node = huianode; HRESULT hr; @@ -990,17 +990,23 @@ static HRESULT traverse_uia_node_tree(HUIANODE huianode, struct UiaCondition *vi * our current depth within the tree. */ incr_depth = TRUE; - hr = uia_condition_check(node, search_cond); - if (FAILED(hr)) - break;
- if (uia_condition_matched(hr)) + if (*root_found) { - IWineUiaNode_AddRef(&node_data->IWineUiaNode_iface); - *out_node = node; - hr = S_FALSE; - break; + hr = uia_condition_check(node, search_cond); + if (FAILED(hr)) + break; + + if (uia_condition_matched(hr)) + { + IWineUiaNode_AddRef(&node_data->IWineUiaNode_iface); + *out_node = node; + hr = S_FALSE; + break; + } } + + *root_found = TRUE; }
if (incr_depth) @@ -1016,7 +1022,7 @@ static HRESULT traverse_uia_node_tree(HUIANODE huianode, struct UiaCondition *vi
if (SUCCEEDED(hr) && node2) hr = traverse_uia_node_tree(node2, view_cond, search_cond, pre_sibling_nav_stop_cond, ascending_stop_cond, - traversal_opts, FALSE, max_depth, cur_depth, out_node); + traversal_opts, FALSE, root_found, max_depth, cur_depth, out_node);
if (FAILED(hr) || hr == S_FALSE) break; @@ -2752,6 +2758,7 @@ HRESULT WINAPI UiaFind(HUIANODE huianode, struct UiaFindParams *find_params, str struct UiaCondition *sibling_stop_cond; int cur_depth = 0; BSTR tree_struct; + BOOL root_found; HUIANODE node2; HRESULT hr; LONG idx; @@ -2769,12 +2776,6 @@ HRESULT WINAPI UiaFind(HUIANODE huianode, struct UiaFindParams *find_params, str return E_NOTIMPL; }
- if (find_params->ExcludeRoot) - { - FIXME("ExcludeRoot currently unimplemented.\n"); - return E_NOTIMPL; - } - /* * If the initial node has a runtime ID, we'll use it as a stop * condition. @@ -2789,10 +2790,16 @@ HRESULT WINAPI UiaFind(HUIANODE huianode, struct UiaFindParams *find_params, str else sibling_stop_cond = (struct UiaCondition *)&UiaFalseCondition;
+ if (find_params->ExcludeRoot) + root_found = FALSE; + else + root_found = TRUE; + node2 = NULL; IWineUiaNode_AddRef(&node->IWineUiaNode_iface); hr = traverse_uia_node_tree(huianode, cache_req->pViewCondition, find_params->pFindCondition, sibling_stop_cond, - cache_req->pViewCondition, TreeTraversalOptions_Default, TRUE, find_params->MaxDepth, &cur_depth, &node2); + cache_req->pViewCondition, TreeTraversalOptions_Default, TRUE, &root_found, find_params->MaxDepth, + &cur_depth, &node2); if (FAILED(hr) || !node2) goto exit;