mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 23:07:47 +00:00
uiautomationcore: Query EVENT_OBJECT_FOCUS HWND for a serverside provider if there is a registered focus change event handler.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
This commit is contained in:
parent
7886e4d08b
commit
6b972a68b8
|
@ -2631,7 +2631,7 @@ static HRESULT uia_get_provider_from_hwnd(struct uia_node *node)
|
||||||
return SendMessageW(client_thread.hwnd, WM_UIA_CLIENT_GET_NODE_PROV, (WPARAM)&args, (LPARAM)node);
|
return SendMessageW(client_thread.hwnd, WM_UIA_CLIENT_GET_NODE_PROV, (WPARAM)&args, (LPARAM)node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT create_uia_node_from_hwnd(HWND hwnd, HUIANODE *out_node, int node_flags)
|
HRESULT create_uia_node_from_hwnd(HWND hwnd, HUIANODE *out_node, int node_flags)
|
||||||
{
|
{
|
||||||
struct uia_node *node;
|
struct uia_node *node;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
|
@ -903,6 +903,7 @@ static HRESULT get_uia_cache_request_struct_from_iface(IUIAutomationCacheRequest
|
||||||
*/
|
*/
|
||||||
static struct uia_com_event_handlers
|
static struct uia_com_event_handlers
|
||||||
{
|
{
|
||||||
|
struct rb_tree handler_event_id_map;
|
||||||
struct rb_tree handler_map;
|
struct rb_tree handler_map;
|
||||||
|
|
||||||
LONG handler_count;
|
LONG handler_count;
|
||||||
|
@ -917,6 +918,22 @@ static CRITICAL_SECTION_DEBUG com_event_handlers_cs_debug =
|
||||||
};
|
};
|
||||||
static CRITICAL_SECTION com_event_handlers_cs = { &com_event_handlers_cs_debug, -1, 0, 0, 0, 0 };
|
static CRITICAL_SECTION com_event_handlers_cs = { &com_event_handlers_cs_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
struct uia_event_handler_event_id_map_entry
|
||||||
|
{
|
||||||
|
struct rb_entry entry;
|
||||||
|
int event_id;
|
||||||
|
|
||||||
|
struct list handlers_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int uia_com_event_handler_event_id_compare(const void *key, const struct rb_entry *entry)
|
||||||
|
{
|
||||||
|
struct uia_event_handler_event_id_map_entry *event_entry = RB_ENTRY_VALUE(entry, struct uia_event_handler_event_id_map_entry, entry);
|
||||||
|
int event_id = *((int *)key);
|
||||||
|
|
||||||
|
return (event_entry->event_id > event_id) - (event_entry->event_id < event_id);
|
||||||
|
}
|
||||||
|
|
||||||
struct uia_event_handler_identifier {
|
struct uia_event_handler_identifier {
|
||||||
IUnknown *handler_iface;
|
IUnknown *handler_iface;
|
||||||
SAFEARRAY *runtime_id;
|
SAFEARRAY *runtime_id;
|
||||||
|
@ -932,6 +949,9 @@ struct uia_event_handler_map_entry
|
||||||
int event_id;
|
int event_id;
|
||||||
|
|
||||||
struct list handlers_list;
|
struct list handlers_list;
|
||||||
|
|
||||||
|
struct uia_event_handler_event_id_map_entry *handler_event_id_map;
|
||||||
|
struct list handler_event_id_map_list_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int uia_com_event_handler_id_compare(const void *key, const struct rb_entry *entry)
|
static int uia_com_event_handler_id_compare(const void *key, const struct rb_entry *entry)
|
||||||
|
@ -1027,6 +1047,32 @@ HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EVENT_OBJECT_FOCUS:
|
||||||
|
{
|
||||||
|
static const int uia_event_id = UIA_AutomationFocusChangedEventId;
|
||||||
|
struct rb_entry *rb_entry;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (obj_id != OBJID_CLIENT)
|
||||||
|
break;
|
||||||
|
|
||||||
|
EnterCriticalSection(&com_event_handlers_cs);
|
||||||
|
|
||||||
|
if ((rb_entry = rb_get(&com_event_handlers.handler_event_id_map, &uia_event_id)))
|
||||||
|
{
|
||||||
|
HUIANODE node = NULL;
|
||||||
|
|
||||||
|
hr = create_uia_node_from_hwnd(hwnd, &node, NODE_FLAG_IGNORE_CLIENTSIDE_HWND_PROVS);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
FIXME("EVENT_OBJECT_FOCUS event advisement currently unimplemented\n");
|
||||||
|
|
||||||
|
UiaNodeRelease(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&com_event_handlers_cs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1034,6 +1080,29 @@ HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT uia_event_handlers_add_handler_to_event_id_map(struct uia_event_handler_map_entry *event_map)
|
||||||
|
{
|
||||||
|
struct uia_event_handler_event_id_map_entry *event_id_map;
|
||||||
|
struct rb_entry *rb_entry;
|
||||||
|
|
||||||
|
if ((rb_entry = rb_get(&com_event_handlers.handler_event_id_map, &event_map->event_id)))
|
||||||
|
event_id_map = RB_ENTRY_VALUE(rb_entry, struct uia_event_handler_event_id_map_entry, entry);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(event_id_map = calloc(1, sizeof(*event_id_map))))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
event_id_map->event_id = event_map->event_id;
|
||||||
|
list_init(&event_id_map->handlers_list);
|
||||||
|
rb_put(&com_event_handlers.handler_event_id_map, &event_map->event_id, &event_id_map->entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_add_tail(&event_id_map->handlers_list, &event_map->handler_event_id_map_list_entry);
|
||||||
|
event_map->handler_event_id_map = event_id_map;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT uia_event_handlers_add_handler(IUnknown *handler_iface, SAFEARRAY *runtime_id, int event_id,
|
static HRESULT uia_event_handlers_add_handler(IUnknown *handler_iface, SAFEARRAY *runtime_id, int event_id,
|
||||||
struct uia_com_event *event)
|
struct uia_com_event *event)
|
||||||
{
|
{
|
||||||
|
@ -1045,7 +1114,10 @@ static HRESULT uia_event_handlers_add_handler(IUnknown *handler_iface, SAFEARRAY
|
||||||
EnterCriticalSection(&com_event_handlers_cs);
|
EnterCriticalSection(&com_event_handlers_cs);
|
||||||
|
|
||||||
if (!com_event_handlers.handler_count)
|
if (!com_event_handlers.handler_count)
|
||||||
|
{
|
||||||
rb_init(&com_event_handlers.handler_map, uia_com_event_handler_id_compare);
|
rb_init(&com_event_handlers.handler_map, uia_com_event_handler_id_compare);
|
||||||
|
rb_init(&com_event_handlers.handler_event_id_map, uia_com_event_handler_event_id_compare);
|
||||||
|
}
|
||||||
|
|
||||||
if ((rb_entry = rb_get(&com_event_handlers.handler_map, &event_ident)))
|
if ((rb_entry = rb_get(&com_event_handlers.handler_map, &event_ident)))
|
||||||
event_map = RB_ENTRY_VALUE(rb_entry, struct uia_event_handler_map_entry, entry);
|
event_map = RB_ENTRY_VALUE(rb_entry, struct uia_event_handler_map_entry, entry);
|
||||||
|
@ -1065,6 +1137,14 @@ static HRESULT uia_event_handlers_add_handler(IUnknown *handler_iface, SAFEARRAY
|
||||||
}
|
}
|
||||||
|
|
||||||
event_map->event_id = event_id;
|
event_map->event_id = event_id;
|
||||||
|
hr = uia_event_handlers_add_handler_to_event_id_map(event_map);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
SafeArrayDestroy(event_map->runtime_id);
|
||||||
|
free(event_map);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
event_map->handler_iface = handler_iface;
|
event_map->handler_iface = handler_iface;
|
||||||
IUnknown_AddRef(event_map->handler_iface);
|
IUnknown_AddRef(event_map->handler_iface);
|
||||||
|
|
||||||
|
@ -1102,6 +1182,13 @@ static void uia_event_handler_map_entry_destroy(struct uia_event_handler_map_ent
|
||||||
com_event_handlers.handler_count--;
|
com_event_handlers.handler_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_remove(&entry->handler_event_id_map_list_entry);
|
||||||
|
if (list_empty(&entry->handler_event_id_map->handlers_list))
|
||||||
|
{
|
||||||
|
rb_remove(&com_event_handlers.handler_event_id_map, &entry->handler_event_id_map->entry);
|
||||||
|
free(entry->handler_event_id_map);
|
||||||
|
}
|
||||||
|
|
||||||
rb_remove(&com_event_handlers.handler_map, &entry->entry);
|
rb_remove(&com_event_handlers.handler_map, &entry->entry);
|
||||||
IUnknown_Release(entry->handler_iface);
|
IUnknown_Release(entry->handler_iface);
|
||||||
SafeArrayDestroy(entry->runtime_id);
|
SafeArrayDestroy(entry->runtime_id);
|
||||||
|
|
|
@ -219,6 +219,7 @@ HRESULT navigate_uia_node(struct uia_node *node, int nav_dir, HUIANODE *out_node
|
||||||
HRESULT create_uia_node_from_elprov(IRawElementProviderSimple *elprov, HUIANODE *out_node,
|
HRESULT create_uia_node_from_elprov(IRawElementProviderSimple *elprov, HUIANODE *out_node,
|
||||||
BOOL get_hwnd_providers, int node_flags) DECLSPEC_HIDDEN;
|
BOOL get_hwnd_providers, int node_flags) DECLSPEC_HIDDEN;
|
||||||
HRESULT uia_node_from_lresult(LRESULT lr, HUIANODE *huianode) DECLSPEC_HIDDEN;
|
HRESULT uia_node_from_lresult(LRESULT lr, HUIANODE *huianode) DECLSPEC_HIDDEN;
|
||||||
|
HRESULT create_uia_node_from_hwnd(HWND hwnd, HUIANODE *out_node, int node_flags) DECLSPEC_HIDDEN;
|
||||||
HRESULT uia_condition_check(HUIANODE node, struct UiaCondition *condition) DECLSPEC_HIDDEN;
|
HRESULT uia_condition_check(HUIANODE node, struct UiaCondition *condition) DECLSPEC_HIDDEN;
|
||||||
BOOL uia_condition_matched(HRESULT hr) DECLSPEC_HIDDEN;
|
BOOL uia_condition_matched(HRESULT hr) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue