From 14a6bf03d44e9d2d0d1caacbfb477f2bad8862f9 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Thu, 8 Aug 2013 15:58:50 +0000 Subject: [PATCH] Mac: Support retina display when building with the 10.6 SDK (issue #1038). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1355 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- include/cef_application_mac.h | 63 +++++++++++++++++++ tests/cefclient/cefclient_osr_widget_mac.mm | 67 +++++++++++---------- 2 files changed, 97 insertions(+), 33 deletions(-) diff --git a/include/cef_application_mac.h b/include/cef_application_mac.h index f26ce17d7..b4e85db22 100644 --- a/include/cef_application_mac.h +++ b/include/cef_application_mac.h @@ -49,6 +49,9 @@ // Use the existing empty protocol definitions. #import "base/mac/cocoa_protocols.h" +// Use the existing empty protocol definitions. +#import "base/mac/sdk_forward_declarations.h" + #else // BUILDING_CEF_SHARED #import @@ -72,6 +75,43 @@ @interface UnderlayOpenGLHostingWindow : NSWindow @end +// Copy of definitions from base/mac/sdk_forward_declarations.h. +// Forward declarations for APIs that are part of the 10.7 SDK. This will allow +// using them when building with the 10.6 SDK. + +#if !defined(MAC_OS_X_VERSION_10_7) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + +enum { + NSEventPhaseNone = 0, // event not associated with a phase. + NSEventPhaseBegan = 0x1 << 0, + NSEventPhaseStationary = 0x1 << 1, + NSEventPhaseChanged = 0x1 << 2, + NSEventPhaseEnded = 0x1 << 3, + NSEventPhaseCancelled = 0x1 << 4, +}; +typedef NSUInteger NSEventPhase; + +@interface NSEvent (LionSDK) ++ (BOOL)isSwipeTrackingFromScrollEventsEnabled; + +- (NSEventPhase)phase; +- (CGFloat)scrollingDeltaX; +- (CGFloat)scrollingDeltaY; +- (BOOL)isDirectionInvertedFromDevice; +@end + +@interface NSScreen (LionSDK) +- (CGFloat)backingScaleFactor; +- (NSRect)convertRectToBacking:(NSRect)aRect; +@end + +@interface NSWindow (LionSDK) +- (CGFloat)backingScaleFactor; +@end + +#endif // MAC_OS_X_VERSION_10_7 + // The Mac OS X 10.6 SDK introduced new protocols used for delegates. These // protocol defintions were not present in earlier releases of the Mac OS X // SDK. In order to support building against the new SDK, which requires @@ -108,6 +148,29 @@ DEFINE_EMPTY_PROTOCOL(NSWindowDelegate) #endif // BUILDING_CEF_SHARED +// Forward declarations for APIs that are part of the 10.7 SDK. This will allow +// using them when building with the 10.6 SDK. + +#if !defined(MAC_OS_X_VERSION_10_7) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + +@interface NSView (NSOpenGLSurfaceResolutionLionAPI) +- (void)setWantsBestResolutionOpenGLSurface:(BOOL)flag; +@end + +@interface NSView (LionAPI) +- (NSSize)convertSizeToBacking:(NSSize)aSize; +- (NSRect)convertRectToBacking:(NSRect)aRect; +- (NSRect)convertRectFromBacking:(NSRect)aRect; +@end + +static NSString* const NSWindowDidChangeBackingPropertiesNotification = + @"NSWindowDidChangeBackingPropertiesNotification"; +static NSString* const NSBackingPropertyOldScaleFactorKey = + @"NSBackingPropertyOldScaleFactorKey"; + +#endif // MAC_OS_X_VERSION_10_7 + // All CEF client applications must subclass NSApplication and implement this // protocol. @protocol CefAppProtocol diff --git a/tests/cefclient/cefclient_osr_widget_mac.mm b/tests/cefclient/cefclient_osr_widget_mac.mm index 6f41caeb8..2f9e9fafd 100644 --- a/tests/cefclient/cefclient_osr_widget_mac.mm +++ b/tests/cefclient/cefclient_osr_widget_mac.mm @@ -3,10 +3,12 @@ // that can be found in the LICENSE file. #import +#import #include #include "cefclient/cefclient_osr_widget_mac.h" +#include "include/cef_application_mac.h" #include "include/cef_browser.h" #include "include/cef_client.h" #include "cefclient/cefclient.h" @@ -14,6 +16,29 @@ #include "cefclient/resource_util.h" #include "cefclient/util.h" +// This method will return YES for OS X versions 10.7.3 and later, and NO +// otherwise. +// Used to prevent a crash when building with the 10.7 SDK and accessing the +// notification below. See: http://crbug.com/260595. +static BOOL SupportsBackingPropertiesChangedNotification() { + // windowDidChangeBackingProperties: method has been added to the + // NSWindowDelegate protocol in 10.7.3, at the same time as the + // NSWindowDidChangeBackingPropertiesNotification notification was added. + // If the protocol contains this method description, the notification should + // be supported as well. + Protocol* windowDelegateProtocol = NSProtocolFromString(@"NSWindowDelegate"); + struct objc_method_description methodDescription = + protocol_getMethodDescription( + windowDelegateProtocol, + @selector(windowDidChangeBackingProperties:), + NO, + YES); + + // If the protocol does not contain the method, the returned method + // description is {NULL, NULL} + return methodDescription.name != NULL || methodDescription.types != NULL; +} + @interface ClientOpenGLView () - (float)getDeviceScaleFactor; - (void)windowDidChangeBackingProperties:(NSNotification*)notification; @@ -58,29 +83,29 @@ ClientOSRHandler::ClientOSRHandler(ClientOpenGLView* view, [view_ retain]; view_->browser_provider_ = browser_provider; -#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - // Do not override the delegate; the mac client already does that - if ([view_ respondsToSelector:@selector(backingScaleFactor:)]) { + // Backing property notifications crash on 10.6 when building with the 10.7 + // SDK, see http://crbug.com/260595. + static BOOL supportsBackingPropertiesNotification = + SupportsBackingPropertiesChangedNotification(); + if (supportsBackingPropertiesNotification) { [[NSNotificationCenter defaultCenter] addObserver:view_ selector:@selector(windowDidChangeBackingProperties:) name:NSWindowDidChangeBackingPropertiesNotification object:[view_ window]]; } -#endif } ClientOSRHandler:: ~ClientOSRHandler() { -#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if ([view_ respondsToSelector:@selector(backingScaleFactor:)]) { + static BOOL supportsBackingPropertiesNotification = + SupportsBackingPropertiesChangedNotification(); + + if (supportsBackingPropertiesNotification) { [[NSNotificationCenter defaultCenter] removeObserver:view_ name:NSWindowDidChangeBackingPropertiesNotification object:[view_ window]]; } -#endif } void ClientOSRHandler::Disconnect() { @@ -283,13 +308,10 @@ void ClientOSRHandler::SetLoading(bool isLoading) { [self addTrackingArea:tracking_area_]; } -#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 if ([self respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { // enable HiDPI buffer [self setWantsBestResolutionOpenGLSurface:YES]; } -#endif return self; } @@ -469,8 +491,6 @@ void ClientOSRHandler::SetLoading(bool isLoading) { } - (void)shortCircuitScrollWheelEvent:(NSEvent*)event { -#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 // Phase is only supported in OS-X 10.7 and newer. if ([event phase] != NSEventPhaseEnded && [event phase] != NSEventPhaseCancelled) @@ -482,12 +502,9 @@ void ClientOSRHandler::SetLoading(bool isLoading) { [NSEvent removeMonitor:endWheelMonitor_]; endWheelMonitor_ = nil; } -#endif } - (void)scrollWheel:(NSEvent *)event { -#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 // Phase is only supported in OS-X 10.7 and newer. // Use an NSEvent monitor to listen for the wheel-end end. This ensures that // the event is received even when the mouse cursor is no longer over the @@ -504,7 +521,6 @@ void ClientOSRHandler::SetLoading(bool isLoading) { } [self sendScrollWheelEvet:event]; -#endif } - (void)sendScrollWheelEvet:(NSEvent *)event { @@ -758,8 +774,6 @@ void ClientOSRHandler::SetLoading(bool isLoading) { } - (void)windowDidChangeBackingProperties:(NSNotification*)notification { -#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 // This delegate method is only called on 10.7 and later, so don't worry about // other backing changes calling it on 10.6 or earlier CGFloat newBackingScaleFactor = [self getDeviceScaleFactor]; @@ -772,7 +786,6 @@ void ClientOSRHandler::SetLoading(bool isLoading) { browser->GetHost()->NotifyScreenInfoChanged(); } -#endif } - (void)drawRect: (NSRect) dirtyRect { @@ -798,12 +811,9 @@ void ClientOSRHandler::SetLoading(bool isLoading) { if (!window) return deviceScaleFactor; -#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 if ([window respondsToSelector:@selector(backingScaleFactor)]) deviceScaleFactor = [window backingScaleFactor]; else -#endif deviceScaleFactor = [window userSpaceScaleFactor]; return deviceScaleFactor; @@ -849,8 +859,6 @@ void ClientOSRHandler::SetLoading(bool isLoading) { *scaled_rects = rects; *scaled_size = size; -#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 if ([self getDeviceScaleFactor] != 1 && [self respondsToSelector:@selector(convertSizeToBacking:)] && [self respondsToSelector:@selector(convertRectToBacking:)]) { @@ -862,15 +870,12 @@ void ClientOSRHandler::SetLoading(bool isLoading) { *scaled_rects = scaled_dirty_rects; *scaled_size = [self convertSizeToBacking:size]; } -#endif } - (CefRect) convertRectToBackingInternal: (const CefRect&) rect { if ([self getDeviceScaleFactor] == 1) return rect; -#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 if ([self respondsToSelector:@selector(convertRectToBacking:)]) { NSRect old_rect = NSMakeRect(rect.x, rect.y, rect.width, rect.height); NSRect scaled_rect = [self convertRectToBacking:old_rect]; @@ -879,14 +884,11 @@ void ClientOSRHandler::SetLoading(bool isLoading) { (int)scaled_rect.size.width, (int)scaled_rect.size.height); } -#endif return rect; } - (CefRect) convertRectFromBackingInternal: (const CefRect&) rect { -#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 if ([self respondsToSelector:@selector(convertRectFromBacking:)]) { NSRect old_rect = NSMakeRect(rect.x, rect.y, rect.width, rect.height); NSRect scaled_rect = [self convertRectFromBacking:old_rect]; @@ -895,7 +897,6 @@ void ClientOSRHandler::SetLoading(bool isLoading) { (int)scaled_rect.size.width, (int)scaled_rect.size.height); } -#endif return rect; }