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
87d1a4a3
Commit
87d1a4a3
authored
Aug 27, 2018
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Scale coordinates in get_window_children_from_point based on DPI awareness.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
6d4e625c
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
65 additions
and
45 deletions
+65
-45
winpos.c
dlls/user32/winpos.c
+4
-1
server_protocol.h
include/wine/server_protocol.h
+3
-1
protocol.def
server/protocol.def
+1
-0
request.h
server/request.h
+2
-1
trace.c
server/trace.c
+1
-0
window.c
server/window.c
+54
-42
No files found.
dlls/user32/winpos.c
View file @
87d1a4a3
...
...
@@ -260,6 +260,7 @@ static HWND *list_children_from_point( HWND hwnd, POINT pt )
req
->
parent
=
wine_server_user_handle
(
hwnd
);
req
->
x
=
pt
.
x
;
req
->
y
=
pt
.
y
;
req
->
dpi
=
get_thread_dpi
();
wine_server_set_reply
(
req
,
list
,
(
size
-
1
)
*
sizeof
(
user_handle_t
)
);
if
(
!
wine_server_call
(
req
))
count
=
reply
->
count
;
}
...
...
@@ -289,6 +290,7 @@ HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
{
int
i
,
res
;
HWND
ret
,
*
list
;
POINT
win_pt
;
if
(
!
hwndScope
)
hwndScope
=
GetDesktopWindow
();
...
...
@@ -319,7 +321,8 @@ HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
*
hittest
=
HTCLIENT
;
break
;
}
res
=
SendMessageW
(
list
[
i
],
WM_NCHITTEST
,
0
,
MAKELONG
(
pt
.
x
,
pt
.
y
)
);
win_pt
=
point_thread_to_win_dpi
(
list
[
i
],
pt
);
res
=
SendMessageW
(
list
[
i
],
WM_NCHITTEST
,
0
,
MAKELPARAM
(
win_pt
.
x
,
win_pt
.
y
));
if
(
res
!=
HTTRANSPARENT
)
{
*
hittest
=
res
;
/* Found the window */
...
...
include/wine/server_protocol.h
View file @
87d1a4a3
...
...
@@ -3634,6 +3634,8 @@ struct get_window_children_from_point_request
user_handle_t
parent
;
int
x
;
int
y
;
int
dpi
;
char
__pad_28
[
4
];
};
struct
get_window_children_from_point_reply
{
...
...
@@ -6533,6 +6535,6 @@ union generic_reply
struct
terminate_job_reply
terminate_job_reply
;
};
#define SERVER_PROTOCOL_VERSION 55
8
#define SERVER_PROTOCOL_VERSION 55
9
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/protocol.def
View file @
87d1a4a3
...
...
@@ -2609,6 +2609,7 @@ enum message_type
user_handle_t parent; /* parent window */
int x; /* point in parent coordinates */
int y;
int dpi; /* dpi for the point coordinates */
@REPLY
int count; /* total count of children */
VARARG(children,user_handles); /* children handles */
...
...
server/request.h
View file @
87d1a4a3
...
...
@@ -1745,7 +1745,8 @@ C_ASSERT( sizeof(struct get_window_children_reply) == 16 );
C_ASSERT
(
FIELD_OFFSET
(
struct
get_window_children_from_point_request
,
parent
)
==
12
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_window_children_from_point_request
,
x
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_window_children_from_point_request
,
y
)
==
20
);
C_ASSERT
(
sizeof
(
struct
get_window_children_from_point_request
)
==
24
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_window_children_from_point_request
,
dpi
)
==
24
);
C_ASSERT
(
sizeof
(
struct
get_window_children_from_point_request
)
==
32
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_window_children_from_point_reply
,
count
)
==
8
);
C_ASSERT
(
sizeof
(
struct
get_window_children_from_point_reply
)
==
16
);
C_ASSERT
(
FIELD_OFFSET
(
struct
get_window_tree_request
,
handle
)
==
12
);
...
...
server/trace.c
View file @
87d1a4a3
...
...
@@ -3181,6 +3181,7 @@ static void dump_get_window_children_from_point_request( const struct get_window
fprintf
(
stderr
,
" parent=%08x"
,
req
->
parent
);
fprintf
(
stderr
,
", x=%d"
,
req
->
x
);
fprintf
(
stderr
,
", y=%d"
,
req
->
y
);
fprintf
(
stderr
,
", dpi=%d"
,
req
->
dpi
);
}
static
void
dump_get_window_children_from_point_reply
(
const
struct
get_window_children_from_point_reply
*
req
)
...
...
server/window.c
View file @
87d1a4a3
...
...
@@ -658,6 +658,29 @@ static void map_dpi_region( struct window *win, struct region *region, unsigned
scale_region
(
region
,
from
,
to
);
}
/* convert coordinates from client to screen coords */
static
inline
void
client_to_screen
(
struct
window
*
win
,
int
*
x
,
int
*
y
)
{
for
(
;
win
&&
!
is_desktop_window
(
win
);
win
=
win
->
parent
)
{
*
x
+=
win
->
client_rect
.
left
;
*
y
+=
win
->
client_rect
.
top
;
}
}
/* convert coordinates from screen to client coords and dpi */
static
void
screen_to_client
(
struct
window
*
win
,
int
*
x
,
int
*
y
,
unsigned
int
dpi
)
{
int
offset_x
=
0
,
offset_y
=
0
;
if
(
is_desktop_window
(
win
))
return
;
client_to_screen
(
win
,
&
offset_x
,
&
offset_y
);
map_dpi_point
(
win
,
x
,
y
,
dpi
,
win
->
dpi
);
*
x
-=
offset_x
;
*
y
-=
offset_y
;
}
/* check if window and all its ancestors are visible */
static
int
is_visible
(
const
struct
window
*
win
)
{
...
...
@@ -686,18 +709,19 @@ int is_window_transparent( user_handle_t window )
return
(
win
->
ex_style
&
(
WS_EX_LAYERED
|
WS_EX_TRANSPARENT
))
==
(
WS_EX_LAYERED
|
WS_EX_TRANSPARENT
);
}
/* check if point is inside the window */
static
in
line
int
is_point_in_window
(
struct
window
*
win
,
int
x
,
int
y
)
/* check if point is inside the window
, and map to window dpi
*/
static
in
t
is_point_in_window
(
struct
window
*
win
,
int
*
x
,
int
*
y
,
unsigned
int
dpi
)
{
if
(
!
(
win
->
style
&
WS_VISIBLE
))
return
0
;
/* not visible */
if
((
win
->
style
&
(
WS_POPUP
|
WS_CHILD
|
WS_DISABLED
))
==
(
WS_CHILD
|
WS_DISABLED
))
return
0
;
/* disabled child */
if
((
win
->
ex_style
&
(
WS_EX_LAYERED
|
WS_EX_TRANSPARENT
))
==
(
WS_EX_LAYERED
|
WS_EX_TRANSPARENT
))
return
0
;
/* transparent */
if
(
!
point_in_rect
(
&
win
->
visible_rect
,
x
,
y
))
map_dpi_point
(
win
,
x
,
y
,
dpi
,
win
->
dpi
);
if
(
!
point_in_rect
(
&
win
->
visible_rect
,
*
x
,
*
y
))
return
0
;
/* not in window */
if
(
win
->
win_region
&&
!
point_in_region
(
win
->
win_region
,
x
-
win
->
window_rect
.
left
,
y
-
win
->
window_rect
.
top
))
!
point_in_region
(
win
->
win_region
,
*
x
-
win
->
window_rect
.
left
,
*
y
-
win
->
window_rect
.
top
))
return
0
;
/* not in window region */
return
1
;
}
...
...
@@ -732,15 +756,18 @@ static struct window *child_window_from_point( struct window *parent, int x, int
LIST_FOR_EACH_ENTRY
(
ptr
,
&
parent
->
children
,
struct
window
,
entry
)
{
if
(
!
is_point_in_window
(
ptr
,
x
,
y
))
continue
;
/* skip it */
int
x_child
=
x
,
y_child
=
y
;
if
(
!
is_point_in_window
(
ptr
,
&
x_child
,
&
y_child
,
parent
->
dpi
))
continue
;
/* skip it */
/* if window is minimized or disabled, return at once */
if
(
ptr
->
style
&
(
WS_MINIMIZE
|
WS_DISABLED
))
return
ptr
;
/* if point is not in client area, return at once */
if
(
!
point_in_rect
(
&
ptr
->
client_rect
,
x
,
y
))
return
ptr
;
if
(
!
point_in_rect
(
&
ptr
->
client_rect
,
x
_child
,
y_child
))
return
ptr
;
return
child_window_from_point
(
ptr
,
x
-
ptr
->
client_rect
.
left
,
y
-
ptr
->
client_rect
.
top
);
return
child_window_from_point
(
ptr
,
x_child
-
ptr
->
client_rect
.
left
,
y_child
-
ptr
->
client_rect
.
top
);
}
return
parent
;
/* not found any child */
}
...
...
@@ -753,13 +780,15 @@ static int get_window_children_from_point( struct window *parent, int x, int y,
LIST_FOR_EACH_ENTRY
(
ptr
,
&
parent
->
children
,
struct
window
,
entry
)
{
if
(
!
is_point_in_window
(
ptr
,
x
,
y
))
continue
;
/* skip it */
int
x_child
=
x
,
y_child
=
y
;
if
(
!
is_point_in_window
(
ptr
,
&
x_child
,
&
y_child
,
parent
->
dpi
))
continue
;
/* skip it */
/* if point is in client area, and window is not minimized or disabled, check children */
if
(
!
(
ptr
->
style
&
(
WS_MINIMIZE
|
WS_DISABLED
))
&&
point_in_rect
(
&
ptr
->
client_rect
,
x
,
y
))
if
(
!
(
ptr
->
style
&
(
WS_MINIMIZE
|
WS_DISABLED
))
&&
point_in_rect
(
&
ptr
->
client_rect
,
x
_child
,
y_child
))
{
if
(
!
get_window_children_from_point
(
ptr
,
x
-
ptr
->
client_rect
.
left
,
y
-
ptr
->
client_rect
.
top
,
array
))
if
(
!
get_window_children_from_point
(
ptr
,
x
_child
-
ptr
->
client_rect
.
left
,
y
_child
-
ptr
->
client_rect
.
top
,
array
))
return
0
;
}
...
...
@@ -778,7 +807,9 @@ user_handle_t shallow_window_from_point( struct desktop *desktop, int x, int y )
LIST_FOR_EACH_ENTRY
(
ptr
,
&
desktop
->
top_window
->
children
,
struct
window
,
entry
)
{
if
(
!
is_point_in_window
(
ptr
,
x
,
y
))
continue
;
/* skip it */
int
x_child
=
x
,
y_child
=
y
;
if
(
!
is_point_in_window
(
ptr
,
&
x_child
,
&
y_child
,
0
))
continue
;
/* skip it */
return
ptr
->
handle
;
}
return
desktop
->
top_window
->
handle
;
...
...
@@ -788,35 +819,26 @@ user_handle_t shallow_window_from_point( struct desktop *desktop, int x, int y )
struct
thread
*
window_thread_from_point
(
user_handle_t
scope
,
int
x
,
int
y
)
{
struct
window
*
win
=
get_user_object
(
scope
,
USER_WINDOW
);
struct
window
*
ptr
;
if
(
!
win
)
return
NULL
;
for
(
ptr
=
win
;
ptr
&&
!
is_desktop_window
(
ptr
);
ptr
=
ptr
->
parent
)
{
x
-=
ptr
->
client_rect
.
left
;
y
-=
ptr
->
client_rect
.
top
;
}
ptr
=
child_window_from_point
(
win
,
x
,
y
);
if
(
!
ptr
->
thread
)
return
NULL
;
return
(
struct
thread
*
)
grab_object
(
ptr
->
thread
);
screen_to_client
(
win
,
&
x
,
&
y
,
0
);
win
=
child_window_from_point
(
win
,
x
,
y
);
if
(
!
win
->
thread
)
return
NULL
;
return
(
struct
thread
*
)
grab_object
(
win
->
thread
);
}
/* return list of all windows containing point (in absolute coords) */
static
int
all_windows_from_point
(
struct
window
*
top
,
int
x
,
int
y
,
struct
user_handle_array
*
array
)
static
int
all_windows_from_point
(
struct
window
*
top
,
int
x
,
int
y
,
unsigned
int
dpi
,
struct
user_handle_array
*
array
)
{
struct
window
*
ptr
;
/* make point relative to top window */
for
(
ptr
=
top
->
parent
;
ptr
&&
!
is_desktop_window
(
ptr
);
ptr
=
ptr
->
parent
)
if
(
!
is_desktop_window
(
top
)
&&
!
is_desktop_window
(
top
->
parent
))
{
x
-=
ptr
->
client_rect
.
left
;
y
-=
ptr
->
client_rect
.
top
;
screen_to_client
(
top
->
parent
,
&
x
,
&
y
,
dpi
)
;
dpi
=
top
->
parent
->
dpi
;
}
if
(
!
is_point_in_window
(
top
,
x
,
y
))
return
1
;
if
(
!
is_point_in_window
(
top
,
&
x
,
&
y
,
dpi
))
return
1
;
/* if point is in client area, and window is not minimized or disabled, check children */
if
(
!
(
top
->
style
&
(
WS_MINIMIZE
|
WS_DISABLED
))
&&
point_in_rect
(
&
top
->
client_rect
,
x
,
y
))
{
...
...
@@ -916,16 +938,6 @@ static struct region *intersect_window_region( struct region *region, struct win
/* convert coordinates from client to screen coords */
static
inline
void
client_to_screen
(
struct
window
*
win
,
int
*
x
,
int
*
y
)
{
for
(
;
win
&&
!
is_desktop_window
(
win
);
win
=
win
->
parent
)
{
*
x
+=
win
->
client_rect
.
left
;
*
y
+=
win
->
client_rect
.
top
;
}
}
/* convert coordinates from client to screen coords */
static
inline
void
client_to_screen_rect
(
struct
window
*
win
,
rectangle_t
*
rect
)
{
for
(
;
win
&&
!
is_desktop_window
(
win
);
win
=
win
->
parent
)
...
...
@@ -2219,7 +2231,7 @@ DECL_HANDLER(get_window_children_from_point)
array
.
handles
=
NULL
;
array
.
count
=
0
;
array
.
total
=
0
;
if
(
!
all_windows_from_point
(
parent
,
req
->
x
,
req
->
y
,
&
array
))
return
;
if
(
!
all_windows_from_point
(
parent
,
req
->
x
,
req
->
y
,
req
->
dpi
,
&
array
))
return
;
reply
->
count
=
array
.
count
;
len
=
min
(
get_reply_max_size
(),
array
.
count
*
sizeof
(
user_handle_t
)
);
...
...
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