Skip to content

macOS Cocoa: fix reshape, resize, and fullscreen handling#42

Merged
SethRobinson merged 44 commits into
SethRobinson:masterfrom
mateusbentes:master
Mar 11, 2026
Merged

macOS Cocoa: fix reshape, resize, and fullscreen handling#42
SethRobinson merged 44 commits into
SethRobinson:masterfrom
mateusbentes:master

Conversation

@mateusbentes

Copy link
Copy Markdown
Contributor
  • Add reshape method to MyOpenGLView: was registered as selector but never defined, so window resize never updated game screen info. Now calls InitDeviceScreenInfoEx with correct bounds + openGLContext update.

  • Remove premature OnResizeFinished call from windowWillResize (used old bounds before resize completed). windowDidResize -> reshape is now the single correct path for all resize and fullscreen transitions.

  • Remove redundant GetBaseApp()->Init() from prepareOpenGL: InitDeviceScreenInfoEx already guards with IsInitted() and owns the init call.

These fixes are macOS Cocoa-only and don't touch Linux/Windows/iOS paths, so they're safe to merge upstream.

- Add reshape method to MyOpenGLView: was registered as selector but
  never defined, so window resize never updated game screen info.
  Now calls InitDeviceScreenInfoEx with correct bounds + openGLContext update.

- Remove premature OnResizeFinished call from windowWillResize (used old
  bounds before resize completed). windowDidResize -> reshape is now the
  single correct path for all resize and fullscreen transitions.

- Remove redundant GetBaseApp()->Init() from prepareOpenGL: InitDeviceScreenInfoEx
  already guards with IsInitted() and owns the init call.
@mateusbentes

mateusbentes commented Mar 6, 2026

Copy link
Copy Markdown
Contributor Author

@SethRobinson without these changes modern Macs will not open, because Macs don’t support support direct SDL anymore.

- OSXUtils.h/mm: add OSXToggleFullscreen() using dispatch_async +
  [window toggleFullScreen:nil] so App.cpp can call it from C++ without
  importing Cocoa headers in a .cpp file.

- MainController.mm: add windowDidEnterFullScreen/windowDidExitFullScreen
  delegates to track g_bIsFullScreen and update the fullscreen var,
  and call reshape on exit to restore correct viewport.
…clarations

- Remove goFullScreen:, goWindow, OnResizeFinished declarations (not implemented,
  fullscreen now handled via OSXToggleFullscreen/toggleFullScreen: delegate).
- Remove old fullscreen ivar block (fullScreenWindow, fullScreenView, CGLContextObj).
- Add App.h import so GetApp() is available in MainController.mm.
@mateusbentes

mateusbentes commented Mar 6, 2026

Copy link
Copy Markdown
Contributor Author

@SethRobinson I wait that migration to Cocoa in Mac to be completed.

The NSTimer was starting before prepareOpenGL was called, so IsInitted()
was always false and drawRect never ran the game. Now we explicitly call
makeCurrentContext + prepareOpenGL (which calls InitDeviceScreenInfoEx ->
GetBaseApp()->Init()) before starting the timer, guaranteeing the game
is initialized when the first frame fires.
…unds

prepareOpenGL is called lazily by the system. At awakeFromNib time the
view bounds are zero, so calling it there initializes with 0x0 screen
size and the game never starts. Instead:
- awakeFromNib: just sets up timer and working directory (no init)
- drawRect: if not yet initted and bounds are valid (>0), call
  prepareOpenGL now - this is the first moment we have real screen size
…artup logging

- Remove NSOpenGLPFAWindow (deprecated macOS 10.14+, may silently fail context creation)
- Add NSOpenGLProfileVersionLegacy for compatibility with OpenGL 2.x code
- Add fallback pixel format if primary fails
- Add NSLog in drawRect and prepareOpenGL to diagnose startup issues
Calling drawRect: directly from a timer bypasses the macOS display
system and the OpenGL context may not be properly current. Using
[self display] triggers the proper display cycle ensuring the context
is set up correctly before drawing.
The app was silently exiting because the window was never made visible.
applicationShouldTerminateAfterLastWindowClosed returns YES, so if the
window never appears macOS terminates the app immediately. Force the
main window to front after launch.
…O, return NO from shouldTerminateAfterLastWindowClosed, terminate on windowWillClose
…ode/resolution changes never being processed
@mateusbentes

Copy link
Copy Markdown
Contributor Author

@SethRobinson let's explain correct, this PR only change files to work in mac, don't change multiplatform.

@mateusbentes

Copy link
Copy Markdown
Contributor Author

@SethRobinson do you have a official controller?

@mateusbentes

Copy link
Copy Markdown
Contributor Author

@SethRobinson gamepad still untested, this PR #42 can now be merged.

