Discussion:
[SDL] tvOS keyboard improvements (patch enclosed)
oviano
2016-12-18 12:11:04 UTC
Permalink
I needed to tweak the way the screen keyboard works in tvOS.

The problem is that it behaves like the iOS one in that it assumes that the application will be rendering the text so you can see what you are typing. This is not the case with tvOS because the keyboard takes overlays the whole screen and provides its own text input box. This wouldn't be so bad if the text input box wasn't set to invisible/not updating, essentially meaning you are typing blind.

The fix was twofold; firstly for tvOS I've made the text input field visible and allowed it's contents to be updated as the user types the text. Secondly, I've added a function to supply the initial text field so that you can start it from whatever you are expecting the user to edit.


Code:

diff -r 007dfe83abf8 include/SDL_keyboard.h
--- a/include/SDL_keyboard.h Wed Oct 19 20:50:33 2016 -0700
+++ b/include/SDL_keyboard.h Sun Dec 18 14:57:42 2016 +0300
@@ -206,6 +206,13 @@
*/
extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenKeyboardShown(SDL_Window *window);

+/**
+ * \brief Sets the contents of the screen keyboard's text field.
+ *
+ * \sa SDL_StartTextInput()
+ */
+extern DECLSPEC void SDLCALL SDL_SetScreenKeyboardText(const char *a);
+
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
diff -r 007dfe83abf8 src/dynapi/SDL_dynapi_overrides.h
--- a/src/dynapi/SDL_dynapi_overrides.h Wed Oct 19 20:50:33 2016 -0700
+++ b/src/dynapi/SDL_dynapi_overrides.h Sun Dec 18 14:57:42 2016 +0300
@@ -235,6 +235,7 @@
#define SDL_SetTextInputRect SDL_SetTextInputRect_REAL
#define SDL_HasScreenKeyboardSupport SDL_HasScreenKeyboardSupport_REAL
#define SDL_IsScreenKeyboardShown SDL_IsScreenKeyboardShown_REAL
+#define SDL_SetScreenKeyboardText SDL_SetScreenKeyboardText_REAL
#define SDL_LoadObject SDL_LoadObject_REAL
#define SDL_LoadFunction SDL_LoadFunction_REAL
#define SDL_UnloadObject SDL_UnloadObject_REAL
diff -r 007dfe83abf8 src/dynapi/SDL_dynapi_procs.h
--- a/src/dynapi/SDL_dynapi_procs.h Wed Oct 19 20:50:33 2016 -0700
+++ b/src/dynapi/SDL_dynapi_procs.h Sun Dec 18 14:57:42 2016 +0300
@@ -264,6 +264,7 @@
SDL_DYNAPI_PROC(void,SDL_SetTextInputRect,(SDL_Rect *a),(a),)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasScreenKeyboardSupport,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_IsScreenKeyboardShown,(SDL_Window *a),(a),return)
+SDL_DYNAPI_PROC(void,SDL_SetScreenKeyboardText,(const char *a),(a),)
SDL_DYNAPI_PROC(void*,SDL_LoadObject,(const char *a),(a),return)
SDL_DYNAPI_PROC(void*,SDL_LoadFunction,(void *a, const char *b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_UnloadObject,(void *a),(a),)
diff -r 007dfe83abf8 src/video/SDL_sysvideo.h
--- a/src/video/SDL_sysvideo.h Wed Oct 19 20:50:33 2016 -0700
+++ b/src/video/SDL_sysvideo.h Sun Dec 18 14:57:42 2016 +0300
@@ -274,6 +274,7 @@
void (*ShowScreenKeyboard) (_THIS, SDL_Window *window);
void (*HideScreenKeyboard) (_THIS, SDL_Window *window);
SDL_bool (*IsScreenKeyboardShown) (_THIS, SDL_Window *window);
+ void (*SetScreenKeyboardText) (_THIS, const char *text);

/* Clipboard */
int (*SetClipboardText) (_THIS, const char *text);
diff -r 007dfe83abf8 src/video/SDL_video.c
--- a/src/video/SDL_video.c Wed Oct 19 20:50:33 2016 -0700
+++ b/src/video/SDL_video.c Sun Dec 18 14:57:42 2016 +0300
@@ -3598,6 +3598,14 @@
return SDL_FALSE;
}

+void
+SDL_SetScreenKeyboardText(const char *text)
+{
+ if (_this && _this->SetScreenKeyboardText) {
+ _this->SetScreenKeyboardText(_this, text);
+ }
+}
+
#if SDL_VIDEO_DRIVER_ANDROID
#include "android/SDL_androidmessagebox.h"
#endif
diff -r 007dfe83abf8 src/video/uikit/SDL_uikitvideo.m
--- a/src/video/uikit/SDL_uikitvideo.m Wed Oct 19 20:50:33 2016 -0700
+++ b/src/video/uikit/SDL_uikitvideo.m Sun Dec 18 14:57:42 2016 +0300
@@ -107,6 +107,7 @@
device->HideScreenKeyboard = UIKit_HideScreenKeyboard;
device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
device->SetTextInputRect = UIKit_SetTextInputRect;
+ device->SetScreenKeyboardText = UIKit_SetScreenKeyboardText;
#endif

device->SetClipboardText = UIKit_SetClipboardText;
diff -r 007dfe83abf8 src/video/uikit/SDL_uikitviewcontroller.h
--- a/src/video/uikit/SDL_uikitviewcontroller.h Wed Oct 19 20:50:33 2016 -0700
+++ b/src/video/uikit/SDL_uikitviewcontroller.h Sun Dec 18 14:57:42 2016 +0300
@@ -84,4 +84,5 @@
void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window);
SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window);
void UIKit_SetTextInputRect(_THIS, SDL_Rect *rect);
+void UIKit_SetScreenKeyboardText(_THIS, const char *text);
#endif
diff -r 007dfe83abf8 src/video/uikit/SDL_uikitviewcontroller.m
--- a/src/video/uikit/SDL_uikitviewcontroller.m Wed Oct 19 20:50:33 2016 -0700
+++ b/src/video/uikit/SDL_uikitviewcontroller.m Sun Dec 18 14:57:42 2016 +0300
@@ -179,8 +179,9 @@
textField = [[UITextField alloc] initWithFrame:CGRectZero];
textField.delegate = self;
/* placeholder so there is something to delete! */
+#if !TARGET_OS_TV
textField.text = @" ";
-
+#endif
/* set UITextInputTrait properties, mostly to defaults */
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
@@ -190,7 +191,9 @@
textField.returnKeyType = UIReturnKeyDefault;
textField.secureTextEntry = NO;

+#if !TARGET_OS_TV
textField.hidden = YES;
+#endif
keyboardVisible = NO;

#if !TARGET_OS_TV
@@ -289,6 +292,11 @@
[self updateKeyboard];
}

+- (void)setKeyboardText:(const char*)text
+{
+ textField.text = [NSString stringWithUTF8String:text];
+}
+
/* UITextFieldDelegate method. Invoked when user types something. */
- (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
@@ -335,7 +343,11 @@
SDL_SendKeyboardText([string UTF8String]);
}

+#if TARGET_OS_TV
+ return YES;
+#else
return NO; /* don't allow the edit! (keep placeholder text there) */
+#endif
}

/* Terminates the editing session */
@@ -423,6 +435,21 @@
}
}

+void
+UIKit_SetScreenKeyboardText(_THIS, const char *text)
+{
+ if (!text) {
+ SDL_InvalidParamError("text");
+ return;
+ }
+
+ @autoreleasepool {
+ SDL_uikitviewcontroller *vc = GetWindowViewController(SDL_GetFocusWindow());
+ if (vc != nil) {
+ [vc setKeyboardText:text];
+ }
+ }
+}

