diff --git a/v3/UNRELEASED_CHANGELOG.md b/v3/UNRELEASED_CHANGELOG.md index 8cd683a1fdb..db33eb0498e 100644 --- a/v3/UNRELEASED_CHANGELOG.md +++ b/v3/UNRELEASED_CHANGELOG.md @@ -29,6 +29,7 @@ After processing, the content will be moved to the main changelog and this file - Track `HICON` ownership so only user-created handles are destroyed, preventing Explorer recycling crashes (#4653). - Release the Windows system-theme listener and retained tray icons during destroy to stop leaking goroutines and device contexts (#4653). - Truncate tray tooltips at 127 UTF-16 units to avoid corrupting surrogate pairs and multi-byte glyphs (#4653). +- Fixed DnD dropzone detection failing at non-100% display scaling on Windows (#4632). ## Deprecated diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/src/window.ts b/v3/internal/runtime/desktop/@wailsio/runtime/src/window.ts index 3a2519d1ad0..a8380d1b2f3 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/src/window.ts +++ b/v3/internal/runtime/desktop/@wailsio/runtime/src/window.ts @@ -539,8 +539,8 @@ class Window { * Gathers information about the drop target element and sends it back to the Go backend. * * @param filenames - An array of file paths (strings) that were dropped. - * @param x - The x-coordinate of the drop event. - * @param y - The y-coordinate of the drop event. + * @param x - The x-coordinate of the drop event, in logical (CSS) pixels relative to the webview. + * @param y - The y-coordinate of the drop event, in logical (CSS) pixels relative to the webview. */ HandlePlatformFileDrop(filenames: string[], x: number, y: number): void { const element = document.elementFromPoint(x, y); diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 86a5bb72a10..d3b875211fa 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -5,6 +5,7 @@ package application import ( "errors" "fmt" + "math" "net/url" "strconv" "strings" @@ -605,12 +606,30 @@ func (w *windowsWebviewWindow) convertWindowToWebviewCoordinates(windowX, window globalApplication.debug("[DragDropDebug] convertWindowToWebviewCoordinates: Calculated offset", "offsetX", offsetX, "offsetY", offsetY) // Convert window-relative coordinates to webview-relative coordinates - webviewX := windowX - offsetX - webviewY := windowY - offsetY + webviewPhysicalX := windowX - offsetX + webviewPhysicalY := windowY - offsetY - globalApplication.debug("[DragDropDebug] convertWindowToWebviewCoordinates: Final webview coordinates", "webviewX", webviewX, "webviewY", webviewY) + globalApplication.debug("[DragDropDebug] convertWindowToWebviewCoordinates: Webview coordinates before DPI Scaling", "webviewPhysicalX", webviewPhysicalX, "webviewPhysicalY", webviewPhysicalY) - return webviewX, webviewY + // Get DPI for this window + dpi := w32.GetDpiForWindow(w.hwnd) + if dpi == 0 { + globalApplication.debug("[DragDropDebug] convertWindowToWebviewCoordinates: Failed to get dpi, returning physical coordinates", "webviewPhysicalX", webviewPhysicalX, "webviewPhysicalY", webviewPhysicalY) + return webviewPhysicalX, webviewPhysicalY + } + + // Convert to scale factor: 96 DPI == 1.0 (100%) + scaleFactor := float64(dpi) / 96.0 + globalApplication.debug("[DragDropDebug] convertWindowToWebviewCoordinates: DPI info", "dpi", dpi, "scaleFactor", scaleFactor) + + // Convert physical pixels -> logical/CSS pixels by dividing by the scale factor + // Use rounding to avoid truncation artefacts + webviewLogicalX := int(math.Round(float64(webviewPhysicalX) / scaleFactor)) + webviewLogicalY := int(math.Round(float64(webviewPhysicalY) / scaleFactor)) + globalApplication.debug("[DragDropDebug] convertWindowToWebviewCoordinates: Final webview coordinates (logical/CSS pixels)", + "webviewLogicalX", webviewLogicalX, "webviewLogicalY", webviewLogicalY) + + return webviewLogicalX, webviewLogicalY } func (w *windowsWebviewWindow) physicalBounds() Rect {