From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Alan Third Newsgroups: gmane.emacs.devel 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 Message-ID: <20170723121701.GA3730@breton.holly.idiocy.org> References: <20170713202234.GA23777@breton.holly.idiocy.org> <20170716230109.GA54914@breton.holly.idiocy.org> <1ce59431-ff6b-dc89-31a6-8fc5bd4e3926@aurox.ch> <20170718221629.GA55506@breton.holly.idiocy.org> <20170722112230.GA58424@breton.holly.idiocy.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="DocE+STaALJfprDB" Content-Transfer-Encoding: 8bit X-Trace: blaine.gmane.org 1500812274 3119 195.159.176.226 (23 Jul 2017 12:17:54 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 23 Jul 2017 12:17:54 +0000 (UTC) User-Agent: Mutt/1.7.2 (2016-11-26) Cc: Paul Michael Reilly , Jean-Christophe Helary , "Charles A. Roelli" , Emacs-Devel devel To: Anders Lindgren Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Jul 23 14:17:48 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dZFpU-0000OI-HK for ged-emacs-devel@m.gmane.org; Sun, 23 Jul 2017 14:17:48 +0200 Original-Received: from localhost ([::1]:50328 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZFpY-0001kK-AJ for ged-emacs-devel@m.gmane.org; Sun, 23 Jul 2017 08:17:52 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:49359) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZFos-0001k1-HR for emacs-devel@gnu.org; Sun, 23 Jul 2017 08:17:12 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZFoq-0006Ej-7d for emacs-devel@gnu.org; Sun, 23 Jul 2017 08:17:10 -0400 Original-Received: from mail-wr0-x236.google.com ([2a00:1450:400c:c0c::236]:35268) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dZFop-0006Dx-QD for emacs-devel@gnu.org; Sun, 23 Jul 2017 08:17:08 -0400 Original-Received: by mail-wr0-x236.google.com with SMTP id k71so43092618wrc.2 for ; Sun, 23 Jul 2017 05:17:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=Qg3l8bzzaA4joEPELDSyRJQhDGGngeyGEIlC1aNhVDk=; b=IUyjvTtEpkSB3NVdgraBhMeDKbnhGHSuH5rLERmR0e+xVV/zAbx1p8dncpL9L7RIHK s0JPHAn3Ecj4Mw5Zf17DvXdyXtTBoTyb+FaFVKhUN1jrkk5O2suUJE3/s4NwfyAN9maS PLf2CUa9KnqRKUHAg0wTwY9psQaTBPFsuFMZ43vMKa0RThLTw1rZBTlf5Jy+IOpjzkhu sIgat46JIERhOdmKduRp8+hyttNUXr7wSeSv6NZ7dmqeTiD1eZOSfdhlLRISAb1wE4r3 YkKhyX4EC811oC9W4SPGei8OyRjxtGsj4DYre40svyOG666RBXDALjToMEbA+KLEjVTu wa/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:cc:subject:message-id :references:mime-version:content-disposition :content-transfer-encoding:in-reply-to:user-agent; bh=Qg3l8bzzaA4joEPELDSyRJQhDGGngeyGEIlC1aNhVDk=; b=HVNNci4h1wEoBFNY9OKiODls24nH1w84NemLpw1H6j8nIf0fUquBCAk3C7T2QWrfnR Gm7r+uGpYBlACWjvrG+dfYaDORXi+ibYT7GrlUOGgY0hECz8YcgPLFbMBByTtSB704Gd I5StLW2/L7B1pJfjgR7EogWm2Cn3YpOYMI3eVg08bC6neoah7sIN38+59nlSg82ZZgLD rGYoxDI4XnO9ga+0askhUKE10dMODwnd2snTtJyuoczUqE/q94hNKArL6f9Y3PDAvJ8+ ST3BdaDXtf2XlKKpAGXH3unjfqWmsqQUFXZQvSMWE8Ugajz0fh6hQ8H0q0jsuHEgzEob WuwA== X-Gm-Message-State: AIVw110bs7KE6R8Cvs20JwsoOL00qBMumK4ImYA29vXeDZHCziUI3vDx 6Sfw7uqv0K7riw== X-Received: by 10.223.136.176 with SMTP id f45mr11397638wrf.289.1500812225189; Sun, 23 Jul 2017 05:17:05 -0700 (PDT) Original-Received: from breton.holly.idiocy.org (ip6-2001-08b0-03f8-8129-38a3-b7bd-bb2f-3561.holly.idiocy.org. [2001:8b0:3f8:8129:38a3:b7bd:bb2f:3561]) by smtp.gmail.com with ESMTPSA id z108sm19861156wrb.41.2017.07.23.05.17.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 23 Jul 2017 05:17:03 -0700 (PDT) Content-Disposition: inline In-Reply-To: <20170722112230.GA58424@breton.holly.idiocy.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::236 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:216942 Archived-At: --DocE+STaALJfprDB Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit 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 --DocE+STaALJfprDB Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0001-Use-a-run-time-check-for-macOS-Sierra-tabbing-suppor.patch" >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 --DocE+STaALJfprDB--