ui_cocoa: converge HAVE_COCOA and HAVE_COCOA_METAL on ARC/MRR

21 preprocessor blocks in ui_cocoa.m guarded [... release] and
[... autorelease] calls behind `#ifndef HAVE_COCOA_METAL`.  Plus
one -dealloc override gated on the same.  This was using
HAVE_COCOA_METAL as a proxy for "are we compiled under ARC?".

The proxy is brittle:

  Build target                 ARC?  MRR?
  qb/make (any)                no    YES (ui_cocoa.m always MRR;
                                      only metal.m + mfi_joypad.m
                                      get -fobjc-arc per Makefile
                                      lines 275-276)
  RetroArch.xcodeproj          YES   no  (BaseConfig.xcconfig:182
  RetroArch_Metal.xcodeproj    YES   no   CLANG_ENABLE_OBJC_ARC=YES
  RetroArch_OSX107.xcodeproj   YES   no   cascades down)
  RetroArch_PPC.xcodeproj      no    YES (explicit override to NO)

The HAVE_COCOA_METAL-based guard happens to be right for 3 of
these 5 by coincidence (Metal xcodeproj + PPC xcodeproj + qb/make),
but wrong for the two that flip the correlation.  The clang-
documented discriminator is __has_feature(objc_arc), which is
exactly true under ARC and false under MRR regardless of other
build options.

Add three macros in cocoa_defines.h that expand to the right thing
either way:

  RARCH_RELEASE(x)       [(x) release]    /  ((void)0) under ARC
  RARCH_AUTORELEASE(x)   [(x) autorelease] / ((void)0) under ARC
  RARCH_SUPER_DEALLOC()  [super dealloc]   / ((void)0) under ARC

Wrapped in the standard __has_feature polyfill so GCC 4.0 (Xcode
3.1, which predates ARC and __has_feature both) falls through to
the MRR branch, which is correct.

Replace 21 conditional release/autorelease blocks with unconditional
macro calls.  Gate the -dealloc override on #if !__has_feature
(objc_arc) instead of #ifndef HAVE_COCOA_METAL - ARC auto-generates
-dealloc from strong ivars and forbids explicit overrides that just
call [super dealloc], so the method stays conditional but on the
correct axis.

The one remaining #ifndef HAVE_COCOA_METAL site (now line 646,
the addSubview:[CocoaView get] / makeFirstResponder: block) is a
legitimate platform branch - Metal installs CocoaView via
apple_platform.renderView through a different codepath - and
stays put.

Net change: -10 LoC, -21 preprocessor blocks, zero runtime
behaviour change on any of the five build configurations.
This commit is contained in:
U-DESKTOP-SPFP6AQ\twistedtechre committed 2026-04-21 06:43:47 +02:00
1 parent 623d38790e
commit 492b9c41d9
2 files changed
+63 -73

No files matched your search

