I too have hit this, and it's blocking our support of VMware WSX on Android for our release, unfortunately.
It seems there's never a keypress event. keypress is great when you want to see what actually was pressed, as this will generally contain the normalized key (shift-A vs. A) and unicode character ('A' vs 'a'). That event never appears, from what I can tell, so we're left with keydown/keyup.
keydown in general (and even more so on Android) doesn't contain enough information to identify the key. In most cases, you'll get the 'A' key, but not 'a' vs. 'A', since it maps more closely to a physical key. (We don't have physical keys on a touch screen, so it's a bit different in this case.)
On Android, as was noted, alphabetical keys, and most others, seem to return keyCode 229. There's no normalized key value anywhere, nor a Unicode character to base anything off of. Numeric keys, interestingly, seem to produce unique key codes, but shifted ones did not.
This basically means that Google Chrome on Android is absolutely broken when it comes to webapps needing any sort of custom key support. Input fields are fine, and you can play games like see what the last character is, but anything else is pretty broken.
My vote, if I had one, would be to restore keypress and use that to send a normalized keycode and Unicode character, and then fix keydown to return something proper. That way, developers don't have to start writing support for a custom keydown, and Android will just do the right thing.

For developers, I think it is better to avoid expecting keycode on android.
The problem is that there are a lot of text suggestion related changes. For example, you type "go", "good" and "gossip"will show up in the text suggestion. The user might click "good" and "gossip" to change the current text input, and it will also clear the composition under "go". If developers are expecting keycode, it is hard to deal with the case above as there is no keycode for user selections.
229 is the composition keycode for chrome, it is sent when user either hit a key or hit a selection.

It's not always about detecting keycodes for characters, but even like hitting a return key or backspace. It sure would be nice to not have to work around this--in my case Android Chrome was the only browser that failed to work. We had to add a button to submit just for Android Chrome.

The same here. This key detection works for all browsers, except android chrome. I made a simple currency edit field, in which the user needs only to type numbers or backspace. I made a huge workaround to make it work on Android Chrome, and as a side effect, at each type, the field bliks, since I need to analyze all the text property, and properly replace the text property to something adequate.

I think this needs serious evaluation, as it is the only browser out there that is flat-out broken. We have to turn away a lot of customers who are Android users and tell them, "Sorry, Android is broken, get an iPhone/iPad/Windows Phone/Surface/Anything else," which doesn't really benefit anybody.
If there's anybody there that our company can get in touch with to have a meeting about this so it's not just conversations over a bug report, I'd be happy to pass a name along.

For android browser app, it sends the key code if I type a key, but it sends nothing if I do a text selection. Also, it has no text composition mode.
To better evaluate the case for chrome on Android, I think we need to understand the use cases here. I am curious what your javascript is expected to do if I select "chip" after I type "hip" on the keyboard.

In my use case, the only reason I used the keycode was to detect when the return/enter key had been pressed, to submit a query. It was triggered from a CodeMirror element (not a textarea/text input), so really I don't care what someone selects for text selection--I just want to know when to submit. It worked fine in every other browser and we added a separate submit button just for Android, as a workaround. It seems silly that this isn't supported. The reasoning that "it might do unexpected stuff if they do a text selection" doesn't mean it shouldn't work normally for all other use cases (and I think the others here feel the same way).

first, i'm not familiar with English
why i need keycode event?
i'm try to contenteditable for html5 attribute-based editor
when i typed key code that space
i have to sending for my server that current selection text
but, i can not catch 'space' keycode
I'm trying to make a simultaneous editing
I am sending it to the server based on the space, enter key event.

In my use case (Gate One: https://github.com/liftoff/GateOne/) I need to capture individual keys as they're typed by the user in order to properly emulate a terminal. For example, say you were running the 'top' application and wanted to sort processes by memory. You'd need to type a capital 'M'. In Chrome for Android that won't work since the keycode will always be 0.
The use case should be irrelevant; the behavior of Chrome in this instance is indisputably broken. I would argue that this is a severe bug since it prevents whole categories of rich applications from working.

At VMware, we have a product (WSX) that allows a user to log in to their VMs from any modern web browser and interact with the OS. Because of this, we need to know exactly what keys are pressed in order to map them to appropriate key codes sent to the VM.
What we do for every other browser is we create an <input type="text"/>, shut off any auto-complete, focus the field, and listen for key events. (This ensures a keyboard will pop up on mobile devices, as there's no API for directly working with mobile keyboards, sadly).
For each key event we get, we intercept, block the default action, and then do our work to transform and serialize the key code and send to the other side.
The biggest feature request we have is "Please make this work on Android," to which we have to reply, "We can't. Chrome on Android is broken wrt key events."
I can see the issue where auto-completion may cause some confusion with key events. However, it's not much different, I don't think, from Safari on iOS, which we have no problem with. There are two scenarios that come to mind:
1) Auto-complete is on, and someone auto-completes (or uses voice input, or something).
In this case, we get a "input" event that has the contents of the paste, speech-to-text, auto-completion, whatever. We can check for this and do something intelligent. (Hey, we suddenly have more than one character! The user probably didn't type that themselves!)
Auto-completed entries and such don't generate keydown/keyup/keypress events. The individual keys do. So, I type "he" and auto-complete the "hello". I'll see the first two key events, then see the input event, and I can be smart about my handling of it all.
2) Auto-complete is turned off for the field.
This is the mode we're in for WSX.
We know we won't auto-complete on iOS, MacOS, whatever. Android, though, ignores our request to turn off auto-complete, so that's a problem for us. Assuming, though, that that was changed to behave like every other browser and platform out there we've tested with, we wouldn't have the concern about what you do with auto-completed entries. We'd just deal with key presses, like we get to for every other browser.
This is pretty clearly broken and a major show-stopper for any web-based product that needs to do anything more advanced than "my text field has changed" or "submit this form," which, given this bug report and some research on Stack Overflow and blogs, is certainly affecting webapp developers out there.
Android's in a great position to be able to become a great platform for the newer, more advanced interactive mobile webapp market. But not with this key input behavior.

I am in complete agreement with the VMWare person on this one... This is a show-stopper bug. I opened it 7 months ago and I am quite surprised that there has been no progress on it thus far.
BTW: VMWare should add Gate One as an HTML5 serial console (terminal) option alongside WSX :) . Fill out the contact form at liftoffsoftware.com and I'll help you get it working =D

It is crazy that this browser doesn't at least have the option to set the virtual keyboard behavior (particularly for keycodes set by onkeydown/onkeyup events) to emulate a physical keyboard. Better yet, have the default behavior to work just like does on desktop machines and have an override option to let it behave in this new way.
As it is, the current "feature" clearly pushes us to recommend browsers other that Chromium for our mobile users. Assuming that a site does not need to filter keystrokes is really a short-sighted change in behavior. This is really a step backwards in basic functionality.

Now that Chrome Mobile browser gives event.keydown keyCode return value as 229 for any key press on inbuilt Android Samsung keyboard, most of above issues will be resolved if you add just another condition check for this value.
Correct me if wrong.

Sending keyCode for entering text using IME makes very little sense in most cases. They only time it can be justified if the user is using Latin IME with that keyboard committing each character one by one (calling InputConnection.commitText()). That way each key could be translated to a keyCode and be sent to JavaScript.
However, this breaks down in a lot of other cases. For example:
1. If the keyboard is entering text by multiple characters at the type (eg. swype using commitText with text longer than one character).
2. If the keyboard is appending one character to composition every time using setComposingText(). This breaks down because keyboard can decide to autocorrect or replace entire work at any time - thus causing the keyCodes that would be sent for each additional character to be wrong.
3. If the keyboard is phonetical.
4. If the keyboard is Japanese and modifies an entered character on each new button click (eg. built in android Japanese IME).
... there are probably other cases here too.
Possible way to solve this bug:
a) Set the type of the input box to password, to force the android software keyboard to show a password keyboard, usually it's just a bare US qwerty keyboard without any auto-completion/auto-correction feature. This keyboard will generate exactly key events wanted. This approach actually doesn't need to change anything from our side.
b) Set flag TYPE_TEXT_FLAG_AUTO_COMPLETE to EditorInfo.inputType to ask the android keyboard to disable auto-completion. Not all android keyboards obey this flag, especially those non-latin keyboards.
c) Set flag IME_FLAG_FORCE_ASCII to EditorInfo.imeOptions. This flag was only available since SDK version 16, so I doubt if there is any android keyboard (except the built-in Android LatinIME) support it.
Comments? Ideas?

