diff --git a/os/macosx/Info.plist.in b/os/macosx/Info.plist.in index 04d6ea6d33..359d28de8d 100644 --- a/os/macosx/Info.plist.in +++ b/os/macosx/Info.plist.in @@ -29,5 +29,7 @@ Copyright 2004-${CURRENT_YEAR} The OpenTTD team NSPrincipalClass NSApplication + NSHighResolutionCapable + True diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm index c1fb996dec..c21edc7acd 100644 --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -322,6 +322,11 @@ void VideoDriver_Cocoa::GameSizeChanged() BlitterFactory::GetCurrentBlitter()->PostResize(); ::GameSizeChanged(); + + /* We need to store the window size as non-Retina size in + * the config file to get same windows size on next start. */ + _cur_resolution.width = [ this->cocoaview frame ].size.width; + _cur_resolution.height = [ this->cocoaview frame ].size.height; } /** @@ -491,7 +496,7 @@ void VideoDriver_Cocoa::Draw(bool force_update) /* Normally drawRect will be automatically called by Mac OS X during next update cycle, * and then blitting will occur. If force_update is true, it will be done right now. */ - [ this->cocoaview setNeedsDisplayInRect:dirtyrect ]; + [ this->cocoaview setNeedsDisplayInRect:[ this->cocoaview getVirtualRect:dirtyrect ] ]; if (force_update) [ this->cocoaview displayIfNeeded ]; } @@ -530,7 +535,7 @@ void VideoDriver_Cocoa::AllocateBackingStore() { if (this->window == nil || this->cocoaview == nil || this->setup) return; - NSRect newframe = [ this->cocoaview frame ]; + NSRect newframe = [ this->cocoaview getRealRect:[ this->cocoaview frame ] ]; this->window_width = (int)newframe.size.width; this->window_height = (int)newframe.size.height; @@ -743,6 +748,13 @@ void VideoDriver_Cocoa::GameLoop() CGImageRelease(fullImage); } +- (void)viewDidChangeBackingProperties +{ + [ super viewDidChangeBackingProperties ]; + + self.layer.contentsScale = [ driver->cocoaview getContentsScale ]; +} + @end #endif /* WITH_COCOA */ diff --git a/src/video/cocoa/cocoa_wnd.h b/src/video/cocoa/cocoa_wnd.h index fa7036396c..55f0561b77 100644 --- a/src/video/cocoa/cocoa_wnd.h +++ b/src/video/cocoa/cocoa_wnd.h @@ -38,6 +38,9 @@ extern NSString *OTTDMainLaunchGameEngine; /** Subclass of NSView to support mouse awareness and text input. */ @interface OTTD_CocoaView : NSView +- (NSRect)getRealRect:(NSRect)rect; +- (NSRect)getVirtualRect:(NSRect)rect; +- (CGFloat)getContentsScale; - (NSPoint)mousePositionFromEvent:(NSEvent *)e; @end diff --git a/src/video/cocoa/cocoa_wnd.mm b/src/video/cocoa/cocoa_wnd.mm index 089bfe8344..cd194f7128 100644 --- a/src/video/cocoa/cocoa_wnd.mm +++ b/src/video/cocoa/cocoa_wnd.mm @@ -417,6 +417,30 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel float _current_magnification; NSUInteger _current_mods; bool _emulated_down; + bool _use_hidpi; +} + +- (instancetype)initWithFrame:(NSRect)frameRect +{ + if (self = [ super initWithFrame:frameRect ]) { + self->_use_hidpi = [ self respondsToSelector:@selector(convertRectToBacking:) ] && [ self respondsToSelector:@selector(convertRectFromBacking:) ]; + } + return self; +} + +- (NSRect)getRealRect:(NSRect)rect +{ + return _use_hidpi ? [ self convertRectToBacking:rect ] : rect; +} + +- (NSRect)getVirtualRect:(NSRect)rect +{ + return _use_hidpi ? [ self convertRectFromBacking:rect ] : rect; +} + +- (CGFloat)getContentsScale +{ + return _use_hidpi && self.window != nil ? [ self.window backingScaleFactor ] : 1.0f; } /** @@ -483,15 +507,13 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel if ([ e window ] == nil) pt = [ self.window convertRectFromScreen:NSMakeRect(pt.x, pt.y, 0, 0) ].origin; pt = [ self convertPoint:pt fromView:nil ]; - pt.y = self.bounds.size.height - pt.y; - - return pt; + return [ self getRealRect:NSMakeRect(pt.x, self.bounds.size.height - pt.y, 0, 0) ].origin; } - (void)internalMouseMoveEvent:(NSEvent *)event { if (_cursor.fix_at) { - _cursor.UpdateCursorPositionRelative(event.deltaX, event.deltaY); + _cursor.UpdateCursorPositionRelative(event.deltaX * self.getContentsScale, event.deltaY * self.getContentsScale); } else { NSPoint pt = [ self mousePositionFromEvent:event ]; _cursor.UpdateCursorPosition(pt.x, pt.y, false);