Skip to content

Commit 26c7ece

Browse files
authored
Merge pull request #2656 from cwensley/curtis/mac-fix-window-location-when-only-size-event-handled
Mac: Fix Window.Location when only SizeChanged is handled
2 parents 3dc13f7 + ba582b5 commit 26c7ece

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed

src/Eto.Mac/Forms/MacWindow.cs

+34-7
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ public override void RecalculateKeyViewLoop()
7575
NSView last = null;
7676
Handler?.RecalculateKeyViewLoop(ref last);
7777
}
78+
79+
#if MONOMAC
80+
protected override void Dispose(bool disposing)
81+
{
82+
// See HandleWillClose for details of this
83+
// This is needed in addition when a window is created but not ever shown.
84+
Delegate = null;
85+
base.Dispose(disposing);
86+
}
87+
#endif
7888
}
7989

8090
public class EtoPanel : NSPanel, IMacControl
@@ -147,6 +157,16 @@ public override void RecalculateKeyViewLoop()
147157
NSView last = null;
148158
Handler?.RecalculateKeyViewLoop(ref last);
149159
}
160+
161+
#if MONOMAC
162+
protected override void Dispose(bool disposing)
163+
{
164+
// See HandleWillClose for details of this
165+
// This is needed in addition when a window is created but not ever shown.
166+
Delegate = null;
167+
base.Dispose(disposing);
168+
}
169+
#endif
150170
}
151171

152172
class EtoContentView : MacPanelView
@@ -313,7 +333,17 @@ static void HandleWillClose(object sender, EventArgs e)
313333
return;
314334
handler.IsClosing = true;
315335
if (ApplicationHandler.Instance.ShouldCloseForm(handler.Widget, true))
336+
{
316337
handler.Callback.OnClosed(handler.Widget, EventArgs.Empty);
338+
#if MONOMAC
339+
// AppKit still calls some delegate methods on the window after closing a form (e.g. WillReturnFieldEditor),
340+
// causing exceptions trying to recreate the delegate if it has been garbage collected.
341+
// This is because MonoMac doesn't use ref counting to determine when objects can be GC'd like MacOS.
342+
// We avoid this problem by clearing out the delegate after the window is disposed.
343+
// In Eto, we don't expect any events to be called after that point anyway.
344+
handler.Control.Delegate = null;
345+
#endif
346+
}
317347
handler.IsClosing = false;
318348
}
319349

@@ -411,6 +441,7 @@ public override void AttachEvent(string id)
411441
}
412442
}
413443
});
444+
HandleEvent(Window.LocationChangedEvent);
414445
}
415446
break;
416447
case Window.LocationChangedEvent:
@@ -483,8 +514,8 @@ static void HandleWillMove(object sender, EventArgs e)
483514
var newLocation = Point.Round(Mouse.Position - moveOffset);
484515
if (handler.oldLocation != newLocation)
485516
{
486-
handler.Callback.OnLocationChanged(handler.Widget, EventArgs.Empty);
487517
handler.oldLocation = newLocation;
518+
handler.Callback.OnLocationChanged(handler.Widget, EventArgs.Empty);
488519
}
489520
// check for mouse up event
490521

@@ -522,13 +553,9 @@ protected virtual void ConfigureWindow()
522553
Control.ShouldZoom = HandleShouldZoom;
523554
Control.WillMiniaturize += HandleWillMiniaturize;
524555
Control.WillResize = HandleWillResize;
556+
525557
#if MONOMAC
526-
// AppKit still calls some delegate methods on the window after closing a form (e.g. WillReturnFieldEditor),
527-
// causing exceptions trying to recreate the delegate if it has been garbage collected.
528-
// This is because MonoMac doesn't use ref counting to determine when objects can be GC'd like MacOS.
529-
// We avoid this problem by clearing out the delegate after the window is closed.
530-
// In Eto, we don't expect any events to be called after that point anyway.
531-
Widget.Closed += (sender, e) => Application.Instance.AsyncInvoke(() => Control.Delegate = null);
558+
HandleEvent(Window.ClosedEvent);
532559
#endif
533560
}
534561

0 commit comments

Comments
 (0)