While it may be true that there are circumstances in which the keyCode value doesn't make sense, there are a large number of cases where it does. As other commenters have pointed out the behavior of Chrome for Android in this regard is non-standard and breaks many scripts that rely on capturing key events. For a project I'm working on Chrome for Android is essentially dead in the water and unsupported due to this bug. I'd love for that not to be the case.

This issue impedes the development of the mobile service at my company as well.
To address #27 for all points: just send the keyCode of the pressed softkey, whatever comes out. On the desktop, you can also do paste/autocomplete etc. stuff, but there are still proper keyCodes if I do Ctrl+V. Everyone got used to it and can get along with the inconsistencies you described.
IMO, it's still better to have some information about key inputs than to have nothing. As a suggestion - set the keyCode to 229 if you get more than one key coming from the keyboard, otherwise - set a normal corresponding keyCode.

To those who have worked around this problem: did you have to do something different for Android Chrome or did you change the way your code worked in all browsers? I'm trying to single out any browser that has this bug, but I'm having trouble detecting the bug programmatically. I'd like to avoid user agent sniffing. Any suggestions?

I think we can use a similar approach android browser uses.
When committing multiple characters, simply send 229. But for the rest cases (only one character change at the cursor), we should send the keycode.

Even you Set the type of the input box to password, you can not capture the backspace key event, another strange thing:
e.preventDefault() will not work on keydown/up event, you can still get text entered, but backspace key will stop working.
Why Android Chrome's behavior is different with all other browsers? We can capture backspace keys on all other mobile browsers. Every time we have to tell our customers you have to use iOS instead of Android. That give me an impression: Android is like an abandon ship, Google only cares about Chrome OS for now.

