Skip to content

getKeyState bug #45

@MatthewZ0823

Description

@MatthewZ0823

There is a bug in the implementation of the keyCheckerFunction in src/GraphicSVG/App.elm which causes certain keys like the "," or "." to not be able to be registered in a game app. For example in the following elm program (fork link)

myShapes model =
  [
    model.buttonPressed
      |> Debug.toString
      |> text
      |> centered
      |> filled black
  ]

type Msg = Tick Float GetKeyState

type alias Model = 
  { time : Float 
  , buttonPressed : String
  }

update msg model = 
  case msg of
    Tick t (getKeyState, _, _) -> 
      { time = t 
      , buttonPressed = getKeyState (Key ",") |> Debug.toString
      }

init = { time = 0, buttonPressed = "" }

main = gameApp Tick { model = init, view = view, update = update, title = "Game Slot" }

view model = collage 192 128 (myShapes model)

The text in the center does not change to "Down" when the comma key is pressed, which is unintended behavior.

This is because the game app subscribes to key events on the document as follows:

-- One line 89 of src/GraphicSVG/App.elm
subs : List (Sub (HiddenMsg userMsg))
subs =
    [ onKeyUp (D.map KeyUp (D.field "keyCode" D.int))
    , onKeyDown (D.map KeyDown (D.field "keyCode" D.int))
    , ...
    ]

When a key is pressed down, the onKeyDown subscription fires and sends a KeyDown message with the keyCode of the button pressed. The KeyDown message is then handled by the hiddenGameUpdate function. Where the keyCode of the button pressed is added to the list of keys in the hiddenModel. hiddenModel.keys keeps track of a list of keys and their pressed state.

        -- In the hiddenGameUpdate function on line 699 of src/GraphicSVG/App.elm
        KeyDown keyCode ->
            ( ( userModel, { hiddenModel | keys = insertKeyDict hiddenModel.keys keyCode WentDown } ), Cmd.none )
        KeyUp keyCode ->
            ( ( userModel, { hiddenModel | keys = insertKeyDict hiddenModel.keys keyCode WentUp } ), Cmd.none )

Then when a user wants to query if a key is being pressed, the keyCheckerFunction function is invoked with the hiddenModel.keys being passed into the dict param:

-- On line 233 of src/GraphicSVG/App.elm
keyCheckerFunction : Dict.Dict Int ( KeyState, a ) -> Keys -> KeyState
keyCheckerFunction dict key =
    let
        state =
            Dict.get kc dict

        kc =
            case key of
                Key str ->
                    Char.toCode <|
                        Char.toUpper <|
                            case String.uncons str of
                                Just ( a, _ ) ->
                                    a
                                Nothing ->
                                    'z'

                Backspace ->
                    8

                ... -- Imagine other special characters below
    in
    case state of
        Just ( JustDown, _ ) ->
            JustDown
        Just ( Down, _ ) ->
            Down
        Just ( JustUp, _ ) ->
            JustUp
        Just ( Up, _ ) ->
            Up
        Nothing ->
            Up

So in our sample program at the start of this bug report, when we query to see the state of Keys ",", the keyCheckerFunction gets the unicode code of the "," character, and then checks in the hiddenModel.keys to see its state.

The problem is that when the comma key is pressed, the onKeyDown subscription puts the Javascript Keycode of the "," button as the key in the hiddenModel.keys dictionary, but the keyCheckerFunction is looking for the Unicode Code of "," as the key. The Javascript KeyCode of a button may be different then its Unicode Code, as is the case with the comma button. This causes the keyCheckerFunction to not find anything in the hiddenModel.keys dictionary, concluding that the button must not be pressed down.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions