diff --git a/plugin-canvas/Cargo.toml b/plugin-canvas/Cargo.toml index 40fba88..354e400 100644 --- a/plugin-canvas/Cargo.toml +++ b/plugin-canvas/Cargo.toml @@ -14,6 +14,7 @@ cursor-icon.workspace = true keyboard-types.workspace = true portable-atomic.workspace = true raw-window-handle.workspace = true +tracing.workspace = true uuid = { version = "1", features = ["fast-rng", "v4"] } [target.'cfg(target_os="linux")'.dependencies] diff --git a/plugin-canvas/src/platform/win32/drop_target.rs b/plugin-canvas/src/platform/win32/drop_target.rs index bded39a..c6066d4 100644 --- a/plugin-canvas/src/platform/win32/drop_target.rs +++ b/plugin-canvas/src/platform/win32/drop_target.rs @@ -5,7 +5,7 @@ use std::os::windows::prelude::OsStringExt; use std::ptr::null_mut; use std::sync::Weak; -use windows::Win32::Foundation::{POINTL, POINT}; +use windows::Win32::Foundation::{POINTL, POINT, GetLastError}; use windows::Win32::Graphics::Gdi::ScreenToClient; use windows::Win32::System::Com::{IDataObject, DVASPECT_CONTENT, FORMATETC, TYMED_HGLOBAL}; use windows::Win32::System::SystemServices::MODIFIERKEYS_FLAGS; @@ -97,15 +97,12 @@ impl DropTarget { let mut point = POINT { x: (point.x as f64) as _, y: (point.y as f64) as _ }; // ScreenToClient doesn't seem to be DPI-aware - if unsafe { !PhysicalToLogicalPointForPerMonitorDPI(None, &mut point).as_bool() } { - return None; - } - - if unsafe { !ScreenToClient(window.hwnd(), &mut point).as_bool() } { - return None; - } - - if unsafe { !LogicalToPhysicalPointForPerMonitorDPI(None, &mut point).as_bool() } { + if unsafe { + !PhysicalToLogicalPointForPerMonitorDPI(None, &mut point).as_bool() + || !ScreenToClient(window.hwnd(), &mut point).as_bool() + || !LogicalToPhysicalPointForPerMonitorDPI(None, &mut point).as_bool() + } { + tracing::warn!("Failed to convert WINAPI drag drop position: LastError: {:?}", unsafe { GetLastError() }); return None; } diff --git a/plugin-canvas/src/platform/win32/window.rs b/plugin-canvas/src/platform/win32/window.rs index ce68373..f791315 100644 --- a/plugin-canvas/src/platform/win32/window.rs +++ b/plugin-canvas/src/platform/win32/window.rs @@ -8,10 +8,10 @@ use keyboard_types::Code; use portable_atomic::AtomicF64; use raw_window_handle::{HasDisplayHandle, HasWindowHandle, RawWindowHandle, Win32WindowHandle}; use uuid::Uuid; -use windows::Win32::UI::Input::KeyboardAndMouse::SetFocus; +use windows::Win32::UI::HiDpi::{LogicalToPhysicalPointForPerMonitorDPI, PhysicalToLogicalPointForPerMonitorDPI}; use windows::Win32::UI::WindowsAndMessaging::{GetParent, WM_CANCELMODE, WM_SETFOCUS, WM_SETCURSOR}; -use windows::{core::PCWSTR, Win32::UI::Input::KeyboardAndMouse::{VK_LWIN, VK_RWIN}}; -use windows::Win32::Foundation::{HWND, LPARAM, LRESULT, POINT, WPARAM}; +use windows::{core::PCWSTR, Win32::UI::Input::KeyboardAndMouse::{SetFocus, VK_LWIN, VK_RWIN}}; +use windows::Win32::Foundation::{HWND, LPARAM, LRESULT, POINT, WPARAM, GetLastError}; use windows::Win32::Graphics::{Dwm::{DwmFlush, DwmIsCompositionEnabled}, Dxgi::{CreateDXGIFactory, IDXGIFactory, IDXGIOutput}, Gdi::{ClientToScreen, MonitorFromWindow, ScreenToClient, HBRUSH, MONITOR_DEFAULTTOPRIMARY}}; use windows::Win32::System::Ole::{IDropTarget, OleInitialize, RegisterDragDrop, RevokeDragDrop}; use windows::Win32::UI::{Controls::WM_MOUSELEAVE, Input::KeyboardAndMouse::{GetAsyncKeyState, SetCapture, TrackMouseEvent, TME_LEAVE, TRACKMOUSEEVENT, VK_CONTROL, VK_MENU, VK_SHIFT}, WindowsAndMessaging::{CreateWindowExW, DefWindowProcW, DestroyWindow, GetWindowLongPtrW, LoadCursorW, MoveWindow, RegisterClassW, SendMessageW, SetCursor, SetCursorPos, SetWindowLongPtrW, ShowCursor, UnregisterClassW, CS_OWNDC, GWLP_USERDATA, HICON, IDC_ARROW, WINDOW_EX_STYLE, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_MOVE, WM_RBUTTONDOWN, WM_RBUTTONUP, WNDCLASSW, WS_CHILD, WS_VISIBLE}}; @@ -410,12 +410,24 @@ unsafe extern "system" fn wnd_proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: let x: i16 = u16::cast_signed(((lparam.0 as usize) & 0xFFFF) as u16); let y: i16 = u16::cast_signed(((lparam.0 as usize) >> 16) as u16); - let mut position = POINT { x: x as i32, y: y as i32 }; - let result = unsafe { ScreenToClient(hwnd, &mut position) }; - assert!(result.as_bool()); + let scale = window.scale(); + let mut point = POINT { x: x as _, y: y as _ }; + + // ScreenToClient doesn't seem to be DPI-aware + if unsafe { + !PhysicalToLogicalPointForPerMonitorDPI(None, &mut point).as_bool() + || !ScreenToClient(window.hwnd(), &mut point).as_bool() + || !LogicalToPhysicalPointForPerMonitorDPI(None, &mut point).as_bool() + } { + tracing::warn!("Failed to convert WINAPI mouse wheel position: LastError: {:?}", unsafe { GetLastError() }); + return LRESULT(0); + } window.send_event(Event::MouseWheel { - position: LogicalPosition { x: position.x as f64, y: position.y as f64 }, + position: LogicalPosition { + x: point.x as f64 / scale, + y: point.y as f64 / scale, + }, delta_x: 0.0, delta_y: wheel_delta as f64 / 120.0, });