@@ -73,4 +73,33 @@
#define HAS_MACOSX_10_12 1
#endif
/* ARC vs MRR macros. Under ARC, release/autorelease are forbidden
* (compile error); under MRR (Manual Retain-Release / MRC) they are
* required. These macros expand to the right thing for the current
* translation unit regardless of which mode it is compiled under.
*
* Previous convention used `#ifndef HAVE_COCOA_METAL` as a proxy
* for 'are we under ARC?' because HAVE_COCOA_METAL builds happened
* to enable ARC via CLANG_ENABLE_OBJC_ARC=YES in BaseConfig.xcconfig.
* That's brittle - RetroArch_PPC.xcodeproj turns ARC off explicitly
* even on the Metal branch, and the qb/make build is always MRR
* regardless. __has_feature(objc_arc) is the canonical discriminator.
*
* GCC 4.0 (Xcode 3.1) doesn't support __has_feature; polyfill to 0
* so the MRR branch is selected (which is correct for GCC 4.0 - it
* predates ARC entirely). */
#ifndef __has_feature
#define __has_feature(x) 0
#endif
#if __has_feature(objc_arc)
#define RARCH_RELEASE(x) ((void)0)
#define RARCH_AUTORELEASE(x) ((void)0)
#define RARCH_SUPER_DEALLOC() ((void)0)
#else
#define RARCH_RELEASE(x) [(x) release]
#define RARCH_AUTORELEASE(x) [(x) autorelease]
#define RARCH_SUPER_DEALLOC() [super dealloc]
#endif
#endif
+34 -73
View File
@@ -609,11 +609,14 @@ static ui_application_t ui_application_cocoa = {
@synthesize window = _window;
#ifndef HAVE_COCOA_METAL
#if !__has_feature(objc_arc)
/* ARC auto-generates -dealloc from strong ivars and forbids explicit
* overrides that just call [super dealloc]. On MRR we have to release
* _window manually. See cocoa_defines.h for the ARC/MRR macro story. */
- (void)dealloc
{
[_window release];
[super dealloc];
RARCH_RELEASE(_window);
RARCH_SUPER_DEALLOC();
}
#endif
@@ -1119,9 +1122,7 @@ static NSMenuItem *cocoa_menu_item_with_action(NSString *title,
[item setTarget:target];
if (tag)
[item setTag:tag];
#ifndef HAVE_COCOA_METAL
[item autorelease];
#endif
RARCH_AUTORELEASE(item);
return item;
}
@@ -1140,10 +1141,8 @@ static NSMenu *cocoa_create_app_menu(id delegate)
[NSApp setServicesMenu:servicesMenu];
[servicesItem setSubmenu:servicesMenu];
[menu addItem:servicesItem];
#ifndef HAVE_COCOA_METAL
[servicesItem release];
[servicesMenu release];
#endif
RARCH_RELEASE(servicesItem);
RARCH_RELEASE(servicesMenu);
[menu addItem:[NSMenuItem separatorItem]];
[menu addItem:cocoa_menu_item_with_action(@"Hide RetroArch",
@@ -1157,9 +1156,7 @@ static NSMenu *cocoa_create_app_menu(id delegate)
[menu addItem:cocoa_menu_item_with_action(@"Quit RetroArch",
@selector(terminate:), @"q", NSEventModifierFlagCommand, NSApp, 0)];
#ifndef HAVE_COCOA_METAL
[menu autorelease];
#endif
RARCH_AUTORELEASE(menu);
return menu;
}
@@ -1181,18 +1178,14 @@ static NSMenu *cocoa_create_file_menu(id delegate)
NSMenuItem *clearItem = cocoa_menu_item_with_action(@"Clear Menu",
@selector(clearRecentDocuments:), @"", 0, nil, 0);
[recentMenu addItem:clearItem];
#ifndef HAVE_COCOA_METAL
[recentItem release];
[recentMenu release];
#endif
RARCH_RELEASE(recentItem);
RARCH_RELEASE(recentMenu);
[menu addItem:[NSMenuItem separatorItem]];
[menu addItem:cocoa_menu_item_with_action(@"Close",
@selector(performClose:), @"w", NSEventModifierFlagCommand, nil, 0)];
#ifndef HAVE_COCOA_METAL
[menu autorelease];
#endif
RARCH_AUTORELEASE(menu);
return menu;
}
@@ -1209,10 +1202,8 @@ static NSMenu *cocoa_create_command_menu(id delegate)
@selector(basicEvent:), @"", 0, delegate, 22)];
[audioItem setSubmenu:audioMenu];
[menu addItem:audioItem];
#ifndef HAVE_COCOA_METAL
[audioItem release];
[audioMenu release];
#endif
RARCH_RELEASE(audioItem);
RARCH_RELEASE(audioMenu);
/* Disk Options submenu */
NSMenuItem *diskItem = [[NSMenuItem alloc] initWithTitle:@"Disk Options"
@@ -1227,10 +1218,8 @@ static NSMenu *cocoa_create_command_menu(id delegate)
@selector(basicEvent:), @"", 0, delegate, 5)];
[diskItem setSubmenu:diskMenu];
[menu addItem:diskItem];
#ifndef HAVE_COCOA_METAL
[diskItem release];
[diskMenu release];
#endif
RARCH_RELEASE(diskItem);
RARCH_RELEASE(diskMenu);
/* Mouse Options submenu */
NSMenuItem *mouseItem = [[NSMenuItem alloc] initWithTitle:@"Mouse Options"
@@ -1241,10 +1230,8 @@ static NSMenu *cocoa_create_command_menu(id delegate)
@selector(basicEvent:), @"", 0, delegate, 7)];
[mouseItem setSubmenu:mouseMenu];
[menu addItem:mouseItem];
#ifndef HAVE_COCOA_METAL
[mouseItem release];
[mouseMenu release];
#endif
RARCH_RELEASE(mouseItem);
RARCH_RELEASE(mouseMenu);
/* Save State Options submenu */
NSMenuItem *stateItem = [[NSMenuItem alloc] initWithTitle:@"Save State Options"
@@ -1257,10 +1244,8 @@ static NSMenu *cocoa_create_command_menu(id delegate)
@selector(basicEvent:), @"", 0, delegate, 3)];
[stateItem setSubmenu:stateMenu];
[menu addItem:stateItem];
#ifndef HAVE_COCOA_METAL
[stateItem release];
[stateMenu release];
#endif
RARCH_RELEASE(stateItem);
RARCH_RELEASE(stateMenu);
[menu addItem:cocoa_menu_item_with_action(@"Reset",
@selector(basicEvent:), @"", 0, delegate, 1)];
@@ -1271,9 +1256,7 @@ static NSMenu *cocoa_create_command_menu(id delegate)
[menu addItem:cocoa_menu_item_with_action(@"Take Screenshot",
@selector(basicEvent:), @"", 0, delegate, 21)];
#ifndef HAVE_COCOA_METAL
[menu autorelease];
#endif
RARCH_AUTORELEASE(menu);
return menu;
}
@@ -1282,9 +1265,7 @@ static NSMenu *cocoa_create_paths_menu(id delegate)
NSMenu *menu = [[NSMenu alloc] initWithTitle:@"Paths"];
[menu addItem:cocoa_menu_item_with_action(@"Core Directory",
@selector(showCoresDirectory:), @"", 0, delegate, 0)];
#ifndef HAVE_COCOA_METAL
[menu autorelease];
#endif
RARCH_AUTORELEASE(menu);
return menu;
}
@@ -1311,10 +1292,8 @@ static NSMenu *cocoa_create_window_menu(id delegate)
}
[scaleItem setSubmenu:scaleMenu];
[menu addItem:scaleItem];
#ifndef HAVE_COCOA_METAL
[scaleItem release];
[scaleMenu release];
#endif
RARCH_RELEASE(scaleItem);
RARCH_RELEASE(scaleMenu);
[menu addItem:cocoa_menu_item_with_action(@"Enter Full Screen",
@selector(toggleFullScreen:), @"f",
@@ -1327,9 +1306,7 @@ static NSMenu *cocoa_create_window_menu(id delegate)
[NSApp setWindowsMenu:menu];
#ifndef HAVE_COCOA_METAL
[menu autorelease];
#endif
RARCH_AUTORELEASE(menu);
return menu;
}
@@ -1345,9 +1322,7 @@ static NSMenu *cocoa_create_help_menu(void)
* for-Help into. */
if ([NSApp respondsToSelector:@selector(setHelpMenu:)])
[NSApp setHelpMenu:menu];
#ifndef HAVE_COCOA_METAL
[menu autorelease];
#endif
RARCH_AUTORELEASE(menu);
return menu;
}
@@ -1362,54 +1337,40 @@ static void cocoa_create_menu_bar(id delegate)
submenu = cocoa_create_app_menu(delegate);
[item setSubmenu:submenu];
[menubar addItem:item];
#ifndef HAVE_COCOA_METAL
[item release];
#endif
RARCH_RELEASE(item);
/* File menu */
item = [[NSMenuItem alloc] init];
[item setSubmenu:cocoa_create_file_menu(delegate)];
[menubar addItem:item];
#ifndef HAVE_COCOA_METAL
[item release];
#endif
RARCH_RELEASE(item);
/* Command menu */
item = [[NSMenuItem alloc] init];
[item setSubmenu:cocoa_create_command_menu(delegate)];
[menubar addItem:item];
#ifndef HAVE_COCOA_METAL
[item release];
#endif
RARCH_RELEASE(item);
/* Paths menu */
item = [[NSMenuItem alloc] init];
[item setSubmenu:cocoa_create_paths_menu(delegate)];
[menubar addItem:item];
#ifndef HAVE_COCOA_METAL
[item release];
#endif
RARCH_RELEASE(item);
/* Window menu */
item = [[NSMenuItem alloc] init];
[item setSubmenu:cocoa_create_window_menu(delegate)];
[menubar addItem:item];
#ifndef HAVE_COCOA_METAL
[item release];
#endif
RARCH_RELEASE(item);
/* Help menu */
item = [[NSMenuItem alloc] init];
[item setSubmenu:cocoa_create_help_menu()];
[menubar addItem:item];
#ifndef HAVE_COCOA_METAL
[item release];
#endif
RARCH_RELEASE(item);
[NSApp setMainMenu:menubar];
#ifndef HAVE_COCOA_METAL
[menubar release];
#endif
RARCH_RELEASE(menubar);
}
static NSWindow *cocoa_create_main_window(void)