Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d1c73ff authored by Jean Chalard's avatar Jean Chalard
Browse files

Import TextUtils.getCapsMode to fix it internally (A1)

This should have on effect at all on behavior,
except an increase in performance.

Bug: 4967874
Bug: 6950087
Change-Id: Ie2b51efefe84ca767f5dc8e3b80bfef7e1faab3d
parent 18fc3bf4
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -700,6 +700,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
            }
        }

        mConnection.resetCachesUponCursorMove(mLastSelectionStart);

        if (isDifferentTextField) {
            mainKeyboardView.closing();
            loadSettings();
@@ -733,8 +735,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
        mainKeyboardView.setGesturePreviewMode(mCurrentSettings.mGesturePreviewTrailEnabled,
                mCurrentSettings.mGestureFloatingPreviewTextEnabled);

        mConnection.resetCachesUponCursorMove(mLastSelectionStart);

        if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
    }

+14 −1
Original line number Diff line number Diff line
@@ -192,7 +192,20 @@ public class RichInputConnection {
    public int getCursorCapsMode(final int inputType) {
        mIC = mParent.getCurrentInputConnection();
        if (null == mIC) return Constants.TextUtils.CAP_MODE_OFF;
        return mIC.getCursorCapsMode(inputType);
        if (!TextUtils.isEmpty(mComposingText)) return Constants.TextUtils.CAP_MODE_OFF;
        // TODO: this will generally work, but there may be cases where the buffer contains SOME
        // information but not enough to determine the caps mode accurately. This may happen after
        // heavy pressing of delete, for example DEFAULT_TEXT_CACHE_SIZE - 5 times or so.
        // getCapsMode should be updated to be able to return a "not enough info" result so that
        // we can get more context only when needed.
        if (TextUtils.isEmpty(mCommittedTextBeforeComposingText) && 0 != mCurrentCursorPosition) {
            mCommittedTextBeforeComposingText.append(
                    getTextBeforeCursor(DEFAULT_TEXT_CACHE_SIZE, 0));
        }
        // This never calls InputConnection#getCapsMode - in fact, it's a static method that
        // never blocks or initiates IPC.
        return StringUtils.getCapsMode(mCommittedTextBeforeComposingText,
                mCommittedTextBeforeComposingText.length(), inputType);
    }

    public CharSequence getTextBeforeCursor(final int i, final int j) {
+94 −0
Original line number Diff line number Diff line
@@ -197,4 +197,98 @@ public final class StringUtils {
        codePoints[dsti] = codePoint;
        return codePoints;
    }

    /**
     * Determine what caps mode should be in effect at the current offset in
     * the text. Only the mode bits set in <var>reqModes</var> will be
     * checked. Note that the caps mode flags here are explicitly defined
     * to match those in {@link InputType}.
     *
     * This code is a straight copy of TextUtils.getCapsMode (modulo namespace and formatting
     * issues). This will change in the future as we simplify the code for our use and fix bugs.
     *
     * @param cs The text that should be checked for caps modes.
     * @param off Location in the text at which to check.
     * @param reqModes The modes to be checked: may be any combination of
     * {@link #CAP_MODE_CHARACTERS}, {@link #CAP_MODE_WORDS}, and
     * {@link #CAP_MODE_SENTENCES}.
     *
     * @return Returns the actual capitalization modes that can be in effect
     * at the current position, which is any combination of
     * {@link #CAP_MODE_CHARACTERS}, {@link #CAP_MODE_WORDS}, and
     * {@link #CAP_MODE_SENTENCES}.
     */
    public static int getCapsMode(CharSequence cs, int off, int reqModes) {
        if (off < 0) {
            return 0;
        }

        int i;
        char c;
        int mode = 0;

        if ((reqModes & TextUtils.CAP_MODE_CHARACTERS) != 0) {
            mode |= TextUtils.CAP_MODE_CHARACTERS;
        }
        if ((reqModes & (TextUtils.CAP_MODE_WORDS | TextUtils.CAP_MODE_SENTENCES)) == 0) {
            return mode;
        }

        // Back over allowed opening punctuation.
        for (i = off; i > 0; i--) {
            c = cs.charAt(i - 1);
            if (c != '"' && c != '\'' && Character.getType(c) != Character.START_PUNCTUATION) {
                break;
            }
        }

        // Start of paragraph, with optional whitespace.
        int j = i;
        while (j > 0 && ((c = cs.charAt(j - 1)) == ' ' || c == '\t')) {
            j--;
        }
        if (j == 0 || cs.charAt(j - 1) == '\n') {
            return mode | TextUtils.CAP_MODE_WORDS;
        }

        // Or start of word if we are that style.
        if ((reqModes & TextUtils.CAP_MODE_SENTENCES) == 0) {
            if (i != j) mode |= TextUtils.CAP_MODE_WORDS;
            return mode;
        }

        // There must be a space if not the start of paragraph.
        if (i == j) {
            return mode;
        }

        // Back over allowed closing punctuation.
        for (; j > 0; j--) {
            c = cs.charAt(j - 1);
            if (c != '"' && c != '\'' && Character.getType(c) != Character.END_PUNCTUATION) {
                break;
            }
        }

        if (j > 0) {
            c = cs.charAt(j - 1);
            if (c == '.' || c == '?' || c == '!') {
                // Do not capitalize if the word ends with a period but
                // also contains a period, in which case it is an abbreviation.
                if (c == '.') {
                    for (int k = j - 2; k >= 0; k--) {
                        c = cs.charAt(k);
                        if (c == '.') {
                            return mode;
                        }
                        if (!Character.isLetter(c)) {
                            break;
                        }
                    }
                }
                return mode | TextUtils.CAP_MODE_SENTENCES;
            }
        }
        return mode;
    }
}