From 144a5a9cf52d12dedd28aa873a371259b9ad7099 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sat, 6 Jun 2020 19:27:25 +0200 Subject: [PATCH] app/internal/window: [macOS] introduce serious cascading This time without arbitrary offsets and with support for multiple windows. Signed-off-by: Elias Naur --- app/internal/window/os_macos.go | 8 ++++++-- app/internal/window/os_macos.m | 9 ++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/internal/window/os_macos.go b/app/internal/window/os_macos.go index accfe298..644c3e5b 100644 --- a/app/internal/window/os_macos.go +++ b/app/internal/window/os_macos.go @@ -39,7 +39,7 @@ __attribute__ ((visibility ("hidden"))) CFTypeRef gio_readClipboard(void); __attribute__ ((visibility ("hidden"))) void gio_writeClipboard(unichar *chars, NSUInteger length); __attribute__ ((visibility ("hidden"))) void gio_setNeedsDisplay(CFTypeRef viewRef); __attribute__ ((visibility ("hidden"))) void gio_appTerminate(void); -__attribute__ ((visibility ("hidden"))) void gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat height); +__attribute__ ((visibility ("hidden"))) NSPoint gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat height, NSPoint topLeft); */ import "C" @@ -65,6 +65,10 @@ var viewFactory func() C.CFTypeRef // launched is closed when applicationDidFinishLaunching is called. var launched = make(chan struct{}) +// nextTopLeft is the offset to use for the next window's call to +// cascadeTopLeftFromPoint. +var nextTopLeft C.NSPoint + // mustView is like lookoupView, except that it panics // if the view isn't mapped. func mustView(view C.CFTypeRef) *window { @@ -331,7 +335,7 @@ func newWindow(win Callbacks, opts *Options) (*window, error) { height := cfg.Px(opts.Height) title := C.CString(opts.Title) defer C.free(unsafe.Pointer(title)) - C.gio_createWindow(view, title, C.CGFloat(width), C.CGFloat(height)) + nextTopLeft = C.gio_createWindow(view, title, C.CGFloat(width), C.CGFloat(height), nextTopLeft) w.w = win insertView(view, w) return w, nil diff --git a/app/internal/window/os_macos.m b/app/internal/window/os_macos.m index fc54eb6c..67ea8535 100644 --- a/app/internal/window/os_macos.m +++ b/app/internal/window/os_macos.m @@ -110,7 +110,7 @@ void gio_setDisplayLinkDisplay(CFTypeRef dl, uint64_t did) { CVDisplayLinkSetCurrentCGDisplay((CVDisplayLinkRef)dl, (CGDirectDisplayID)did); } -void gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat height) { +NSPoint gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat height, NSPoint topLeft) { @autoreleasepool { NSRect rect = NSMakeRect(0, 0, width, height); NSUInteger styleMask = NSTitledWindowMask | @@ -127,9 +127,16 @@ void gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width, CGFlo NSView *view = (__bridge NSView *)viewRef; [window setContentView:view]; [window makeFirstResponder:view]; + if (topLeft.x == 0 && topLeft.y == 0) { + // cascadeTopLeftFromPoint treats (0, 0) as a no-op, + // and just returns the offset we need for the first window. + topLeft = [window cascadeTopLeftFromPoint:topLeft]; + } + topLeft = [window cascadeTopLeftFromPoint:topLeft]; window.releasedWhenClosed = NO; window.delegate = globalWindowDel; [window makeKeyAndOrderFront:nil]; + return topLeft; } }