diff --git a/ui/app/gl_macos.m b/ui/app/gl_macos.m index fa317191..165188fe 100644 --- a/ui/app/gl_macos.m +++ b/ui/app/gl_macos.m @@ -13,7 +13,7 @@ static void handleMouse(NSView *view, NSEvent *event, int typ, CGFloat dx, CGFloat dy) { NSPoint p = [view convertPoint:[event locationInWindow] fromView:nil]; - CGFloat scale = view.layer.contentsScale; + CGFloat scale = view.window.backingScaleFactor; if (!event.hasPreciseScrollingDeltas) { // dx and dy are in rows and columns. dx *= 10; diff --git a/ui/app/os_macos.go b/ui/app/os_macos.go index 97666e8d..0aa4e2fd 100644 --- a/ui/app/os_macos.go +++ b/ui/app/os_macos.go @@ -33,6 +33,7 @@ type window struct { view C.CFTypeRef w *Window stage Stage + ppdp float32 } type viewCmd struct { @@ -183,11 +184,14 @@ func gio_onFocus(view C.CFTypeRef, focus C.BOOL) { } func (w *window) draw(sync bool) { - width, height := int(C.gio_viewWidth(w.view)+.5), int(C.gio_viewHeight(w.view)+.5) - if width == 0 || height == 0 { + wf, hf := float32(C.gio_viewWidth(w.view)), float32(C.gio_viewHeight(w.view)) + if wf == 0 || hf == 0 { return } - cfg := getConfig() + scale := float32(C.gio_getViewBackingScale(w.view)) + width := int(wf*scale + .5) + height := int(hf*scale + .5) + cfg := configFor(w.ppdp, scale) cfg.now = time.Now() w.setStage(StageRunning) w.w.event(DrawEvent{ @@ -200,12 +204,17 @@ func (w *window) draw(sync bool) { }) } -func getConfig() Config { +func getPixelsPerDp(scale float32) float32 { ppdp := float32(C.gio_getPixelsPerDP()) - ppdp *= monitorScale + ppdp = ppdp * scale * monitorScale if ppdp < minDensity { ppdp = minDensity } + return ppdp / scale +} + +func configFor(ppdp, scale float32) Config { + ppdp = ppdp * scale return Config{ pxPerDp: ppdp, pxPerSp: ppdp, @@ -240,8 +249,10 @@ func gio_onShow(view C.CFTypeRef) { //export gio_onCreate func gio_onCreate(view C.CFTypeRef) { viewDo(view, func(views viewMap, view C.CFTypeRef) { + scale := float32(C.gio_getBackingScale()) w := &window{ view: view, + ppdp: getPixelsPerDp(scale), } wopts := <-mainWindow.out w.w = wopts.window @@ -262,10 +273,15 @@ func Main() { // TODO: return this error from CreateWindow. panic(errors.New("CreateWindow: failed to create view")) } - cfg := getConfig() + scale := float32(C.gio_getBackingScale()) + ppdp := getPixelsPerDp(scale) + cfg := configFor(ppdp, scale) opts := wopts.opts w := cfg.Px(opts.Width) h := cfg.Px(opts.Height) + // Window sizes is on screen coordinates, not device pixels. + w = int(float32(w) / scale) + h = int(float32(h) / scale) title := C.CString(opts.Title) defer C.free(unsafe.Pointer(title)) C.gio_main(view, title, C.CGFloat(w), C.CGFloat(h)) diff --git a/ui/app/os_macos.h b/ui/app/os_macos.h index 94a92316..0e17d34b 100644 --- a/ui/app/os_macos.h +++ b/ui/app/os_macos.h @@ -13,5 +13,7 @@ __attribute__ ((visibility ("hidden"))) CGFloat gio_viewHeight(CFTypeRef viewRef __attribute__ ((visibility ("hidden"))) void gio_setAnimating(CFTypeRef viewRef, BOOL anim); __attribute__ ((visibility ("hidden"))) void gio_updateDisplayLink(CFTypeRef viewRef, CGDirectDisplayID dispID); __attribute__ ((visibility ("hidden"))) CGFloat gio_getPixelsPerDP(void); +__attribute__ ((visibility ("hidden"))) CGFloat gio_getBackingScale(void); +__attribute__ ((visibility ("hidden"))) CGFloat gio_getViewBackingScale(CFTypeRef viewRef); #endif diff --git a/ui/app/os_macos.m b/ui/app/os_macos.m index 731814a8..f8751d23 100644 --- a/ui/app/os_macos.m +++ b/ui/app/os_macos.m @@ -13,8 +13,8 @@ @implementation GioDelegate - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - [[NSRunningApplication currentApplication] activateWithOptions:(NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps)]; - [self.window makeKeyAndOrderFront:self]; + [[NSRunningApplication currentApplication] activateWithOptions:(NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps)]; + [self.window makeKeyAndOrderFront:self]; gio_onShow((__bridge CFTypeRef)self.window.contentView); } - (void)applicationDidHide:(NSNotification *)aNotification { @@ -31,7 +31,8 @@ } - (void)windowDidChangeScreen:(NSNotification *)notification { CGDirectDisplayID dispID = [[[self.window screen] deviceDescription][@"NSScreenNumber"] unsignedIntValue]; - gio_updateDisplayLink((__bridge CFTypeRef)self.window.contentView, dispID); + CFTypeRef view = (__bridge CFTypeRef)self.window.contentView; + gio_updateDisplayLink(view, dispID); } - (void)windowDidBecomeKey:(NSNotification *)notification { gio_onFocus((__bridge CFTypeRef)self.window.contentView, YES); @@ -48,14 +49,12 @@ CGFloat gio_viewHeight(CFTypeRef viewRef) { NSView *view = (__bridge NSView *)viewRef; - NSRect bounds = [view convertRectToBacking:[view bounds]]; - return bounds.size.height; + return [view bounds].size.height; } CGFloat gio_viewWidth(CFTypeRef viewRef) { NSView *view = (__bridge NSView *)viewRef; - NSRect bounds = [view convertRectToBacking:[view bounds]]; - return bounds.size.width; + return [view bounds].size.width; } // Points pr. dp. @@ -68,8 +67,18 @@ static CGFloat getPointsPerDP(NSScreen *screen) { // Pixels pr dp. CGFloat gio_getPixelsPerDP(void) { - NSScreen *screen = [NSScreen mainScreen]; - return [screen backingScaleFactor] * getPointsPerDP(screen); + NSScreen *screen = [NSScreen mainScreen]; + return getPointsPerDP(screen); +} + +CGFloat gio_getBackingScale() { + NSScreen *screen = [NSScreen mainScreen]; + return [screen backingScaleFactor]; +} + +CGFloat gio_getViewBackingScale(CFTypeRef viewRef) { + NSView *view = (__bridge NSView *)viewRef; + return [view.window backingScaleFactor]; } void gio_main(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat height) { @@ -94,11 +103,6 @@ void gio_main(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat heigh [menuBar addItem:mainMenu]; [NSApp setMainMenu:menuBar]; - // Width and height are in pixels; convert to points - CGFloat scale = [[NSScreen mainScreen] backingScaleFactor]; - width /= scale; - height /= scale; - NSRect rect = NSMakeRect(0, 0, width, height); NSWindowStyleMask styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable |