@WrapForJNI @Override public void notifyIME(final int type) { if (DEBUG) { // GeckoEditableListener methods should all be called from the Gecko thread ThreadUtils.assertOnGeckoThread(); // NOTIFY_IME_REPLY_EVENT is logged separately, inside geckoActionReply() if (type != NOTIFY_IME_REPLY_EVENT) { Log.d( LOGTAG, "notifyIME(" + getConstantName(GeckoEditableListener.class, "NOTIFY_IME_", type) + ")"); } } if (type == NOTIFY_IME_REPLY_EVENT) { try { if (mGeckoFocused) { // When mGeckoFocused is false, the reply is for a stale action, // and we should not do anything geckoActionReply(); } else if (DEBUG) { Log.d(LOGTAG, "discarding stale reply"); } } finally { // Ensure action is always removed from queue // even if stale action results in exception in geckoActionReply mActionQueue.poll(); } return; } else if (type == NOTIFY_IME_TO_COMMIT_COMPOSITION) { notifyCommitComposition(); return; } else if (type == NOTIFY_IME_TO_CANCEL_COMPOSITION) { notifyCancelComposition(); return; } geckoPostToIc( new Runnable() { @Override public void run() { if (type == NOTIFY_IME_OF_FOCUS) { mFocused = true; // Unmask events on the Gecko side mActionQueue.offer(new Action(Action.TYPE_ACKNOWLEDGE_FOCUS)); } // Make sure there are no other things going on. If we sent // Action.TYPE_ACKNOWLEDGE_FOCUS, this line also makes us // wait for Gecko to update us on the newly focused content mActionQueue.syncWithGecko(); mListener.notifyIME(type); // Unset mFocused after we call syncWithGecko because // syncWithGecko becomes a no-op when mFocused is false. if (type == NOTIFY_IME_OF_BLUR) { mFocused = false; } } }); // Register/unregister Gecko-side text selection listeners // and update the mGeckoFocused flag. if (type == NOTIFY_IME_OF_BLUR && mGeckoFocused) { // Check for focus here because Gecko may send us a blur before a focus in some // cases, and we don't want to unregister an event that was not registered. mGeckoFocused = false; mSuppressCompositions = false; EventDispatcher.getInstance() .unregisterGeckoThreadListener(this, "TextSelection:DraggingHandle"); } else if (type == NOTIFY_IME_OF_FOCUS) { mGeckoFocused = true; mSuppressCompositions = false; EventDispatcher.getInstance() .registerGeckoThreadListener(this, "TextSelection:DraggingHandle"); } }