Chromium Code Reviews| Index: remoting/android/java/src/org/chromium/chromoting/Desktop.java |
| diff --git a/remoting/android/java/src/org/chromium/chromoting/Desktop.java b/remoting/android/java/src/org/chromium/chromoting/Desktop.java |
| index 5ba3f013e16f49b117df19707bc794c946d21f7a..34107369b69f566bb933044f041b4dee729553d7 100644 |
| --- a/remoting/android/java/src/org/chromium/chromoting/Desktop.java |
| +++ b/remoting/android/java/src/org/chromium/chromoting/Desktop.java |
| @@ -9,6 +9,7 @@ import android.app.Activity; |
| import android.content.res.Configuration; |
| import android.os.Build; |
| import android.os.Bundle; |
| +import android.view.KeyCharacterMap; |
| import android.view.KeyEvent; |
| import android.view.Menu; |
| import android.view.MenuItem; |
| @@ -18,6 +19,9 @@ import android.widget.ImageButton; |
| import org.chromium.chromoting.jni.JniInterface; |
| +import java.util.Set; |
| +import java.util.TreeSet; |
| + |
| /** |
| * A simple screen that does nothing except display a DesktopView and notify it of rotations. |
| */ |
| @@ -32,6 +36,9 @@ public class Desktop extends Activity implements View.OnSystemUiVisibilityChange |
| /** The button used to show the action bar. */ |
| private ImageButton mOverlayButton; |
| + /** Set of pressed keys for which we've sent TextEvent. */ |
| + private Set<Integer> mPressedTextKeys = new TreeSet<Integer>(); |
| + |
| /** Called when the activity is first created. */ |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| @@ -176,48 +183,66 @@ public class Desktop extends Activity implements View.OnSystemUiVisibilityChange |
| */ |
| @Override |
| public boolean dispatchKeyEvent(KeyEvent event) { |
| - // Send ACTION_MULTIPLE event as TextEvent. |
| - // |
| - // TODO(sergeyu): For all keys on English keyboard Android generates |
| - // ACTION_DOWN/ACTION_UP events, so they are sent as KeyEvent instead of |
| - // TextEvent. As result the host may handle them as non-English chars |
| - // when it has non-English layout selected, which might be confusing for |
| - // the user. This code should be fixed to send all text input events as |
| - // TextEvent, but it cannot be done now because not all hosts support |
| - // TextEvent. Also, to handle keyboard shortcuts properly this code will |
| - // need to track the state of modifier keys (such as Ctrl or Alt) and |
| - // send KeyEvents in the case any of the modifier keys are pressed. |
| + // Send TextEvent in two cases: |
| + // 1. This is an ACTION_MULTIPLE event. |
| + // 2. The event was generated by on-screen keyboard and Ctrl, Alt and |
| + // Meta are not pressed. |
| + // This ensures that on-screen keyboard always inject input that |
|
Lambros
2014/05/28 22:32:28
s/inject/injects
Sergey Ulanov
2014/06/06 18:43:45
Done.
|
| + // correspond to what user sees on the screen, while physical keyboard |
| + // acts as if it is connected to the remote host. |
| if (event.getAction() == KeyEvent.ACTION_MULTIPLE) { |
| JniInterface.sendTextEvent(event.getCharacters()); |
| return super.dispatchKeyEvent(event); |
| } |
| - boolean depressed = event.getAction() == KeyEvent.ACTION_DOWN; |
| + int keyCode = event.getKeyCode(); |
| + boolean pressed = event.getAction() == KeyEvent.ACTION_DOWN; |
| + |
| + // For Enter getUnicodeChar() returns 10 (line feed), but we still |
| + // want to send it as KeyEvent. |
|
Lambros
2014/05/28 22:32:28
What about Backspace - will that work as expected?
Sergey Ulanov
2014/06/06 18:43:45
Yes. getCharacter() is not set for Backspace.
|
| + int unicode = keyCode != KeyEvent.KEYCODE_ENTER ? event.getUnicodeChar() : 0; |
| + |
| + boolean no_modifiers = !event.isAltPressed() && |
| + !event.isCtrlPressed() && !event.isMetaPressed(); |
| + |
| + if (event.getDeviceId() == KeyCharacterMap.VIRTUAL_KEYBOARD && |
| + pressed && unicode != 0 && no_modifiers) { |
| + mPressedTextKeys.add(keyCode); |
| + int[] codePoints = new int[1]; |
|
Lambros
2014/05/28 22:32:28
This could be: int[] codePoints = { unicode }
but
Sergey Ulanov
2014/06/06 18:43:45
Done.
|
| + codePoints[0] = unicode; |
| + JniInterface.sendTextEvent(new String(codePoints, 0, 1)); |
|
Lambros
2014/05/28 22:32:28
You can convert to string like this:
String.valueO
Sergey Ulanov
2014/06/06 18:43:45
In Java char is 16 bits and can encode only plane
|
| + return super.dispatchKeyEvent(event); |
| + } |
| + |
| + if (!pressed && mPressedTextKeys.contains(keyCode)) { |
| + mPressedTextKeys.remove(keyCode); |
| + return super.dispatchKeyEvent(event); |
| + } |
| - switch (event.getKeyCode()) { |
| + switch (keyCode) { |
| case KeyEvent.KEYCODE_AT: |
| - JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, depressed); |
| - JniInterface.sendKeyEvent(KeyEvent.KEYCODE_2, depressed); |
| + JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed); |
| + JniInterface.sendKeyEvent(KeyEvent.KEYCODE_2, pressed); |
| break; |
| case KeyEvent.KEYCODE_POUND: |
| - JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, depressed); |
| - JniInterface.sendKeyEvent(KeyEvent.KEYCODE_3, depressed); |
| + JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed); |
| + JniInterface.sendKeyEvent(KeyEvent.KEYCODE_3, pressed); |
| break; |
| case KeyEvent.KEYCODE_STAR: |
| - JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, depressed); |
| - JniInterface.sendKeyEvent(KeyEvent.KEYCODE_8, depressed); |
| + JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed); |
| + JniInterface.sendKeyEvent(KeyEvent.KEYCODE_8, pressed); |
| break; |
| case KeyEvent.KEYCODE_PLUS: |
| - JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, depressed); |
| - JniInterface.sendKeyEvent(KeyEvent.KEYCODE_EQUALS, depressed); |
| + JniInterface.sendKeyEvent(KeyEvent.KEYCODE_SHIFT_LEFT, pressed); |
| + JniInterface.sendKeyEvent(KeyEvent.KEYCODE_EQUALS, pressed); |
| break; |
| default: |
| // We try to send all other key codes to the host directly. |
| - JniInterface.sendKeyEvent(event.getKeyCode(), depressed); |
| + JniInterface.sendKeyEvent(keyCode, pressed); |
| } |
| return super.dispatchKeyEvent(event); |