mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 711648 - Pre-commit underline is not shown for the composing text. r=blassey
This commit is contained in:
parent
28b141d8f2
commit
c603276047
@ -48,6 +48,7 @@ import org.mozilla.gecko.gfx.InputConnectionHandler;
|
||||
import android.os.*;
|
||||
import android.app.*;
|
||||
import android.text.*;
|
||||
import android.text.style.*;
|
||||
import android.view.*;
|
||||
import android.view.inputmethod.*;
|
||||
import android.content.*;
|
||||
@ -101,13 +102,20 @@ public class GeckoInputConnection
|
||||
@Override
|
||||
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||
replaceText(text, newCursorPosition, false);
|
||||
mComposing = false;
|
||||
|
||||
if (mComposing) {
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . commitText: endComposition");
|
||||
endComposition();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finishComposingText() {
|
||||
mComposing = false;
|
||||
if (mComposing) {
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . finishComposingText: endComposition");
|
||||
endComposition();
|
||||
}
|
||||
|
||||
final Editable content = getEditable();
|
||||
if (content != null) {
|
||||
@ -257,12 +265,12 @@ public class GeckoInputConnection
|
||||
}
|
||||
|
||||
if (composing) {
|
||||
mComposing = true;
|
||||
|
||||
Spannable sp = null;
|
||||
if (!(text instanceof Spannable)) {
|
||||
sp = new SpannableStringBuilder(text);
|
||||
text = sp;
|
||||
sp.setSpan(COMPOSING_SPAN, 0, sp.length(),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_COMPOSING);
|
||||
} else {
|
||||
sp = (Spannable)text;
|
||||
}
|
||||
@ -306,6 +314,16 @@ public class GeckoInputConnection
|
||||
endBatchEdit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComposingRegion(int start, int end) {
|
||||
if (mComposing) {
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . setComposingRegion: endComposition");
|
||||
endComposition();
|
||||
}
|
||||
|
||||
return super.setComposingRegion(start, end);
|
||||
}
|
||||
|
||||
public String getComposingText() {
|
||||
final Editable content = getEditable();
|
||||
if (content == null) {
|
||||
@ -393,6 +411,19 @@ public class GeckoInputConnection
|
||||
if (start != a || end != b) {
|
||||
if (DEBUG) Log.d(LOGTAG, String.format(". . . notifySelectionChange: current editable selection: [%d, %d]", a, b));
|
||||
super.setSelection(start, end);
|
||||
|
||||
// Check if the selection is inside composing span
|
||||
int ca = getComposingSpanStart(content);
|
||||
int cb = getComposingSpanEnd(content);
|
||||
if (cb < ca) {
|
||||
int tmp = ca;
|
||||
ca = cb;
|
||||
cb = tmp;
|
||||
}
|
||||
if (start < ca || start > cb || end < ca || end > cb) {
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . notifySelectionChange: removeComposingSpans");
|
||||
removeComposingSpans(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -411,32 +442,112 @@ public class GeckoInputConnection
|
||||
// TextWatcher
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count)
|
||||
{
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_SET_SELECTION, start, before));
|
||||
if (!mComposing) {
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . onTextChanged: IME_COMPOSITION_BEGIN");
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_COMPOSITION_BEGIN, 0, 0));
|
||||
mComposing = true;
|
||||
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . onTextChanged: IME_SET_SELECTION, start=" + start + ", len=" + before);
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_SET_SELECTION, start, before));
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . onTextChanged: IME_DELETE_TEXT");
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_DELETE_TEXT, 0, 0));
|
||||
} else {
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_COMPOSITION_BEGIN, 0, 0));
|
||||
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(0, count,
|
||||
GeckoEvent.IME_RANGE_RAWINPUT, 0, 0, 0,
|
||||
s.subSequence(start, start + count).toString()));
|
||||
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_COMPOSITION_END, 0, 0));
|
||||
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_SET_SELECTION, start + count, 0));
|
||||
sendTextToGecko(s.subSequence(start, start + count), start + count);
|
||||
}
|
||||
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . onTextChanged: IME_SET_SELECTION, start=" + (start + count) + ", 0");
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_SET_SELECTION, start + count, 0));
|
||||
|
||||
// Block this thread until all pending events are processed
|
||||
GeckoAppShell.geckoEventSync();
|
||||
}
|
||||
|
||||
private void endComposition() {
|
||||
if (DEBUG) Log.d(LOGTAG, "IME: endComposition: IME_COMPOSITION_END");
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_COMPOSITION_END, 0, 0));
|
||||
mComposing = false;
|
||||
}
|
||||
|
||||
private void sendTextToGecko(CharSequence text, int caretPos) {
|
||||
if (DEBUG) Log.d(LOGTAG, "IME: sendTextToGecko(\"" + text + "\")");
|
||||
|
||||
// Handle composition text styles
|
||||
if (text != null && text instanceof Spanned) {
|
||||
Spanned span = (Spanned) text;
|
||||
int spanStart = 0, spanEnd = 0;
|
||||
boolean pastSelStart = false, pastSelEnd = false;
|
||||
|
||||
do {
|
||||
int rangeType = GeckoEvent.IME_RANGE_CONVERTEDTEXT;
|
||||
int rangeStyles = 0, rangeForeColor = 0, rangeBackColor = 0;
|
||||
|
||||
// Find next offset where there is a style transition
|
||||
spanEnd = span.nextSpanTransition(spanStart + 1, text.length(),
|
||||
CharacterStyle.class);
|
||||
|
||||
// Empty range, continue
|
||||
if (spanEnd <= spanStart)
|
||||
continue;
|
||||
|
||||
// Get and iterate through list of span objects within range
|
||||
CharacterStyle styles[] = span.getSpans(
|
||||
spanStart, spanEnd, CharacterStyle.class);
|
||||
|
||||
for (CharacterStyle style : styles) {
|
||||
if (style instanceof UnderlineSpan) {
|
||||
// Text should be underlined
|
||||
rangeStyles |= GeckoEvent.IME_RANGE_UNDERLINE;
|
||||
|
||||
} else if (style instanceof ForegroundColorSpan) {
|
||||
// Text should be of a different foreground color
|
||||
rangeStyles |= GeckoEvent.IME_RANGE_FORECOLOR;
|
||||
rangeForeColor =
|
||||
((ForegroundColorSpan)style).getForegroundColor();
|
||||
|
||||
} else if (style instanceof BackgroundColorSpan) {
|
||||
// Text should be of a different background color
|
||||
rangeStyles |= GeckoEvent.IME_RANGE_BACKCOLOR;
|
||||
rangeBackColor =
|
||||
((BackgroundColorSpan)style).getBackgroundColor();
|
||||
}
|
||||
}
|
||||
|
||||
// Add range to array, the actual styles are
|
||||
// applied when IME_SET_TEXT is sent
|
||||
if (DEBUG) Log.d(LOGTAG, String.format(". . . sendTextToGecko: IME_ADD_RANGE, %d, %d, %d, %d, %d, %d",
|
||||
spanStart, spanEnd - spanStart, rangeType, rangeStyles, rangeForeColor, rangeBackColor));
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(spanStart, spanEnd - spanStart,
|
||||
rangeType, rangeStyles,
|
||||
rangeForeColor, rangeBackColor));
|
||||
|
||||
spanStart = spanEnd;
|
||||
} while (spanStart < text.length());
|
||||
} else {
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . sendTextToGecko: IME_ADD_RANGE, 0, " + text.length() +
|
||||
", IME_RANGE_RAWINPUT, IME_RANGE_UNDERLINE)");
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(0, text == null ? 0 : text.length(),
|
||||
GeckoEvent.IME_RANGE_RAWINPUT,
|
||||
GeckoEvent.IME_RANGE_UNDERLINE, 0, 0));
|
||||
}
|
||||
|
||||
// Change composition (treating selection end as where the caret is)
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . sendTextToGecko: IME_SET_TEXT, IME_RANGE_CARETPOSITION, \"" + text + "\")");
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(caretPos, 0,
|
||||
GeckoEvent.IME_RANGE_CARETPOSITION, 0, 0, 0,
|
||||
text.toString()));
|
||||
}
|
||||
|
||||
public void afterTextChanged(Editable s)
|
||||
{
|
||||
}
|
||||
@ -785,6 +896,8 @@ public class GeckoInputConnection
|
||||
public static final int IME_STATE_PASSWORD = 2;
|
||||
public static final int IME_STATE_PLUGIN = 3;
|
||||
|
||||
final CharacterStyle COMPOSING_SPAN = new UnderlineSpan();
|
||||
|
||||
KeyListener mKeyListener;
|
||||
Editable mEditable;
|
||||
Editable.Factory mEditableFactory;
|
||||
|
Loading…
Reference in New Issue
Block a user