Issues

Issue #649 wontfix

Removing key repeating

hahawoo
created an issue

I think it might be good to remove get/setKeyRepeat, because this functionality can be achieved using Lua.

It's useful for things like text box input, but there are heaps of other things like key repeat in games too: there's "joystick repeat" for using a menu or navigating a grid with a game controller, there's maybe even "mouse repeat" for holding down a scrollbar arrow, and there are cases where you want key repeat for some keys but not others, imagine a Tetris-style game where you want key repeat for moving the piece left and right, but not for rotating, and also you want the same controls for a game controller too. So I think key repeat should be handled just like the timing of anything else.

It's also got a kind of weird API, I think this is because of how SDL does it. I would expect the function to be love.keyboard.setKeyRepeat( delay, interval ), where delay and interval could be any non-negative numbers, and calling it without arguments turns the key repeating off. However, the delay can't be 0, which seems like a reasonable value to have, and to turn the key repeating off you call the function with 0 as the delay.

And basically, I'm not sure it fits nicely into LÖVE. I think that things in LÖVE either:

  • Do something you couldn't do otherwise.
  • Do something which would be really slow otherwise.
  • Are a simple and useful shortcut, like love.graphics.getHeight is a shortcut for select(2, love.graphics.getMode()), and Canvas:renderTo(f) is a shortcut for love.graphics.setCanvas(Canvas) f() love.graphics.setCanvas().

And I'm not sure if setKeyRepeat falls into any of those categories.

Comments (11)

  1. hahawoo reporter

    Oh right, that's pretty cool. I'm still not sure if that would make sense for LÖVE to have, but it's certainly more reasonable I think.

  2. Alex Szpakowski

    Key repeat is especially useful for text input boxes and menu navigation, and once LÖVE switches to SDL 2.0, it'll use the user's system-wide key repeat preference.

  3. hahawoo reporter
    • changed status to open

    No wait, I actually still think this should be removed, at least until LÖVE uses SDL 2.0. :P

    I think SDL 2.0 style key repeating may have a use for text input. Like for a chat system in a multiplayer game, you might want key repeating when typing with the same feel as your operating system. This is a still a bit... you know... not-super-necessary-maybe, but it's still a valid mechanism I think. But for something like a menu system, I don't think it's quite right, because you'd want the same repeating settings for navigating the menu with joysticks, and the mouse too if there are buttons, right?

    Here's a demo of key repeating using what LÖVE already provides:

    function love.load()
        keyrepeat.set(0.5, 0.04)
        s = ''
    end
    
    function love.update(dt)
        keyrepeat.update(dt)
    end
    
    function love.keypressed(key, unicode)
        keyrepeat.pressed(key, unicode)
        s = s .. key
    end
    
    function love.keyreleased(key)
        keyrepeat.released(key)
    end
    
    function love.draw()
        love.graphics.print(s, 0, 0)
        love.graphics.print('\n\n'..keyrepeat.state, 0, 0)
        love.graphics.print('\n\n\n'..keyrepeat.key, 0, 0)
    end
    
    keyrepeat = {}
    
    keyrepeat.enabled = false
    keyrepeat.delay = 0
    keyrepeat.interval = 0
    keyrepeat.time = 0
    keyrepeat.state = 'off'
    keyrepeat.key = ''
    keyrepeat.unicode = 0
    
    function keyrepeat.set(delay, interval)
        if delay == 0 then
            keyrepeat.enabled = false
        else
            keyrepeat.enabled = true
            keyrepeat.delay = delay
            keyrepeat.interval = interval
            keyrepeat.time = 0
            keyrepeat.state = 'off'
        end
    end
    
    function keyrepeat.get()
        return keyrepeat.delay, keyrepeat.interval
    end
    
    function keyrepeat.update(dt)
        if keyrepeat.enabled and keyrepeat.state ~= 'off' then
            keyrepeat.time = keyrepeat.time + dt
    
            if keyrepeat.state == 'delay' and keyrepeat.time > keyrepeat.delay then
                keyrepeat.time = keyrepeat.time - keyrepeat.delay
                keyrepeat.state = 'interval'
            end
    
            if keyrepeat.state == 'interval' then
                while keyrepeat.time > keyrepeat.interval do
                    keyrepeat.time = keyrepeat.time - keyrepeat.interval
                    love.keypressed(keyrepeat.key, keyrepeat.unicode)
                end
            end
        end
    end
    
    function keyrepeat.pressed(key, unicode)
        if keyrepeat.enabled and (keyrepeat.key ~= key or keyrepeat.state == 'off') then
            keyrepeat.state = 'delay'
            keyrepeat.key = key
            keyrepeat.unicode = unicode
        end
    end
    
    
    function keyrepeat.released(key)
        if keyrepeat.enabled and keyrepeat.key == key then
            keyrepeat.state = 'off'
        end
    end
    
  4. hahawoo reporter

    Actually maybe it shouldn't be removed. Otherwise it'd be like "Hey, this functionality has been removed!" And then later it would be like "Hey, it's back again!".

  5. Log in to comment