Loading core/java/android/widget/Editor.java +47 −12 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Path; import android.graphics.Point; import android.graphics.PointF; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.RectF; Loading Loading @@ -4837,14 +4838,48 @@ public class Editor { return true; return true; } } private boolean handleOverlapsMagnifier() { private boolean handleOverlapsMagnifier(@NonNull final HandleView handle, final int handleY = mContainer.getDecorViewLayoutParams().y; @NonNull final Rect magnifierRect) { final int magnifierBottomWhenAtWindowTop = final PopupWindow window = handle.mContainer; mTextView.getRootWindowInsets().getSystemWindowInsetTop() if (!window.hasDecorView()) { + mMagnifierAnimator.mMagnifier.getHeight(); return false; return handleY <= magnifierBottomWhenAtWindowTop; } final Rect handleRect = new Rect( window.getDecorViewLayoutParams().x, window.getDecorViewLayoutParams().y, window.getDecorViewLayoutParams().x + window.getContentView().getWidth(), window.getDecorViewLayoutParams().y + window.getContentView().getHeight()); return Rect.intersects(handleRect, magnifierRect); } } private @Nullable HandleView getOtherSelectionHandle() { final SelectionModifierCursorController controller = getSelectionController(); if (controller == null || !controller.isActive()) { return null; } return controller.mStartHandle != this ? controller.mStartHandle : controller.mEndHandle; } private final Magnifier.Callback mHandlesVisibilityCallback = new Magnifier.Callback() { @Override public void onOperationComplete() { final Point magnifierTopLeft = mMagnifierAnimator.mMagnifier.getWindowCoords(); if (magnifierTopLeft == null) { return; } final Rect magnifierRect = new Rect(magnifierTopLeft.x, magnifierTopLeft.y, magnifierTopLeft.x + mMagnifierAnimator.mMagnifier.getWidth(), magnifierTopLeft.y + mMagnifierAnimator.mMagnifier.getHeight()); setVisible(!handleOverlapsMagnifier(HandleView.this, magnifierRect)); final HandleView otherHandle = getOtherSelectionHandle(); if (otherHandle != null) { otherHandle.setVisible(!handleOverlapsMagnifier(otherHandle, magnifierRect)); } } }; protected final void updateMagnifier(@NonNull final MotionEvent event) { protected final void updateMagnifier(@NonNull final MotionEvent event) { if (mMagnifierAnimator == null) { if (mMagnifierAnimator == null) { return; return; Loading @@ -4858,12 +4893,8 @@ public class Editor { mRenderCursorRegardlessTiming = true; mRenderCursorRegardlessTiming = true; mTextView.invalidateCursorPath(); mTextView.invalidateCursorPath(); suspendBlink(); suspendBlink(); // Hide handle if it overlaps the magnifier. mMagnifierAnimator.mMagnifier if (handleOverlapsMagnifier()) { .setOnOperationCompleteCallback(mHandlesVisibilityCallback); setVisible(false); } else { setVisible(true); } mMagnifierAnimator.show(showPosInView.x, showPosInView.y); mMagnifierAnimator.show(showPosInView.x, showPosInView.y); } else { } else { Loading @@ -4877,6 +4908,10 @@ public class Editor { mRenderCursorRegardlessTiming = false; mRenderCursorRegardlessTiming = false; resumeBlink(); resumeBlink(); setVisible(true); setVisible(true); final HandleView otherHandle = getOtherSelectionHandle(); if (otherHandle != null) { otherHandle.setVisible(true); } } } } } Loading core/java/android/widget/Magnifier.java +17 −1 Original line number Original line Diff line number Diff line Loading @@ -233,6 +233,17 @@ public final class Magnifier { return mZoom; return mZoom; } } /** * @hide */ @Nullable public Point getWindowCoords() { if (mWindow == null) { return null; } return new Point(mWindow.mLastDrawContentPositionX, mWindow.mLastDrawContentPositionY); } @Nullable @Nullable private Surface getValidViewSurface() { private Surface getValidViewSurface() { // TODO: deduplicate this against the first part of #performPixelCopy // TODO: deduplicate this against the first part of #performPixelCopy Loading Loading @@ -374,8 +385,11 @@ public final class Magnifier { private final Runnable mMagnifierUpdater; private final Runnable mMagnifierUpdater; // The handler where the magnifier updater jobs will be post'd. // The handler where the magnifier updater jobs will be post'd. private final Handler mHandler; private final Handler mHandler; // The callback to be run after the next draw. Only used for testing. // The callback to be run after the next draw. private Callback mCallback; private Callback mCallback; // The position of the magnifier content when the last draw was requested. private int mLastDrawContentPositionX; private int mLastDrawContentPositionY; // Members below describe the state of the magnifier. Reads/writes to them // Members below describe the state of the magnifier. Reads/writes to them // have to be synchronized between the UI thread and the thread that handles // have to be synchronized between the UI thread and the thread that handles Loading Loading @@ -598,6 +612,8 @@ public final class Magnifier { callback = null; callback = null; } } mLastDrawContentPositionX = mWindowPositionX + mOffsetX; mLastDrawContentPositionY = mWindowPositionY + mOffsetY; mFrameDrawScheduled = false; mFrameDrawScheduled = false; } } Loading Loading
core/java/android/widget/Editor.java +47 −12 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Path; import android.graphics.Point; import android.graphics.PointF; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.RectF; Loading Loading @@ -4837,14 +4838,48 @@ public class Editor { return true; return true; } } private boolean handleOverlapsMagnifier() { private boolean handleOverlapsMagnifier(@NonNull final HandleView handle, final int handleY = mContainer.getDecorViewLayoutParams().y; @NonNull final Rect magnifierRect) { final int magnifierBottomWhenAtWindowTop = final PopupWindow window = handle.mContainer; mTextView.getRootWindowInsets().getSystemWindowInsetTop() if (!window.hasDecorView()) { + mMagnifierAnimator.mMagnifier.getHeight(); return false; return handleY <= magnifierBottomWhenAtWindowTop; } final Rect handleRect = new Rect( window.getDecorViewLayoutParams().x, window.getDecorViewLayoutParams().y, window.getDecorViewLayoutParams().x + window.getContentView().getWidth(), window.getDecorViewLayoutParams().y + window.getContentView().getHeight()); return Rect.intersects(handleRect, magnifierRect); } } private @Nullable HandleView getOtherSelectionHandle() { final SelectionModifierCursorController controller = getSelectionController(); if (controller == null || !controller.isActive()) { return null; } return controller.mStartHandle != this ? controller.mStartHandle : controller.mEndHandle; } private final Magnifier.Callback mHandlesVisibilityCallback = new Magnifier.Callback() { @Override public void onOperationComplete() { final Point magnifierTopLeft = mMagnifierAnimator.mMagnifier.getWindowCoords(); if (magnifierTopLeft == null) { return; } final Rect magnifierRect = new Rect(magnifierTopLeft.x, magnifierTopLeft.y, magnifierTopLeft.x + mMagnifierAnimator.mMagnifier.getWidth(), magnifierTopLeft.y + mMagnifierAnimator.mMagnifier.getHeight()); setVisible(!handleOverlapsMagnifier(HandleView.this, magnifierRect)); final HandleView otherHandle = getOtherSelectionHandle(); if (otherHandle != null) { otherHandle.setVisible(!handleOverlapsMagnifier(otherHandle, magnifierRect)); } } }; protected final void updateMagnifier(@NonNull final MotionEvent event) { protected final void updateMagnifier(@NonNull final MotionEvent event) { if (mMagnifierAnimator == null) { if (mMagnifierAnimator == null) { return; return; Loading @@ -4858,12 +4893,8 @@ public class Editor { mRenderCursorRegardlessTiming = true; mRenderCursorRegardlessTiming = true; mTextView.invalidateCursorPath(); mTextView.invalidateCursorPath(); suspendBlink(); suspendBlink(); // Hide handle if it overlaps the magnifier. mMagnifierAnimator.mMagnifier if (handleOverlapsMagnifier()) { .setOnOperationCompleteCallback(mHandlesVisibilityCallback); setVisible(false); } else { setVisible(true); } mMagnifierAnimator.show(showPosInView.x, showPosInView.y); mMagnifierAnimator.show(showPosInView.x, showPosInView.y); } else { } else { Loading @@ -4877,6 +4908,10 @@ public class Editor { mRenderCursorRegardlessTiming = false; mRenderCursorRegardlessTiming = false; resumeBlink(); resumeBlink(); setVisible(true); setVisible(true); final HandleView otherHandle = getOtherSelectionHandle(); if (otherHandle != null) { otherHandle.setVisible(true); } } } } } Loading
core/java/android/widget/Magnifier.java +17 −1 Original line number Original line Diff line number Diff line Loading @@ -233,6 +233,17 @@ public final class Magnifier { return mZoom; return mZoom; } } /** * @hide */ @Nullable public Point getWindowCoords() { if (mWindow == null) { return null; } return new Point(mWindow.mLastDrawContentPositionX, mWindow.mLastDrawContentPositionY); } @Nullable @Nullable private Surface getValidViewSurface() { private Surface getValidViewSurface() { // TODO: deduplicate this against the first part of #performPixelCopy // TODO: deduplicate this against the first part of #performPixelCopy Loading Loading @@ -374,8 +385,11 @@ public final class Magnifier { private final Runnable mMagnifierUpdater; private final Runnable mMagnifierUpdater; // The handler where the magnifier updater jobs will be post'd. // The handler where the magnifier updater jobs will be post'd. private final Handler mHandler; private final Handler mHandler; // The callback to be run after the next draw. Only used for testing. // The callback to be run after the next draw. private Callback mCallback; private Callback mCallback; // The position of the magnifier content when the last draw was requested. private int mLastDrawContentPositionX; private int mLastDrawContentPositionY; // Members below describe the state of the magnifier. Reads/writes to them // Members below describe the state of the magnifier. Reads/writes to them // have to be synchronized between the UI thread and the thread that handles // have to be synchronized between the UI thread and the thread that handles Loading Loading @@ -598,6 +612,8 @@ public final class Magnifier { callback = null; callback = null; } } mLastDrawContentPositionX = mWindowPositionX + mOffsetX; mLastDrawContentPositionY = mWindowPositionY + mOffsetY; mFrameDrawScheduled = false; mFrameDrawScheduled = false; } } Loading