The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
tvOS keyboard improvements (patch enclosed)
oviano


Joined: 05 Mar 2016
Posts: 24
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 */
tvOS keyboard improvements (patch enclosed)
Alex Szpakowski
Guest

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.
Quote:
On Dec 18, 2016, at 8:11 AM, oviano wrote:
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_REALdiff -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" #endifdiff -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); #endifdiff -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 */

_______________________________________________SDL mailinghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
oviano


Joined: 05 Mar 2016
Posts: 24
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.