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

Commit e067ddfc authored by Evan Rosky's avatar Evan Rosky
Browse files

Shift Primary stack as well as secondary during ime adjustment

Previously, was only 'adjusting' the secondary split for
ime. So the secondary had functional insets and drag/drop.
However, the primary wasn't being adjusted (accorcding to
WM). This caused its insets to be calculated against its
originla position (which allowed ime insets to potentially
overlap it) and it meant that WM didn't use its visual
position when calculating drag/drop coordinates.

So, this does the same with the primary stack as what was
done with secondary.

However, doing this required some other fixes in WM. Basically,
if appbounds is explicitly overridden, just use them instead of
intersecting with parent. Also, WSA doesn't apply crop for
splits (maybe it shouldn't apply crop to anything anymore).

Additionally, insets calculation was applying top insets to the
bottom if the inset frame's top wasn't exactly equal to the
window's top -- because of a catch-all else condition. So this
adds checks for matching the bottoms as well.

Bug: 154056542
Bug: 151862790
Test: Open two apps in split screen and open IME in secondary. Drag
      from secondary to primary.
Change-Id: I2391783e726e4a1c8ed3150628af2f398218fe90
parent 046df72d
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -136,20 +136,25 @@ public class InsetsSource implements Parcelable {
        if (mTmpFrame.width() == relativeFrame.width()) {
            if (mTmpFrame.top == relativeFrame.top) {
                return Insets.of(0, mTmpFrame.height(), 0, 0);
            } else {
            } else if (mTmpFrame.bottom == relativeFrame.bottom) {
                return Insets.of(0, 0, 0, mTmpFrame.height());
            }
            // TODO: remove when insets are shell-customizable.
            // This is a hack that says "if this is a top-inset (eg statusbar), always apply it
            // to the top". It is used when adjusting primary split for IME.
            if (mTmpFrame.top == 0) {
                return Insets.of(0, mTmpFrame.height(), 0, 0);
            }
        }
        // Intersecting at left/right
        else if (mTmpFrame.height() == relativeFrame.height()) {
            if (mTmpFrame.left == relativeFrame.left) {
                return Insets.of(mTmpFrame.width(), 0, 0, 0);
            } else {
            } else if (mTmpFrame.right == relativeFrame.right) {
                return Insets.of(0, 0, mTmpFrame.width(), 0);
            }
        } else {
            return Insets.NONE;
        }
        return Insets.NONE;
    }

    /**
+14 −0
Original line number Diff line number Diff line
@@ -263,11 +263,25 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
                wct.setScreenSizeDp(mSplits.mSecondary.token,
                        mSplits.mSecondary.configuration.screenWidthDp,
                        mSplits.mSecondary.configuration.screenHeightDp);

                wct.setBounds(mSplits.mPrimary.token, mSplitLayout.mAdjustedPrimary);
                adjustAppBounds = new Rect(mSplits.mPrimary.configuration
                        .windowConfiguration.getAppBounds());
                adjustAppBounds.offset(0, mSplitLayout.mAdjustedPrimary.top
                        - mSplitLayout.mPrimary.top);
                wct.setAppBounds(mSplits.mPrimary.token, adjustAppBounds);
                wct.setScreenSizeDp(mSplits.mPrimary.token,
                        mSplits.mPrimary.configuration.screenWidthDp,
                        mSplits.mPrimary.configuration.screenHeightDp);
            } else {
                wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mSecondary);
                wct.setAppBounds(mSplits.mSecondary.token, null);
                wct.setScreenSizeDp(mSplits.mSecondary.token,
                        SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
                wct.setBounds(mSplits.mPrimary.token, mSplitLayout.mPrimary);
                wct.setAppBounds(mSplits.mPrimary.token, null);
                wct.setScreenSizeDp(mSplits.mPrimary.token,
                        SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
            }

            WindowOrganizer.applyTransaction(wct);
+21 −17
Original line number Diff line number Diff line
@@ -2299,21 +2299,24 @@ class Task extends WindowContainer<WindowContainer> {
            insideParentBounds = parentBounds.contains(resolvedBounds);
        }

        // Non-null compatibility insets means the activity prefers to keep its original size, so
        // out bounds doesn't need to be restricted by the parent or current display
        final boolean customContainerPolicy = compatInsets != null;

        Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
        if (outAppBounds == null || outAppBounds.isEmpty()) {
            // App-bounds hasn't been overridden, so calculate a value for it.
            inOutConfig.windowConfiguration.setAppBounds(mTmpFullBounds);
            outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
        }
        // Non-null compatibility insets means the activity prefers to keep its original size, so
        // the out bounds doesn't need to be restricted by the parent or current display.
        final boolean customContainerPolicy = compatInsets != null;

            if (!customContainerPolicy && windowingMode != WINDOWING_MODE_FREEFORM) {
                final Rect containingAppBounds;
                if (insideParentBounds) {
                    containingAppBounds = parentConfig.windowConfiguration.getAppBounds();
                } else {
                // Restrict appBounds to display non-decor rather than parent because the override
                // bounds are beyond the parent. Otherwise, it won't match the overridden bounds.
                    // Restrict appBounds to display non-decor rather than parent because the
                    // override bounds are beyond the parent. Otherwise, it won't match the
                    // overridden bounds.
                    final TaskDisplayArea displayArea = getDisplayArea();
                    containingAppBounds = displayArea != null
                            ? displayArea.getWindowConfiguration().getAppBounds() : null;
@@ -2322,6 +2325,7 @@ class Task extends WindowContainer<WindowContainer> {
                    outAppBounds.intersect(containingAppBounds);
                }
            }
        }

        if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED
                || inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
+3 −1
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import static com.android.server.wm.WindowStateAnimatorProto.SURFACE;
import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT;
import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;

import android.app.WindowConfiguration;
import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
@@ -787,7 +788,8 @@ class WindowStateAnimator {
            return false;
        }

        if (w.getWindowConfiguration().tasksAreFloating()) {
        if (w.getWindowConfiguration().tasksAreFloating()
                || WindowConfiguration.isSplitScreenWindowingMode(w.getWindowingMode())) {
            return false;
        }

+21 −0
Original line number Diff line number Diff line
@@ -189,4 +189,25 @@ public class InsetsSourceProviderTest extends WindowTestsBase {
        mProvider.onInsetsModified(target, state.getSource(ITYPE_STATUS_BAR));
        assertTrue(mSource.isVisible());
    }

    @Test
    public void testInsetGeometries() {
        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
        statusBar.getFrameLw().set(0, 0, 500, 100);
        statusBar.mHasSurface = true;
        mProvider.setWindow(statusBar, null, null);
        mProvider.onPostLayout();
        assertEquals(new Rect(0, 0, 500, 100), mProvider.getSource().getFrame());
        // Still apply top insets if window overlaps even if it's top doesn't exactly match
        // the inset-window's top.
        assertEquals(Insets.of(0, 100, 0, 0),
                mProvider.getSource().calculateInsets(new Rect(0, -100, 500, 400),
                        false /* ignoreVisibility */));

        // Don't apply left insets if window is left-of inset-window but still overlaps
        statusBar.getFrameLw().set(100, 0, 0, 0);
        assertEquals(Insets.of(0, 0, 0, 0),
                mProvider.getSource().calculateInsets(new Rect(-100, 0, 400, 500),
                        false /* ignoreVisibility */));
    }
}