floooh / sokol

minimal cross-platform standalone C headers
https://floooh.github.io/sokol-html5
zlib License
6.84k stars 483 forks source link

Sokol + Imgui + emscripten `InputText` not working. #809

Closed voidware closed 1 year ago

voidware commented 1 year ago

Cannot enter any text in an Imgui InputText widget on mobile using Firefox browser (only one tested).

Keyboard appears. Text appears, but Enter does not work. so the line cannot be submitted.

voidware commented 1 year ago

Ok, false alarm. Or rather i forgot to patch in my previous hacks when updating Sokol. This should really be sorted.

Here's the fix:

Use event->key not event->code. I know apparently code supersedes key, but it doesn't work!

sokol_app.h

_SOKOL_PRIVATE EM_BOOL _sapp_emsc_key_cb(int emsc_type, const EmscriptenKeyboardEvent* emsc_event, void* user_data) {
...
            else {

                // XXX HACK VOIDWARE
                //_sapp.event.key_code = _sapp_emsc_translate_key(emsc_event->code);
                _sapp.event.key_code = _sapp_emsc_translate_key(emsc_event->key);
                ...
floooh commented 1 year ago

I think it's ok to use key instead of code (needs a different translation table, but that should be ok).

(strike that, the key item is all sorts of messed up: it sends localized keys, e.g. when switching english vs german keyboard layout, it will send either 'y' or 'z', and it will also send different strings when Shift is pressed (e.g. 'z' vs 'Z').

Unfortunately the localization of the key item kills the whole idea, the key code in sapp_event is supposed to be the physical key code, not a localized key name.

I'm rather confused why the Dear ImGui TextInput field uses raw keyboard events though instead of the localized SAPP_EVENTTYPE_CHAR input, I need to check that.

floooh commented 1 year ago

...ah ok, the TextInput field does take the char code from SAPP_EVENTTYPE_CHAR, but only for regular characters, not for special keys like Enter.

The underlying problem remains though that mobile browsers don't send a physical key code (I guess because mobile devices don't have a "physical keyboard", and the only alternative are keys that are already localized, which doesn't allow to map back to the physical key codes).

The only solution would be to treat some keys special as fallback if the key code isn't set (e.g. only send a handful of special keys which are not affected by localization, like Enter, Arrows, etc...).

floooh commented 1 year ago

(PS: on Android Chrome I actually don't get any input in the Dear ImGui text input field... I'll try Android Firefox next)

floooh commented 1 year ago

Ok, I have committed a fix for this specific problem which makes Text Input work in Android Firefox.

The solution is simply to fallback to EmscriptenKeyboardEvent.key if EmscriptenKeyboardEvent.code isn't populated. This will only yield a valid result for any 'translation-agnostic' keys, like Enter or the Arrow keys, but that's actually ok.

The bigger remaining problem is however that character input doesn't work at all on Android Chrome, but that's a separate issue.

floooh commented 1 year ago

PS: reading up on html5 keyboard input here: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent...

...it looks like all event-based methods to get UNICODE character input are deprecated, and the only intended way is to use a HTML5 text input field and inspect its contents for changes after a key press event is received.

sokol_app.h opens such a hidden text input field, but this comes with all sorts of its own problems (e.g. IIRC on Safari this isn't allowed to be hidden for fishing-protection purposes).

...I think I found a way to emulate text input in a clean way on mobile, it's just a bit of a hassle, I'll create a separate ticket.

floooh commented 1 year ago

=> see https://github.com/floooh/sokol/issues/812