#endif /* SDL_IPHONE_KEYBOARD */
Alex Szpakowski
2016-12-18 14:34:54 UTC
Permalink
Thanks for the patch! I’ll probably make the keyboard text setter a hint for now, since I don’t think other operating systems will be making use of it.
Post by oviano
I needed to tweak the way the screen keyboard works in tvOS.
The problem is that it behaves like the iOS one in that it assumes that the application will be rendering the text so you can see what you are typing. This is not the case with tvOS because the keyboard takes overlays the whole screen and provides its own text input box. This wouldn't be so bad if the text input box wasn't set to invisible/not updating, essentially meaning you are typing blind.
The fix was twofold; firstly for tvOS I've made the text input field visible and allowed it's contents to be updated as the user types the text. Secondly, I've added a function to supply the initial text field so that you can start it from whatever you are expecting the user to edit.
diff -r 007dfe83abf8 include/SDL_keyboard.h
--- a/include/SDL_keyboard.h Wed Oct 19 20:50:33 2016 -0700
+++ b/include/SDL_keyboard.h Sun Dec 18 14:57:42 2016 +0300
@@ -206,6 +206,13 @@
*/
extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenKeyboardShown(SDL_Window *window);
+/**
+ * \brief Sets the contents of the screen keyboard's text field.
+ *
+ * \sa SDL_StartTextInput()
+ */
+extern DECLSPEC void SDLCALL SDL_SetScreenKeyboardText(const char *a);
+
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
diff -r 007dfe83abf8 src/dynapi/SDL_dynapi_overrides.h
--- a/src/dynapi/SDL_dynapi_overrides.h Wed Oct 19 20:50:33 2016 -0700
+++ b/src/dynapi/SDL_dynapi_overrides.h Sun Dec 18 14:57:42 2016 +0300
@@ -235,6 +235,7 @@
#define SDL_SetTextInputRect SDL_SetTextInputRect_REAL
#define SDL_HasScreenKeyboardSupport SDL_HasScreenKeyboardSupport_REAL
#define SDL_IsScreenKeyboardShown SDL_IsScreenKeyboardShown_REAL
+#define SDL_SetScreenKeyboardText SDL_SetScreenKeyboardText_REAL
#define SDL_LoadObject SDL_LoadObject_REAL
#define SDL_LoadFunction SDL_LoadFunction_REAL
#define SDL_UnloadObject SDL_UnloadObject_REAL
diff -r 007dfe83abf8 src/dynapi/SDL_dynapi_procs.h
--- a/src/dynapi/SDL_dynapi_procs.h Wed Oct 19 20:50:33 2016 -0700
+++ b/src/dynapi/SDL_dynapi_procs.h Sun Dec 18 14:57:42 2016 +0300
@@ -264,6 +264,7 @@
SDL_DYNAPI_PROC(void,SDL_SetTextInputRect,(SDL_Rect *a),(a),)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasScreenKeyboardSupport,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_IsScreenKeyboardShown,(SDL_Window *a),(a),return)
+SDL_DYNAPI_PROC(void,SDL_SetScreenKeyboardText,(const char *a),(a),)
SDL_DYNAPI_PROC(void*,SDL_LoadObject,(const char *a),(a),return)
SDL_DYNAPI_PROC(void*,SDL_LoadFunction,(void *a, const char *b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_UnloadObject,(void *a),(a),)
diff -r 007dfe83abf8 src/video/SDL_sysvideo.h
--- a/src/video/SDL_sysvideo.h Wed Oct 19 20:50:33 2016 -0700
+++ b/src/video/SDL_sysvideo.h Sun Dec 18 14:57:42 2016 +0300
@@ -274,6 +274,7 @@
void (*ShowScreenKeyboard) (_THIS, SDL_Window *window);
void (*HideScreenKeyboard) (_THIS, SDL_Window *window);
SDL_bool (*IsScreenKeyboardShown) (_THIS, SDL_Window *window);
+ void (*SetScreenKeyboardText) (_THIS, const char *text);
/* Clipboard */
int (*SetClipboardText) (_THIS, const char *text);
diff -r 007dfe83abf8 src/video/SDL_video.c
--- a/src/video/SDL_video.c Wed Oct 19 20:50:33 2016 -0700
+++ b/src/video/SDL_video.c Sun Dec 18 14:57:42 2016 +0300
@@ -3598,6 +3598,14 @@
return SDL_FALSE;
}
+void
+SDL_SetScreenKeyboardText(const char *text)
+{
+ if (_this && _this->SetScreenKeyboardText) {
+ _this->SetScreenKeyboardText(_this, text);
+ }
+}
+
#if SDL_VIDEO_DRIVER_ANDROID
#include "android/SDL_androidmessagebox.h"
#endif
diff -r 007dfe83abf8 src/video/uikit/SDL_uikitvideo.m
--- a/src/video/uikit/SDL_uikitvideo.m Wed Oct 19 20:50:33 2016 -0700
+++ b/src/video/uikit/SDL_uikitvideo.m Sun Dec 18 14:57:42 2016 +0300
@@ -107,6 +107,7 @@
device->HideScreenKeyboard = UIKit_HideScreenKeyboard;
device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
device->SetTextInputRect = UIKit_SetTextInputRect;
+ device->SetScreenKeyboardText = UIKit_SetScreenKeyboardText;
#endif
device->SetClipboardText = UIKit_SetClipboardText;
diff -r 007dfe83abf8 src/video/uikit/SDL_uikitviewcontroller.h
--- a/src/video/uikit/SDL_uikitviewcontroller.h Wed Oct 19 20:50:33 2016 -0700
+++ b/src/video/uikit/SDL_uikitviewcontroller.h Sun Dec 18 14:57:42 2016 +0300
@@ -84,4 +84,5 @@
void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window);
SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window);
void UIKit_SetTextInputRect(_THIS, SDL_Rect *rect);
+void UIKit_SetScreenKeyboardText(_THIS, const char *text);
#endif
diff -r 007dfe83abf8 src/video/uikit/SDL_uikitviewcontroller.m
--- a/src/video/uikit/SDL_uikitviewcontroller.m Wed Oct 19 20:50:33 2016 -0700
+++ b/src/video/uikit/SDL_uikitviewcontroller.m Sun Dec 18 14:57:42 2016 +0300
@@ -179,8 +179,9 @@
textField = [[UITextField alloc] initWithFrame:CGRectZero];
textField.delegate = self;
/* placeholder so there is something to delete! */
+#if !TARGET_OS_TV
-
+#endif
/* set UITextInputTrait properties, mostly to defaults */
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
@@ -190,7 +191,9 @@
textField.returnKeyType = UIReturnKeyDefault;
textField.secureTextEntry = NO;
+#if !TARGET_OS_TV
textField.hidden = YES;
+#endif
keyboardVisible = NO;
#if !TARGET_OS_TV
@@ -289,6 +292,11 @@
[self updateKeyboard];
}
+- (void)setKeyboardText:(const char*)text
+{
+ textField.text = [NSString stringWithUTF8String:text];
+}
+
/* UITextFieldDelegate method. Invoked when user types something. */
- (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
@@ -335,7 +343,11 @@
SDL_SendKeyboardText([string UTF8String]);
}
+#if TARGET_OS_TV
+ return YES;
+#else
return NO; /* don't allow the edit! (keep placeholder text there) */
+#endif
}
/* Terminates the editing session */
@@ -423,6 +435,21 @@
}
}
+void
+UIKit_SetScreenKeyboardText(_THIS, const char *text)
+{
+ if (!text) {
+ SDL_InvalidParamError("text");
+ return;
+ }
+
+ SDL_uikitviewcontroller *vc = GetWindowViewController(SDL_GetFocusWindow());
+ if (vc != nil) {
+ [vc setKeyboardText:text];
+ }
+ }
+}
#endif /* SDL_IPHONE_KEYBOARD */
_______________________________________________
SDL mailing list
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org <http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org>
oviano
2016-12-19 11:44:12 UTC
Permalink
Yes that makes sense, it's pretty specific to tvOS.

The other suggestion I have is kind of related - because the tvOS screen keyboard takes up the whole screen it's easy to forget what you are editing. It would be great if that screen could have a title that you could set in a similar manner.

When the keyboard appears elsewhere (e.g. the ATV settings for example) then it always has a title.
Loading...