brownplt / code.pyret.org

Website for serving Pyret to folks.
Other
24 stars 44 forks source link

key events #35

Open schanzer opened 8 years ago

schanzer commented 8 years ago

This comes as no surprise to anyone, but I've been knee-deep in it with WeScheme for the last few days so I figured I might as well file a report. This is based on the Pyret program found at https://code.pyret.org/editor#share=0BzzMl1BJlJDkeFFTUVhURk1rd0E&v=v0.5r1428

1) Caps lock is ignored (CapsLock+k -> k, instead of K) 2) Shift modifier is ignored (Shift+k -> k, instead of K) 3) Alt/Opt modifier is ignored (Alt-c -> c, instead of ç)

I don't know how much of the old jsBigBang code Pyret inherited, but here's the issue: the only way to get modifier keys (shift, alt, etc) is to listen for keydown events, and the only [easy] way to get the modified character (ç) is to listen for keypress events.

I briefly attempted to reconstruct the typed character solely from the keydown event, but that got complicated fast. For WeScheme, I instead signed up the key-event handler for both down and press, and then had it sift through some conditions to know when to ignore one and listen for the other. It feels like a bit of a fragile solution, but I don't expect anyone to re-assign the extended ASCII character set anytime soon. :)

Hope this is helpful!

jpolitz commented 8 years ago

Wait, if I do:

document.body.addEventListener("keypress", function(e) { console.log(e); })

And type "Shift-K", I get an object with:

altKey: false
shiftKey: true
metaKey: false
ctrlKey: false

So some of these are certainly present.

If I type Option-[ (for curly quote on a Mac), I get:

altKey: true
shiftKey: false
...
keyIdentifier: "U+005B" // unfortunately, thats [, not “, as we might hope

I think that the modifier keys are reasonably cross-browser (Caps Lock isn't considered a modifier key). I think getting option-based input via OSX is probably best done by hiding a text area and focusing that, then reading the input out of it after an "input" event, rather than rebuilding the modifier logic ourselves.

(NB: This is all in Chromium, but CPO does Ctrl-S and Ctrl-Enter for save/run this way, and it works across all the major browsers).

schanzer commented 8 years ago

Huh? keypress isn't fired if you just hit a modifier key.

jpolitz commented 8 years ago

Agreed. I didn't realize part of the goal was to fire key events for standalone modifier keys; I thought you were just saying it was hard to get the modifier information period. I take it you want to support a key event that fires "Shift" and having Shift+a show up as "A" for the key? Or is there another reason keydown rather than keypress is necessary?

schanzer commented 8 years ago

If we want to preserve compatibility with DrRacket's on-key handler, we need to use keydown.

schanzer commented 8 years ago

Small poke. Seems relevant in light of https://groups.google.com/forum/#!topic/pyret-discuss/lEDVirNisRI

shriram commented 8 years ago

One of the teachers at the physics workshop had asked whether we had key-down vs. key-up events.

justinpombrio commented 8 years ago

Per the thread on pyret-discuss:

The best proposed solution is to add another kind of key event (call it on-key-detailed for now) that is provided with much more information than on-key. The goal, of course, is to keep on-key simple, while providing the richer functionality.

Regardless of the more detailed function, on-key could still reflect weather shift is used, and produce "K" when you type "shift-k". I believe this is standard behavior: in OpenGL you get the capitalized key, and in JavaScript you get both the capitalized and lowercase key.

schanzer commented 8 years ago

I'd suggest something like on-raw-key, and try to expose something similar to the JS Key Event. This would have the advantage of making the library more friendly to folks coming from JS-land, and free us from having to design a different API for "detailed" key events by piggybacking on the one that already exists.

jpolitz commented 7 years ago

Concrete proposal:

on-raw-key is a handler that expects a function with the following signature:

state :: a, key :: RawKeyEvent -> a

Where a is the reactor state and RawKeyEvent is a datatype:

data RawKeyEvent:
  | raw-key-event(key :: String, type :: RawKeyEventType, caps :: Boolean, shift :: Boolean, alt :: Boolean, command :: Boolean, control :: Boolean)
end
data RawKeyEventType:
  | up
  | down
  | press
end

Feel free to point out missing things in the above definition.

blerner commented 7 years ago

How does this interact with on-key handlers? Which happens first? Do we call both on-key and on-raw-key for sustained keypresses? Or do we make it a well-formedness error to have both kinds of key handlers?

jpolitz commented 7 years ago

Proposal:

It's a well-formedness error to have both. on-key should desugar into a use of on-raw-key.

schanzer commented 7 years ago

I like this. Can you say more about what key is? For example, could it be ç? Any printable character? What about non-printable key combos, such as "Ctrl-Shift"?

jpolitz commented 7 years ago

We've discussed this a bunch this morning while resolving https://github.com/brownplt/code.pyret.org/pull/167/files

It seems like the .key field on the keydown event has all the properties needed for this. Browsers have (since this issue was opened) converged on support for this in the last few years, so I think this can be much more straightforward.

To answer the direct, most recent question, if a user typed "Alt-Shift Y" on OSX (which produces Á on my laptop), there would be three calls to the reactor's on-key handler:

  1. One containing the key "alt"
  2. One containing the key "shift"
  3. One containing the key "Á"

Since students already (implicitly) learn to filter out keys in games to not crash if expressions, I think it's fine to have them filter out modifier keys.

Of course, we should also add on-raw-key, this discussion just addresses what the value provided to on-key is.

(CC @blerner @ds26gte )

blerner commented 7 years ago

(Docs: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key and https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values)

schanzer commented 6 years ago

Just a note that @jpolitz has been working on this inside the on-raw-key branch. See #262

schanzer commented 4 years ago

It looks like PR #262 may have come almost all the way to implementing this. Is it stuck in PR purgatory, or did it get implemented elsewhere?

schanzer commented 3 years ago

@jpolitz I know you have a PR for this. I'm guessing it's gone stale? Could this be something for an undergrad to clean up?

schanzer commented 2 years ago

@jpolitz did this PR ever get merged?