diff --git a/src/Eto.Mac/Forms/FloatingFormHandler.cs b/src/Eto.Mac/Forms/FloatingFormHandler.cs index 6cc80f5eca..a19bebf48a 100644 --- a/src/Eto.Mac/Forms/FloatingFormHandler.cs +++ b/src/Eto.Mac/Forms/FloatingFormHandler.cs @@ -65,12 +65,16 @@ void SetLevelAdjustment() { lastOwner.GotFocus -= Owner_GotFocus; lastOwner.LostFocus -= Owner_LostFocus; + Widget.GotFocus -= Owner_GotFocus; + Widget.LostFocus -= Owner_LostFocus; Widget.Closed -= Widget_Closed; } if (owner != null) { owner.GotFocus += Owner_GotFocus; owner.LostFocus += Owner_LostFocus; + Widget.GotFocus += Owner_GotFocus; + Widget.LostFocus += Owner_LostFocus; Widget.Closed += Widget_Closed; } } @@ -87,6 +91,8 @@ private void Widget_Closed(object sender, EventArgs e) // when closed we need to disconnect from owner to prevent leaks lastOwner.GotFocus -= Owner_GotFocus; lastOwner.LostFocus -= Owner_LostFocus; + Widget.GotFocus -= Owner_GotFocus; + Widget.LostFocus -= Owner_LostFocus; } } @@ -125,9 +131,15 @@ void SetAsTopmost() private void Owner_LostFocus(object sender, EventArgs e) { + if (HasFocus || Widget.Owner.HasFocus) + return; Control.Level = NSWindowLevel.Normal; + + // Window will still be topmost until we order the window explicitly. + // If there are multiple app windows, we use this instead of OrderFront otherwise + // the original parent window steals focus again. if (Control.IsVisible) - Control.OrderFront(Control); + Control.OrderWindow(NSWindowOrderingMode.Above, Control.ParentWindow?.WindowNumber ?? 0); } protected override NSPanel CreateControl() diff --git a/src/Eto.Mac/Forms/NativeFormHandler.cs b/src/Eto.Mac/Forms/NativeFormHandler.cs index 313318e858..fe49d9ae7a 100644 --- a/src/Eto.Mac/Forms/NativeFormHandler.cs +++ b/src/Eto.Mac/Forms/NativeFormHandler.cs @@ -17,20 +17,20 @@ public NativeFormHandler(NSWindowController windowController) public override void AttachEvent(string id) { - // native window, so attach notifications instead of using the delegate so we don't clobber existing functionality + // native window, so attach observers instead of using the delegate so we don't clobber existing functionality switch (id) { case Window.ClosedEvent: - NSNotificationCenter.DefaultCenter.AddObserver(NSWindow.WillCloseNotification, n => Callback.OnClosed(Widget, EventArgs.Empty)); + AddObserver(NSWindow.WillCloseNotification, n => Callback.OnClosed(Widget, EventArgs.Empty)); break; case Window.SizeChangedEvent: - NSNotificationCenter.DefaultCenter.AddObserver(NSWindow.DidResizeNotification, n => Callback.OnSizeChanged(Widget, EventArgs.Empty)); + AddObserver(NSWindow.DidResizeNotification, n => Callback.OnSizeChanged(Widget, EventArgs.Empty)); break; case Window.GotFocusEvent: - NSNotificationCenter.DefaultCenter.AddObserver(NSWindow.DidBecomeKeyNotification, n => Callback.OnGotFocus(Widget, EventArgs.Empty)); + AddObserver(NSWindow.DidBecomeKeyNotification, n => Callback.OnGotFocus(Widget, EventArgs.Empty)); break; case Window.LostFocusEvent: - NSNotificationCenter.DefaultCenter.AddObserver(NSWindow.DidResignKeyNotification, n => Callback.OnLostFocus(Widget, EventArgs.Empty)); + AddObserver(NSWindow.DidResignKeyNotification, n => Callback.OnLostFocus(Widget, EventArgs.Empty)); break; } return;