Hi,

I finally managed to track the problem with keyboard events with OSWindow. However, I cannot fix it without introducing a crash in an autorelease, or a memory leak.

The SDL2 problem can be fixed by applying the following patch:

diff --git a/platforms/iOS/vm/Common/Classes/sqSqueakEventsAPI.m b/platforms/iOS/vm/Common/Classes/sqSqueakEventsAPI.m
index 94c3c4c82..4b5aec8c5 100644
--- a/platforms/iOS/vm/Common/Classes/sqSqueakEventsAPI.m
+++ b/platforms/iOS/vm/Common/Classes/sqSqueakEventsAPI.m
@@ -100,9 +100,7 @@ sqInt ioProcessEvents(void) {
��
�� // We need to run the vmIOProcessEvents even if we are using SDL2,
�� // otherwise we end with some double free errors in an autorelease pool.
- vmIOProcessEvents();
- �� ��if(ioProcessEventsHandler && ioProcessEventsHandler != vmIOProcessEvents)
- �� �� �� ��ioProcessEventsHandler();
+ �� ��ioProcessEventsHandler();

However, this introduces a crash in an Objective-C autorelease pool, in at leas two locations:

diff --git a/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.m b/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.m
index 4f2ac06ea..c1ec3e1ea 100644
--- a/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.m
+++ b/platforms/iOS/vm/OSX/sqSqueakOSXApplication+events.m
@@ -152,9 +152,10 @@ - (void) recordCharEvent:(NSString *) unicodeString fromView: (NSView <sqSqueakO
�� }
�� }
��
- NSString *lookupString = AUTORELEASEOBJ([[NSString alloc] initWithCharacters: &unicode length: 1]);
+ NSString *lookupString = [[NSString alloc] initWithCharacters: &unicode length: 1];
�� [lookupString getBytes: &macRomanCharacter maxLength: 1 usedLength: NULL encoding: NSMacOSRomanStringEncoding
�� �� options: 0 range: picker remainingRange: NULL];
+ �� �� �� ��[lookupString release];
��
�� evt.pressCode = EventKeyDown;
�� unsigned short keyCodeRemembered = evt.charCode;

diff --git a/platforms/iOS/vm/OSX/sqSqueakOSXOpenGLView.m b/platforms/iOS/vm/OSX/sqSqueakOSXOpenGLView.m
index c441332a3..72aa8c42d 100644
--- a/platforms/iOS/vm/OSX/sqSqueakOSXOpenGLView.m
+++ b/platforms/iOS/vm/OSX/sqSqueakOSXOpenGLView.m
@@ -747,7 +747,7 @@ - (NSString *) dealWithOpenStepChars: (NSString *) openStep {
��
��
��-(void)keyDown:(NSEvent*)theEvent {
- keyBoardStrokeDetails *aKeyBoardStrokeDetails = AUTORELEASEOBJ([[keyBoardStrokeDetails alloc] init]);
+ keyBoardStrokeDetails *aKeyBoardStrokeDetails = ([[keyBoardStrokeDetails alloc] init]);
�� aKeyBoardStrokeDetails.keyCode = [theEvent keyCode];
�� aKeyBoardStrokeDetails.modifierFlags = [theEvent modifierFlags];
��
@@ -757,6 +757,8 @@ -(void)keyDown:(NSEvent*)theEvent {
�� [self interpretKeyEvents: down];
�� self.lastSeenKeyBoardStrokeDetails = NULL;
�� }
+
+ //[aKeyBoardStrokeDetails release];
��}

In the last location I had to comment my attempt on doing a manual release because it introduces a crash.

OSWindow can be tested in a fresh Pharo image by doing the following in a workspace:

FFIExternalStructure allSubclassesDo: #rebuildFieldAccessors.
SDL_Event initialize.
SDL2 findSDL2.
OSWindowWorldMorph new open.
��
I have attached the full diff with my bug fix attempt. I hope that someone that is more familiar with the OS X platform code and Objective-C can remove these autoreleases without introducing crashes.

When executed in a debugger, the crash is detected in SDL2 Cocoa_PumpEvents:

void
Cocoa_PumpEvents(_THIS)
{ @autoreleasepool
{
�� �� /* Update activity every 30 seconds to prevent screensaver */
�� �� SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
�� �� if (_this->suspend_screensaver && !data->screensaver_use_iopm) {
�� �� �� �� Uint32 now = SDL_GetTicks();
�� �� �� �� if (!data->screensaver_activity ||
�� �� �� �� �� �� SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) {
�� �� �� �� �� �� UpdateSystemActivity(UsrActivity);
�� �� �� �� �� �� data->screensaver_activity = now;
�� �� �� �� }
�� �� }

�� �� for ( ; ; ) {
�� �� �� �� NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
�� �� �� �� if ( event == nil ) {
�� �� �� �� �� �� break;
�� �� �� �� }

�� �� �� �� if (!s_bShouldHandleEventsInSDLApplication) {
�� �� �� �� �� �� Cocoa_DispatchEvent(event);
�� �� �� �� }

�� �� �� �� // Pass events down to SDLApplication to be handled in sendEvent:
�� �� �� �� [NSApp sendEvent:event];
�� �� }
}}


For tracking these actual calls to #autorelease, I had to set a breakpoint on the #autorelease Objective-C selector, and log the stacktrace to find where it is called in our code.

Best regards,
Ronie��