Index: src/views/mac/SkNSView.mm |
=================================================================== |
--- src/views/mac/SkNSView.mm (revision 9805) |
+++ src/views/mac/SkNSView.mm (working copy) |
@@ -13,6 +13,9 @@ |
SK_COMPILE_ASSERT(SK_SUPPORT_GPU, not_implemented_for_non_gpu_build); |
//#define FORCE_REDRAW |
+// Can be dropped when we no longer support 10.6. |
+#define RETINA_API_AVAILABLE (defined(MAC_OS_X_VERSION_10_7) && \ |
+ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7) |
@implementation SkNSView |
@synthesize fWind, fTitle, fOptionsDelegate, fGLContext; |
@@ -33,15 +36,26 @@ |
} |
- (id)initWithDefaults { |
+#if RETINA_API_AVAILABLE |
+ [self setWantsBestResolutionOpenGLSurface:YES]; |
+#endif |
fRedrawRequestPending = false; |
fWind = NULL; |
return self; |
} |
- (void)setUpWindow { |
+ [[NSNotificationCenter defaultCenter] addObserver:self |
+ selector:@selector(backingPropertiesChanged:) |
+ name:@"NSWindowDidChangeBackingPropertiesNotification" |
+ object:[self window]]; |
if (NULL != fWind) { |
fWind->setVisibleP(true); |
- fWind->resize((int) self.frame.size.width, (int) self.frame.size.height, |
+ NSSize size = self.frame.size; |
+#if RETINA_API_AVAILABLE |
+ size = [self convertSizeToBacking:self.frame.size]; |
+#endif |
+ fWind->resize((int) size.width, (int) size.height, |
SkBitmap::kARGB_8888_Config); |
} |
} |
@@ -54,13 +68,49 @@ |
return YES; |
} |
+- (float)scaleFactor { |
+ NSWindow *window = [self window]; |
+#if RETINA_API_AVAILABLE |
+ if (window) { |
+ return [window backingScaleFactor]; |
+ } |
+ return [[NSScreen mainScreen] backingScaleFactor]; |
+#else |
+ if (window) { |
+ return [window userSpaceScaleFactor]; |
+ } |
+ return [[NSScreen mainScreen] userSpaceScaleFactor]; |
+#endif |
+} |
+ |
+- (void)backingPropertiesChanged:(NSNotification *)notification { |
+ CGFloat oldBackingScaleFactor = [ |
+ [notification.userInfo objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue |
+ ]; |
+ CGFloat newBackingScaleFactor = [self scaleFactor]; |
+ if (oldBackingScaleFactor == newBackingScaleFactor) { |
+ return; |
+ } |
+ |
+ // TODO: need a better way to force a refresh (that works). |
+ // [fGLContext update] does not appear to update if the point size has not changed, |
+ // even if the backing size has changed. |
+ [self setFrameSize:NSMakeSize(self.frame.size.width + 1, self.frame.size.height + 1)]; |
+} |
+ |
- (void)resizeSkView:(NSSize)newSize { |
- if (NULL != fWind && (fWind->width() != newSize.width || fWind->height() != newSize.height)) { |
+#if RETINA_API_AVAILABLE |
+ newSize = [self convertSizeToBacking:newSize]; |
+#endif |
+ if (NULL != fWind && |
+ (fWind->width() != newSize.width || |
+ fWind->height() != newSize.height)) |
+ { |
fWind->resize((int) newSize.width, (int) newSize.height); |
if (NULL != fGLContext) { |
glClear(GL_STENCIL_BUFFER_BIT); |
+ [fGLContext update]; |
} |
- [fGLContext update]; |
} |
} |
@@ -219,6 +269,10 @@ |
if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
NSPoint loc = [self convertPoint:p fromView:nil]; |
+#if RETINA_API_AVAILABLE |
+ loc = [self convertPointToBacking:loc]; //y-up |
+ loc.y = -loc.y; |
+#endif |
fWind->handleClick((int) loc.x, (int) loc.y, |
SkView::Click::kDown_State, self, modi); |
} |
@@ -230,6 +284,10 @@ |
if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
NSPoint loc = [self convertPoint:p fromView:nil]; |
+#if RETINA_API_AVAILABLE |
+ loc = [self convertPointToBacking:loc]; //y-up |
+ loc.y = -loc.y; |
+#endif |
fWind->handleClick((int) loc.x, (int) loc.y, |
SkView::Click::kMoved_State, self, modi); |
} |
@@ -241,6 +299,10 @@ |
if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
NSPoint loc = [self convertPoint:p fromView:nil]; |
+#if RETINA_API_AVAILABLE |
+ loc = [self convertPointToBacking:loc]; //y-up |
+ loc.y = -loc.y; |
+#endif |
fWind->handleClick((int) loc.x, (int) loc.y, |
SkView::Click::kMoved_State, self, modi); |
} |
@@ -252,6 +314,10 @@ |
if ([self mouse:p inRect:[self bounds]] && NULL != fWind) { |
NSPoint loc = [self convertPoint:p fromView:nil]; |
+#if RETINA_API_AVAILABLE |
+ loc = [self convertPointToBacking:loc]; //y-up |
+ loc.y = -loc.y; |
+#endif |
fWind->handleClick((int) loc.x, (int) loc.y, |
SkView::Click::kUp_State, self, modi); |
} |
@@ -329,7 +395,11 @@ |
CGLPixelFormatObj format = CGLGetPixelFormat((CGLContextObj)[fGLContext CGLContextObj]); |
CGLDescribePixelFormat(format, 0, kCGLPFASamples, &info->fSampleCount); |
CGLDescribePixelFormat(format, 0, kCGLPFAStencilSize, &info->fStencilBits); |
- glViewport(0, 0, (int) self.bounds.size.width, (int) self.bounds.size.width); |
+ NSSize size = self.bounds.size; |
+#if RETINA_API_AVAILABLE |
+ size = [self convertSizeToBacking:size]; |
+#endif |
+ glViewport(0, 0, (int) size.width, (int) size.height); |
glClearColor(0, 0, 0, 0); |
glClearStencil(0); |
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |