app/internal/window: [macOS] introduce serious cascading

This time without arbitrary offsets and with support for multiple
windows.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2020-06-06 19:27:25 +02:00
parent 4408c2a695
commit 144a5a9cf5
2 changed files with 14 additions and 3 deletions
+6 -2
View File
@@ -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_writeClipboard(unichar *chars, NSUInteger length);
__attribute__ ((visibility ("hidden"))) void gio_setNeedsDisplay(CFTypeRef viewRef); __attribute__ ((visibility ("hidden"))) void gio_setNeedsDisplay(CFTypeRef viewRef);
__attribute__ ((visibility ("hidden"))) void gio_appTerminate(void); __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" import "C"
@@ -65,6 +65,10 @@ var viewFactory func() C.CFTypeRef
// launched is closed when applicationDidFinishLaunching is called. // launched is closed when applicationDidFinishLaunching is called.
var launched = make(chan struct{}) 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 // mustView is like lookoupView, except that it panics
// if the view isn't mapped. // if the view isn't mapped.
func mustView(view C.CFTypeRef) *window { func mustView(view C.CFTypeRef) *window {
@@ -331,7 +335,7 @@ func newWindow(win Callbacks, opts *Options) (*window, error) {
height := cfg.Px(opts.Height) height := cfg.Px(opts.Height)
title := C.CString(opts.Title) title := C.CString(opts.Title)
defer C.free(unsafe.Pointer(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 w.w = win
insertView(view, w) insertView(view, w)
return w, nil return w, nil
+8 -1
View File
@@ -110,7 +110,7 @@ void gio_setDisplayLinkDisplay(CFTypeRef dl, uint64_t did) {
CVDisplayLinkSetCurrentCGDisplay((CVDisplayLinkRef)dl, (CGDirectDisplayID)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 { @autoreleasepool {
NSRect rect = NSMakeRect(0, 0, width, height); NSRect rect = NSMakeRect(0, 0, width, height);
NSUInteger styleMask = NSTitledWindowMask | NSUInteger styleMask = NSTitledWindowMask |
@@ -127,9 +127,16 @@ void gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width, CGFlo
NSView *view = (__bridge NSView *)viewRef; NSView *view = (__bridge NSView *)viewRef;
[window setContentView:view]; [window setContentView:view];
[window makeFirstResponder: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.releasedWhenClosed = NO;
window.delegate = globalWindowDel; window.delegate = globalWindowDel;
[window makeKeyAndOrderFront:nil]; [window makeKeyAndOrderFront:nil];
return topLeft;
} }
} }