Fixed bug 2525 - Keyboard focus crash
authorSam Lantinga <slouken@libsdl.org>
Wed, 25 Jun 2014 02:08:37 -0700
changeset 892638e89ab78465
parent 8925 8469a1c3e484
child 8953 dc80dc0bd22e
Fixed bug 2525 - Keyboard focus crash

Todd Seiler

Call Stack:
#0 0x0000000101c29291 in Cocoa_StartTextInput at /Users/Todd/Desktop/codes/sources/SDL/src/video/cocoa/SDL_cocoakeyboard.m:512
#1 0x0000000101c110c5 in SDL_SetKeyboardFocus at /Users/Todd/Desktop/codes/sources/SDL/src/events/SDL_keyboard.c:643
#2 0x0000000101c32be4 in SetupWindowData at /Users/Todd/Desktop/codes/sources/SDL/src/video/cocoa/SDL_cocoawindow.m:981
#3 0x0000000101c32d2a in Cocoa_CreateWindowFrom at /Users/Todd/Desktop/codes/sources/SDL/src/video/cocoa/SDL_cocoawindow.m:1092
#4 0x0000000101c99999 in SDL_CreateWindowFrom_REAL at /Users/Todd/Desktop/codes/sources/SDL/src/video/SDL_video.c:1338
#5 0x0000000101ce1484 in SDL_CreateWindowFrom at /Users/Todd/Desktop/codes/sources/SDL/src/dynapi/SDL_dynapi_procs.h:547
#6 0x0000000100018a5e in SceneRenderer at /Users/Todd/Desktop/codes/sources/tseiler_Todds-MacBook-Pro_3405/AppName/src/SceneRenderer.cpp:138
#7 0x0000000100017ca5 in SceneRenderer at /Users/Todd/Desktop/codes/sources/tseiler_Todds-MacBook-Pro_3405/AppName/src/SceneRenderer.cpp:145
#8 0x000000010000cd96 in App::execute(int, char**) at /Users/Todd/Desktop/codes/sources/tseiler_Todds-MacBook-Pro_3405/AppName/src/App.cpp:28
#9 0x0000000100004402 in main at /Users/Todd/Desktop/codes/sources/tseiler_Todds-MacBook-Pro_3405/AppName/src/main.cpp:8


This issue occurred when using Ogre3D Graphics engine on Mac (cocoa) to create the window. Then handing the window handle off to SDL_CreateWindowFrom().

In Ogre3D application you do the following:
window_ = root_->initialise(true, "Ogre Window 2");
loadOgreResources();
Ogre::WindowEventUtilities::addWindowEventListener(window_, this);

#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
NSWindow* Data = 0;
window_->getCustomAttribute("WINDOW", &Data);
sdl_window_ = SDL_CreateWindowFrom((void*)Data);
#endif

It results in a crash in this function:
SDL_cocoakeyboard.m

void
Cocoa_StartTextInput(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SDL_Window *window = SDL_GetKeyboardFocus();
NSWindow *nswindow = nil;
if (window)
nswindow = ((SDL_WindowData*)window->driverdata)->nswindow;

// ...
}

The crash occurred because "driverdata" was nil. Before this function call, a call to SetupWindowData is called:

SDL_cocoawindow.m

static int
SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
{
// ...

if ([nswindow isKeyWindow]) {
window->flags |= SDL_WINDOW_INPUT_FOCUS;
SDL_SetKeyboardFocus(data->window);
}

/* Prevents the window's "window device" from being destroyed when it is
* hidden. See http://www.mikeash.com/pyblog/nsopenglcontext-and-one-shot.html
*/
[nswindow setOneShot:NO];

/* All done! */
[pool release];
window->driverdata = data;
return 0;
}

As you can see: "window->driverdata = data" is performed after the "SDL_SetKeyboardFocus()" call, which eventually leads to "Cocoa_StartTextInput()" where the crash occurs.
src/video/cocoa/SDL_cocoawindow.m
     1.1 --- a/src/video/cocoa/SDL_cocoawindow.m	Wed Jun 25 01:43:58 2014 -0700
     1.2 +++ b/src/video/cocoa/SDL_cocoawindow.m	Wed Jun 25 02:08:37 2014 -0700
     1.3 @@ -921,7 +921,7 @@
     1.4      SDL_WindowData *data;
     1.5  
     1.6      /* Allocate the window data */
     1.7 -    data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
     1.8 +    window->driverdata = data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
     1.9      if (!data) {
    1.10          return SDL_OutOfMemory();
    1.11      }
    1.12 @@ -995,7 +995,6 @@
    1.13  
    1.14      /* All done! */
    1.15      [pool release];
    1.16 -    window->driverdata = data;
    1.17      return 0;
    1.18  }
    1.19