Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
4569157b
Commit
4569157b
authored
Oct 10, 2023
by
Connor McAdams
Committed by
Alexandre Julliard
Oct 10, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Use EVENT_OBJECT_DESTROY to remove HWNDs from the COM API focus change HWND map.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
a275834b
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
75 additions
and
0 deletions
+75
-0
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+24
-0
uia_com_client.c
dlls/uiautomationcore/uia_com_client.c
+32
-0
uia_event.c
dlls/uiautomationcore/uia_event.c
+1
-0
uia_private.h
dlls/uiautomationcore/uia_private.h
+1
-0
uia_utils.c
dlls/uiautomationcore/uia_utils.c
+17
-0
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
4569157b
...
@@ -15475,6 +15475,30 @@ static void test_uia_com_event_handler_event_advisement(IUIAutomation *uia_iface
...
@@ -15475,6 +15475,30 @@ static void test_uia_com_event_handler_event_advisement(IUIAutomation *uia_iface
check_uia_hwnd_expects_at_most
(
0
,
1
,
1
,
3
,
0
);
check_uia_hwnd_expects_at_most
(
0
,
1
,
1
,
3
,
0
);
test_hwnd_providers_event_advise_added
(
&
Provider
,
&
Provider_hwnd2
,
&
Provider_nc2
,
0
,
FALSE
);
test_hwnd_providers_event_advise_added
(
&
Provider
,
&
Provider_hwnd2
,
&
Provider_nc2
,
0
,
FALSE
);
/* HWND destruction is tracked with EVENT_OBJECT_DESTROY/OBJID_WINDOW. */
NotifyWinEvent
(
EVENT_OBJECT_DESTROY
,
test_child_hwnd
,
OBJID_WINDOW
,
CHILDID_SELF
);
if
(
wait_for_clientside_callbacks
(
2000
))
trace
(
"Kept getting callbacks up until timeout
\n
"
);
/*
* EVENT_OBJECT_DESTROY removed this HWND, EVENT_OBJECT_FOCUS will now
* advise it again.
*/
reset_event_advise_values_for_hwnd_providers
(
&
Provider2
,
&
Provider_hwnd3
,
&
Provider_nc3
);
set_provider_method_event_data
(
&
Provider2
,
method_event
[
0
],
ADVISE_EVENTS_EVENT_ADDED
);
SET_EXPECT_MULTI
(
child_winproc_GETOBJECT_UiaRoot
,
3
);
/* Only sent 3 times on Win11. */
set_uia_hwnd_expects
(
0
,
1
,
1
,
2
,
0
);
/* Only Win11 sends WM_GETOBJECT 2 times. */
NotifyWinEvent
(
EVENT_OBJECT_FOCUS
,
test_child_hwnd
,
OBJID_CLIENT
,
CHILDID_SELF
);
ok
(
msg_wait_for_all_events
(
method_event
,
1
,
2000
)
!=
WAIT_TIMEOUT
,
"Wait for method_event(s) timed out.
\n
"
);
if
(
wait_for_clientside_callbacks
(
2000
))
trace
(
"Kept getting callbacks up until timeout
\n
"
);
set_provider_method_event_data
(
&
Provider2
,
NULL
,
-
1
);
check_uia_hwnd_expects_at_most
(
0
,
1
,
1
,
2
,
0
);
CHECK_CALLED_AT_MOST
(
child_winproc_GETOBJECT_UiaRoot
,
3
);
test_provider_event_advise_added
(
&
Provider2
,
UIA_AutomationFocusChangedEventId
,
FALSE
);
test_provider_event_advise_added
(
&
Provider_hwnd3
,
0
,
FALSE
);
test_provider_event_advise_added
(
&
Provider_nc3
,
0
,
FALSE
);
set_uia_hwnd_expects
(
0
,
1
,
1
,
0
,
0
);
set_uia_hwnd_expects
(
0
,
1
,
1
,
0
,
0
);
hr
=
IUIAutomation_RemoveFocusChangedEventHandler
(
uia_iface
,
hr
=
IUIAutomation_RemoveFocusChangedEventHandler
(
uia_iface
,
&
FocusChangedHandler
.
IUIAutomationFocusChangedEventHandler_iface
);
&
FocusChangedHandler
.
IUIAutomationFocusChangedEventHandler_iface
);
...
...
dlls/uiautomationcore/uia_com_client.c
View file @
4569157b
...
@@ -1108,6 +1108,38 @@ HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG
...
@@ -1108,6 +1108,38 @@ HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG
break
;
break
;
}
}
case
EVENT_OBJECT_DESTROY
:
{
static
const
int
uia_event_id
=
UIA_AutomationFocusChangedEventId
;
struct
rb_entry
*
rb_entry
;
if
(
obj_id
!=
OBJID_WINDOW
)
break
;
EnterCriticalSection
(
&
com_event_handlers_cs
);
if
((
rb_entry
=
rb_get
(
&
com_event_handlers
.
handler_event_id_map
,
&
uia_event_id
)))
{
struct
uia_event_handler_event_id_map_entry
*
event_id_map
;
struct
uia_event_handler_map_entry
*
entry
;
event_id_map
=
RB_ENTRY_VALUE
(
rb_entry
,
struct
uia_event_handler_event_id_map_entry
,
entry
);
LIST_FOR_EACH_ENTRY
(
entry
,
&
event_id_map
->
handlers_list
,
struct
uia_event_handler_map_entry
,
handler_event_id_map_list_entry
)
{
struct
uia_com_event
*
event
;
LIST_FOR_EACH_ENTRY
(
event
,
&
entry
->
handlers_list
,
struct
uia_com_event
,
event_handler_map_list_entry
)
{
uia_hwnd_map_remove_hwnd
(
&
event
->
focus_hwnd_map
,
hwnd
);
}
}
}
LeaveCriticalSection
(
&
com_event_handlers_cs
);
break
;
}
default:
default:
break
;
break
;
}
}
...
...
dlls/uiautomationcore/uia_event.c
View file @
4569157b
...
@@ -56,6 +56,7 @@ static int win_event_to_uia_event_id(int win_event)
...
@@ -56,6 +56,7 @@ static int win_event_to_uia_event_id(int win_event)
case
EVENT_OBJECT_FOCUS
:
return
UIA_AutomationFocusChangedEventId
;
case
EVENT_OBJECT_FOCUS
:
return
UIA_AutomationFocusChangedEventId
;
case
EVENT_SYSTEM_ALERT
:
return
UIA_SystemAlertEventId
;
case
EVENT_SYSTEM_ALERT
:
return
UIA_SystemAlertEventId
;
case
EVENT_OBJECT_SHOW
:
return
UIA_StructureChangedEventId
;
case
EVENT_OBJECT_SHOW
:
return
UIA_StructureChangedEventId
;
case
EVENT_OBJECT_DESTROY
:
return
UIA_StructureChangedEventId
;
default:
default:
break
;
break
;
...
...
dlls/uiautomationcore/uia_private.h
View file @
4569157b
...
@@ -270,5 +270,6 @@ BOOL uia_hwnd_is_visible(HWND hwnd) DECLSPEC_HIDDEN;
...
@@ -270,5 +270,6 @@ BOOL uia_hwnd_is_visible(HWND hwnd) DECLSPEC_HIDDEN;
BOOL
uia_is_top_level_hwnd
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
BOOL
uia_is_top_level_hwnd
(
HWND
hwnd
)
DECLSPEC_HIDDEN
;
BOOL
uia_hwnd_map_check_hwnd
(
struct
rb_tree
*
hwnd_map
,
HWND
hwnd
)
DECLSPEC_HIDDEN
;
BOOL
uia_hwnd_map_check_hwnd
(
struct
rb_tree
*
hwnd_map
,
HWND
hwnd
)
DECLSPEC_HIDDEN
;
HRESULT
uia_hwnd_map_add_hwnd
(
struct
rb_tree
*
hwnd_map
,
HWND
hwnd
)
DECLSPEC_HIDDEN
;
HRESULT
uia_hwnd_map_add_hwnd
(
struct
rb_tree
*
hwnd_map
,
HWND
hwnd
)
DECLSPEC_HIDDEN
;
void
uia_hwnd_map_remove_hwnd
(
struct
rb_tree
*
hwnd_map
,
HWND
hwnd
)
DECLSPEC_HIDDEN
;
void
uia_hwnd_map_init
(
struct
rb_tree
*
hwnd_map
)
DECLSPEC_HIDDEN
;
void
uia_hwnd_map_init
(
struct
rb_tree
*
hwnd_map
)
DECLSPEC_HIDDEN
;
void
uia_hwnd_map_destroy
(
struct
rb_tree
*
hwnd_map
)
DECLSPEC_HIDDEN
;
void
uia_hwnd_map_destroy
(
struct
rb_tree
*
hwnd_map
)
DECLSPEC_HIDDEN
;
dlls/uiautomationcore/uia_utils.c
View file @
4569157b
...
@@ -459,6 +459,23 @@ HRESULT uia_hwnd_map_add_hwnd(struct rb_tree *hwnd_map, HWND hwnd)
...
@@ -459,6 +459,23 @@ HRESULT uia_hwnd_map_add_hwnd(struct rb_tree *hwnd_map, HWND hwnd)
return
S_OK
;
return
S_OK
;
}
}
void
uia_hwnd_map_remove_hwnd
(
struct
rb_tree
*
hwnd_map
,
HWND
hwnd
)
{
struct
rb_entry
*
rb_entry
=
rb_get
(
hwnd_map
,
hwnd
);
struct
uia_hwnd_map_entry
*
entry
;
if
(
!
rb_entry
)
{
TRACE
(
"hwnd %p not in map %p, nothing to remove.
\n
"
,
hwnd
,
hwnd_map
);
return
;
}
TRACE
(
"Removing hwnd %p from map %p
\n
"
,
hwnd
,
hwnd_map
);
entry
=
RB_ENTRY_VALUE
(
rb_entry
,
struct
uia_hwnd_map_entry
,
entry
);
rb_remove
(
hwnd_map
,
&
entry
->
entry
);
free
(
entry
);
}
void
uia_hwnd_map_init
(
struct
rb_tree
*
hwnd_map
)
void
uia_hwnd_map_init
(
struct
rb_tree
*
hwnd_map
)
{
{
rb_init
(
hwnd_map
,
uia_hwnd_map_hwnd_compare
);
rb_init
(
hwnd_map
,
uia_hwnd_map_hwnd_compare
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment