Skip to content

Commit

Permalink
Fix embedded TopLevel coordinate conversion (#16181)
Browse files Browse the repository at this point in the history
* Fix embedded TopLevel coordinate conversion

* Adjust client / screen coordinate conversion

* Remove commented code
  • Loading branch information
Gillibald committed Jul 4, 2024
1 parent 640a9dd commit 3eda9a0
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 24 deletions.
1 change: 0 additions & 1 deletion native/Avalonia.Native/src/OSX/AvnView.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@
-(void) setResizeReason:(AvnPlatformResizeReason)reason;
-(void) setRenderTarget:(NSObject<IRenderTarget>* _Nonnull)target;
-(void) raiseAccessibilityChildrenChanged;
+ (AvnPoint)toAvnPoint:(CGPoint)p;
@end
22 changes: 8 additions & 14 deletions native/Avalonia.Native/src/OSX/AvnView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -734,7 +728,7 @@ - (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)
- (NSDragOperation)triggerAvnDragEvent: (AvnDragEventType) type info: (id <NSDraggingInfo>)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];
Expand Down
2 changes: 1 addition & 1 deletion native/Avalonia.Native/src/OSX/AvnWindow.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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 };

Expand Down
41 changes: 33 additions & 8 deletions native/Avalonia.Native/src/OSX/TopLevelImpl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down

0 comments on commit 3eda9a0

Please sign in to comment.