From 3eda9a0e2251cfd3e31da71448c3a236e7147334 Mon Sep 17 00:00:00 2001 From: Benedikt Stebner Date: Thu, 4 Jul 2024 18:03:56 +0200 Subject: [PATCH] Fix embedded TopLevel coordinate conversion (#16181) * Fix embedded TopLevel coordinate conversion * Adjust client / screen coordinate conversion * Remove commented code --- native/Avalonia.Native/src/OSX/AvnView.h | 1 - native/Avalonia.Native/src/OSX/AvnView.mm | 22 ++++------ native/Avalonia.Native/src/OSX/AvnWindow.mm | 2 +- .../Avalonia.Native/src/OSX/TopLevelImpl.mm | 41 +++++++++++++++---- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/AvnView.h b/native/Avalonia.Native/src/OSX/AvnView.h index 5e778737619..75a5e98ed46 100644 --- a/native/Avalonia.Native/src/OSX/AvnView.h +++ b/native/Avalonia.Native/src/OSX/AvnView.h @@ -23,5 +23,4 @@ -(void) setResizeReason:(AvnPlatformResizeReason)reason; -(void) setRenderTarget:(NSObject* _Nonnull)target; -(void) raiseAccessibilityChildrenChanged; -+ (AvnPoint)toAvnPoint:(CGPoint)p; @end diff --git a/native/Avalonia.Native/src/OSX/AvnView.mm b/native/Avalonia.Native/src/OSX/AvnView.mm index 554f1b6deba..36e2307f427 100644 --- a/native/Avalonia.Native/src/OSX/AvnView.mm +++ b/native/Avalonia.Native/src/OSX/AvnView.mm @@ -189,16 +189,6 @@ - (AvnPoint) translateLocalPoint:(AvnPoint)pt return pt; } -+ (AvnPoint)toAvnPoint:(CGPoint)p -{ - AvnPoint result; - - result.X = p.x; - result.Y = p.y; - - return result; -} - - (void) viewDidChangeBackingProperties { auto fsize = [self convertSizeToBacking: [self frame].size]; @@ -255,9 +245,13 @@ - (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type return; } - auto localPoint = [self convertPoint:[event locationInWindow] toView:self]; - auto avnPoint = [AvnView toAvnPoint:localPoint]; - auto point = [self translateLocalPoint:avnPoint]; + NSPoint eventLocation = [event locationInWindow]; + + auto viewLocation = [self convertPoint:NSMakePoint(0, 0) toView:nil]; + + auto localPoint = NSMakePoint(eventLocation.x - viewLocation.x, viewLocation.y - eventLocation.y); + + auto point = ToAvnPoint(localPoint); AvnVector delta = { 0, 0}; if(type == Wheel) @@ -734,7 +728,7 @@ - (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer) - (NSDragOperation)triggerAvnDragEvent: (AvnDragEventType) type info: (id )info { auto localPoint = [self convertPoint:[info draggingLocation] toView:self]; - auto avnPoint = [AvnView toAvnPoint:localPoint]; + auto avnPoint = ToAvnPoint(localPoint); auto point = [self translateLocalPoint:avnPoint]; auto modifiers = [self getModifiers:[[NSApp currentEvent] modifierFlags]]; NSDragOperation nsop = [info draggingSourceOperationMask]; diff --git a/native/Avalonia.Native/src/OSX/AvnWindow.mm b/native/Avalonia.Native/src/OSX/AvnWindow.mm index 5b5f3abb764..9b92dba5239 100644 --- a/native/Avalonia.Native/src/OSX/AvnWindow.mm +++ b/native/Avalonia.Native/src/OSX/AvnWindow.mm @@ -462,7 +462,7 @@ - (void)sendEvent:(NSEvent *_Nonnull)event if (!NSPointInRect(viewPoint, view.bounds)) { - auto avnPoint = [AvnView toAvnPoint:windowPoint]; + auto avnPoint = ToAvnPoint(windowPoint); auto point = [self translateLocalPoint:avnPoint]; AvnVector delta = { 0, 0 }; diff --git a/native/Avalonia.Native/src/OSX/TopLevelImpl.mm b/native/Avalonia.Native/src/OSX/TopLevelImpl.mm index 0a56b71f822..8915dd0e771 100644 --- a/native/Avalonia.Native/src/OSX/TopLevelImpl.mm +++ b/native/Avalonia.Native/src/OSX/TopLevelImpl.mm @@ -192,11 +192,23 @@ return S_OK; } - point = ConvertPointY(point); - NSRect convertRect = [window convertRectFromScreen:NSMakeRect(point.X, point.Y, 0.0, 0.0)]; - auto viewPoint = NSMakePoint(convertRect.origin.x, convertRect.origin.y); + auto frame = [View frame]; + + auto viewRect = [View convertRect:frame toView:nil]; + + auto viewScreenRect = [window convertRectToScreen:viewRect]; + + auto primaryDisplayHeight = NSMaxY([[[NSScreen screens] firstObject] frame]); + + //Window coord are bottom to top so we need to adjust by primaryScreenHeight + auto viewScreenLocation = NSMakePoint(viewScreenRect.origin.x, primaryDisplayHeight - viewScreenRect.origin.y - frame.size.height); + + //Substract client point from screen position of the view + auto localPoint = NSMakePoint(point.X - viewScreenLocation.x, point.Y - viewScreenLocation.y); + + point = ToAvnPoint(localPoint); - *ret = [View translateLocalPoint:ToAvnPoint(viewPoint)]; + *ret = point; return S_OK; } @@ -217,11 +229,24 @@ return S_OK; } + + auto frame = [View frame]; + + //Get rect inside current window + auto viewRect = [View convertRect:frame toView:nil]; + + //Get screen rect of the view + auto viewScreenRect = [window convertRectToScreen:viewRect]; + + auto primaryDisplayHeight = NSMaxY([[[NSScreen screens] firstObject] frame]); + + //Window coord are bottom to top so we need to adjust by primaryScreenHeight + auto viewScreenLocation = NSMakePoint(viewScreenRect.origin.x, primaryDisplayHeight - viewScreenRect.origin.y - frame.size.height); - auto cocoaViewPoint = ToNSPoint([View translateLocalPoint:point]); - NSRect convertRect = [window convertRectToScreen:NSMakeRect(cocoaViewPoint.x, cocoaViewPoint.y, 0.0, 0.0)]; - auto cocoaScreenPoint = NSPointFromCGPoint(NSMakePoint(convertRect.origin.x, convertRect.origin.y)); - *ret = ConvertPointY(ToAvnPoint(cocoaScreenPoint)); + //Add client point to screen position of the view + auto screenPoint = ToAvnPoint(NSMakePoint(viewScreenLocation.x + point.X, viewScreenLocation.y + point.Y)); + + *ret = screenPoint; return S_OK; }