From c94005e4b93e2d39a2cb963965e24b9939de0d90 Mon Sep 17 00:00:00 2001 From: Local Admin Date: Wed, 28 Jun 2023 12:20:40 -0700 Subject: [PATCH] Mac: Fix setting tracking rectangles for mouse enter/move/leave events This is a regression on Monterey (caused by #2505) where the bounds of the tracking rectangles aren't set up correctly since the visibleRect of views can now be larger than the bounds of the control itself. --- src/Eto.Mac/Forms/MacView.cs | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Eto.Mac/Forms/MacView.cs b/src/Eto.Mac/Forms/MacView.cs index ee727fe94..cad3ede56 100644 --- a/src/Eto.Mac/Forms/MacView.cs +++ b/src/Eto.Mac/Forms/MacView.cs @@ -118,6 +118,7 @@ public interface IMacViewHandler : IMacControlHandler bool TriggerMouseCallback(); MouseEventArgs TriggerMouseDown(NSObject obj, IntPtr sel, NSEvent theEvent); MouseEventArgs TriggerMouseUp(NSObject obj, IntPtr sel, NSEvent theEvent); + void UpdateTrackingAreas(); } static partial class MacView @@ -176,6 +177,7 @@ static partial class MacView public static readonly IntPtr selPerformZoom = Selector.GetHandle("performZoom:"); public static readonly IntPtr selArrangeInFront = Selector.GetHandle("arrangeInFront:"); public static readonly IntPtr selPerformMiniaturize = Selector.GetHandle("performMiniaturize:"); + public static readonly IntPtr selUpdateTrackingAreas = Selector.GetHandle("updateTrackingAreas"); public static readonly Dictionary systemActionSelectors = new Dictionary { { "cut", selCut }, @@ -208,6 +210,20 @@ static partial class MacView // before 10.12, we have to call base.Layout() AFTER we do our layout otherwise it doesn't work correctly.. // however, that causes (temporary) glitches when resizing especially with Scrollable >= 10.12 public static readonly bool NewLayout = MacVersion.IsAtLeast(10, 12); + + internal static MarshalDelegates.Action_IntPtr_IntPtr TriggerUpdateTrackingAreas_Delegate = TriggerUpdateTrackingAreas; + static void TriggerUpdateTrackingAreas(IntPtr sender, IntPtr sel) + { + var obj = Runtime.GetNSObject(sender); + + Messaging.void_objc_msgSendSuper(obj.SuperHandle, sel); + + if (MacBase.GetHandler(obj) is IMacViewHandler handler) + { + handler.UpdateTrackingAreas(); + } + } + internal static MarshalDelegates.Action_IntPtr_IntPtr_IntPtr TriggerMouseDragged_Delegate = TriggerMouseDragged; static void TriggerMouseDragged(IntPtr sender, IntPtr sel, IntPtr e) { @@ -636,7 +652,6 @@ public virtual Size Size if (oldFrame.Size != newFrame.Size) Callback.OnSizeChanged(Widget, EventArgs.Empty); - CreateTracking(); InvalidateMeasure(); } } @@ -722,8 +737,8 @@ public virtual SizeF GetPreferredSize(SizeF availableSize) return size; } - - void CreateTracking() + + public virtual void UpdateTrackingAreas() { if (!mouseMove) return; @@ -742,8 +757,6 @@ void CreateTracking() frame = GetAlignmentRectForFrame(frame); var options = mouseOptions | NSTrackingAreaOptions.ActiveAlways | NSTrackingAreaOptions.EnabledDuringMouseDrag; - if (!UseAlignmentFrame) - options |= NSTrackingAreaOptions.InVisibleRect; tracking = new NSTrackingArea(frame, options, mouseDelegate, null); EventControl.AddTrackingArea(tracking); @@ -768,14 +781,14 @@ public override void AttachEvent(string id) case Eto.Forms.Control.MouseLeaveEvent: mouseOptions |= NSTrackingAreaOptions.MouseEnteredAndExited; mouseMove = true; - HandleEvent(Eto.Forms.Control.SizeChangedEvent); - CreateTracking(); + AddMethod(MacView.selUpdateTrackingAreas, MacView.TriggerUpdateTrackingAreas_Delegate, "v@:@", EventControl); + EventControl.UpdateTrackingAreas(); break; case Eto.Forms.Control.MouseMoveEvent: mouseOptions |= NSTrackingAreaOptions.MouseMoved; mouseMove = true; - HandleEvent(Eto.Forms.Control.SizeChangedEvent); - CreateTracking(); + AddMethod(MacView.selUpdateTrackingAreas, MacView.TriggerUpdateTrackingAreas_Delegate, "v@:@", EventControl); + EventControl.UpdateTrackingAreas(); AddMethod(MacView.selMouseDragged, MacView.TriggerMouseDragged_Delegate, "v@:@"); AddMethod(MacView.selRightMouseDragged, MacView.TriggerMouseDragged_Delegate, "v@:@"); AddMethod(MacView.selOtherMouseDragged, MacView.TriggerMouseDragged_Delegate, "v@:@"); @@ -896,7 +909,6 @@ public bool TriggerMouseCallback() public virtual void OnSizeChanged(EventArgs e) { - CreateTracking(); } public virtual void Invalidate(bool invalidateChildren)