imgui_bundle icon indicating copy to clipboard operation
imgui_bundle copied to clipboard

Text input on Android: toggle soft keyboard

Open max22- opened this issue 4 months ago • 3 comments

Hi, I am trying to port a project i am working on to Android (a little programming environment based on Lua + Dear Imgui). imgui_bundle looks fantastic to do that !

Maybe i am missing something, but the soft keyboard doesn't toggle when it needs to. I have tested with imgui_bundle_template, added an ImGuiColorTextEdit widget, and an InputTextMultiline.

I've managed to get it working (with the help of chatGPT... because android is not really my cup of tea :s). If you want i can share the little piece of code (a java method to toggle the keyboard, and a jni wrapper to call it). But you will probably come up with something better !

imgui_bundle_template commit : 771fb9e103a39b60713a275f2142dabab604eff0 imgui_bundle commit : 55b2cd34efaf740cddf17c0141c710b3abf84d43

platform : Debian testing, compiling for android language : C++ compiler: gcc 15.2.0 backend : SDL2 + OpenGL

btw, thank you very much for your online imgui manual. i use it all the time !

max22- avatar Nov 02 '25 23:11 max22-

Hi,

Thanks for your message. Actually, Android is not my cup of tea either. I'd be interested if you are willing to share a working piece of code to toggle the keyboard.

Thanks!

pthom avatar Nov 03 '25 09:11 pthom

Here is my code. It would have been better to make a pull request maybe, but i don't know where is the best place to put each part. And the java file i needed to edit (imguibundleexampleintegration.java) is generated. I hope this is helpful.

diff --git a/hello_world.cpp b/hello_world.cpp
index 6287d93..7d4cb62 100644
--- a/hello_world.cpp
+++ b/hello_world.cpp
@@ -7,6 +7,23 @@
 
 #include <cmath>
 
+#ifdef __ANDROID__
+#include <jni.h>
+#include <SDL.h>
+#include <SDL_system.h>
+
+void ShowAndroidKeyboard()
+{
+    JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();
+    jobject activity = (jobject)SDL_AndroidGetActivity();
+    jclass clazz = env->GetObjectClass(activity);
+    jmethodID method_id = env->GetMethodID(clazz, "ShowAndroidKeyboard", "()V");
+    if (method_id)
+        env->CallVoidMethod(activity, method_id);
+    env->DeleteLocalRef(activity);
+    env->DeleteLocalRef(clazz);
+}
+#endif
 
 void DemoImplot()
 {
@@ -32,6 +49,10 @@ void DemoImplot()
         ImPlot::EndPlot();
     }
 #endif
+
+    static char buf[1024];
+    ImGui::InputTextMultiline("InputTextMultiline", buf, sizeof(buf));
+
 }
 
 
@@ -63,14 +84,34 @@ int main(int , char *[])
     HelloImGui::SetAssetsFolder(ASSETS_LOCATION);
 #endif
 
-    HelloImGui::SimpleRunnerParams runnnerParams;
-    runnnerParams.guiFunction = Gui;
-    runnnerParams.windowSize = {600, 800};
+    HelloImGui::SimpleRunnerParams simpleRunnerParams;
+    simpleRunnerParams.guiFunction = Gui;
+    simpleRunnerParams.windowSize = {600, 800};
+
+#ifdef __ANDROID__
+    HelloImGui::RunnerParams runnerParams = simpleRunnerParams.ToRunnerParams();
+    runnerParams.callbacks.AfterSwap = []() {
+        static bool keyboardVisible = false;
+        bool wantText = ImGui::GetIO().WantTextInput;
+        if(wantText && !keyboardVisible) {
+            SDL_StartTextInput();
+            ShowAndroidKeyboard();
+            keyboardVisible = true;
+        } else if(!wantText && keyboardVisible) {
+            SDL_StopTextInput();
+            keyboardVisible = false;
+        }
+    };
+#endif
 
     ImmApp::AddOnsParams addOnsParams;
     addOnsParams.withMarkdown = true;
     addOnsParams.withImplot = true;
 
-    ImmApp::Run(runnnerParams, addOnsParams);
+#ifdef __ANDROID__
+    ImmApp::Run(runnerParams, addOnsParams);
+#else
+    ImmApp::Run(simpleRunnerParams, addOnsParams);
+#endif
     return 0;
 }

And the "ShowAndroidKeyboard" function in imguibundleexampleintegration.java :

package com.helloimgui.imguibundleexampleintegration;
import android.view.inputmethod.InputMethodManager;
import android.content.Context;

import org.libsdl.app.SDLActivity;

/**
* A sample wrapper class that just calls SDLActivity
*/
public class imguibundleexampleintegration extends SDLActivity
{
    /**
     * This method is called by SDL before loading the native shared libraries.
     * It can be overridden to provide names of shared libraries to be loaded.
     * The default implementation returns the defaults. It never returns null.
     * An array returned by a new implementation must at least contain "SDL2".
     * Also keep in mind that the order the libraries are loaded may matter.
     * @return names of shared libraries to be loaded (e.g. "SDL2", "main").
     */
    protected String[] getLibraries() {
        return new String[] {
            // "hidapi",
            "SDL2",
            // "SDL2_image",
            // "SDL2_mixer",
            // "SDL2_net",
            // "SDL2_ttf",
            "imgui_bundle_example_integration"
        };
    }

    public void ShowAndroidKeyboard() {
        InputMethodManager imm = null;
        imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
        }
    }

}

/*
This code was generated from apkCMake_activityClassName.java
and will be placed in the appropriate folder.

You can customize your application id via
* ${apkCMake_applicationIdUrlPart}
* ${apkCMake_applicationIdNamePart}
* ${apkCMake_activityClassName}

For example, if:
* apkCMake_applicationIdUrlPart=com.my_company
* apkCMake_applicationIdNamePart=my_app
* apkCMake_activityClassName=MyApp
then a file MyApp.java will be created into
app/src/main/java/com/my_company/my_app/MyApp.java
*/

max22- avatar Nov 03 '25 11:11 max22-

Thanks, I labeled this as a faq issue, so that other users can find it.

pthom avatar Nov 04 '25 09:11 pthom