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