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

Commit 3d01006f authored by Gilles Debunne's avatar Gilles Debunne
Browse files

Fixes around cursor blink.

Bug 3394800

A previous fix called cancel when the window was detached. The cancel/uncancel
mechanism does not actually removes the Blink runnable.

It is indeed more a suspend, which is used when the window loses focus.
The problem here was that uncancel was never called.

Removing the runnable callback instead.

Also rationalized the use of makeBlink and the setting of mShowCursor

Change-Id: I92aac43a891991b7cc98738de0f12332ab16907a
parent 3ca6d6bb
Loading
Loading
Loading
Loading
+45 −49
Original line number Diff line number Diff line
@@ -3998,7 +3998,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        }

        if (mBlink != null) {
            mBlink.cancel();
            mBlink.removeCallbacks(mBlink);
        }

        if (mInsertionPointCursorController != null) {
@@ -5421,19 +5421,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        invalidate();
        int curs = getSelectionStart();

        if (curs >= 0 || (mGravity & Gravity.VERTICAL_GRAVITY_MASK) ==
                             Gravity.BOTTOM) {
        if (curs >= 0 || (mGravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
            registerForPreDraw();
        }

        if (curs >= 0) {
            mHighlightPathBogus = true;

            if (isFocused()) {
                mShowCursor = SystemClock.uptimeMillis();
            makeBlink();
        }
        }

        checkForResize();
    }
@@ -6589,6 +6584,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
     */
    @android.view.RemotableViewMethod
    public void setCursorVisible(boolean visible) {
        if (mCursorVisible != visible) {
            mCursorVisible = visible;
            invalidate();

@@ -6597,6 +6593,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            // InsertionPointCursorController depends on mCursorVisible
            prepareCursorControllers();
        }
    }

    private boolean isCursorVisible() {
        return mCursorVisible && isTextEditable();
@@ -6934,13 +6931,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
            if (oldStart >= 0 || newStart >= 0) {
                invalidateCursor(Selection.getSelectionStart(buf), oldStart, newStart);
                registerForPreDraw();

                if (isFocused()) {
                    mShowCursor = SystemClock.uptimeMillis();
                makeBlink();
            }
        }
        }

        if (what == Selection.SELECTION_START) {
            mHighlightPathBogus = true;
@@ -7089,22 +7082,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        }
    }

    private void makeBlink() {
        if (!isCursorVisible()) {
            if (mBlink != null) {
                mBlink.removeCallbacks(mBlink);
            }

            return;
        }

        if (mBlink == null)
            mBlink = new Blink(this);

        mBlink.removeCallbacks(mBlink);
        mBlink.postAtTime(mBlink, mShowCursor + BLINK);
    }

    /**
     * @hide
     */
@@ -7271,12 +7248,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        if (hasWindowFocus) {
            if (mBlink != null) {
                mBlink.uncancel();

                if (isFocused()) {
                    mShowCursor = SystemClock.uptimeMillis();
                makeBlink();
            }
            }
        } else {
            if (mBlink != null) {
                mBlink.cancel();
@@ -7544,11 +7517,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener

            TextView tv = mView.get();

            if (tv != null && tv.isFocused()) {
                int st = tv.getSelectionStart();
                int en = tv.getSelectionEnd();

                if (st == en && st >= 0 && en >= 0) {
            if (tv != null && tv.shouldBlink()) {
                if (tv.mLayout != null) {
                    tv.invalidateCursorPath();
                }
@@ -7556,7 +7525,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
                postAtTime(this, SystemClock.uptimeMillis() + BLINK);
            }
        }
        }

        void cancel() {
            if (!mCancelled) {
@@ -7570,6 +7538,34 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        }
    }

    /**
     * @return True when the TextView isFocused and has a valid zero-length selection (cursor).
     */
    private boolean shouldBlink() {
        if (!isFocused()) return false;

        final int start = getSelectionStart();
        if (start < 0) return false;

        final int end = getSelectionEnd();
        if (end < 0) return false;

        return start == end;
    }

    private void makeBlink() {
        if (isCursorVisible()) {
            if (shouldBlink()) {
                mShowCursor = SystemClock.uptimeMillis();
                if (mBlink == null) mBlink = new Blink(this);
                mBlink.removeCallbacks(mBlink);
                mBlink.postAtTime(mBlink, mShowCursor + BLINK);
            }
        } else {
            if (mBlink != null) mBlink.removeCallbacks(mBlink);
        }
    }

    @Override
    protected float getLeftFadingEdgeStrength() {
        if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return 0.0f;