code.pyret.org icon indicating copy to clipboard operation
code.pyret.org copied to clipboard

key events

Open schanzer opened this issue 10 years ago • 18 comments
trafficstars

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!

schanzer avatar Sep 15 '15 05:09 schanzer

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).

jpolitz avatar Sep 15 '15 17:09 jpolitz

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

schanzer avatar Sep 23 '15 13:09 schanzer

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?

jpolitz avatar Oct 01 '15 01:10 jpolitz

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

schanzer avatar Oct 01 '15 10:10 schanzer

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

schanzer avatar Aug 10 '16 14:08 schanzer

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

shriram avatar Aug 15 '16 11:08 shriram

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.

justinpombrio avatar Aug 15 '16 19:08 justinpombrio

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.

schanzer avatar Aug 15 '16 20:08 schanzer

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.

jpolitz avatar Feb 08 '17 18:02 jpolitz

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?

blerner avatar Feb 08 '17 18:02 blerner

Proposal:

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

jpolitz avatar Feb 08 '17 18:02 jpolitz

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"?

schanzer avatar Feb 08 '17 18:02 schanzer

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 )

jpolitz avatar Jun 29 '17 14:06 jpolitz

(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)

blerner avatar Jun 29 '17 14:06 blerner

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

schanzer avatar Mar 31 '18 13:03 schanzer

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 avatar Mar 17 '20 02:03 schanzer

@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 avatar Nov 22 '20 20:11 schanzer

@jpolitz did this PR ever get merged?

schanzer avatar Feb 10 '22 18:02 schanzer