Skip to content

Commit 23a9456

Browse files
committed
ui_cocoa: unify Cocoa + Metal event pump on RAWindow
On 10.5 Leopard (and any macOS make-build that runs the bare binary from a terminal rather than a .app bundle), the window appeared but didn't respond to keyboard or mouse. The menu was unreachable. ROOT CAUSE: input delivery used two different architectures: HAVE_COCOA_METAL: RAWindow : NSWindow with a -sendEvent: override. AppKit calls -[NSWindow sendEvent:] unconditionally on every event destined for the key window, so the override fires with no setup. HAVE_COCOA: RApplication : NSApplication with a -sendEvent: override. Only fires if NSApp is actually an RApplication instance, which requires either NSApplicationMain() + NSPrincipalClass=RApplication in Info.plist, or an explicit [RApplication sharedApplication] call before any [NSApplication sharedApplication]. The qb/make build bootstraps via plain [NSApplication sharedApplication] in main() with no NSApplicationMain / Info.plist lookup, so RApplication was declared but never instantiated. -sendEvent: was dead code. Events flowed through plain NSApplication, got forwarded to the key window's responder chain, and died in CocoaView's empty -keyDown: stub (which exists only to squelch the system beep). Result: window visible, utterly unresponsive. FIX: unify on the Metal architecture. Make HAVE_COCOA also use RAWindow : NSWindow with the same -sendEvent: override. AppKit calls it automatically - no NSPrincipalClass, no class-registration dance. The two code paths converge on the same event-dispatch structure. ui_cocoa.m: - Merge the conditional RAWindow-or-RApplication declaration into a single unconditional @interface RAWindow : NSWindow. - Bracket all 11 NSEvent dot-syntax sites (event.type -> [event type], etc.) - now that sendEvent: compiles on the Cocoa path instead of being dead code, every dot-access is a compile error on the 10.5 SDK / GCC 4.0 (pre-Obj-C-2.0, NSEvent's getters aren't declared @Property there). Same class of fix as c49a525, d38dcb5, f4d1390. - Collapse three #if HAVE_COCOA_METAL / #elif HAVE_COCOA case-label splits (NSEventTypeFlagsChanged vs NSFlagsChanged, etc.) into single modern-name labels. cocoa_defines.h already provides the modern names as aliases on pre-10.12 SDKs. - cocoa_create_main_window(): drop the #ifdef HAVE_COCOA_METAL - both paths now allocate RAWindow. Behavioral impact: * HAVE_COCOA_METAL (modern macOS, Xcode/make-bundle builds): unchanged. Same RAWindow, same sendEvent:, same event flow. * HAVE_COCOA on modern macOS make-bundle: still works - now via RAWindow instead of going through the NSPrincipalClass dance. * HAVE_COCOA bare-binary from terminal (Leopard PPC, and any make build run without .app bundling): NOW WORKS. Previously unable to receive input at all. * HAVE_COCOA Xcode builds (RetroArch.xcodeproj, RetroArch_OSX107. xcodeproj, RetroArch_PPC.xcodeproj): still work. Those set NSPrincipalClass=RApplication in pkg/apple/OSX/Info.plist, which becomes a dangling reference now - but a dangling NSPrincipalClass falls back to NSApplication, which is what we want. The plists can be cleaned up in a separate commit. No per-event overhead change. NSWindow's sendEvent: dispatch has the same Obj-C message-send cost as NSApplication's did. Binary size grows by a few hundred bytes (the sendEvent: body now compiles into the non-Metal binary instead of being dead code).
1 parent 53c32a2 commit 23a9456

1 file changed

Lines changed: 27 additions & 36 deletions

File tree

ui/drivers/ui_cocoa.m

Lines changed: 27 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -365,17 +365,16 @@ - (void)perform
365365

366366
@end /* @implementation CommandPerformer */
367367

368-
#if defined(HAVE_COCOA_METAL)
368+
/* RAWindow : NSWindow override. Both the Metal and non-Metal paths
369+
* use this: it's the NSWindow-level sendEvent: hook that AppKit calls
370+
* unconditionally for every event destined for this window. Doing it
371+
* here (rather than subclassing NSApplication) means we don't depend
372+
* on NSPrincipalClass being set in Info.plist, and the Cocoa / Metal
373+
* paths converge on the same event-dispatch architecture. */
369374
@interface RAWindow : NSWindow
370375
@end
371376

372377
@implementation RAWindow
373-
#elif defined(HAVE_COCOA)
374-
@interface RApplication : NSApplication
375-
@end
376-
377-
@implementation RApplication
378-
#endif
379378

380379
#ifdef HAVE_COCOA_METAL
381380
#define CONVERT_POINT() [apple_platform.renderView convertPoint:[event locationInWindow] fromView:nil]
@@ -395,7 +394,11 @@ - (void)keyDown:(NSEvent *)theEvent
395394
}
396395

397396
- (void)sendEvent:(NSEvent *)event {
398-
NSEventType event_type = event.type;
397+
/* Bracket syntax throughout - GCC 4.0 on the pre-Obj-C-2.0 10.5
398+
* SDK doesn't accept dot-syntax on NSEvent's plain getter methods
399+
* (they aren't declared as @property there). Modern clang emits
400+
* identical code for either form. */
401+
NSEventType event_type = [event type];
399402

400403
[super sendEvent:event];
401404

@@ -405,12 +408,12 @@ - (void)sendEvent:(NSEvent *)event {
405408
case NSEventTypeKeyUp:
406409
{
407410
uint32_t i;
408-
NSString* ch = event.characters;
411+
NSString* ch = [event characters];
409412
uint32_t mod = 0;
410-
const char *inputTextUTF8 = ch.UTF8String;
413+
const char *inputTextUTF8 = [ch UTF8String];
411414
uint32_t character = inputTextUTF8[0];
412-
NSUInteger mods = event.modifierFlags;
413-
uint16_t keycode = event.keyCode;
415+
NSUInteger mods = [event modifierFlags];
416+
uint16_t keycode = [event keyCode];
414417

415418
if (mods & NSEventModifierFlagCapsLock)
416419
mod |= RETROKMOD_CAPSLOCK;
@@ -425,7 +428,7 @@ - (void)sendEvent:(NSEvent *)event {
425428
if (mods & NSEventModifierFlagNumericPad)
426429
mod |= RETROKMOD_NUMLOCK;
427430

428-
for (i = 1; i < ch.length; i++)
431+
for (i = 1; i < [ch length]; i++)
429432
apple_input_keyboard_event(event_type == NSEventTypeKeyDown,
430433
0, inputTextUTF8[i], mod, RETRO_DEVICE_KEYBOARD);
431434

@@ -436,16 +439,12 @@ - (void)sendEvent:(NSEvent *)event {
436439
keycode, character, mod, RETRO_DEVICE_KEYBOARD);
437440
}
438441
break;
439-
#if defined(HAVE_COCOA_METAL)
440-
case NSEventTypeFlagsChanged:
441-
#elif defined(HAVE_COCOA)
442-
case NSFlagsChanged:
443-
#endif
442+
case NSEventTypeFlagsChanged:
444443
{
445444
static NSUInteger old_flags = 0;
446-
NSUInteger new_flags = event.modifierFlags;
445+
NSUInteger new_flags = [event modifierFlags];
447446
NSUInteger changed_flags = new_flags ^ old_flags;
448-
uint16_t keycode = event.keyCode;
447+
uint16_t keycode = [event keyCode];
449448
bool down = false;
450449

451450
/* Determine if the changed modifier is being pressed or released
@@ -468,8 +467,8 @@ - (void)sendEvent:(NSEvent *)event {
468467
case NSEventTypeRightMouseDragged:
469468
case NSEventTypeOtherMouseDragged:
470469
{
471-
CGFloat delta_x = event.deltaX;
472-
CGFloat delta_y = event.deltaY;
470+
CGFloat delta_x = [event deltaX];
471+
CGFloat delta_y = [event deltaY];
473472
NSPoint pos = CONVERT_POINT();
474473
cocoa_input_data_t
475474
*apple = (cocoa_input_data_t*)
@@ -496,18 +495,14 @@ - (void)sendEvent:(NSEvent *)event {
496495
}
497496
}
498497
break;
499-
#if defined(HAVE_COCOA_METAL)
500-
case NSEventTypeScrollWheel:
501-
#elif defined(HAVE_COCOA)
502-
case NSScrollWheel:
503-
#endif
498+
case NSEventTypeScrollWheel:
504499
/* TODO/FIXME - properly implement. */
505500
break;
506501
case NSEventTypeLeftMouseDown:
507502
case NSEventTypeRightMouseDown:
508503
case NSEventTypeOtherMouseDown:
509504
{
510-
NSInteger number = event.buttonNumber;
505+
NSInteger number = [event buttonNumber];
511506
NSPoint pos = CONVERT_POINT();
512507
cocoa_input_data_t
513508
*apple = (cocoa_input_data_t*)
@@ -522,7 +517,7 @@ - (void)sendEvent:(NSEvent *)event {
522517
case NSEventTypeRightMouseUp:
523518
case NSEventTypeOtherMouseUp:
524519
{
525-
NSInteger number = event.buttonNumber;
520+
NSInteger number = [event buttonNumber];
526521
NSPoint pos = CONVERT_POINT();
527522
cocoa_input_data_t
528523
*apple = (cocoa_input_data_t*)
@@ -1410,17 +1405,13 @@ static void cocoa_create_menu_bar(id delegate)
14101405
| NSWindowStyleMaskResizable;
14111406
NSRect frame = NSMakeRect(0, 0, 480, 360);
14121407

1413-
#ifdef HAVE_COCOA_METAL
1408+
/* Both HAVE_COCOA and HAVE_COCOA_METAL use RAWindow now; its
1409+
* -sendEvent: override is what feeds keyboard/mouse events into
1410+
* the cocoa_input driver. */
14141411
NSWindow *window = [[RAWindow alloc] initWithContentRect:frame
14151412
styleMask:style
14161413
backing:NSBackingStoreBuffered
14171414
defer:NO];
1418-
#else
1419-
NSWindow *window = [[NSWindow alloc] initWithContentRect:frame
1420-
styleMask:style
1421-
backing:NSBackingStoreBuffered
1422-
defer:NO];
1423-
#endif
14241415
[window setTitle:@"RetroArch"];
14251416
[window setReleasedWhenClosed:NO];
14261417
[window setAllowsToolTipsWhenApplicationIsInactive:NO];

0 commit comments

Comments
 (0)