OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |