Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/input/ImeAdapter.java

Issue 759033002: Handle accent keys from physical keyboards. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: changed where characters get accented so hidden editor contents are also correct (and test works pr… Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.content.browser.input; 5 package org.chromium.content.browser.input;
6 6
7 import android.os.Handler; 7 import android.os.Handler;
8 import android.os.ResultReceiver; 8 import android.os.ResultReceiver;
9 import android.os.SystemClock; 9 import android.os.SystemClock;
10 import android.text.Editable; 10 import android.text.Editable;
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 } 331 }
332 332
333 /** 333 /**
334 * @return true if the selected text is of password. 334 * @return true if the selected text is of password.
335 */ 335 */
336 public boolean isSelectionPassword() { 336 public boolean isSelectionPassword() {
337 return mTextInputType == sTextInputTypePassword; 337 return mTextInputType == sTextInputTypePassword;
338 } 338 }
339 339
340 public boolean dispatchKeyEvent(KeyEvent event) { 340 public boolean dispatchKeyEvent(KeyEvent event) {
341 return translateAndSendNativeEvents(event); 341 // Physical keyboards have their events come through here instead of
342 // AdapterInputConnection.
343 if (mInputConnection != null) {
344 return mInputConnection.sendKeyEvent(event);
345 }
346 return translateAndSendNativeEvents(event, 0);
342 } 347 }
343 348
344 private int shouldSendKeyEventWithKeyCode(String text) { 349 private int shouldSendKeyEventWithKeyCode(String text) {
345 if (text.length() != 1) return COMPOSITION_KEY_CODE; 350 if (text.length() != 1) return COMPOSITION_KEY_CODE;
346 351
347 if (text.equals("\n")) return KeyEvent.KEYCODE_ENTER; 352 if (text.equals("\n")) return KeyEvent.KEYCODE_ENTER;
348 else if (text.equals("\t")) return KeyEvent.KEYCODE_TAB; 353 else if (text.equals("\t")) return KeyEvent.KEYCODE_TAB;
349 else return COMPOSITION_KEY_CODE; 354 else return COMPOSITION_KEY_CODE;
350 } 355 }
351 356
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 // modification) so return an unknown key-code. 405 // modification) so return an unknown key-code.
401 return null; 406 return null;
402 } 407 }
403 408
404 void sendKeyEventWithKeyCode(int keyCode, int flags) { 409 void sendKeyEventWithKeyCode(int keyCode, int flags) {
405 long eventTime = SystemClock.uptimeMillis(); 410 long eventTime = SystemClock.uptimeMillis();
406 mLastSyntheticKeyCode = keyCode; 411 mLastSyntheticKeyCode = keyCode;
407 translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime, 412 translateAndSendNativeEvents(new KeyEvent(eventTime, eventTime,
408 KeyEvent.ACTION_DOWN, keyCode, 0, 0, 413 KeyEvent.ACTION_DOWN, keyCode, 0, 0,
409 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 414 KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
410 flags)); 415 flags), 0);
411 translateAndSendNativeEvents(new KeyEvent(SystemClock.uptimeMillis(), ev entTime, 416 translateAndSendNativeEvents(new KeyEvent(SystemClock.uptimeMillis(), ev entTime,
412 KeyEvent.ACTION_UP, keyCode, 0, 0, 417 KeyEvent.ACTION_UP, keyCode, 0, 0,
413 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 418 KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
414 flags)); 419 flags), 0);
415 } 420 }
416 421
417 // Calls from Java to C++ 422 // Calls from Java to C++
418 // TODO: Add performance tracing to more complicated functions. 423 // TODO: Add performance tracing to more complicated functions.
419 424
420 boolean checkCompositionQueueAndCallNative(CharSequence text, int newCursorP osition, 425 boolean checkCompositionQueueAndCallNative(CharSequence text, int newCursorP osition,
421 boolean isCommit) { 426 boolean isCommit) {
422 if (mNativeImeAdapterAndroid == 0) return false; 427 if (mNativeImeAdapterAndroid == 0) return false;
423 mViewEmbedder.onImeEvent(); 428 mViewEmbedder.onImeEvent();
424 429
(...skipping 14 matching lines...) Expand all
439 keyCode = KeyEvent.KEYCODE_UNKNOWN; 444 keyCode = KeyEvent.KEYCODE_UNKNOWN;
440 } else { 445 } else {
441 keyCode = -1; 446 keyCode = -1;
442 } 447 }
443 448
444 // If this is a commit with no previous composition, then treat it a s a native 449 // If this is a commit with no previous composition, then treat it a s a native
445 // KeyDown/KeyUp pair with no composition rather than a synthetic pa ir with 450 // KeyDown/KeyUp pair with no composition rather than a synthetic pa ir with
446 // composition below. 451 // composition below.
447 if (keyCode > 0 && isCommit && mLastComposeText == null) { 452 if (keyCode > 0 && isCommit && mLastComposeText == null) {
448 mLastSyntheticKeyCode = keyCode; 453 mLastSyntheticKeyCode = keyCode;
449 return translateAndSendNativeEvents(keyEvent) 454 return translateAndSendNativeEvents(keyEvent, 0)
450 && translateAndSendNativeEvents( 455 && translateAndSendNativeEvents(
451 KeyEvent.changeAction(keyEvent, KeyEvent.ACTION_ UP)); 456 KeyEvent.changeAction(keyEvent, KeyEvent.ACTION_ UP), 0);
452 } 457 }
453 458
454 // When typing, there is no issue sending KeyDown and KeyUp events a round the 459 // When typing, there is no issue sending KeyDown and KeyUp events a round the
455 // composition event because those key events do nothing (other than call JS 460 // composition event because those key events do nothing (other than call JS
456 // handlers). Typing does not cause changes outside of a KeyPress e vent which 461 // handlers). Typing does not cause changes outside of a KeyPress e vent which
457 // we don't call here. However, if the key-code is a control key su ch as 462 // we don't call here. However, if the key-code is a control key su ch as
458 // KEYCODE_DEL then there never is an associated KeyPress event and the KeyDown 463 // KEYCODE_DEL then there never is an associated KeyPress event and the KeyDown
459 // event itself causes the action. The net result below is that the Renderer calls 464 // event itself causes the action. The net result below is that the Renderer calls
460 // cancelComposition() and then Android starts anew with setComposin gRegion(). 465 // cancelComposition() and then Android starts anew with setComposin gRegion().
461 // This stopping and restarting of composition could be a source of problems 466 // This stopping and restarting of composition could be a source of problems
(...skipping 30 matching lines...) Expand all
492 mLastComposeText = textStr; 497 mLastComposeText = textStr;
493 return true; 498 return true;
494 } 499 }
495 500
496 void finishComposingText() { 501 void finishComposingText() {
497 mLastComposeText = null; 502 mLastComposeText = null;
498 if (mNativeImeAdapterAndroid == 0) return; 503 if (mNativeImeAdapterAndroid == 0) return;
499 nativeFinishComposingText(mNativeImeAdapterAndroid); 504 nativeFinishComposingText(mNativeImeAdapterAndroid);
500 } 505 }
501 506
502 boolean translateAndSendNativeEvents(KeyEvent event) { 507 boolean translateAndSendNativeEvents(KeyEvent event, int accentChar) {
503 if (mNativeImeAdapterAndroid == 0) return false; 508 if (mNativeImeAdapterAndroid == 0) return false;
504 509
505 int action = event.getAction(); 510 int action = event.getAction();
506 if (action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_UP) { 511 if (action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_UP) {
507 // action == KeyEvent.ACTION_MULTIPLE 512 // action == KeyEvent.ACTION_MULTIPLE
508 // TODO(bulach): confirm the actual behavior. Apparently: 513 // TODO(bulach): confirm the actual behavior. Apparently:
509 // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a 514 // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a
510 // composition key down (229) followed by a commit text with the 515 // composition key down (229) followed by a commit text with the
511 // string from event.getUnicodeChars(). 516 // string from event.getUnicodeChars().
512 // Otherwise, we'd need to send an event with a 517 // Otherwise, we'd need to send an event with a
513 // WebInputEvent::IsAutoRepeat modifier. We also need to verify when 518 // WebInputEvent::IsAutoRepeat modifier. We also need to verify when
514 // we receive ACTION_MULTIPLE: we may receive it after an ACTION_DOW N, 519 // we receive ACTION_MULTIPLE: we may receive it after an ACTION_DOW N,
515 // and if that's the case, we'll need to review when to send the Cha r 520 // and if that's the case, we'll need to review when to send the Cha r
516 // event. 521 // event.
517 return false; 522 return false;
518 } 523 }
519 mViewEmbedder.onImeEvent(); 524 mViewEmbedder.onImeEvent();
525 int unichar = event.getUnicodeChar();
Ted C 2014/12/03 02:30:14 The other file called them unicodeChar, so I would
bcwhite 2014/12/03 15:49:09 Done.
526 if (accentChar != 0) {
527 int combined = KeyCharacterMap.getDeadChar(accentChar, unichar);
Ted C 2014/12/03 02:30:14 Any reason to use KeyCharacterMap instead of KeyEv
bcwhite 2014/12/03 15:49:10 Not particularly. I was typing both names in diff
528 if (combined != 0) {
529 unichar = combined;
530 }
531 }
520 return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, event.getActi on(), 532 return nativeSendKeyEvent(mNativeImeAdapterAndroid, event, event.getActi on(),
521 getModifiers(event.getMetaState()), event.getEventTime(), event. getKeyCode(), 533 getModifiers(event.getMetaState()), event.getEventTime(), event. getKeyCode(),
522 /*isSystemKey=*/false, event.getUnicodeChar()); 534 /*isSystemKey=*/false, unichar);
523 } 535 }
524 536
525 boolean sendSyntheticKeyEvent(int eventType, long timestampMs, int keyCode, int modifiers, 537 boolean sendSyntheticKeyEvent(int eventType, long timestampMs, int keyCode, int modifiers,
526 int unicodeChar) { 538 int unicodeChar) {
527 if (mNativeImeAdapterAndroid == 0) return false; 539 if (mNativeImeAdapterAndroid == 0) return false;
528 540
529 nativeSendSyntheticKeyEvent( 541 nativeSendSyntheticKeyEvent(
530 mNativeImeAdapterAndroid, eventType, timestampMs, keyCode, modif iers, unicodeChar); 542 mNativeImeAdapterAndroid, eventType, timestampMs, keyCode, modif iers, unicodeChar);
531 return true; 543 return true;
532 } 544 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid , 753 private native void nativeDeleteSurroundingText(long nativeImeAdapterAndroid ,
742 int before, int after); 754 int before, int after);
743 755
744 private native void nativeUnselect(long nativeImeAdapterAndroid); 756 private native void nativeUnselect(long nativeImeAdapterAndroid);
745 private native void nativeSelectAll(long nativeImeAdapterAndroid); 757 private native void nativeSelectAll(long nativeImeAdapterAndroid);
746 private native void nativeCut(long nativeImeAdapterAndroid); 758 private native void nativeCut(long nativeImeAdapterAndroid);
747 private native void nativeCopy(long nativeImeAdapterAndroid); 759 private native void nativeCopy(long nativeImeAdapterAndroid);
748 private native void nativePaste(long nativeImeAdapterAndroid); 760 private native void nativePaste(long nativeImeAdapterAndroid);
749 private native void nativeResetImeAdapter(long nativeImeAdapterAndroid); 761 private native void nativeResetImeAdapter(long nativeImeAdapterAndroid);
750 } 762 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698