>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