@@ -6,18 +6,17 @@ use std::ptr::null_mut;
66use std:: sync:: Weak ;
77
88use windows:: Win32 :: Foundation :: { POINTL , POINT } ;
9- use windows:: Win32 :: Graphics :: Gdi :: MapWindowPoints ;
9+ use windows:: Win32 :: Graphics :: Gdi :: ScreenToClient ;
1010use windows:: Win32 :: System :: Com :: { IDataObject , DVASPECT_CONTENT , FORMATETC , TYMED_HGLOBAL } ;
1111use windows:: Win32 :: System :: SystemServices :: MODIFIERKEYS_FLAGS ;
12+ use windows:: Win32 :: UI :: HiDpi :: { LogicalToPhysicalPointForPerMonitorDPI , PhysicalToLogicalPointForPerMonitorDPI } ;
1213use windows:: Win32 :: UI :: Shell :: { DragQueryFileW , HDROP } ;
1314use windows:: core:: implement;
1415use windows:: Win32 :: System :: Ole :: { IDropTarget , IDropTarget_Impl , DROPEFFECT , CF_HDROP , DROPEFFECT_NONE , DROPEFFECT_COPY , DROPEFFECT_MOVE , DROPEFFECT_LINK } ;
15- use windows:: Win32 :: UI :: WindowsAndMessaging :: HWND_DESKTOP ;
1616
1717use crate :: event:: EventResponse ;
18- use crate :: platform:: interface:: OsWindowInterface ;
1918use crate :: thread_bound:: ThreadBound ;
20- use crate :: { LogicalPosition , PhysicalPosition } ;
19+ use crate :: LogicalPosition ;
2120use crate :: drag_drop:: { DropData , DropOperation } ;
2221use super :: window:: OsWindow ;
2322
@@ -52,7 +51,7 @@ impl DropTarget {
5251 unsafe {
5352 let medium = data_object. GetData ( & format) ?;
5453 let hdrop = HDROP ( medium. u . hGlobal . 0 ) ;
55-
54+
5655 let item_count = DragQueryFileW ( hdrop, 0xFFFFFFFF , None ) ;
5756 if item_count == 0 {
5857 * self . drop_data . borrow_mut ( ) = DropData :: None ;
@@ -91,24 +90,29 @@ impl DropTarget {
9190 }
9291 }
9392
94- fn convert_coordinates ( & self , point : & POINTL ) -> LogicalPosition {
95- let Some ( window) = self . window . upgrade ( ) else {
96- return LogicalPosition :: default ( ) ;
97- } ;
93+ fn convert_coordinates ( & self , point : & POINTL ) -> Option < LogicalPosition > {
94+ let window = self . window . upgrade ( ) ?;
9895
99- let scale = window. os_scale ( ) ;
96+ let scale = window. scale ( ) ;
97+ let mut point = POINT { x : ( point. x as f64 ) as _ , y : ( point. y as f64 ) as _ } ;
10098
101- // It looks like MapWindowPoints isn 't DPI aware (and neither is ScreenToClient),
102- // so we need to pre-scale the point here?
103- // TODO: Find out what's going on
104- let mut points = [ POINT { x : ( point . x as f64 / scale ) as i32 , y : ( point . y as f64 / scale ) as i32 } ] ;
99+ // ScreenToClient doesn 't seem to be DPI-aware
100+ if unsafe { ! PhysicalToLogicalPointForPerMonitorDPI ( None , & mut point) . as_bool ( ) } {
101+ return None ;
102+ }
105103
106- unsafe { MapWindowPoints ( Some ( HWND_DESKTOP ) , Some ( window. hwnd ( ) ) , & mut points) ; }
104+ if unsafe { !ScreenToClient ( window. hwnd ( ) , & mut point) . as_bool ( ) } {
105+ return None ;
106+ }
107+
108+ if unsafe { !LogicalToPhysicalPointForPerMonitorDPI ( None , & mut point) . as_bool ( ) } {
109+ return None ;
110+ }
107111
108- PhysicalPosition {
109- x : points [ 0 ] . x ,
110- y : points [ 0 ] . y ,
111- } . to_logical ( 1.0 )
112+ Some ( LogicalPosition {
113+ x : point . x as f64 / scale ,
114+ y : point . y as f64 / scale ,
115+ } )
112116 }
113117}
114118
@@ -121,13 +125,15 @@ impl IDropTarget_Impl for DropTarget_Impl {
121125
122126 self . parse_drag_data ( pdataobj) ?;
123127
124- let response = window. send_event ( crate :: Event :: DragEntered {
125- position : self . convert_coordinates ( pt) ,
126- data : self . drop_data . borrow ( ) . clone ( ) ,
127- } ) ;
128-
129- unsafe { * pdweffect = self . convert_drag_operation ( response) } ;
130-
128+ if let Some ( position) = self . convert_coordinates ( pt) {
129+ let response = window. send_event ( crate :: Event :: DragEntered {
130+ position,
131+ data : self . drop_data . borrow ( ) . clone ( ) ,
132+ } ) ;
133+
134+ unsafe { * pdweffect = self . convert_drag_operation ( response) } ;
135+ }
136+
131137 Ok ( ( ) )
132138 }
133139
@@ -136,12 +142,14 @@ impl IDropTarget_Impl for DropTarget_Impl {
136142 return Ok ( ( ) ) ;
137143 } ;
138144
139- let response = window. send_event ( crate :: Event :: DragMoved {
140- position : self . convert_coordinates ( pt) ,
141- data : self . drop_data . borrow ( ) . clone ( ) ,
142- } ) ;
143-
144- unsafe { * pdweffect = self . convert_drag_operation ( response) } ;
145+ if let Some ( position) = self . convert_coordinates ( pt) {
146+ let response = window. send_event ( crate :: Event :: DragMoved {
147+ position,
148+ data : self . drop_data . borrow ( ) . clone ( ) ,
149+ } ) ;
150+
151+ unsafe { * pdweffect = self . convert_drag_operation ( response) } ;
152+ }
145153
146154 Ok ( ( ) )
147155 }
@@ -163,12 +171,14 @@ impl IDropTarget_Impl for DropTarget_Impl {
163171
164172 self . parse_drag_data ( pdataobj) ?;
165173
166- let response = window. send_event ( crate :: Event :: DragDropped {
167- position : self . convert_coordinates ( pt) ,
168- data : self . drop_data . borrow ( ) . clone ( ) ,
169- } ) ;
170-
171- unsafe { * pdweffect = self . convert_drag_operation ( response) } ;
174+ if let Some ( position) = self . convert_coordinates ( pt) {
175+ let response = window. send_event ( crate :: Event :: DragDropped {
176+ position,
177+ data : self . drop_data . borrow ( ) . clone ( ) ,
178+ } ) ;
179+
180+ unsafe { * pdweffect = self . convert_drag_operation ( response) } ;
181+ }
172182
173183 Ok ( ( ) )
174184 }
0 commit comments