OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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.SystemClock; | 7 import android.os.SystemClock; |
8 import android.text.Editable; | 8 import android.text.Editable; |
9 import android.text.InputType; | 9 import android.text.InputType; |
10 import android.text.Selection; | 10 import android.text.Selection; |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 public boolean sendKeyEvent(KeyEvent event) { | 384 public boolean sendKeyEvent(KeyEvent event) { |
385 if (DEBUG) { | 385 if (DEBUG) { |
386 Log.w(TAG, "sendKeyEvent [" + event.getAction() + "] [" + event.getK
eyCode() + "]"); | 386 Log.w(TAG, "sendKeyEvent [" + event.getAction() + "] [" + event.getK
eyCode() + "]"); |
387 } | 387 } |
388 | 388 |
389 // Short-cut modifier keys so they're not affected by accents. | 389 // Short-cut modifier keys so they're not affected by accents. |
390 if (KeyEvent.isModifierKey(event.getKeyCode())) { | 390 if (KeyEvent.isModifierKey(event.getKeyCode())) { |
391 return mImeAdapter.translateAndSendNativeEvents(event, NO_ACCENT); | 391 return mImeAdapter.translateAndSendNativeEvents(event, NO_ACCENT); |
392 } | 392 } |
393 | 393 |
| 394 // Some keys we just want to pass events straight through. This allows |
| 395 // proper "repeating key" behavior with physical keyboards. |
| 396 int eventKeyCode = event.getKeyCode(); |
| 397 if (eventKeyCode == KeyEvent.KEYCODE_DEL || eventKeyCode == KeyEvent.KEY
CODE_FORWARD_DEL) { |
| 398 mPendingAccent = 0; |
| 399 return mImeAdapter.translateAndSendNativeEvents(event, NO_ACCENT); |
| 400 } |
| 401 |
394 int unicodeChar = event.getUnicodeChar(); | 402 int unicodeChar = event.getUnicodeChar(); |
395 | 403 |
396 // If this is a key-up, and backspace/del or if the key has a character
representation, | 404 // If this is a key-up, and backspace/del or if the key has a character
representation, |
397 // need to update the underlying Editable (i.e. the local representation
of the text | 405 // need to update the underlying Editable (i.e. the local representation
of the text |
398 // being edited). | 406 // being edited). |
399 if (event.getAction() == KeyEvent.ACTION_UP) { | 407 if (event.getAction() == KeyEvent.ACTION_UP) { |
400 if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) { | 408 if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) { |
401 deleteSurroundingText(1, 0); | 409 deleteSurroundingText(1, 0); |
402 return true; | 410 return true; |
403 } else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) { | 411 } else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) { |
(...skipping 18 matching lines...) Expand all Loading... |
422 finishComposingText(); | 430 finishComposingText(); |
423 mImeAdapter.translateAndSendNativeEvents(event, 0); | 431 mImeAdapter.translateAndSendNativeEvents(event, 0); |
424 endBatchEdit(); | 432 endBatchEdit(); |
425 return true; | 433 return true; |
426 } else if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) { | 434 } else if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) { |
427 return true; | 435 return true; |
428 } else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) { | 436 } else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) { |
429 return true; | 437 return true; |
430 } | 438 } |
431 } | 439 } |
432 mImeAdapter.translateAndSendNativeEvents(event, mPendingAccent); | |
433 | 440 |
434 // Physical keyboards also have their events come through here though no
t | 441 // Physical keyboards also have their events come through here though no
t |
435 // by BaseInputConnection. In order to support "accent" key sequences | 442 // by BaseInputConnection. In order to support "accent" key sequences |
436 // such as "~n" or "^o" we have to record that one has been pressed | 443 // such as "~n" or "^o" we have to record that one has been pressed |
437 // and, if an accentable letter follows, delete the accent glyph and | 444 // and, if an accentable letter follows, delete the accent glyph and |
438 // insert the composed character. | 445 // insert the composed character. |
439 | 446 |
440 // Copy class variable to local because class version may get indirectly | 447 // Copy class variable to local because class version may get indirectly |
441 // cleared by the deleteSurroundingText() call below. | 448 // cleared by the deleteSurroundingText() call below. |
442 int pendingAccent = mPendingAccent; | 449 int pendingAccent = mPendingAccent; |
| 450 int nextAccent = mPendingAccent; |
443 | 451 |
444 if ((unicodeChar & KeyCharacterMap.COMBINING_ACCENT) != 0) { | 452 if ((unicodeChar & KeyCharacterMap.COMBINING_ACCENT) != 0) { |
445 pendingAccent = unicodeChar & KeyCharacterMap.COMBINING_ACCENT_MASK; | 453 pendingAccent = NO_ACCENT; |
| 454 nextAccent = unicodeChar & KeyCharacterMap.COMBINING_ACCENT_MASK; |
446 } else if (pendingAccent != NO_ACCENT) { | 455 } else if (pendingAccent != NO_ACCENT) { |
447 if (event.getAction() == KeyEvent.ACTION_DOWN) { | 456 if (event.getAction() == KeyEvent.ACTION_DOWN) { |
448 int combined = KeyEvent.getDeadChar(pendingAccent, unicodeChar); | 457 int combined = KeyEvent.getDeadChar(pendingAccent, unicodeChar); |
449 if (combined != 0) { | 458 if (combined != 0) { |
450 // Previous accent combines with new character to create | 459 // Previous accent combines with new character to create |
451 // a new accented character. First delete the displayed | 460 // a new accented character. First delete the displayed |
452 // accent so it appears overwritten by the composition. | 461 // accent so it appears overwritten by the composition. |
453 super.deleteSurroundingText(1, 0); | 462 super.deleteSurroundingText(1, 0); |
454 mImeAdapter.deleteSurroundingText(1, 0); | 463 mImeAdapter.deleteSurroundingText(1, 0); |
455 } else { | 464 } else { |
456 // Previous accent doesn't combine with this character | 465 // Previous accent doesn't combine with this character |
457 // so assume both are completely independent. | 466 // so assume both are completely independent. |
458 pendingAccent = NO_ACCENT; | 467 pendingAccent = NO_ACCENT; |
| 468 nextAccent = NO_ACCENT; |
459 } | 469 } |
460 } | 470 } |
461 | 471 |
462 if (event.getAction() == KeyEvent.ACTION_UP) { | 472 if (event.getAction() == KeyEvent.ACTION_UP) { |
463 // Forget accent after release of key being accented. | 473 // Forget accent after release of key being accented. |
464 pendingAccent = NO_ACCENT; | 474 nextAccent = NO_ACCENT; |
465 } | 475 } |
466 } | 476 } |
467 | 477 |
468 mPendingAccent = pendingAccent; | 478 mImeAdapter.translateAndSendNativeEvents(event, pendingAccent); |
| 479 mPendingAccent = nextAccent; |
469 return true; | 480 return true; |
470 } | 481 } |
471 | 482 |
472 /** | 483 /** |
473 * @see BaseInputConnection#finishComposingText() | 484 * @see BaseInputConnection#finishComposingText() |
474 */ | 485 */ |
475 @Override | 486 @Override |
476 public boolean finishComposingText() { | 487 public boolean finishComposingText() { |
477 if (DEBUG) Log.w(TAG, "finishComposingText"); | 488 if (DEBUG) Log.w(TAG, "finishComposingText"); |
478 if (getComposingSpanStart(mEditable) == getComposingSpanEnd(mEditable))
{ | 489 if (getComposingSpanStart(mEditable) == getComposingSpanEnd(mEditable))
{ |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 @VisibleForTesting | 605 @VisibleForTesting |
595 ImeState getImeStateForTesting() { | 606 ImeState getImeStateForTesting() { |
596 String text = mEditable.toString(); | 607 String text = mEditable.toString(); |
597 int selectionStart = Selection.getSelectionStart(mEditable); | 608 int selectionStart = Selection.getSelectionStart(mEditable); |
598 int selectionEnd = Selection.getSelectionEnd(mEditable); | 609 int selectionEnd = Selection.getSelectionEnd(mEditable); |
599 int compositionStart = getComposingSpanStart(mEditable); | 610 int compositionStart = getComposingSpanStart(mEditable); |
600 int compositionEnd = getComposingSpanEnd(mEditable); | 611 int compositionEnd = getComposingSpanEnd(mEditable); |
601 return new ImeState(text, selectionStart, selectionEnd, compositionStart
, compositionEnd); | 612 return new ImeState(text, selectionStart, selectionEnd, compositionStart
, compositionEnd); |
602 } | 613 } |
603 } | 614 } |
OLD | NEW |