Android software keyboards can choose whether to send key events or not. Most of them are not sending any key events and instead use IME commands to achieve the same affect. For example Android's stock LatinIme does not send back space key anymore when it is deleting text, instead it is using DeleteSuroundingText(1,0). Since there are no key events being sent, the only way for Chrome to figure out what key would the previous call represent would be guess work. For example, if we receive setComposingText("a",1) and then receive setComposingText("ab",1), we have exactly same about of information as JavaScript would by querying the value of the input field. We would have to look at the diff, find if the diff is one character, then convert that character to a keycode (that's assuming user did not use some sort of swiping functionality to enter multiple characters at once). The same can be done directly on JavaScript.
There is work being done on better IME API (https://dvcs.w3.org/hg/ime-api/raw-file/default/Overview.html) by Googlers. Please contact them if you have any concerns about that this API and if you need an extension to this API that would be used for wide audience of developers.

Thanks for the background information, #34. From the perspective of a web developer this sounds like Android's software keyboards are broken. I know very little about IME and it very well may be a better API for handling text input than what the existing web standards were built on, but the bottom line is that Chrome for Android does not adhere to those existing standards and therefore appears broken.
But please, by all means, work toward better standards. If there is something fundamentally broken about the existing web keyboard events then we should fix them. But we should do it together with enough backward compatibility to allow for applications that work everywhere else to work on Chrome for Android, too.
Do you have any insight into why the stock Browser application on Android does not have this issue? Does it not use the same keyboard, or does it do the kind of diffing you describe in your example?

Stock Android browser does exactly the thing I described in #34, it determines if a character was added or deleted and if so, it sends out a key event. See https://github.com/android/platform_frameworks_base/blob/master/core/java/android/webkit/WebViewClassic.java#L483
We are hesitant to add something that is kind of fragile and just happens to work for LatinIME (and all of its forks sold on the Play Store). We would much rather have a direct JavaScript API that would enable developers to directly get listeners for IME events instead of hoping the user will enter their text character by character thus producing key events. If you look at http://www.w3.org/TR/ime-api/, there is a proposed example Example1, where you could simply call node.addEventListener('compositionupdate', onCompositionUpdate, false);
Android does have a very convoluted API for text input that does not work very well with browsers. Every popular Android browser is having some sorts of IME issues.

Test results on Nexus 7, stock Android Keyboard:
Using a native app(Remote RDP), we can capture BACKSPACE key in View's onkeydown/up event.
But in Chrome, we can not (even not on a password type input). On Firefox, we can. As I remember, the previous Chrome (16 or 18?) can capture the BACKSPACE key.
There must be some other reasons behind this.

IME does send key events to InputConnection for non-printable keys, but if you don't handle it in sendKeyEvent, onkeydown/up event will be triggered. You should not translate DEL key to deleteSurroundingText here, this is based on assumption that apps only need to deal with InputConnection, but actually an app also need to deal with external (USB) keyboard, that's be processed in onkeydown/up.

+kochi@ author of the IME API mentioned at comment #36.
AFAICT, you should be able to solve your use case in a robust way by using the DOM level 3 composition events that aurimas@ highlighted:
compositionstart
compositionupdate
compositionend
node.addEventListener('compositionupdate', onCompositionUpdate, false);

Hello folks,
Why i tend to agree with the web developpers above that the Android implementation of key events is impractical at best, I have a more specific issue.
I am working with an input that has autocompletion disabled, and the IME events are not even fired in this case, which means that the backspace key has NO EVENT that i could possibly catch (test file is attached).
<input id='testinput' type="email"></input>
<script>
var ip = document.getElementById('testinput');
ip.addEventListener('keydown', function() {alert("keydown");});
ip.addEventListener('keypress', function() {alert("keypress");});
ip.addEventListener('compositionupdate', function() {alert("composition");});
</script>
Writing anything then pressing backspace will not trigger any of those events. What should I do in this case?

Chrome will not fire an backspace event even the IME sending backspace key
event instead of deleteSurroundingText. The good thing about keyevent is
it's compatible with existing web applications and good for developers,
like on IOS, LatinIME will always send keyevent even for printable
characters.
Actually most of IME end keyevent on Ctrl/Shift, backspace, del etc. on my
nexus 7, the IME is still sending keyevent for backspace.
All external bluetooth/usb keyboards (from what I tested) will send key
events.
Basically, I think sending deleteSurroundingText instead keyevent for
backspace (non-printable keys) is a wrong decision. It's good for final
users, but a disaster for developers, how can we know if a backspace key is
pressed. No any other browsers are doing same thing.

#54, for me, I think "keycode is zero" is acceptable if it's a printable character, but it's not acceptable for non-printable characters, like backspace, return.
My web page could capture the backspace someday and I thought this was fixed, but looks like the fix only stayed for several days and you can not capture backspace key again in Chrome beta right now.

Any update on this? My website needs to detect keycodes for a custom search box, and the website works on every browser except Android Chrome because of all keycodes are zero except for backspace(which is 8). This is a serious bug, and needs to be fixed. Any updates?

Seeing as how latest comment in this bug is 4 hours old, I know I can stop banging my head against the brick wall trying to figure out what I am doing wrong.
It would be super if mobile chrome could disable autosuggest/autocomplete/autocapitalize and would send keypress events after each key entered. Please work like how iOS does? I will *not* workaround something as fundamental as keypress trapping in a textarea. My app will simply not respond on your browser and I will point users to this bug to complain. My onkeypress code works fine in desktop Chrome.
THANKS!

For what it's worth, I'm handling a backspace/delete key event on Android Chrome in specifically this one fashion. I'm using jQuery. Note that "#inp" is a hidden field somewhere with a non-breaking space character already inside of it.
$('#inp').on('input', function(event) {
if ($(event.target).val() == '')
// do something that normally would have required the backspace key
});
Hope this helps someone until the Android / Chromium teams gets this mess straightened out.

How can something as fundamental as keypress/keydown/keyup events be broken in android chrome? Stripe now has a nice library for formatting credit card numbers / expirations/ cvc codes that is useless (even harmful) on android chrome.

This issue has remained unchanged since over one year, I guess I have to recommend my users to choose another Browser on Android, like Dolphin. That one is using the same software keybord as Chrome while not only sending correct keycodes in keydown and keyup but also providing the input character with keypress event!
All what is said about the reasons why Chrome behaves like it is doing because of auto completion, text suggestion, ... seems to me like a statement "we know that we better should correct this but we don't like to". Other browsers in the same environment are able to provide keyboard input in a standard way!

Maybe there will be a temporary solution for any need, but every workaround has contraindications.
What happen if user move the cursor on inputfield? What if user uses a phisical keyboard with a Android device? Will you be able to capture CTRL and other non-printable keys?
This is a bug and it seems it will not be solved in short times. This behaviour on Android seems wanted by Chrome team.
Because of this I don't even know if they want to solve this bug...

I believe a keydown event should always be sent with a keyCode because:
* any arguments about autocorrect/autocomplete are irrelevant for keydown
* iPad/iPhone sends keydown events and sets keyCode
* JavaScript code for any browser should never expect a keypress for every keydown
* JavaScript code already deals with keyCodes on keydown not generating keypress (e.g. select some text and press backspace or a key etc).
* arguments it can't be done (re. aurimus #27 #34) just don't apply to the keydown event (I do understand why the problem can be argued for the keypress event).
My particular problem is that there is no keydown event generated if backspace is pressed when the input is empty - as per https://code.google.com/p/chromium/issues/detail?id=184812 - which I am sure is a side effect of this issue. I checked the keydown, keypress, keyup, compositionstart, compositionupdate, compositionend events and no event is generated.
bazilla (#75) a physical keyboard (USB or bluetooth) sends through the events correctly with correct keyCode. Other virtual keyboards such as "Hackers keyboard" may send through the keyboard events correctly.

Yes, this is really annoying. The funny thing is that numeric keys (0-9) send the normal keypress events, but the rest only send the keydown/keyup. This is my littele piece of code:
$(this).keypress(function(){
if (!$(this).data('changed')) {
$(this).css('color',typing_color);
$(this).val('');
$(this).data('changed', true);
}
});
This is for in-field labels, that disappear when the user enters the first character. Because of this bug, this functionality is not working. I've tried to replace keypress with keydown, and in that case the function is triggered, but then the first character is 'swallowed' by Chrome (if it's not a number!).

This is crazy! How can this bug be open for so long? I just spent most of the past year building a pretty large AngularJS app that is practically non-functional on Android because of this issue. As others have expressed, Keypress events are a fundamental part of the web platform. I am shocked that with all the great work Google does with the web platform standards, they can't fix this in over a year and a half.

@aurimas, Can you give an update on this ticket? It's in our top 10 most starred Chrome on Android bugs.
As comment 81 points out, this is a BIG compatibility issue. Classic Android Browser and iOS provide no problems here and we're breaking expectations.

At Microsoft, my team and I are working on supporting Office Web Apps when using Chrome on Android tablets. We rely on getting the backspace key event as we periodically synchronize user input with displayed content on the page. Unfortunately, this bug is causing issues with basic text editing functions such as text reappearing because we don’t know the user pressed Backspace. While we are trying to find workarounds, this is a core issue that could block us from providing support for Chrome on Android, which would be sad. Like others in this thread, we would love to see this bug fixed as soon as possible!
-Chris Gallello, Program Manager, Microsoft

We are discussing how other mobile browsers are handling this in order to find a (hopefully) quick solution while we think about a better solution Which might involve new APIs.
#92: Chris, can you tell me how things are working with other Android mobile browsers and Firefox in particular?
- does the issue with the backspace key also exists there?
- if it does but you have a workaround, would you mind explaining it?
Our current preference goes for FF's model, so I am interested to hear if this would work for you or not.
FF's model as we understand it: sends key events for one character commitText() and does not send key events when composition is taking place (underline in chrome). We believe that no event would be sent for some keys such as backspace/delete.
Note: webapps developers will have to pay special attention when dealing with say a Japanese input method (involves composition events: http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents).

In my previous test. Firefox did send backspace/delete keycode. For IME,
like Japanese or Chinese. You can use textInput event which is more
convenient than commitText, but right now textInput event is broken in
Android Chrome too because of issue 330662 .
In the old version of Android Chrome, you can get backspace/delete keycode
if you are using textarea instead of input, but don't know since when, you
can not get backsapce/delete keycode if there is no characters in the
textarea.

Backspace is an important key for application keyboard usage. Like many, many others we need to be able to receive key events from it as well. Firefox does not send key events for backspace/delete, but that is not acceptable behavior from them either. If Chrome for Android wants to be supported as a legitimate web application platform, they need to respect the functionality web application authors rely on.

#100: I do not think that my issue is different then this issue... So, I believe that if this issue will be solved and closed then my problem will be solved too... the problem is in incorrect behaviour of keypress, keydown and keyup events.

#96: Hi Kenji - we aren't able to get backspace keycodes in Firefox either, so I'm not sure that their model would resolve our issues. We tried a few workarounds, but nothing ultimately worked for us. Thanks for your help on this!

#102 I think you can get backspace keycodes in Firefox when firing keypress/keydown event on an empty <input>. It does not send the correct keycodes if you started writing.
You can test it here: http://api.jquery.com/keypress , http://api.jquery.com/keydown .
You can find a library which worked around this issue by having a hidden textarea which is always empty to capture backspace: http://mathquill.com/. I hope this can help other.

This bug is also causing trouble for my mobile web app which uses bluetooth barcode scanners. We normally attach a keydown listener to the body tag to capture all keyboard input and look for barcodes with a regex. But it's always 0
Any news on this bug?

Andrew: could you check out issue 335421 and provide additional insights.
From discussing with Android folks, the latest takeaways are:
1. For the general key event bug: the only way would be for Chrome to be able to force IMEs into "dumb" mode where they simply send key events, but given current Android API it is not really possible to enforce. If it were possible, it would also result in a poor user experience where the IMEs don't provide any suggestions nor corrections.
2. For the backspace on empty input issue, Software keyboards (e.g. Google Keyboard) do not send anything if the user is trying to delete text for an empty input box.
The only thing that we could possibly do for the backspace case is to always lie to IME and say there is something in the input box when it is empty, but this will cause all sorts of issues and it is not a workable solution.
3. Allegedly, getting raw key events or backspace on empty inputs isn't possible on a native Android app. Assuming that PC input as a reasonable paradigm on new devices like the ones powered by Android is incorrect: not all of these devices/installable input software have a backspace key or keys for that matter, so requiring key events does not work.
In conclusion, the Android team believes that choosing a radically different approach to the issue is the right solution and would result in a better user experience.
I would be interested in hearing your feedback if it turns out that there aren't any viable alternatives:
A. on both Android native and Android mobile web
B. or if Android mobile web fails to deliver while Android native does.

The thing is, native apps can get Backspace key event from the same IME, so the problem is Chrome browser can not get the key event from the same IME, or Chrome browser can get the key event but think it's ridiculous and choose to ignore it.

#107 doesn't address the issue where events aren't being sent at all for the backspace key, even where there _is_ text in the input (mentioned in #43). Since in that case the text is actually being changed it seems reasonable to expect some type of event to fire. Is there some workaround for this that I'm not aware of?

I am only having this issue on my mobile device, but not on my desktop (both browsers are the latest versions). Aren't both Chrome browsers using the Chromium engine? I wonder what the discrepancy is? Anyone have a workaround going in the meanwhile?

It looks like there is some positive movement forward on this issue. Thank you, Kenji, for taking the initiative.
Meanwhile, is there any way to detect the loss of functionality? It appears that the keydown and keyup and keypress functions still exist in the object model, but they just don't return anything useful. If they don't do anything useful then could they be removed from the model? That way I could detect if it exists and use the oninput event instead (kludge though that is). As it is I am reduced to trying to figure out which browser/OS combinations work and which don't work and then responding to the user agent string which is really not the way we should be going...
RE the big picture issue... Can't we treat a text replacement (I type "teh" and then select "the" as the correction) just like a select/paste? So I would get a keydown for t, for e, and for h, but then the correction would act like an implicit select & paste had occurred (which don't really involve keypresses and thus wouldn't generate keyboard events). I'm not familiar with the internals, but this seems like the only logical way to move forward since the keyboard is not really involved in the correction...
But, as I mentioned above, the bigger issue for me is getting a way I can reliably detect the situation so I can implement my workaround.

That would make sense if it weren't possible to map to any key code, but every other browser on Android, including the original Android browser, has shown that that's not the case. Given that, I don't think this portion of the spec applies.

Even if Chrome can emulate some of keyCode from virtual keyboard input,
it can't be perfect anyway.
Other than cases that legacy web apps that depend on keyCode,
what are your legitimate use cases that definitely need exact keyCode,
which can't be implemented using composition events etc. which are
available to today's Android Chrome?

As Apple announced that iOS6 would adopt third-party IMEs and new keyboard model,
I guess sooner or later iOS devices will have the same issue.
So for future-proof, web apps should work as is with the current chrome on Android
without depending on keyCode.
We recognize there are legacy desktop web apps which are not compatible
on Android devices, which are serious for those who depend on such apps,
but if apps could be fixed e.g. with composition events, they should be fixed.

How about external keyboard and games. Right now, external keyboard in Chrome can always get keycode.
How about my game want to response Backspace key, right now, backsapce can not be detected in input, but it can be detected in textarea if there is data in it.

This is not only a feature for legacy desktop web apps. Guessing that Apple might sooner or later face the same issue does not seem like a reasonable thing to do. Keyboard events and composition events support different use cases. Those of us who want to implement custom controls that respond to keyboard events are basically being prevented from doing so in the web, and being encouraged to create our own native keyboard handlers. This seems like a very good way to discourage web apps on Android, and a cop out on what is clearly a painful bug for many developers.

I believe the point is simply that there is no perfect solution. Mobile devices inherently have vastly different input mechanisms than the traditional keyboard that many Web apps are handling. I can't speak about iOS, but Android's IME does not emulate a keyboard. There are some installable keyboards that do, but most will not.
I'm certainly going to be doing my best to improve upon what exists and provide a workable solution for many cases, but there is always going to be some places where the adapter fails to match a true keyboard.

This sounds promising and I am looking forward to see any progress. I see your points but the current behaviour looks strange to me. Even if there are no IME composition events the keydown/keyup events provide no correct keyCode. This can be seen if you just enter numbers or special characters. For our project it would be sufficient to get IME events and in cases where no IME events are notified the keydown/up events have proper keyCodes.

#134: can you please specify exactly what are the cases where you do not get a composition event and only a keydown/up with incorrect keyCodes?
Please add device model, android version, chrome version, IME name + version, special characters and keys that cause this behavior.

Just checked with my Nexus 4, Android 4.4.2 using Chrome 35.0.1916.141 and now I can see keyCodes for numeric keys, but not for other keys (like +-) and no composition events. You can check it yourself with the following web page.
http://www.danilatos.com/event-test/ExperimentTest.html

I've found another issue which may be related?
I need to detect the delete key being pressed, especially when the input field is empty.
After a keyup I check the input value and if the length has reduced then the delete key has obviously been pressed.
To catch a delete being pressed when the input field is empty I've added an invisible character (\uFFFC) to the start. If value.length === 0 then I add the invisible char to the input field again. ie. (the input always has 1 or more characters in it).
if (input.value.length === 0) {
console.log('delete pressed!')
input.value = '\uFFFC';
}
This works perfectly in Chrome on my laptop but fails on my Android device (Nexus 5, Android 4.4.3, Chrome 34.0.1847.114). Adding content to the input field doesn't get picked up by the VKB... pressing delete does nothing, neither keyup, keydown fire. It seems that the VKB is tracking what has been typed/deleted, so any characters that are added/deleted without using the VKB are ignored.
In short, if I add/change/replace text in an input with javascript the keyboard (delete key) should still work!!
Anyone know of a fix / workaround??
(Or another solution to detect the delete key being pressed)

@gregoredwards, the issue that no key event is generated when pressing DEL key is tracked in a separate bug 184812 and a fix was landed yesterday.
I am investigating if it is possible to send DEL keycode when DEL key is pressed in non-composition mode.

Okay, everyone... Thanks for your patience on this. It'll be a while before these changes make it into the Beta build of Chrome for Android but you can test the current changes against your own web pages using a development build of the ContentShell.apk that I've made available here:
https://drive.google.com/a/chromium.org/?usp=chrome_app#folders/0B9nbVwtdJ_FpRmlFS2pQWXhKMmM
Let me know what problems you encounter. It's *impossible* to build a perfect solution that will behave in all situations exactly as a real keyboard would behave but we'd like to be reasonably close and correct for at least most uses.

First of all your fix and providing the ContentShell.apk for testing is a big step forward and we can see more events with key codes ('-', ';', '\', ...). There are still codes missing for keys that don't trigger composition events, e.g. '!','?','+','(',')', ...
Another thing we notice in your ContentShell.apk: Write a word e.g. hello and press space. The composition ends correclty. Now remove the space (with backspace) and a compositionstart event is triggered, that's ok. If you press backspace again, the composition ends (looks not good). If you press backspace again, the compositionstart event is again triggered. This "toggle effect" can be seen until the last letter is deleted.
We don't see this using the latest Chrome for Android. The composition ends if you delete the last remaining letter with backspace.
We would like to have the proper key codes whenever there are no composition events (compositionend provides the correct entered text). Especially special characters (e.g. +-.,!?"§$ ...) don't trigger composition events.

Yes, shifted keys were not creating events. I've fixed that. There are no key events for the modifiers but they are included in the key events for the key that produced the input. Updated test binary (-2) is the same Drive folder:
https://drive.google.com/a/chromium.org/?usp=chrome_app#folders/0B9nbVwtdJ_FpRmlFS2pQWXhKMmM
The termination and restart of composition seems to be done inside Blink in response to the KeyDown event for KEYCODE_DEL. It doesn't happen for regular typing because activity for them is caused by the KeyPress event (which we're not generating) but as there is no such beast for special keys like <backspace>, all activity occurs on the KeyDown event. I'm not sure the composition restarting can be avoided.
It doesn't occur with the stable and beta releases of Chrome for Android because those didn't generate proper KEYCODE_DEL KeyDown events but KEYCODE_UNKNOWN (0) which doesn't do anything.

Ok, thanks for the explanation and your fast answer. We will see how we can cope with the new composition behaviour. Something additional we noticed while testing your latest version. The special character keys now have a key code in "keydown"/"keyup", but don't raise a "keypress" event (which digit keys do). Fixing this would align the behaviour for all keys and help to support more use cases. Again we appreciate your work and try to provide feedback as soon as possible.

I actually had a solution that created KeyPress events during composition but it caused the same problem as the KeyDown::KEYCODE_DEL, namely that it aborts composition at the Blink layer. This might have been manageable except that it broke Android's composition when backspacing -- it did not recognize that you were not working on the previous word.
Some inputs on Android don't go through composition but rather appear as distinct characters. Those do create KeyPress events. Different keyboards will make different calls, too.
Remember that any reliance on key events will continue to break if the user swipes (or swypes, or swiftkeys) a word.

What we experience is that some inputs don't create composition events but key-events without keypress event. E.g. on my virtual keyboard (Nexus 4, Android 4.4.4 and your apk) the key '!' creates: keydown, textinput, input and keyup but no keypress event. '1' on the other hand: keydown, keypress, textinput, input, keyup events. Swipes create composition events which are no problem for us. We use the contenteditable attribute for our use case and currently rely on key-events, if there are no composition events.
A good solution for us would be:
Composition events to catch all for kind of text input. If a key doesn't start a composition, we need the correct sequence of key-events including keypress. So from our point of view we don't need valid keycodes during composition. But that's just our use case/point of view. This issue hurts many developers, so their requirements could be different.

The difference is that the Google Keyboard, when typing a "1", is explicitly calling sendKeyEvent() with KeyDown and KeyUp events. The KeyPress gets added because it's a native event from the operating system. A "!" is handled by the Google Keyboard as a commitText() and hence the KeyDown and KeyUp are _synthetic_ and no KeyPress gets injected.
Different keyboards may behave differently.
However, there seems no reason why we can't recognize the case of a commit with no existing composition and treat it as a native key event.
I've uploaded a new version that does exactly that. Give it a try and let me know if that is better for you.

We checked your latest version and now everything looks good. This is a huge improvement for us. Hopefully other people can also provide feedback, if your changes solve their issues too. We are currently working on some problems with composition, but that's another story. Thanks for your support and help on this bug report.

bcwh,
I can confirm that I do get backspace key presses using ContentShell- issue118639 -3.apk :)
In the market version of Chrome, I don't get any backspace key presses at all.
In our use case, we type internal IP address into the browser bar.
In ContentShell- issue118639 -3.apk, I need to add http:// at the front or else the url will not open at all.
I mean if I type something like 192.168.1.123:8080, this won't open, need to type http://192.168.1.123:8080
The market version of Chrome do not have such problem.
Is the apk supposed to work with older version of Android?
The app crash on Android 4.0.4, Galaxy Nexus, log attached.
The app works on Android 4.4.2, Samsung Galaxy Zoom.

Eric, the ContentShell has no "chrome" (not the product, but the smarts outside of the content area) at all. It takes only a raw URL and makes that available in the content area.
Ivan, Chrome's M38 branch point is on 2014-08-15 with the first Beta cut from it at the end of the month, give or take a few days. Chrome for Android should follow the same.

Hello and thanks for the fix!
I tested it on a Nexus 7 device, with Google Keyboard installed and the Auto-Correction option set to Very Aggressive. In the attached html file, if I try to delete the last '.' (period) using backspace, the 'input' event is triggered although I call prevent default on the keydown event (which is correctly fired).
A little bit of context about my usecase:
I'm working at a company which develops an XML WYSIWYG editor web application. The general strategy is to use 'contenteditable' and to intercept all the user edits, block them and perform the XML-aware version of the edit.
Right now, we are using (and blocking) the 'textinput' event that comes when user inserts some text and everything works great (even with handwriting recognition and voice input). The problem we have is that the 'backspace' key does not fire such an event (because it does not input any text). So, for us, the best thing would be to be able to prevent the default action on 'backspace' by calling 'preventDefault' on the keydown event.
Before this fix we had to intercept the 'input' event and figure out what the user has deleted. With the current fix, blocking the backspace keydown event works in most cases, but not in particular cases like the one I described above.

There are some known issues with "preventdefault" but I'm unable to find a specific crbug that would match what you are describing. Feel free to open a new one (label it with Cr-UI-Input-Text-IME).
I assume, then, that the key-events and key-codes (at least) are correct for you?

Sorry for the delay. I initially tested only the backspace key as I was interested only in it. I also tested the other keys and it works with some issues caused by 'preventDefault'-ing the 'textInput' event. I will file separate bugs for those.
So, I think the bug is fixed. Thanks!

OK thanks for that..I know this isn't the right place to be asking this..for us, the customers are tracking against one bug where in we are not able to prevent default in chrome and opera alone, amongst the list of selected browsers.. So one is getting the right key codes and the second one is preventing default.. Will both be resolved in the 38 build? I did check in my nexus 7 tab and it does not fire the keydown event for special characters..?really need help cos we have to commit dates as well and chrome is on top priority support.. Please help us on this..

The preventDefault item is a different problem and is not yet resolved. I don't see a specific existing issue for it. Please open one with a reproducible test-case and it'll get worked on. Add "Cr-UI-Input-Text-IME" and "OS-Android" to the labels.

Hi, this problem (keyCode = 0, etc) still affects Android default browser (Navigator). In Chrome it's solve, ok, thanks. But in my company's web-app most of our Android customers use the native browser. We need to know what they are writing to reflect it on canvas (we are using Fabric.js for it and more things also, and Fabric.js uses key events). So what can we do? I try with composition events, but rewriting fabric.js is not an option and adding it only for native browser... you know?? What do you, google people, think about?
Thanks!!

Sorry, Browser, yes (Navegador in Spanish, bad direct translate...)
When? Android L? The preview SDK had it an also doesn't work...
What about people with old phones that are not going to update it soon?

Phones that do not come with Chrome by default will have to install Chrome from the Play Store. It should be easy enough to replace the app on the home screen or however it is started by your users.
While it would be nice to add improvements to the old browser, even Google doesn't have infinite resources so we must prioritize our efforts.

Question 1:
Will older versions of Android (KitKat, Ice Cream Sandwich, Jellybean) get an updated webview that runs Chromium, since browser is no longer supported?
Question 2:
If so what version of Chromium would likely run the webview in these older versions of Android?

> Question 1:
> Will older versions of Android (KitKat, Ice Cream Sandwich, Jellybean) get an updated webview that runs Chromium, since browser is no longer supported?
No.
Webview in Kitkat was based chromium m30 and m33. Before that it was a fork of webkit.
> Question 2:
> If so what version of Chromium would likely run the webview in these older versions of Android?
Chrome supports ICS and later.

Do you know the last version of "Browser". I'm getting from navigator.userAgent in my device "Mozilla/5.0 (Linux; Android 4.4.4; Nexus 4 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36" --> (Nexus 4 with custom rom)
I suppose that Chrome/XX is what I need to know if is "Browser". My questions are, is this correct? And, You know the last version?
Thanks again!

> Do you know the last version of "Browser". I'm getting from navigator.userAgent in my device "Mozilla/5.0 (Linux; Android 4.4.4; Nexus 4 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36" --> (Nexus 4 with custom rom)
That's the chromium m33 based android webview in kitkat. It won't be updated unless the whole OS is upgraded to L.
When I say "chrome" that supports ICS and later, I meant the chrome browser app: https://play.google.com/store/apps/details?id=com.android.chrome

Stock roms for the nexus 4 don't contain the old AOSP browser app; it's not supported, the default browser there is Chrome. There is no "last version" as Browser doesn't really have a meaningful version - Browser is just a small shell over WebView.
That is a Chromium-based WebView since it's Kitkat, version 33 as you can see in the useragent.

Various vendors have their own browser applications, which may also be called Browser (or another name), and which may use the WebView on that Android version, or some other rendering engine. You'd have to investigate that specific device.

One last question, which I think was for +boilu@ to confirm:
What version of Chromium (M37 or M38) does the Android L WebView ship with?
Since this issue is resolved in M38, understanding what build ships with Android L is key to understanding if this issue will actually be resolved (going forward) for WebView apps that now leverage Chromium.

HEADS UP: Due to problems with multi-to-single character composition on keyboards other than English, keycode generation had to be changed from always-on to manually-enabled.
To make keycode generation work for your inputs, add the attribute "autocomplete=off". Without it, you'll get "compose" events (229) instead of proper keycodes.
See: https://code.google.com/p/chromium/issues/detail?id=422685

I too hit this problem developing a phone gap app. I was unable to get any difference by turning off autocomplete.
However my project leverages angular 1.2 and very fortunately I was able to pull and detect changes in an input field with type="number" using a directive that set a keyup listener on the element.
I can get a key by key diff on the field by inspecting the $viewValue on the control - hope this helps someone out there!
Example:
...
link: function (scope, element, attrs, control) {
// listen for key ups on the element
element.bind("keyup", function (evtObj) {
// pull DOM value to work on - angular nabbed the correct viewValue for us, WOOT!
var charsval = control.$viewValue.toString();
cordova -version
4.0.0
phonegap -version
3.5.0-0.20.4

Ugh. Well, are there plans to support KeyboardEvent.key (https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)? That would probably allow me to work around the problem at least. The real problem keys are the specials like backspace, shift, enter, delete, etc. For KeyboardEvent.key those have hard-coded values that should be the same no matter what language or layout you're using.
For all other keystrokes I can just capture the output of the IME.

#214, 'key' has been discussed in Issue 227231 . However, the real problem is that there is no technical reason for a software keyboard in mobile to behave like a traditional physical keyboard. See the post from Kenji in #107.
https://code.google.com/p/chromium/issues/detail?id=118639#c107
I understand that your applications rely on some key events like backspace, shift, enter, delete, etc, but did you make sure that you would be able to receive those events if your apps were Android native apps? I doubt it.

CONCERNS:
This change is not backwards compatible; it was not communicated beforehand and there is no way to opt-out. Additionally, workarounds and new approaches that work across active browsers have not been well communicated.
As a result of this change my own app and many others completely stopped working in important ways that affected our users.
The change breaks existing web pages using key events that may have been written before Android even existed. This seems to go against the philosophy that has typically governed web development. Backwards compatibility should not be given up without good reason.
PROPOSAL:
While sending key events is not possible for many new soft keyboards, that doesn’t mean it has to be impossible for every keyboard. The browser is a platform for developers, and developers have written and will continue to want to write applications including uses cases that require interacting with the keyboard one key at a time. There ARE use cases for a traditional keyboard that simply mimics a hardware keyboard. As long as hardware keyboards exist people are going to want key codes.
There should be a way to get the the traditional behavior by requesting a traditional keyboard (with the option of disabling autocorrect / suggestions).
SUMMARY:
1) Don’t break backwards compatibility, at least not without an escape hatch.
2) Key events with key codes are still a useful paradigm for some use cases and there should be a way to keep that behavior.
3) If you are going to break it, tell us what to do instead (clearly).
Thank you for your effort on this and the interest and concern that you have already demonstrated.

Hi Yukawa,
What we would like as developers is at the very least a coherent explanation for the revert.
You mention bugs, but as I pointed out, other browsers (namely FF and Safari iOS) do it the correct way, without the bugs.
Your implementation has bugs, fine, then fix them, but both having keycodes and doing composition right are NOT incompatible.
Also I would like to mention that Chrome on Desktop (I'm using Chromium on ubuntu with Anthy to see the composition text) has done it the correct way. It sends 229 when composing. Correct keycodes when actually typing keys.
The argument internally to get this issue fixed could be to be at least on par with the desktop, which do get composition too ! Don't tell us that softkeyboards are special, it is not true.
I am sorry to say that your approach so far seems close to "Clicking on a tablet is not valid, because you now have touch events, do let's ditch all click events on mobile".
This is NOT the correct approach and you know it.
Lastly, I would like to mention, that you are also probably experiencing troubles with Android keyboards implementations (most notably the Google US one) which is not sending keycodes. This is really strange since the Google Japanese Keyboard does, and Swiftkey does.
If the keyboards are not sending keycodes I can see why it's extremely hard for chromium to handle it, it's probably best to just file a bug for given keyboard and not handle it.
I would like to I add that the only reason I take time for this bug, is not because of my users, which are using Firefox right now, but because I do love Chrome which is an awesome product, and I would like to be able to recommend it.

You can't compare FireFox and Safari to Chrome because the internals are very different. Internally, Chrome depends on composition codes (instead of real key codes) to operate properly during composition. It would require some significant changes inside Chrome to adapt to the change. It's not impossible, but it's certainly not trivial.
> they are able to correctly send key codes when the classic keyboards are used
This is because the keyboards actually have physical keys and the OS sends the expected key events. It's Android *soft* keyboards that do not (many, anyway), sending only composition events. We tried to make an educated guess where possible but, well... see the first paragraph.
Composition events occur even on desktop, as has been mentioned. This means that web sites need to handle them anyway in order to be fully compatible.
I still believe it would be great to support this. Instead of analogies and comparisons to other products, how about providing distinct use-cases that are impossible without this? What real products are not possible because of this deficiency?

As I mentioned, I really can see why educated guess can get quite tricky.
As you mention, it should be the OS responsibility to handle input.
I tried to look into chromium code for reasons on why you reimplement input, but could not find anything, are there any specific reasons ? It might help us understand why it's harder to support this.
> This is because the keyboards actually have physical keys and the OS sends the expected key events.
> It's Android *soft* keyboards that do not (many, anyway), sending only composition events. We tried
> to make an educated guess where possible but, well... see the first paragraph.
If I read this correctly, it would be possible to send correct keycodes if the keyboard properly sends them. I think that would be the saner way for everyone to handle things.
When you say many Android keyboards don't send keycodes it, what is your frame of reference ?
Isn't it possible to have correct key codes at least on the Google keyboards and go from there ?
It seems not providing keycodes on a keyboard where it makes sense would be a keyboard bug, not a Chrome one.
Our use case uses heavily Mathquill (https://github.com/mathquill/mathquill) which basically reimplements input for math. Keycodes are a natural choice as math is usually written with ascii symbols.
I looked into patching for composition event when I first met this bug, but honestly browser compatibility was not that great, and for a developer there are lots of hoops to make it work (or there was at the time). Keycodes work almost everywhere.
Anything I missed that might make patching for compositionevent easy ?

The Android IME system is *not* designed to have software IMEs send key codes and it's *not* considered a bug in a keyboard if it doesn't send key codes. Soft keyboards are perfectly within their rights to never send any key codes at all. Only hardware keyboards are expected to send them.

Nicolas, I certainly understand where you're coming from -- it's a discussion we've had internally many times. The Android Keyboard team, however, has decided that key-codes are *not* the way to go... and I cannot say they are wrong.
While there are certain advantages to key-codes, they are also very limiting. They get in the way of auto-correct, auto-suggest, swiping, voice dictation, and many others. There are many possible capabilities of a soft "input method" that do not fit the paradigm of key codes.
While we try to make mobile Chrome support desktop Web on a mobile device, there are limitations and sometimes the better choice is to make mobile Chrome first support the mobile device and push desktop Web to second.
We understand that developers are essential to the Web (and Chrome) but if the choices we make create a jarring experience for our users (e.g. auto-whatever isn't functional, swiping doesn't work, etc.) then they won't use mobile web and *everybody* loses.
Regarding your specific use-case... There are ways in Android to put the keyboard into "raw" mode where all advanced features are turned off and key-codes appear. That would be sufficient, no? I'll have to check how that is set within a web page.

Thank your for the constructive answer.
I do get that keycodes are limited in lots of respects and why they are not enough in some cases.
My point was only to have some legacy support.
A "raw" mode definitely would work. I actually never expected anything more.
Something like autocomplete="off" or <input type="password"> do.
The bug as it was in 2012 however did not work no matter how (keycodes were always 0), which is why the potential revert was a real let down.

Hi all,
I'm using Cordova 3.6.4 in Visual Studio 2013 Community Update 4 to build an apps with a "chat" functionality, the main reason that I use this technology is because I want to, hopefully, write once and can use it in all platforms such as android phones, iphones, all mobile phone browsers, all desktop browsers.
In order to let the users inputting the "message" to be sent, I create a [div] which is contenteditable="true" at the bottom left of the html, at the right hand side of this [div], I have two [image buttons], one is the [happy face] button, the other is the [send button]. (You know, just like Whatsapp, Line and WeChat!)
At any time the user can click the [happy face] button to select one of the many "face image" to insert into the cursor at the [div], then I'll add the html codes into the [div], e.g. div.innerHTML += '<img src="1.jpg">'
So, the innerHTML of this [div] can contain characters AND images, e.g.
12<img src="1.jpg" />34<img src="2.jpg" />
Of course, the actual display is:
12[1st Picture]34[2nd Picture]
If the cursor is at the end of this [div], and I clicked the [BACKSPACE], I expect the [2nd Picture] will be removed, if I clicked the [BACKSPACE] again, I expect the letter [4] will be removed from the [div], this is work at ALMOST every platform I mentioned including all mobile browsers in android and iphone/ipad, all desktop browsers. But IT DOES NOT WORK when I build an android apps and run it in ANY android phone.
Running it as a WebView in android phone, when I click the the [BACKSPACE], the letter [4] is removed instead of the [2nd Picture], when I click the [BACKSPACE] again, the letter[3] is removed. I can NEVER remove the 2 images no matter which IME I'm using.
To work around, I tried to add a keyup/keydown/keypress listener to the [BACKSPACE} but it never fires.
At last, to work around this [BUG], I need to add a third [X] image button and use javascript string.replace to remove the <img> tag when users click this [X] button, but it looks very stupid to the users!
It makes me crazy that ALL IMEs do not remove the image for me by pressing the [BACKSPACE], and if the key events are not fired, I cannot remove the images myself!!!
What should I do?
Please help! Thanks in advance!

There are some issues with having IME deal with embedded objects. Typically the IME gets U+FFFC (obj) character in place of the holder which makes it look like a single character that can be deleted. This may be related to Issue #466755 or it could be completely different.
Either way, it's IME's inability to delete the image within a WebView that is the problem that needs to be addressed. If you have a test page that can be opened in a WebView that reproduces the problem, please create a new issue with those details and we'll look into it.

Thanks for your response #226.
The test page would be simple:
<html>
<body>
<div contenteditable="true">
12<img src="1.jpg">34<img src="2.jpg">
</div>
</body>
</html>
If the above html file is opened using a browser, everything is ok. However, use any android app that has a webview and can open the above html, then, place the cursor at the end of the div (the software keyboard should be opened automatically), then press BACKSPACE.
Expected result: the image 2.jpg is removed.
Actual result: letter "4" is removed. AND, there is NO WAY to remove images 1.jpg and 2.jpg.
I cannot ask the developers of those IMEs: pls. remove the images for me when my users click the BACKSPACE key!
So if the IMEs have problems, I expect I can "listen" to this "BACKSPACE" event and remove the images myself, but this event never fires!
Is there any work around for the time being?
Many thanks for your quick response!

Forgive my ignorance (I don't know much about the complexities here), but to what extent do the new DOM3 'key' and 'code' properties help here? If we ship those consistently for desktop and Android ( issue 227231 ) does that address the scenarios where keyCode=0 is a problem? Since 'keyCode' is now considered 'legacy' I'm loathe to invest a ton there, but I do think we should be investing more in the new DOM UIEvent APIs including high interoperability between browsers and consistency across platforms.

Re #229: In principle |key| is the replacement for |keyCode| for most applications, though some specialist apps will likely want to use |code| instead, for layout/modifier/lock-state independence in certain situations.
If we can get to a state of having working |key| and |code| and find that |keyCode| is still important for older content then it should be possible to construct a shim that will generate |keyCode| that will work correctly for most keys.
Some of the uses for keydown/keyup/keypress on this thread sound more like workarounds of other brokenness in the platform (whether due to implementation or issues w/ the standard), so those may also be worth looking at.

Any new updated ? Still facing the problem on Android 4.4.4 and Chrome (latest version). I've tried Chrome version 37.0.2062 bu still same case (event.keyCode,event.which returning 0 and 229).The testing is done on the KeyDown of a contentEditable div
Any help would be appreciated,the case is critical

The simple answer is: It's not going to happen. I tried several times using different concepts, and each introduces a set of problems that is "bigger" than than this issue.
If you're thinking in terms of key-codes on a mobile platform, you're limiting yourself. Mobile does swipes and voice-transcription and who knows what other kinds of input. Any attempt to rely upon key-codes is going to alienate some subset of your users.

I tried to get this working for a long time after it had generally been agreed that it was not going to work out well no matter how it was implemented. I held out hope because it seemed a good thing to do it at all feasible. I was eventually forced to agree that it is not.

Recently, in Android Chrome, pressing Enter on the soft keyboard in a <textarea> has gone from sending keyCode 13 to sending keyCode 229.
This seems related, but it only started happening a few weeks ago so I'm wondering what changed.
I also don't really understand the explanation given for why this is so difficult to solve. One explanation given:
> They get in the way of auto-correct, auto-suggest, swiping, voice dictation, and many others. There are many possible capabilities of a soft "input method" that do not fit the paradigm of key codes.
I understand that many things don't fit the paradigm of key codes, but I don't understand why that affects your ability to send a keyCode when something does.
> I tried several times using different concepts, and each introduces a set of problems that is "bigger" than than this issue.
Could you name the exact concepts and set of problems involved? It might also help save work from the next person who tries to solve this issue.

> I understand that many things don't fit the paradigm of key codes, but
> I don't understand why that affects your ability to send a keyCode when
> something does.
If the input device sends key-codes then Chrome will pass those along but the Google Android on-screen keyboard does NOT send key-codes. There are other keyboards that do such as the "hacker's keyboard". Physical Bluetooth keyboards also send key-codes.
Not sending key-codes is a purposeful choice by the Android Keyboard Team because it frees them to expand on the capabilities of the keyboard without being limited to the desktops-with-physical-keyboards paradigm.
There is no compromise that is good for the end users. Assuming the soft keyboard generated key-codes for individual presses like a physical keyboard, users would run into intermittent problems where it only works when they do some things. The first time they swipe a word, it fails. The first time they do voice dictation, it fails. And then they'll complain that Android only works some of the time, never know when or where, and just be basically frustrated with the experience.
It's hard for us developers, I'll grant you that, but we need to adapt to the new world instead of trying to adapt it to us.

Can't you give developers an option to force a "dumb" keyboard to be used? In specific situations it would be nice to have the option instead of having this functionality completely taken away. Give developers freedom to opt out of the fancy keyboards if they need to.

Thousands and thousands of developers all over the world wait until you fix this bug, because they want to forget it.
The world and olympics champions have changed many times while Android Keybord Team still think that the world don't needs "desktops-with-physical-keyboards paradigm".
And you just can say "adapt to the new world"?
Physical keyboards are enabled by hundred years. It's absurdly to think that you can create a new useful behavior of the keyboard. You can invent new input devices/modules/plugins, but it will be another story. 60 years old keyboard behavior must not be broken. If user press some key - just let developers know which.
I think you just have broken some laws of robotics. Really. Code wins you.
P.S. I just think guys that you have architecture problems with keyboard.

No. Applications cannot really control the choice of IME on Android. Which IME to use is entirely a user decision. Most devices don't even *have* a "dumb" keyboard - the standard Google keyboard doesn't have a mode that generates keycodes at all.

> Can't you give developers an option to force a "dumb" keyboard to be used?
> In specific situations it would be nice to have the option instead of
> having this functionality completely taken away.
But YOU are asking to take functionality away in certain situations. You're just asking to take it away from the user (e.g. functionality to swipe or dictate) rather than take it away from the developer.
I understand what you want but it's not up to Chrome. I tried work-arounds but they all fail in some respect. You're going to have to take this up with the Android group as they control the keyboard.
But consider this first: If asking your users to install and use the "hacker's keyboard" is a problem for some users then asking them to *not* use swipe or voice dictation or whatever else will also be a problem for some users.
front.end can talk about physical keyboards being around for a hundred years but there's a good chance there are more soft keyboards in the world today than physical ones, possibly more than have ever been built.
Times *have* changed. The only viable option is to adapt.

I agree that we can't force users to use dumb keyboards. But the classic Google default android keyboard does have keys !
SwiftKey, which is not a dumb keyboard, can manage sending keycodes properly when it makes sense (for instance when I hit a key, and not when I swipe or input in Kanji)
If they can do it, why can't you ? There are probably good reasons, but so far we fail to see them. Please enlighten us.
Also, if this bug needs to be duplicated on a Android Keyboard issues board please tell us where we can do so, I would be happy to switch the conversation to more appropriate people. As you mentioned, this is more a keyboard bug that a chromium one.

I agree that we can't force users to use dumb keyboards. But the classic Google default android keyboard does have keys !
SwiftKey, which is not a dumb keyboard, can manage sending keycodes properly when it makes sense (for instance when I hit a key, and not when I swipe or input in Kanji)
If they can do it, why can't you ? There are probably good reasons, but so far we fail to see them. Please enlighten us.
Also, if this bug needs to be duplicated on a Android Keyboard issues board please tell us where we can do so, I would be happy to switch the conversation to more appropriate people. As you mentioned, this is more a keyboard bug that a chromium one.

Yes, it was a choice by the Android Keyboard team for reasons I've explained. They _could_, as you say, but choose not to. They want to force developers to adapt to how users interact with their devices, not the other way around.
What they don't want is users being told, "Sorry, can't swipe here. Press each key." because that is a discontinuity and in breaks the experience as a whole and users complain, "Why doesn't it _just_work_?!?".
You're free to disagree with this but you should at least understand their point of view.

I managed to work around this for the most part because it does detect the 'enter' key and I jiggered something up to make the enter key act like the 'tab' key. Most of my other keydown code was moved to the 'input' event. The only thing I can't do so far is detect the backspace key, but I can rig up a 'swipe to delete' kind of functionality to replace that. So my fires are not burning too brightly with regards to this issue at present. Nevertheless, I still don't see why this issue can't be solved at some point.

This issue is urgent for me as well. I have a few arguments to make about the UX for soft keyboards not sending keycodes.
> Yes, it was a choice by the Android Keyboard team for reasons I've explained.
> They _could_, as you say, but choose not to. They want to force developers to
> adapt to how users interact with their devices, not the other way around.
Chrome and other browsers can disable swipe for textfields by setting autocomplete="false" as detailed by the W3 specifications: http://www.w3schools.com/tags/att_input_autocomplete.asp
This is an urgent issue as some versions of Android triggers an the same keycode (229) for enter key when pressing Shift. This causes really bad UX, extremely buggy behavior. There are currently no work around that I'm aware of that solves this for me.
> What they don't want is users being told, "Sorry, can't swipe here. Press
> each key." because that is a discontinuity and in breaks the experience as a
> whole and users complain, "Why doesn't it _just_work_?!?".
You cannot force developers to write bad apps. Bad developers will still write bad apps with bad UX, same as how style codes cannot force bad programmers from writing bad code. I think the Android keyboard team is focusing too much on purist view instead of the more pragmatic approach on this issue, just my opinion.

> There is no compromise that is good for the end users.
The compromise was to send at least the identifiable key-codes for control keys like backspace, enter, etc. Right now every existing wysiwyg editor has unfixable bugs in chrome.

>> This bug is also causing trouble for my mobile web app which uses bluetooth barcode scanners. We normally attach a keydown listener to the body tag to capture all keyboard input and look for barcodes with a regex. But it's always 0
I also hit this bug with the same reason, as a workaround, we told our users to use Firefox Android instead.

These problems still seem to be plaguing browsers on Android devices. Keypress events are not firing at all, and keydown/up events are returning incorrect characters, whether using keycode or charcode. The only choice I see is to switch to input event, but the goal of keypress is to get the character before its committed to the inputValue, then I can validate and allow or prevent default. Now I have to do more lifting to back out existing input values if it's invalid, and then ensure all input value changes are still being handled wherever they've been applied.

> Right now every existing wysiwyg editor has unfixable bugs in chrome.
I want to second this. I'm working on a code editor (CodeMirror, as used in Chrome devtools) and a rich text editor (ProseMirror) which use the contenteditable feature. Both need custom, configurable behavior for when the user presses backspace at the start of a paragraph/line, and in the current Andoid Chrome, that part is broken.
I am not married to key events, I don't even necessarily need to be able to prevent the default behavior (I can patch things up after the fact), but I do need _some_ way to figure out when backspace was pressed, so that I can perform my custom backspace-specific logic.

It's not really a Chrome thing. Google's soft keyboard does not send key codes. Attempts to programmatically determine what the key codes might have been all end up breaking something else.
You can try taking this up with the Google Keyboard team but they'll tell you what they told us: Keyboards are the way of the past with mobile devices. Don't expect them for input.
Note that if you use a physical keyboard on an Android device, then you will get the codes. Same with some other soft keyboards, like the Hacker's Keyboard.

For reference, you can work around this bug in some cases using composition events: compositionstart, compositionupdate, and compositionend. For example, if you were using my HumanInput library (https://github.com/liftoff/HumanInput) you could trigger a function whenever any input element on the page is changed (e.g. the user types a key in their software keyboard):
var HI = new HumanInput();
HI.on('compositionupdate', function(event, whatWasTyped) { console.log("User typed: " + whatWasTyped); });
That would log "Abc" if the user typed those characters on their software keyboard. You can detect the backspace character by checking the length (if it's -1 from previously then the backspace key was pressed).
If you only care about when the user is *done* typing something (or they press the enter key) you can use compositionend:
HI.on('compositionend', function(event, whatWasTyped) { console.log("User typed: " + whatWasTyped); });
These two events should make it possible to detect regular character input at least (still no good for modifiers like Shift or specials like ESC). Probably good enough for barcode scanners (just make sure your input element has focus). You can also perform some trickery by having an invisible <input> element always regaining focus after mouseup or keyup. That way all new input can be detected this way *in addition* to regular keystroke handling.
Note: The 'input' and 'beforeinput' events don't provide enough information to actually work around this issue.

To some extent I understand that emitting keyCode does not makes sense since the word is not yet committed, but I have a confusion that same should be the case with safari on iOS. There it can capture keyCode on every keyup event. Why and how are they doing so?
Any answer pls ??

Key codes are a feature of the keyboard, not the app. There are soft keyboards for Android (e.g. the "hackers" keyboard) that always emit codes but the official Google keyboard does not for all the reasons discussed above.

"I think the Android keyboard team is focusing too much on purist view instead of the more pragmatic approach"
So it's too hard for engineers to figure out, or just like an engineer's pride thing? I submit to the team: the customer is always right. Can we swallow the pride and Just Make It Work? This single issue has had multiple of my customers switch to using iOS. I prefer Android, but barcode scanning and other key-based activity that doesn't work in Android/Chrome works in every other browser we support.

raymoro@ You haven't indicated why you cannot handle the other types of events (input, composition, etc) in your javascript. It should be relatively easy to handle.
keydown, keyup, keypress are related to physical key events. There is no physical keyboard on Android unless you plug in a physical keyboard via the USB port. If you do that then you will get keyboard events.
It sounds like you are narrowly focusing your opinion on Latin1 language systems and there are many more languages that produce characters in a sequence that cannot be mapped to physical key presses on an imaginary keyboard. We are trying to be consistent that key events are hardware based events. The logical layer above that is composition events which encompass all writing systems.

It's not necessarily "cannot handle" but generally "will not" create one-off hacks when better solutions exist (iOS/Safari, and all the desktop browsers, for example).
Narrow focus: absolutely. The focus is based on the hardware and the audience. Programming is only one "narrow" facet of the problem, but believe-it-or-not not all companies are Google-scale and are prepared to staff call centers for multi-language support, multi-language docs, customer care, services, and content authors and therefore operate only in a "narrow" band of locales and languages. I believe this is fairly common hence the various comments in this thread, and perhaps the reason this bug report exists.
Thank you for the suggestion - I will pass that to the team. Can input and composition events block ranges of characters from being input in the first place the way that keydown can? For input masks, for example?

The purist decision has been made for us by the Android keyboard apps a long time ago. It's not within Chromium's power to Just Make It Work,
not without serious compromises. At most we could fake keyboard events from the composition events, but it's strictly better to cleanly passthrough the composition events fully to JS and let the JS implement their own faking, which can then take application-specific needs into account.
> Can input and composition events block ranges of characters from being input in the first place the way that keydown can?
No, input and composition events are not cancelable, because Android keyboard apps don't expect this and may react buggily. If needed, I recommend you delete the character(s) that was input in your JS in reaction to the "input" event.
> barcode scanning
If your barcode scanner sends physical keyboard-style events, Chrome for Android ought to send keydown/keyup. It's possible there's a separate bug here unrelated to the core issue that we might investigate, for example we currently have http://crbug.com/662386 filed about a scanner usecase, might that be your problem?

<html>
<body>
<div contenteditable="true">
12<img src="1.jpg">34<img src="2.jpg">
</div>
</body>
</html>
Similar to comment 227,
When a space key is pressed, text prediction keyboard app will remove all the <img> within the contenteditable's innerHtml. I was trying to listen to space key and do something to prevent text prediction.
Is there any way around this?
Thank you!

Well great to see the andriod ux preserved. I have an app with a wysiwyg editor, that only exposes key events. My users are able to type @ and have a nice employee mention feature, that spawns an ajax backed element to select fellow employees. After serverside provides some processing the mentionee can recieve an email or in app notification.
Its crucial i support desktop and mobile devices for best interests of my 80k odd user base.
I pointed my team to this thread.
We managed to adapt,
We added a button on the toolbar triggered by UA string check for chrome android, updated call centre scripts, internal comms etc.
Pass on my thanks to the keyboard team, the web community enjoys browser wars when vendors defend their ux innovation ideas.
And special thanks for the feature detection on the navigator once the wont fix was established.
My users will appreciate the discontinous experience as they move from device to device.
All the best from my team to yours.

It does seem possible to write your own on-screen keyboard for Android so that tapping each key produces a key event instead of inputting text through IME commands (users would then have to select your keyboard to use your site properly). Or, you could build a keyboard UI in JavaScript and do whatever you want when each key is pressed. I don’t know if either of these is the best solution for your use case, but they seem possible.

About "the hackers keyboard" I didn't know (thx), unfortunately my comment to the whole situation (it's nothing personal) is: the most popular platform doesn't support some apps, because few teams from one company can't find agreement.
I could write own keyboard, I could even write own OS or make device (this is not irony or inpolite comment), but it's not case and I think, that one of biggest company on the world really has resources to resolve it in "default" Android taste.

If by "most popular platform", you mean Chrome, it's not a Chrome thing.
If you mean Android, it's a deliberate choice by the Android Keyboard team and they have made that choice for good and considered reasons. It's true that there are some issues with the choice but there are good things, too, namely that it encourages developers to not rely on a "feature" that does not apply swiping, voice dictation, and other alternative input methods.
So while it may be that some apps are not supported, the alternative would be some users not supported. Developers have many incentives and options to do things in other ways. Users have fewer.

bcwhite@, thank you for your comment, which is interesting.
Please note, that I have seen info about "good and considered reasons" many times about many people and companies. I believe, that it was case for many Microsoft, VW, Samsung, Apple and others actions, unfortunately thx to these "good and considered reasons" users were loosing something.
We have this bug, we have https://bugs.chromium.org/p/chromium/issues/detail?id=809107, we have https://bugs.chromium.org/p/chromium/issues/detail?id=809107#c32 and maybe others. It's about Chrome+GBoard.
If something cannot be resolved, can we at least get official documents about it, how to make workarounds?
Or can we get API update in next Androids, which will allow inform keyboard if it should produce these events or not? If application ask for keyCode, it will be enabled; done
There are also many other ways to resolve it, it's just question, if somebody want or not to do it.

two more words: I'm reading, that MS added resuming downloads in Windows Update.
Do we really want to have the same with keyboard features? Or are they really so obsolete that we want to remove them now?