app: [macOS] send ViewEvents when the NSView is attached to a NSWindow

Instead of sending ViewEvents once at construction and once at destruction,
it's better to send them when the underlying NSView changes attachment.

The main advantage is that we're about to move the destruction and
emitting of DestroyEvent to the NSView's dealloc method. However, the
dealloc will not be called if user code has a strong reference to it
through a non-empty ViewEvent. By sending an empty ViewEvent when the
view is detached, well-behaving users will remove the strong reference.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2023-12-13 18:10:40 -06:00
parent caba422d9c
commit 1527e91a02
2 changed files with 13 additions and 4 deletions
+12 -4
View File
@@ -857,11 +857,21 @@ func configFor(scale float32) unit.Metric {
}
}
//export gio_onAttached
func gio_onAttached(h C.uintptr_t, attached C.int) {
w := windowFor(h)
if attached != 0 {
layer := C.layerForView(w.view)
w.ProcessEvent(ViewEvent{View: uintptr(w.view), Layer: uintptr(layer)})
} else {
w.ProcessEvent(ViewEvent{})
w.setStage(StagePaused)
}
}
//export gio_onClose
func gio_onClose(h C.uintptr_t) {
w := windowFor(h)
w.ProcessEvent(ViewEvent{})
w.setStage(StagePaused)
w.ProcessEvent(DestroyEvent{})
w.displayLink.Close()
w.displayLink = nil
@@ -927,8 +937,6 @@ func newWindow(win *callbacks, options []Option) {
nextTopLeft = C.cascadeTopLeftFromPoint(window, nextTopLeft)
// makeKeyAndOrderFront assumes ownership of our window reference.
C.makeKeyAndOrderFront(window)
layer := C.layerForView(w.view)
w.ProcessEvent(ViewEvent{View: uintptr(w.view), Layer: uintptr(layer)})
})
<-res
}
+1
View File
@@ -89,6 +89,7 @@ static void handleMouse(GioView *view, NSEvent *event, int typ, CGFloat dx, CGFl
return layer;
}
- (void)viewDidMoveToWindow {
gio_onAttached(self.handle, self.window != nil ? 1 : 0);
if (self.window == nil) {
gio_onClose(self.handle);
}