@SethRobinson

Copy link
Copy Markdown
Owner

An official controller for Proton? No, the goal is just to support as many popular ones as possible. I'd prefer not to review things until they are tested (ie, arm, controller support). Keep in mind you can put up a build on your fork and ask for testing.

Please clearly let me know which parts are tested on real hardware and untested vibe code

@mateusbentes

Copy link
Copy Markdown
Contributor Author

@SethRobinson this changes in Proton dont change just the controller, but the main thing is implemented Cocoa Windows functions on Mac.

@mateusbentes

Copy link
Copy Markdown
Contributor Author

@SethRobinson without Cocoa functions in Proton the game on Mac doesn't work, Mac does not support direct SDL anymore.

@mateusbentes

mateusbentes commented Mar 8, 2026

Copy link
Copy Markdown
Contributor Author

@SethRobinson I tested on Mac Intel, and Arm with MacInCloud (not real Mac MacInCloud) the game Works but without gamepad, the Luketon is just a example, i am testing with gamepad but i don't know if it is problem in Driver on Mac.

@SethRobinson

Copy link
Copy Markdown
Owner

Proton has its own apps designed to test (generally this is a lot easier than a big external game like Dink as they are tiny)

RTBareBones -> Test app/windowing (super basic)
RTSimpleApp -> Test app/Windowing with audio
RTLooneyLadders -> Has a joystick sticks/dpad/buttons tester with display

If you can get these demo/example apps to work on Mac, it will allow Proton users to have a working example without getting Dink

If this is out of scope for you to do (ie, you only really need dink working), I understand. In that case maybe just put up your Dink build and wait for me to do this when I get more time

@mateusbentes

Copy link
Copy Markdown
Contributor Author

@SethRobinson The shared OSX/app/ fixes (MainController.mm, MyOpenGLView.mm) are already structured to work for all Proton apps — they use the same shared code. RTSimpleApp already has PLATFORM_OSX defined. RTBareBones and RTLooneyLadders just need PLATFORM_OSX added to their Xcode preprocessor definitions (same one-line fix done for RTDink).

@mateusbentes

mateusbentes commented Mar 8, 2026

Copy link
Copy Markdown
Contributor Author

@SethRobinson I can get RTBareBones working on macOS — it's minimal and has no audio dependency. For RTSimpleApp and RTLooneyLadders, the blocker is FMOD: they use it for audio on macOS, and I'd need to either switch them to SDL audio (like I did for RTDink) or skip audio. RTLooneyLadders also has no OSX Xcode project at all and would need one created from scratch. I'm happy to do RTBareBones now as a clean point for the PR.

AudioManagerFMODStudio.cpp was still in the Sources build phase causing
'fmod.h not found' compile error. Remove all FMOD references:
- AudioManagerFMODStudio.cpp/h from Sources, file refs, and Audio group
- libfmod.dylib from Frameworks build phase, file ref, and Frameworks group
- CopyFiles build phase (was only used to embed libfmod.dylib)
…anager

RTSimpleApp does not have a GamepadManager instance, so the PLATFORM_OSX
block calling GetGamepadManager()->AddProvider(new GamepadProviderSDL2())
caused 'member access into incomplete type GamepadManager' compile error.

Remove:
- SDL_Init + GamepadProviderSDL2 from App::Init
- SDL_PumpEvents/SDL_PeepEvents event drain from App::Update
- Unused GamepadProviderSDL2.h, SDL2/SDL.h includes
- g_sig_SDLEvent definition (not needed without event pump)

AudioManagerSDL handles its own SDL init internally.
All three apps (RTSimpleApp, RTBareBones, RTLooneyLadders) were failing
with undefined _png_* linker errors because libpng was not compiled in.

RTDink compiles libpng from source (shared/Irrlicht/source/Irrlicht/libpng/).
Apply the same approach to all three demo projects:
- Add all 15 libpng .c files to Sources build phase
- Add file references and libpng group in project navigator
- Copy pnglibconf.h from pnglibconf.h.prebuilt (required by libpng headers)
Add arm_init.c, filter_neon_intrinsics.c, palette_neon_intrinsics.c from
libpng/arm/ to fix undefined _png_*_neon linker errors on ARM64.

Also add EXCLUDED_SOURCE_FILE_NAMES[arch=x86_64] to exclude these ARM-only
files when building for Intel, matching RTDink's approach.
… apps

Two linker errors in RTSimpleApp (and potentially RTBareBones/RTLooneyLadders):

1. _LogMsg undefined: RT_CUSTOM_LOGMSG was set in all 3 Xcode projects,
   which suppresses LogMsg definition in OSXUtils.mm. The demo apps have
   no custom LogMsg, so remove RT_CUSTOM_LOGMSG from all 3 projects.

