>From 5e2c7950c404de6be42f257adf927d71ca59507d Mon Sep 17 00:00:00 2001 From: Alan Third Date: Thu, 6 Jul 2017 23:10:49 +0100 Subject: [PATCH] Use a run-time check for macOS Sierra tabbing support * configure.ac: Add --enable-macos-runtime-feature-detection flag. * src/nsterm.h (NSWindowTabbingMode): Define in pre-Sierra macOS. (MACOS_MIN_VERSION, MACOS_MAX_VERSION): Add new defines for version detection. * src/nsterm.m (colorForEmacsRed): (colorUsingDefaultColorSpace): (runAlertPanel): (firstRectForCharacterRange): (initFrameFromEmacs): (windowDidEnterFullScreen): (toggleFullScreen): (constrainFrameRect): (scrollerWidth): Switch from compile-time to run-time checks. --- configure.ac | 6 ++++ src/nsterm.h | 16 ++++++++- src/nsterm.m | 113 ++++++++++++++++++++++++++++++++++++----------------------- 3 files changed, 91 insertions(+), 44 deletions(-) diff --git a/configure.ac b/configure.ac index 5e6dbda2b6..09ce9a851a 100644 --- a/configure.ac +++ b/configure.ac @@ -426,6 +426,12 @@ AC_DEFUN EN_NS_SELF_CONTAINED=$enableval, EN_NS_SELF_CONTAINED=yes) +AC_ARG_ENABLE(macos-runtime-feature-detection, +[AS_HELP_STRING([--enable-macos-runtime-feature-detection], + [bypass compiler checks of macOS versions])], + AC_DEFINE(NS_RUNTIME_CHECKS, 1, + [Perform runtime checks of macOS features.])) + locallisppathset=no AC_ARG_ENABLE(locallisppath, [AS_HELP_STRING([--enable-locallisppath=PATH], diff --git a/src/nsterm.h b/src/nsterm.h index 0f1b36db7b..9578591d9d 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -49,6 +49,13 @@ along with GNU Emacs. If not, see . */ #endif /* NS_IMPL_COCOA */ +#define MACOS_MIN_VERSION(min) (defined (NS_IMPL_COCOA) \ + && (MAC_OS_X_VERSION_MAX_ALLOWED >= min \ + || defined (NS_RUNTIME_CHECKS))) +#define MACOS_MAX_VERSION(max) (defined (NS_IMPL_COCOA) \ + && (MAC_OS_X_VERSION_MAX_ALLOWED <= max \ + || defined (NS_RUNTIME_CHECKS))) + #ifdef __OBJC__ /* CGFloat on GNUstep may be 4 or 8 byte, but functions expect float* for some @@ -1317,6 +1324,13 @@ extern char gnustep_base_version[]; /* version tracking */ #ifdef __OBJC__ typedef NSUInteger NSWindowStyleMask; #endif -#endif +/* Window tabbing mode enums are new too. */ +enum NSWindowTabbingMode + { + NSWindowTabbingModeAutomatic, + NSWindowTabbingModePreferred, + NSWindowTabbingModeDisallowed + }; +#endif #endif /* HAVE_NS */ diff --git a/src/nsterm.m b/src/nsterm.m index a3c7031331..e57493afd4 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -136,15 +136,15 @@ @implementation NSColor (EmacsColor) + (NSColor *)colorForEmacsRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { -#ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - if (ns_use_srgb_colorspace) +#if MACOS_MIN_VERSION (MAC_OS_X_VERSION_10_7) + if (ns_use_srgb_colorspace + && [NSColor respondsToSelector: + @selector(colorWithSRGBRed:green:blue:alpha:)]) return [NSColor colorWithSRGBRed: red green: green blue: blue alpha: alpha]; #endif -#endif return [NSColor colorWithCalibratedRed: red green: green blue: blue @@ -153,12 +153,15 @@ + (NSColor *)colorForEmacsRed:(CGFloat)red green:(CGFloat)green - (NSColor *)colorUsingDefaultColorSpace { -#ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - if (ns_use_srgb_colorspace) +#if MACOS_MIN_VERSION (MAC_OS_X_VERSION_10_7) + /* FIXMES: We're checking for colorWithSRGBRed here so this will + only work in the same place as in the method above. It should + really be a check whether we're on macOS 10.7 or above. */ + if (ns_use_srgb_colorspace + && [NSColor respondsToSelector: + @selector(colorWithSRGBRed:green:blue:alpha:)]) return [self colorUsingColorSpace: [NSColorSpace sRGBColorSpace]]; #endif -#endif return [self colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; } @@ -5550,8 +5553,7 @@ - (void) terminate: (id)sender NSString *defaultButton, NSString *alternateButton) { -#if !defined (NS_IMPL_COCOA) || \ - MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_9 +#ifdef NS_IMPL_GNUSTEP return NSRunAlertPanel(title, msgFormat, defaultButton, alternateButton, nil) == NSAlertDefaultReturn; #else @@ -6312,14 +6314,28 @@ - (NSRect)firstRectForCharacterRange: (NSRange)theRange +FRAME_LINE_HEIGHT (emacsframe)); pt = [self convertPoint: pt toView: nil]; -#if !defined (NS_IMPL_COCOA) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 - pt = [[self window] convertBaseToScreen: pt]; - rect.origin = pt; -#else - rect.origin = pt; - rect = [[self window] convertRectToScreen: rect]; + +#ifdef NS_RUNTIME_CHECKS + if ([[self window] respondsToSelector: @selector(convertRectToScreen:)]) + { +#endif +#if MACOS_MIN_VERSION (MAC_OS_X_VERSION_10_7) + rect.origin = pt; + rect = [[self window] convertRectToScreen: rect]; +#endif +#ifdef NS_RUNTIME_CHECKS + } + else + { +#endif +#if MACOS_MAX_VERSION (MAC_OS_X_VERSION_10_6) || defined (NS_IMPL_GNUSTEP) + pt = [[self window] convertBaseToScreen: pt]; + rect.origin = pt; +#endif +#ifdef NS_RUNTIME_CHECKS + } #endif + return rect; } @@ -7019,9 +7035,9 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f [win setAcceptsMouseMovedEvents: YES]; [win setDelegate: self]; -#if !defined (NS_IMPL_COCOA) || \ - MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_9 - [win useOptimizedDrawing: YES]; +#if !defined (NS_IMPL_COCOA) || MACOS_MAX_VERSION (MAC_OS_X_VERSION_10_9) + if ([win respondsToSelector: @selector(useOptimizedDrawing:)]) + [win useOptimizedDrawing: YES]; #endif [[win contentView] addSubview: self]; @@ -7081,19 +7097,19 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f if ([col alphaComponent] != (EmacsCGFloat) 1.0) [win setOpaque: NO]; -#if !defined (NS_IMPL_COCOA) || \ - MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_9 - [self allocateGState]; +#if !defined (NS_IMPL_COCOA) || MACOS_MAX_VERSION (MAC_OS_X_VERSION_10_9) + if ([self respondsToSelector: @selector(allocateGState)]) + [self allocateGState]; #endif [NSApp registerServicesMenuSendTypes: ns_send_types returnTypes: [NSArray array]]; +#if MACOS_MIN_VERSION (MAC_OS_X_VERSION_10_12) /* macOS Sierra automatically enables tabbed windows. We can't allow this to be enabled until it's available on a Free system. Currently it only happens by accident and is buggy anyway. */ -#if defined (NS_IMPL_COCOA) && \ - MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12 - [win setTabbingMode: NSWindowTabbingModeDisallowed]; + if ([win respondsToSelector: @selector(setTabbingMode:)]) + [win setTabbingMode: NSWindowTabbingModeDisallowed]; #endif ns_window_num++; @@ -7349,7 +7365,11 @@ - (void)windowDidEnterFullScreen /* provided for direct calls */ { BOOL tbar_visible = FRAME_EXTERNAL_TOOL_BAR (emacsframe) ? YES : NO; #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_6 + /* These two values are only defined in 10.7 and above. */ + int NSApplicationPresentationFullScreen = (1 << 10); + int NSApplicationPresentationAutoHideToolbar = (1 << 11); +#endif unsigned val = (unsigned)[NSApp presentationOptions]; // Mac OS X 10.7 bug fix, the menu won't appear without this. @@ -7365,7 +7385,6 @@ - (void)windowDidEnterFullScreen /* provided for direct calls */ [NSApp setPresentationOptions: options]; } #endif -#endif [toolbar setVisible:tbar_visible]; } } @@ -7499,10 +7518,10 @@ - (void)toggleFullScreen: (id)sender { NSScreen *screen = [w screen]; -#if defined (NS_IMPL_COCOA) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 +#if MACOS_MIN_VERSION (MAC_OS_X_VERSION_10_9) /* Hide ghost menu bar on secondary monitor? */ - if (! onFirstScreen) + if (! onFirstScreen + && [NSScreen respondsToSelector: @selector(screensHaveSeparateSpaces)]) onFirstScreen = [NSScreen screensHaveSeparateSpaces]; #endif /* Hide dock and menubar if we are on the primary screen. */ @@ -7530,9 +7549,9 @@ - (void)toggleFullScreen: (id)sender [fw setTitle:[w title]]; [fw setDelegate:self]; [fw setAcceptsMouseMovedEvents: YES]; -#if !defined (NS_IMPL_COCOA) || \ - MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_9 - [fw useOptimizedDrawing: YES]; +#if !defined (NS_IMPL_COCOA) || MACOS_MAX_VERSION (MAC_OS_X_VERSION_10_9) + if ([fw respondsToSelector: @selector(useOptimizedDrawing:)]) + [fw useOptimizedDrawing: YES]; #endif [fw setBackgroundColor: col]; if ([col alphaComponent] != (EmacsCGFloat) 1.0) @@ -8093,10 +8112,11 @@ - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen NSTRACE_ARG_RECT (frameRect)); #ifdef NS_IMPL_COCOA -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 +#if MACOS_MIN_VERSION (MAC_OS_X_VERSION_10_9) // If separate spaces is on, it is like each screen is independent. There is // no spanning of frames across screens. - if ([NSScreen screensHaveSeparateSpaces]) + if ([NSScreen respondsToSelector: @selector(screensHaveSeparateSpaces)] + && [NSScreen screensHaveSeparateSpaces]) { NSTRACE_MSG ("Screens have separate spaces"); frameRect = [super constrainFrameRect:frameRect toScreen:screen]; @@ -8104,7 +8124,7 @@ - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen return frameRect; } else -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 */ +#endif /* MACOS_MIN_VERSION (MAC_OS_X_VERSION_10_9) */ // Check that the proposed frameRect is visible in at least one // screen. If it is not, ask the system to reposition it (only // for non-child windows). @@ -8310,12 +8330,19 @@ + (CGFloat) scrollerWidth /* TODO: if we want to allow variable widths, this is the place to do it, however neither GNUstep nor Cocoa support it very well */ CGFloat r; -#if !defined (NS_IMPL_COCOA) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 - r = [NSScroller scrollerWidth]; -#else - r = [NSScroller scrollerWidthForControlSize: NSControlSizeRegular - scrollerStyle: NSScrollerStyleLegacy]; +#ifdef NS_RUNTIME_CHECKS + if ([NSScroller respondsToSelector: + @selector(scrollerWidthForControlSize:scrollerStyle:)]) +#endif +#if MACOS_MIN_VERSION (MAC_OS_X_VERSION_10_7) + r = [NSScroller scrollerWidthForControlSize: NSControlSizeRegular + scrollerStyle: NSScrollerStyleLegacy]; +#endif +#ifdef NS_RUNTIME_CHECKS + else +#endif +#if MACOS_MAX_VERSION (MAC_OS_X_VERSION_10_6) + r = [NSScroller scrollerWidth]; #endif return r; } -- 2.12.0