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

uiautomationcore: Add support for translating EVENT_OBJECT_FOCUS for native MSAA IAccessibles.

parent f26d4709
...@@ -1079,6 +1079,78 @@ static void uia_com_focus_win_event_handler(HUIANODE node, HWND hwnd, struct uia ...@@ -1079,6 +1079,78 @@ static void uia_com_focus_win_event_handler(HUIANODE node, HWND hwnd, struct uia
VariantClear(&v); VariantClear(&v);
} }
static HRESULT uia_com_focus_win_event_msaa_callback(struct uia_event *event, void *user_data)
{
struct uia_event_args args = { { EventArgsType_Simple, UIA_AutomationFocusChangedEventId }, 0 };
HUIANODE node = (HUIANODE)user_data;
/* Only match desktop events. */
if (!event->desktop_subtree_event)
return S_OK;
return uia_event_invoke(node, NULL, &args, event);
}
static void uia_com_focus_win_event_msaa_handler(HWND hwnd, LONG child_id)
{
IRawElementProviderFragmentRoot *elroot;
IRawElementProviderFragment *elfrag;
IRawElementProviderSimple *elprov;
HRESULT hr;
VARIANT v;
hr = create_msaa_provider_from_hwnd(hwnd, child_id, &elprov);
if (FAILED(hr))
{
WARN("create_msaa_provider_from_hwnd failed with hr %#lx\n", hr);
return;
}
hr = IRawElementProviderSimple_QueryInterface(elprov, &IID_IRawElementProviderFragmentRoot, (void **)&elroot);
if (FAILED(hr))
goto exit;
hr = IRawElementProviderFragmentRoot_GetFocus(elroot, &elfrag);
IRawElementProviderFragmentRoot_Release(elroot);
if (FAILED(hr))
goto exit;
if (elfrag)
{
IRawElementProviderSimple *elprov2;
hr = IRawElementProviderFragment_QueryInterface(elfrag, &IID_IRawElementProviderSimple, (void **)&elprov2);
IRawElementProviderFragment_Release(elfrag);
if (FAILED(hr))
goto exit;
IRawElementProviderSimple_Release(elprov);
elprov = elprov2;
}
VariantInit(&v);
hr = IRawElementProviderSimple_GetPropertyValue(elprov, UIA_HasKeyboardFocusPropertyId, &v);
if (FAILED(hr))
goto exit;
if (V_VT(&v) == VT_BOOL && V_BOOL(&v) == VARIANT_TRUE)
{
HUIANODE node;
hr = create_uia_node_from_elprov(elprov, &node, TRUE, 0);
if (SUCCEEDED(hr))
{
hr = uia_event_for_each(UIA_AutomationFocusChangedEventId, uia_com_focus_win_event_msaa_callback, (void *)node, TRUE);
if (FAILED(hr))
WARN("uia_event_for_each failed with hr %#lx\n", hr);
UiaNodeRelease(node);
}
}
exit:
IRawElementProviderSimple_Release(elprov);
}
HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG child_id, DWORD thread_id, DWORD event_time) HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG child_id, DWORD thread_id, DWORD event_time)
{ {
LONG handler_count; LONG handler_count;
...@@ -1168,6 +1240,8 @@ HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG ...@@ -1168,6 +1240,8 @@ HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG
hr = create_uia_node_from_hwnd(hwnd, &node, NODE_FLAG_IGNORE_CLIENTSIDE_HWND_PROVS); hr = create_uia_node_from_hwnd(hwnd, &node, NODE_FLAG_IGNORE_CLIENTSIDE_HWND_PROVS);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
uia_com_focus_win_event_handler(node, hwnd, event_id_map); uia_com_focus_win_event_handler(node, hwnd, event_id_map);
else
uia_com_focus_win_event_msaa_handler(hwnd, child_id);
UiaNodeRelease(node); UiaNodeRelease(node);
} }
......
...@@ -587,8 +587,6 @@ static struct uia_queue_event *uia_event_queue_pop(struct list *event_queue) ...@@ -587,8 +587,6 @@ static struct uia_queue_event *uia_event_queue_pop(struct list *event_queue)
return queue_event; return queue_event;
} }
static HRESULT uia_event_invoke(HUIANODE node, HUIANODE nav_start_node, struct uia_event_args *args,
struct uia_event *event);
static HRESULT uia_raise_clientside_event(struct uia_queue_uia_event *event) static HRESULT uia_raise_clientside_event(struct uia_queue_uia_event *event)
{ {
HUIANODE node, nav_start_node; HUIANODE node, nav_start_node;
...@@ -676,7 +674,7 @@ static BOOL uia_win_event_hwnd_map_contains_ancestors(struct rb_tree *hwnd_map, ...@@ -676,7 +674,7 @@ static BOOL uia_win_event_hwnd_map_contains_ancestors(struct rb_tree *hwnd_map,
return FALSE; return FALSE;
} }
static HRESULT create_msaa_provider_from_hwnd(HWND hwnd, int in_child_id, IRawElementProviderSimple **ret_elprov) HRESULT create_msaa_provider_from_hwnd(HWND hwnd, int in_child_id, IRawElementProviderSimple **ret_elprov)
{ {
IRawElementProviderSimple *elprov; IRawElementProviderSimple *elprov;
IAccessible *acc; IAccessible *acc;
...@@ -1733,7 +1731,7 @@ HRESULT WINAPI UiaRemoveEvent(HUIAEVENT huiaevent) ...@@ -1733,7 +1731,7 @@ HRESULT WINAPI UiaRemoveEvent(HUIAEVENT huiaevent)
return S_OK; return S_OK;
} }
static HRESULT uia_event_invoke(HUIANODE node, HUIANODE nav_start_node, struct uia_event_args *args, struct uia_event *event) HRESULT uia_event_invoke(HUIANODE node, HUIANODE nav_start_node, struct uia_event_args *args, struct uia_event *event)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
......
...@@ -241,6 +241,7 @@ HRESULT uia_event_add_win_event_hwnd(struct uia_event *event, HWND hwnd) DECLSPE ...@@ -241,6 +241,7 @@ HRESULT uia_event_add_win_event_hwnd(struct uia_event *event, HWND hwnd) DECLSPE
HRESULT uia_event_for_each(int event_id, UiaWineEventForEachCallback *callback, void *user_data, HRESULT uia_event_for_each(int event_id, UiaWineEventForEachCallback *callback, void *user_data,
BOOL clientside_only) DECLSPEC_HIDDEN; BOOL clientside_only) DECLSPEC_HIDDEN;
BOOL uia_clientside_event_start_event_thread(struct uia_event *event) DECLSPEC_HIDDEN; BOOL uia_clientside_event_start_event_thread(struct uia_event *event) DECLSPEC_HIDDEN;
HRESULT create_msaa_provider_from_hwnd(HWND hwnd, int in_child_id, IRawElementProviderSimple **ret_elprov) DECLSPEC_HIDDEN;
HRESULT create_serverside_uia_event(struct uia_event **out_event, LONG process_id, LONG event_cookie) DECLSPEC_HIDDEN; HRESULT create_serverside_uia_event(struct uia_event **out_event, LONG process_id, LONG event_cookie) DECLSPEC_HIDDEN;
HRESULT uia_event_add_provider_event_adviser(IRawElementProviderAdviseEvents *advise_events, HRESULT uia_event_add_provider_event_adviser(IRawElementProviderAdviseEvents *advise_events,
struct uia_event *event) DECLSPEC_HIDDEN; struct uia_event *event) DECLSPEC_HIDDEN;
...@@ -249,6 +250,8 @@ HRESULT uia_event_advise_node(struct uia_event *event, HUIANODE node) DECLSPEC_H ...@@ -249,6 +250,8 @@ HRESULT uia_event_advise_node(struct uia_event *event, HUIANODE node) DECLSPEC_H
HRESULT uia_add_clientside_event(HUIANODE huianode, EVENTID event_id, enum TreeScope scope, PROPERTYID *prop_ids, HRESULT uia_add_clientside_event(HUIANODE huianode, EVENTID event_id, enum TreeScope scope, PROPERTYID *prop_ids,
int prop_ids_count, struct UiaCacheRequest *cache_req, SAFEARRAY *rt_id, UiaWineEventCallback *cback, int prop_ids_count, struct UiaCacheRequest *cache_req, SAFEARRAY *rt_id, UiaWineEventCallback *cback,
void *cback_data, HUIAEVENT *huiaevent) DECLSPEC_HIDDEN; void *cback_data, HUIAEVENT *huiaevent) DECLSPEC_HIDDEN;
HRESULT uia_event_invoke(HUIANODE node, HUIANODE nav_start_node, struct uia_event_args *args,
struct uia_event *event) DECLSPEC_HIDDEN;
HRESULT uia_event_check_node_within_event_scope(struct uia_event *event, HUIANODE node, SAFEARRAY *rt_id, HRESULT uia_event_check_node_within_event_scope(struct uia_event *event, HUIANODE node, SAFEARRAY *rt_id,
HUIANODE *clientside_nav_node_out) DECLSPEC_HIDDEN; HUIANODE *clientside_nav_node_out) DECLSPEC_HIDDEN;
......
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