2. _g_bIsFullScreen (shown as _p_linearScreen in linker output) undefined:
   This global is defined in SDL2Main.cpp for SDL builds, but the OSX Cocoa
   build does not compile SDL2Main.cpp. Add definition in each App.cpp for
   the PLATFORM_OSX / macOS branch.
…er errors

Add ArcadeInputComponent, DPadComponent, EmitVirtualKeyComponent,
EmitVirtualKeyComponentAdvanced, and TouchHandlerArcadeComponent to
the Xcode project build phases. These were referenced by game code
but missing from the pbxproj, causing undefined symbol linker errors.
… error

LogDisplayComponent.cpp defines SetConsole(bool, bool) which is called
by ControllerTestMenu.cpp but was missing from the Xcode project.
TouchDragComponent.cpp is included by LogDisplayComponent.cpp (for the
scrollable console widget) but was missing from the Xcode project.
…ow bug

MainController.mm now creates the window programmatically in
applicationDidFinishLaunching. The XIB window definition was still
present, causing two windows to appear on launch. Remove the <window>
block and the openGLView outlet from both XIBs so only the
programmatic window is created.
Same fix as RTSimpleApp/RTLooneyLadders: MainController.mm creates
the window programmatically, so the XIB window block and openGLView
outlet are removed to prevent a second blank window on launch.
The Release XCBuildConfiguration was missing the closing }; for its
buildSettings block, causing Xcode to report a parse error and refuse
to open the project.
GetApp() returns the app-specific subclass which may not have GetVar
(e.g. RTBareBones). GetBaseApp()->GetVar() works for all apps.
Neither BaseApp nor all App subclasses have GetVar. The global
g_bIsFullScreen flag is sufficient for OSX fullscreen tracking.
These files provide JPEG loading support (RT_JPG_SUPPORT is defined
in the build settings) but were missing from the Xcode project,
causing undefined symbol linker errors.
@mateusbentes

Copy link
Copy Markdown
Contributor Author

@SethRobinson now I tested and the three examples are working, Dink Smallworld HD continues working on Mac, in Dink code I just removed the code that change Proton SDK because nil->0 script in Dink code that is not necessary anymore because in commit c21614d I fixed that.

Captura de tela de 2026-03-09 11-09-58 Captura de tela de 2026-03-09 11-10-36 Captura de tela de 2026-03-09 11-11-17

PS: sorry to just fix these problems today (in Monday), Sunday (yesterday) I was making public competition to possible be an analyst in Brazilian Parliament.

@SethRobinson

Copy link
Copy Markdown
Owner

Ok, I'm merging these now (found some minor issues I want to fix first, but will push in an hour or two probably)

@SethRobinson SethRobinson merged commit b100f3b into SethRobinson:master Mar 11, 2026
@SethRobinson

Copy link
Copy Markdown
Owner

Ok, I merged, worked ok - a few notes:

  • Tested on M2 studio mac
  • Some fixes with retina/fullscreen

The gamepad does not work - but I think it's an SDL2/Mac issue.

Gamepad Support on macOS (Cocoa build path)

During testing of PR #42, I found that SDL2 gamepad detection doesn't work in the native Cocoa build path (RTLooneyLadders). The Xbox controller is recognized by macOS (visible in System Settings > Game Controllers) but SDL2 never sees it. This is because SDL2's joystick subsystem conflicts with the Cocoa NSApplication run loop - SDL2 expects to own the event loop, but in our Cocoa builds it doesn't.

The fix for a future PR would be to create a new GamepadProviderGCController (similar to the existing GamepadProviderSDL2) that uses Apple's native Game Controller framework (GameController. framework / GCController). This integrates natively with the Cocoa run loop and supports Xbox, PlayStation, Switch Pro, and MFi controllers out of the box. Key APIs: [GCController controllers] for enumeration, the extendedGamepad profile for button/axis mapping, and GCController notifications for connect/disconnect.

However - please do not submit a Mac gamepad PR unless it's actually been tested with real gamepads. <--- important!

@mateusbentes

Copy link
Copy Markdown
Contributor Author

@SethRobinson sorry to not work, i can make another PR trying to work joystick, perhaps its the problem of joystick of Dink Smallwood HD.

@SethRobinson

SethRobinson commented Mar 11, 2026

Copy link
Copy Markdown
Owner

No worries. LooneyLadders is the Proton joystick/gamepad testing app, if it works there, it should work ok with Dink

@mateusbentes

Copy link
Copy Markdown
Contributor Author

@SethRobinson if you want you can merge, SethRobinson/RTDink#23 PR, but I warn, will not work joystick on Mac util fixed Lonely Ladders.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants