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

Commit dc5831fb authored by Demon000's avatar Demon000 Committed by LuK1337
Browse files

ScreenshotSelector: handle rotation issues

Disable rotation while the screenshot selector is visible,
because it cannot handle rotation internally,
and rotating while a certain selection is made might cause
the selection to go off-screen.

Also, adjust the crop coordinates so that they function properly.
The native screenshot taking functions expect the coordinates
to be in a physical left-to-right, top-to-bottom order, which
is not the case for 90 degree rotation, where the top is
actually the right physical edge, or for 270 degree rotation,
where the right is actually the top physical edge, or for
180 degrees, where both axes are flipped.

https://gitlab.com/LineageOS/issues/android/-/issues/1749

Change-Id: I18da90592cf7baa46547554df954bdb071961311
parent a92e8f7b
Loading
Loading
Loading
Loading
+47 −7
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
@@ -669,6 +670,45 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
        }
    }

    Rect getRotationAdjustedRect(Rect rect) {
        Display defaultDisplay = mWindowManager.getDefaultDisplay();
        Rect adjustedRect = new Rect(rect);

        mDisplay.getRealMetrics(mDisplayMetrics);
        int rotation = defaultDisplay.getRotation();
        switch (rotation) {
            case Surface.ROTATION_0:
                // properly rotated
                break;
            case Surface.ROTATION_90:
                adjustedRect.top = mDisplayMetrics.heightPixels - rect.bottom;
                adjustedRect.bottom = mDisplayMetrics.heightPixels - rect.top;
                break;
            case Surface.ROTATION_180:
                adjustedRect.left = mDisplayMetrics.widthPixels - rect.right;
                adjustedRect.top = mDisplayMetrics.heightPixels - rect.bottom;
                adjustedRect.right = mDisplayMetrics.widthPixels - rect.left;
                adjustedRect.bottom = mDisplayMetrics.heightPixels - rect.top;
                break;
            case Surface.ROTATION_270:
                adjustedRect.left = mDisplayMetrics.widthPixels - rect.right;
                adjustedRect.right = mDisplayMetrics.widthPixels - rect.left;
                break;
            default:
                throw new IllegalArgumentException("Unknown rotation: " + rotation);
        }

        return adjustedRect;
    }

    void setLockedScreenOrientation(boolean locked) {
        if (locked) {
            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED;
        } else {
            mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
        }
    }

    /**
     * Displays a screenshot selector
     */
@@ -683,6 +723,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
        mOnCompleteRunnable = onComplete;

        setBlockedGesturalNavigation(true);
        setLockedScreenOrientation(true);
        mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
        mScreenshotSelectorView.setSelectionListener((rect, firstSelection) -> {
            if (firstSelection) {
@@ -696,7 +737,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
            });
        });
        mCaptureButton.setOnClickListener(v -> {
            final Rect rect = mScreenshotSelectorView.getSelectionRect();
            Rect rect = mScreenshotSelectorView.getSelectionRect();
            final Rect adjustedRect = getRotationAdjustedRect(rect);
            LayoutTransition layoutTransition = mScreenshotButtonsLayout.getLayoutTransition();
            layoutTransition.addTransitionListener(new TransitionListener() {
                @Override
@@ -707,7 +749,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
                @Override
                public void endTransition(LayoutTransition transition, ViewGroup container,
                        View view, int transitionType) {
                    takeScreenshot(finisher, rect);
                    takeScreenshot(finisher, adjustedRect);
                    transition.removeTransitionListener(this);
                }
            });
@@ -720,6 +762,7 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
    }

    void hideScreenshotSelector() {
        setLockedScreenOrientation(false);
        mWindowManager.removeView(mScreenshotLayout);
        mScreenshotSelectorView.stopSelection();
        mScreenshotSelectorView.setVisibility(View.GONE);
@@ -732,12 +775,9 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset
     */
    void stopScreenshot() {
        // If the selector layer still presents on screen, we remove it and resets its state.
        if (mScreenshotSelectorView.getSelectionRect() != null) {
            mWindowManager.removeView(mScreenshotLayout);
            mScreenshotSelectorView.stopSelection();
        if (mScreenshotLayout.getParent() != null) {
            hideScreenshotSelector();
        }

        setBlockedGesturalNavigation(false);
    }

    /**