diff --git a/include/SDL_events.h b/include/SDL_events.h index 640b0096b..7a5d42c54 100644 --- a/include/SDL_events.h +++ b/include/SDL_events.h @@ -138,6 +138,7 @@ typedef struct SDL_KeyboardEvent typedef struct SDL_TextEditingEvent { Uint32 type; /**< ::SDL_TEXTEDITING */ + Uint32 windowID; /**< The window with keyboard focus, if any */ char text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */ int start; /**< The start cursor of selected editing text */ int length; /**< The length of selected editing text */ diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index a975ae098..e8e6831b6 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -679,6 +679,8 @@ SDL_SetKeyboardFocus(int index, SDL_Window * window) if (keyboard->focus) { SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0); + if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) + SDL_StartTextInput(); } } @@ -839,10 +841,14 @@ SDL_SendKeyboardText(int index, const char *text) } int -SDL_SendEditingText(const char *text, int start, int length) +SDL_SendEditingText(int index, const char *text, int start, int length) { + SDL_Keyboard *keyboard = SDL_GetKeyboard(index); int posted; + if (!keyboard) + return 0; + /* Post the event, if desired */ posted = 0; if (SDL_GetEventState(SDL_TEXTEDITING) == SDL_ENABLE) { @@ -851,6 +857,7 @@ SDL_SendEditingText(const char *text, int start, int length) event.edit.start = start; event.edit.length = length; SDL_strlcpy(event.edit.text, text, SDL_arraysize(event.text.text)); + event.edit.windowID = keyboard->focus->id; posted = (SDL_PushEvent(&event) > 0); } return (posted); diff --git a/src/events/SDL_keyboard_c.h b/src/events/SDL_keyboard_c.h index f574fcce8..d4021ff35 100644 --- a/src/events/SDL_keyboard_c.h +++ b/src/events/SDL_keyboard_c.h @@ -82,7 +82,7 @@ extern int SDL_SendKeyboardKey(int index, Uint8 state, SDL_scancode scancode); extern int SDL_SendKeyboardText(int index, const char *text); /* Send editing text for selected range from start to end */ -extern int SDL_SendEditingText(const char *text, int start, int end); +extern int SDL_SendEditingText(int index, const char *text, int start, int end); /* Shutdown the keyboard subsystem */ extern void SDL_KeyboardQuit(void); diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m index 7dd4e154c..322023ceb 100644 --- a/src/video/cocoa/SDL_cocoakeyboard.m +++ b/src/video/cocoa/SDL_cocoakeyboard.m @@ -140,7 +140,8 @@ _selectedRange = selRange; _markedRange = NSMakeRange(0, [aString length]); - SDL_SendEditingText([aString UTF8String], selRange.location, selRange.length); + SDL_SendEditingText(_keyboard, [aString UTF8String], + selRange.location, selRange.length); DEBUG_IME(@"setMarkedText: %@, (%d, %d)", _markedText, selRange.location, selRange.length); @@ -632,7 +633,15 @@ Cocoa_StartTextInput(_THIS) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSView *parentView = [[NSApp keyWindow] contentView]; - data->fieldEdit = [[SDLTranslatorResponder alloc] initWithFrame:NSMakeRect(0.0, 0.0, 0.0, 0.0)]; + /* We only keep one field editor per process, since only the front most + * window can receive text input events, so it make no sense to keep more + * than one copy. When we switched to another window and requesting for + * text input, simply remove the field editor from its superview then add + * it to the front most window's content view */ + if (! data->fieldEdit) + data->fieldEdit = + [[SDLTranslatorResponder alloc] initWithFrame: NSMakeRect(0.0, 0.0, 0.0, 0.0)]; + [data->fieldEdit setKeyboard: data->keyboard]; if (! [[data->fieldEdit superview] isEqual: parentView])