unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Alan Third <alan@idiocy.org>
To: Anders Lindgren <andlind@gmail.com>
Cc: Paul Michael Reilly <pmr@pajato.com>,
	Jean-Christophe Helary <jean.christophe.helary@gmail.com>,
	"Charles A. Roelli" <charles@aurox.ch>,
	Emacs-Devel devel <emacs-devel@gnu.org>
Subject: NS runtime feature detection (was: Mac OS Sierra tab feature breaks C-x 5 2)
Date: Sun, 23 Jul 2017 13:17:01 +0100	[thread overview]
Message-ID: <20170723121701.GA3730@breton.holly.idiocy.org> (raw)
In-Reply-To: <20170722112230.GA58424@breton.holly.idiocy.org>

[-- Attachment #1: Type: text/plain, Size: 728 bytes --]

On Sat, Jul 22, 2017 at 12:22:30PM +0100, Alan Third wrote:
> Or perhaps we provide a flag that enables a universal binary build
> that doesn’t bother about hiding the warnings?

Attached is a first attempt at this in nsterm.m. I think I’ve got
everything, but there may be some new variables and things defined
that I’ve missed which will throw up errors in older macOS versions.

It seems ‘universal binary’ means something specific, so I went with a
different name.

Use:

    ./configure --with-ns --enable-macos-runtime-feature-detection

It will give a lot of deprecation and unknown method warnings, but
hopefully that’s all.

If you build normally there should be no (new) warnings or errors.
-- 
Alan Third

[-- Attachment #2: 0001-Use-a-run-time-check-for-macOS-Sierra-tabbing-suppor.patch --]
[-- Type: text/plain, Size: 11489 bytes --]

From 5e2c7950c404de6be42f257adf927d71ca59507d Mon Sep 17 00:00:00 2001
From: Alan Third <alan@idiocy.org>
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 <http://www.gnu.org/licenses/>.  */
 
 #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


  reply	other threads:[~2017-07-23 12:17 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-06 11:29 Mac OS Sierra tab feature breaks C-x 5 2 Paul Michael Reilly
2017-07-06 12:14 ` Jean-Christophe Helary
2017-07-06 12:46   ` Sebastian Christ
2017-07-06 12:53 ` Alan Third
2017-07-06 14:35   ` Alan Third
2017-07-06 15:05     ` Jean-Christophe Helary
2017-07-06 17:42       ` Alan Third
2017-07-06 22:16         ` Alan Third
2017-07-10 19:17           ` Anders Lindgren
2017-07-10 19:52             ` Alan Third
2017-07-10 20:22               ` Anders Lindgren
2017-07-12 18:23                 ` Alan Third
2017-07-12 21:20                   ` Anders Lindgren
2017-07-13 20:22                     ` Alan Third
2017-07-16 18:43                       ` Anders Lindgren
2017-07-16 23:01                         ` Alan Third
2017-07-17 20:09                           ` Charles A. Roelli
2017-07-18  6:06                             ` Anders Lindgren
2017-07-18 18:33                               ` Charles A. Roelli
2017-07-18 22:16                                 ` Alan Third
2017-07-19  4:57                                   ` Charles A. Roelli
2017-07-21 20:31                                     ` Anders Lindgren
2017-07-22 11:22                                       ` Alan Third
2017-07-23 12:17                                         ` Alan Third [this message]
2017-07-24 19:02                                           ` NS runtime feature detection Charles A. Roelli
2017-07-24 20:45                                             ` Alan Third
2017-07-23 22:35                                         ` Mac OS Sierra tab feature breaks C-x 5 2 Tim Cross

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170723121701.GA3730@breton.holly.idiocy.org \
    --to=alan@idiocy.org \
    --cc=andlind@gmail.com \
    --cc=charles@aurox.ch \
    --cc=emacs-devel@gnu.org \
    --cc=jean.christophe.helary@gmail.com \
    --cc=pmr@pajato.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).