love2d / love

LÖVE is an awesome 2D game framework for Lua.
https://love2d.org
Other
4.83k stars 388 forks source link

iOS: love.textinput(text) callback stops working after Love app looses focus #1959

Open SugarRayLua opened 1 year ago

SugarRayLua commented 1 year ago

Noted when using love console libraries love-console and Vudu that unable to enter further text in console after returning to Love app after Love app looses focus (e.g. after utilizing browser app and returning to Love app). Problem seems to be in love.textinput callback; love.keypressed() still works after returning to Love app after Love app looses focus. Problem does not occur in Love on Linux or Mac.

Tested with the following script (top left of screen shows input received by keypressed; below that shows input received by textinput which stops showing user input after Love app looses focus)

function love.load() love.keyboard.setKeyRepeat(true) love.keyboard.setTextInput(true) keyvalue = "" textvalue = "" end

function love.keypressed(key, scancode, isrepeat) if key then keyvalue = key end end

function love.textinput(text) if text then textvalue = textvalue..text end end

function love.update(dt) end

function love.draw() love.graphics.setColor(0,1,0) love.graphics.print(keyvalue,20,30) love.graphics.setColor(0,0,1) love.graphics.print(textvalue,20,80) end

Fyi,

Thanks

SugarRayLua commented 1 year ago

Fyi,

To clarify this bug, I did further testing. It turns out that love.textinput(text) callback works if the love app is moved to the background and then comes back to the foreground again (i.e. LOVE window loses and gains focus); it doesn't work when one runs LOVE app 'split screen' with another app and go to the other app and type in the other app then return to LOVE app (love.textinput(text) no longer works in that case (but love.keypressed(key) still does in that situation).

And, if I try and keep love.textinput on by putting

love.keyboard.setTextInput(true)

Inside love update:

function love.update(dt)
love.keyboard.setTextInput(true)
end

What ends up happening is that when one tries to type in the app one is using split screen, it is very difficult to do so (almost every keystroke instead gets sent back to the LOVE app) despite the cursor being focused on and otherwise being able to use functions on the other app in the split screen mode

*Interestingly, there is a strategically placed one statement workaround that remedies this bug: Place:

love.keyboard.setTextInput(true)

into the love.keypressed(key) callback.

The love.textinput(text) then works fine in split screen mode after that! :-)

akkartik commented 9 months ago

One more piece of the puzzle: it looks like calls to love.window.setMode reliably cause LÖVE on iOS to stop triggering love.textinput events.

Combined with the rest of this issue above, it seems like textinput on iOS is just really fragile. Resizing breaks textinput, and something else is breaking textinput on any/most frames, that necessitates the hack above.

slime73 commented 9 months ago

The text input field in iOS is part of the window, so it makes sense that it wouldn't stay around longer than the window if it's destroyed via setMode. love's code might be able to restore it manually afterward though.

For situations where another app takes focus and the text input field doesn't come back afterward, have you tried re-enabling text input in love.focus instead of every frame in love.update?

If love.focus is not called in that multi-window situation, that's probably the root issue.

akkartik commented 9 months ago

I'll let @SugarRayLua answer that, but FYI we're currently enabling text input in love.keypressed rather than love.update.

slime73 commented 9 months ago

My question remains the same. :)

akkartik commented 9 months ago

The text input field in iOS is part of the window, so it makes sense that it wouldn't stay around longer than the window if it's destroyed via setMode.

:bulb: :boom:

SugarRayLua commented 9 months ago

Thanks, Everyone for the additional input.

I hadn't used love.focus before, but inserting:

function love.focus()
     love.keyboard.setTextInput(true)
end

Into that test snippet at the top of this issue did not restore test input functionality in the test snippet fyi