// TextWatcher public void onTextChanged(CharSequence s, int start, int before, int count) { if (hasCompositionString() && mCompositionStart != start) { // Changed range is different from the composition, need to reset the composition endComposition(); } CharSequence changedText = s.subSequence(start, start + count); if (changedText.length() == 1) { char changedChar = changedText.charAt(0); // Some IMEs (e.g. SwiftKey X) send a string with '\n' when Enter is pressed // Such string cannot be handled by Gecko, so we convert it to a key press instead if (changedChar == '\n') { processKeyDown( KeyEvent.KEYCODE_ENTER, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER), false); processKeyUp( KeyEvent.KEYCODE_ENTER, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER), false); return; } // If we are committing a single character and didn't have an active composition string, // we can send Gecko keydown/keyup events instead of composition events. if (mCommittingText && !hasCompositionString() && synthesizeKeyEvents(changedChar)) { // Block this thread until all pending events are processed GeckoAppShell.geckoEventSync(); return; } } if (!hasCompositionString()) { if (DEBUG) Log.d(LOGTAG, ". . . onTextChanged: IME_COMPOSITION_BEGIN"); GeckoAppShell.sendEventToGecko( GeckoEvent.createIMEEvent(GeckoEvent.IME_COMPOSITION_BEGIN, 0, 0)); mCompositionStart = start; if (DEBUG) { Log.d(LOGTAG, ". . . onTextChanged: IME_SET_SELECTION, start=" + start + ", len=" + before); } GeckoAppShell.sendEventToGecko( GeckoEvent.createIMEEvent(GeckoEvent.IME_SET_SELECTION, start, before)); } sendTextToGecko(changedText, start + count); if (DEBUG) { Log.d(LOGTAG, ". . . onTextChanged: IME_SET_SELECTION, start=" + (start + count) + ", 0"); } GeckoAppShell.sendEventToGecko( GeckoEvent.createIMEEvent(GeckoEvent.IME_SET_SELECTION, start + count, 0)); // End composition if all characters in the word have been deleted. // This fixes autocomplete results not appearing. if (count == 0) endComposition(); // Block this thread until all pending events are processed GeckoAppShell.geckoEventSync(); }