@@ 186,6 186,11 @@ static CFTypeRef layerForView(CFTypeRef viewRef) {
return (__bridge CFTypeRef)view.layer;
}
+static CFTypeRef windowForView(CFTypeRef viewRef) {
+ NSView *view = (__bridge NSView *)viewRef;
+ return (__bridge CFTypeRef)view.window;
+}
+
static void raiseWindow(CFTypeRef windowRef) {
NSWindow* window = (__bridge NSWindow *)windowRef;
[window makeKeyAndOrderFront:nil];
@@ 237,7 242,6 @@ type ViewEvent struct {
type window struct {
view C.CFTypeRef
- window C.CFTypeRef
w *callbacks
stage system.Stage
displayLink *displayLink
@@ 305,7 309,7 @@ func (w *window) WriteClipboard(s string) {
}
func (w *window) updateWindowMode() {
- style := int(C.getWindowStyleMask(w.window))
+ style := int(C.getWindowStyleMask(C.windowForView(w.view)))
if style&C.NSWindowStyleMaskFullScreen != 0 {
w.config.Mode = Fullscreen
} else {
@@ 321,70 325,71 @@ func (w *window) Configure(options []Option) {
w.updateWindowMode()
cnf := w.config
cnf.apply(cfg, options)
+ window := C.windowForView(w.view)
switch cnf.Mode {
case Fullscreen:
switch prev.Mode {
case Fullscreen:
case Minimized:
- C.unhideWindow(w.window)
+ C.unhideWindow(window)
fallthrough
default:
w.config.Mode = Fullscreen
- C.toggleFullScreen(w.window)
+ C.toggleFullScreen(window)
}
case Minimized:
switch prev.Mode {
case Minimized, Fullscreen:
default:
w.config.Mode = Minimized
- C.hideWindow(w.window)
+ C.hideWindow(window)
}
case Maximized:
switch prev.Mode {
case Fullscreen:
case Minimized:
- C.unhideWindow(w.window)
+ C.unhideWindow(window)
fallthrough
default:
w.config.Mode = Maximized
w.setTitle(prev, cnf)
- if C.isWindowZoomed(w.window) == 0 {
- C.zoomWindow(w.window)
+ if C.isWindowZoomed(window) == 0 {
+ C.zoomWindow(window)
}
}
case Windowed:
switch prev.Mode {
case Fullscreen:
- C.toggleFullScreen(w.window)
+ C.toggleFullScreen(window)
case Minimized:
- C.unhideWindow(w.window)
+ C.unhideWindow(window)
case Maximized:
}
w.config.Mode = Windowed
- if C.isWindowZoomed(w.window) != 0 {
- C.zoomWindow(w.window)
+ if C.isWindowZoomed(window) != 0 {
+ C.zoomWindow(window)
}
w.setTitle(prev, cnf)
if prev.Size != cnf.Size {
w.config.Size = cnf.Size
cnf.Size = cnf.Size.Div(int(screenScale))
- C.setSize(w.window, C.CGFloat(cnf.Size.X), C.CGFloat(cnf.Size.Y))
+ C.setSize(window, C.CGFloat(cnf.Size.X), C.CGFloat(cnf.Size.Y))
}
if prev.MinSize != cnf.MinSize {
w.config.MinSize = cnf.MinSize
cnf.MinSize = cnf.MinSize.Div(int(screenScale))
- C.setMinSize(w.window, C.CGFloat(cnf.MinSize.X), C.CGFloat(cnf.MinSize.Y))
+ C.setMinSize(window, C.CGFloat(cnf.MinSize.X), C.CGFloat(cnf.MinSize.Y))
}
if prev.MaxSize != cnf.MaxSize {
w.config.MaxSize = cnf.MaxSize
cnf.MaxSize = cnf.MaxSize.Div(int(screenScale))
- C.setMaxSize(w.window, C.CGFloat(cnf.MaxSize.X), C.CGFloat(cnf.MaxSize.Y))
+ C.setMaxSize(window, C.CGFloat(cnf.MaxSize.X), C.CGFloat(cnf.MaxSize.Y))
}
}
if cnf.Decorated != prev.Decorated {
w.config.Decorated = cnf.Decorated
- mask := C.getWindowStyleMask(w.window)
+ mask := C.getWindowStyleMask(window)
style := C.NSWindowStyleMask(C.NSWindowStyleMaskTitled | C.NSWindowStyleMaskResizable | C.NSWindowStyleMaskMiniaturizable | C.NSWindowStyleMaskClosable)
style = C.NSWindowStyleMaskFullSizeContentView
mask &^= style
@@ 395,12 400,12 @@ func (w *window) Configure(options []Option) {
barTrans = C.YES
titleVis = C.NSWindowTitleHidden
}
- C.setWindowTitlebarAppearsTransparent(w.window, barTrans)
- C.setWindowTitleVisibility(w.window, titleVis)
- C.setWindowStyleMask(w.window, mask)
- C.setWindowStandardButtonHidden(w.window, C.NSWindowCloseButton, barTrans)
- C.setWindowStandardButtonHidden(w.window, C.NSWindowMiniaturizeButton, barTrans)
- C.setWindowStandardButtonHidden(w.window, C.NSWindowZoomButton, barTrans)
+ C.setWindowTitlebarAppearsTransparent(window, barTrans)
+ C.setWindowTitleVisibility(window, titleVis)
+ C.setWindowStyleMask(window, mask)
+ C.setWindowStandardButtonHidden(window, C.NSWindowCloseButton, barTrans)
+ C.setWindowStandardButtonHidden(window, C.NSWindowMiniaturizeButton, barTrans)
+ C.setWindowStandardButtonHidden(window, C.NSWindowZoomButton, barTrans)
}
w.w.Event(ConfigEvent{Config: w.config})
}
@@ 410,25 415,26 @@ func (w *window) setTitle(prev, cnf Config) {
w.config.Title = cnf.Title
title := stringToNSString(cnf.Title)
defer C.CFRelease(title)
- C.setTitle(w.window, title)
+ C.setTitle(C.windowForView(w.view), title)
}
}
func (w *window) Perform(acts system.Action) {
+ window := C.windowForView(w.view)
walkActions(acts, func(a system.Action) {
switch a {
case system.ActionCenter:
- r := C.getScreenFrame(w.window) // the screen size of the window
+ r := C.getScreenFrame(window) // the screen size of the window
sz := w.config.Size
x := (int(r.size.width) - sz.X) / 2
y := (int(r.size.height) - sz.Y) / 2
- C.setScreenFrame(w.window, C.CGFloat(x), C.CGFloat(y), C.CGFloat(sz.X), C.CGFloat(sz.Y))
+ C.setScreenFrame(window, C.CGFloat(x), C.CGFloat(y), C.CGFloat(sz.X), C.CGFloat(sz.Y))
case system.ActionRaise:
- C.raiseWindow(w.window)
+ C.raiseWindow(window)
}
})
if acts&system.ActionClose != 0 {
- C.closeWindow(w.window)
+ C.closeWindow(window)
}
}
@@ 531,7 537,7 @@ func gio_onMouse(view, evt C.CFTypeRef, cdir C.int, cbtn C.NSInteger, x, y, dx,
if ok && w.config.Mode != Fullscreen {
switch act {
case system.ActionMove:
- C.performWindowDragWithEvent(w.window, evt)
+ C.performWindowDragWithEvent(C.windowForView(w.view), evt)
return
}
}
@@ 781,14 787,12 @@ func configFor(scale float32) unit.Metric {
//export gio_onClose
func gio_onClose(view C.CFTypeRef) {
w := mustView(view)
+ w.displayLink.Close()
w.w.Event(ViewEvent{})
deleteView(view)
w.w.Event(system.DestroyEvent{})
- w.displayLink.Close()
C.CFRelease(w.view)
- C.CFRelease(w.window)
w.view = 0
- w.window = 0
w.displayLink = nil
}
@@ 848,17 852,18 @@ func newWindow(win *callbacks, options []Option) error {
}
errch <- nil
w.w = win
- w.window = C.gio_createWindow(w.view, 0, 0, 0, 0, 0, 0)
+ window := C.gio_createWindow(w.view, 0, 0, 0, 0, 0, 0)
w.updateWindowMode()
win.SetDriver(w)
w.Configure(options)
if nextTopLeft.x == 0 && nextTopLeft.y == 0 {
// cascadeTopLeftFromPoint treats (0, 0) as a no-op,
// and just returns the offset we need for the first window.
- nextTopLeft = C.cascadeTopLeftFromPoint(w.window, nextTopLeft)
+ nextTopLeft = C.cascadeTopLeftFromPoint(window, nextTopLeft)
}
- nextTopLeft = C.cascadeTopLeftFromPoint(w.window, nextTopLeft)
- C.makeKeyAndOrderFront(w.window)
+ nextTopLeft = C.cascadeTopLeftFromPoint(window, nextTopLeft)
+ // makeKeyAndOrderFront assumes ownership of our window reference.
+ C.makeKeyAndOrderFront(window)
layer := C.layerForView(w.view)
w.w.Event(ViewEvent{View: uintptr(w.view), Layer: uintptr(layer)})
})
@@ 45,11 45,6 @@ __attribute__ ((visibility ("hidden"))) CALayer *gio_layerFactory(void);
NSWindow *window = (NSWindow *)[notification object];
gio_onFocus((__bridge CFTypeRef)window.contentView, 0);
}
-- (void)windowWillClose:(NSNotification *)notification {
- NSWindow *window = (NSWindow *)[notification object];
- window.delegate = nil;
- gio_onClose((__bridge CFTypeRef)window.contentView);
-}
@end
static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFloat dy) {
@@ 86,6 81,11 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFlo
layer.delegate = self;
return layer;
}
+- (void)viewDidMoveToWindow {
+ if (self.window == nil) {
+ gio_onClose((__bridge CFTypeRef)self);
+ }
+}
- (void)mouseDown:(NSEvent *)event {
handleMouse(self, event, MOUSE_DOWN, 0, 0);
}
@@ 357,7 357,6 @@ CFTypeRef gio_createWindow(CFTypeRef viewRef, CGFloat width, CGFloat height, CGF
NSView *view = (__bridge NSView *)viewRef;
[window setContentView:view];
[window makeFirstResponder:view];
- window.releasedWhenClosed = NO;
window.delegate = globalWindowDel;
return (__bridge_retained CFTypeRef)window;
}