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

Commit 7ffa8c71 authored by mattsziklay's avatar mattsziklay Committed by Matt Sziklay
Browse files

Require partially offscreen apps to have 48dp empty space visible.

When a freeform task is dragged offscreen, prevent task position from
going further on the x axis if doing so would cause less than 48dp of
empty header space to be visible, or on the y axis if doing so would
cause less than 48dp + gesture nav height to be visible.

Bug: 312747430
Bug: 315333951
Test: Manual
Change-Id: I2bfb195e6e707fc43f99555bd51d59318f69685e
parent bb4db1a7
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -30,8 +30,8 @@
        android:orientation="horizontal"
        android:clickable="true"
        android:focusable="true"
        android:paddingStart="16dp">

        android:paddingStart="6dp"
        android:paddingEnd="8dp">
        <ImageView
            android:id="@+id/application_icon"
            android:layout_width="@dimen/desktop_mode_caption_icon_radius"
@@ -43,7 +43,7 @@
            android:id="@+id/application_name"
            android:layout_width="0dp"
            android:layout_height="20dp"
            android:minWidth="80dp"
            android:maxWidth="86dp"
            android:textAppearance="@android:style/TextAppearance.Material.Title"
            android:textSize="14sp"
            android:textFontWeight="500"
+19 −0
Original line number Diff line number Diff line
@@ -413,6 +413,25 @@
    <!-- Height of desktop mode caption for fullscreen tasks. -->
    <dimen name="desktop_mode_fullscreen_decor_caption_height">36dp</dimen>

    <!-- Required empty space to be visible for partially offscreen tasks. -->
    <dimen name="freeform_required_visible_empty_space_in_header">48dp</dimen>

    <!-- Required empty space to be visible for partially offscreen tasks on a smaller screen. -->
    <dimen name="small_screen_required_visible_empty_space_in_header">12dp</dimen>

    <!-- 32dp width back button + 10dp margin -->
    <dimen name="caption_left_buttons_width">32dp</dimen>

    <!-- (32 dp buttons + 10dp margins) * 3 buttons-->
    <dimen name="caption_right_buttons_width">126dp</dimen>

    <!-- 2 buttons * 48dp button size. -->
    <dimen name="desktop_mode_right_edge_buttons_width">96dp</dimen>

    <!-- 22dp padding + 24dp app icon + 16dp expand button.
         Text varies in size, we will calculate that width separately. -->
    <dimen name="desktop_mode_app_details_width_minus_text">62dp</dimen>

    <!-- The width of the maximize menu in desktop mode. -->
    <dimen name="desktop_mode_maximize_menu_width">287dp</dimen>

+65 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.app.WindowConfiguration.WindowingMode;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.VectorDrawable;
import android.os.Handler;
@@ -34,6 +35,7 @@ import android.window.WindowContainerTransaction;
import com.android.wm.shell.R;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;

/**
@@ -84,6 +86,69 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL
        mDragPositioningCallback = dragPositioningCallback;
    }

    @Override
    Rect calculateValidDragArea() {
        final int leftButtonsWidth = loadDimensionPixelSize(mContext.getResources(),
                R.dimen.caption_left_buttons_width);

        // On a smaller screen, don't require as much empty space on screen, as offscreen
        // drags will be restricted too much.
        final int requiredEmptySpaceId = mDisplayController.getDisplayContext(mTaskInfo.taskId)
                .getResources().getConfiguration().smallestScreenWidthDp >= 600
                ? R.dimen.freeform_required_visible_empty_space_in_header :
                R.dimen.small_screen_required_visible_empty_space_in_header;
        final int requiredEmptySpace = loadDimensionPixelSize(mContext.getResources(),
                requiredEmptySpaceId);

        final int rightButtonsWidth = loadDimensionPixelSize(mContext.getResources(),
                R.dimen.caption_right_buttons_width);
        final int taskWidth = mTaskInfo.configuration.windowConfiguration.getBounds().width();
        final DisplayLayout layout = mDisplayController.getDisplayLayout(mTaskInfo.displayId);
        final int displayWidth = layout.width();
        final Rect stableBounds = new Rect();
        layout.getStableBounds(stableBounds);
        return new Rect(
                determineMinX(leftButtonsWidth, rightButtonsWidth, requiredEmptySpace,
                        taskWidth),
                stableBounds.top,
                determineMaxX(leftButtonsWidth, rightButtonsWidth, requiredEmptySpace, taskWidth,
                        displayWidth),
                determineMaxY(requiredEmptySpace, stableBounds));
    }


    /**
     * Determine the lowest x coordinate of a freeform task. Used for restricting drag inputs.
     */
    private int determineMinX(int leftButtonsWidth, int rightButtonsWidth, int requiredEmptySpace,
            int taskWidth) {
        // Do not let apps with < 48dp empty header space go off the left edge at all.
        if (leftButtonsWidth + rightButtonsWidth + requiredEmptySpace > taskWidth) {
            return 0;
        }
        return -taskWidth + requiredEmptySpace + rightButtonsWidth;
    }

    /**
     * Determine the highest x coordinate of a freeform task. Used for restricting drag inputs.
     */
    private int determineMaxX(int leftButtonsWidth, int rightButtonsWidth, int requiredEmptySpace,
            int taskWidth, int displayWidth) {
        // Do not let apps with < 48dp empty header space go off the right edge at all.
        if (leftButtonsWidth + rightButtonsWidth + requiredEmptySpace > taskWidth) {
            return displayWidth - taskWidth;
        }
        return displayWidth - requiredEmptySpace - leftButtonsWidth;
    }

    /**
     * Determine the highest y coordinate of a freeform task. Used for restricting drag inputs.
     */
    private int determineMaxY(int requiredEmptySpace, Rect stableBounds) {
        return stableBounds.bottom - requiredEmptySpace;
    }


    void setDragDetector(DragDetector dragDetector) {
        mDragDetector = dragDetector;
        mDragDetector.setTouchSlop(ViewConfiguration.get(mContext).getScaledTouchSlop());
+60 −0
Original line number Diff line number Diff line
@@ -442,6 +442,66 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin
        mResizeVeil = null;
    }

    /**
     * Determine valid drag area for this task based on elements in the app chip.
     */
    @Override
    Rect calculateValidDragArea() {
        final int appTextWidth = ((DesktopModeAppControlsWindowDecorationViewHolder)
                mWindowDecorViewHolder).getAppNameTextWidth();
        final int leftButtonsWidth = loadDimensionPixelSize(mContext.getResources(),
                R.dimen.desktop_mode_app_details_width_minus_text) + appTextWidth;
        final int requiredEmptySpace = loadDimensionPixelSize(mContext.getResources(),
                R.dimen.freeform_required_visible_empty_space_in_header);
        final int rightButtonsWidth = loadDimensionPixelSize(mContext.getResources(),
                R.dimen.desktop_mode_right_edge_buttons_width);
        final int taskWidth = mTaskInfo.configuration.windowConfiguration.getBounds().width();
        final DisplayLayout layout = mDisplayController.getDisplayLayout(mTaskInfo.displayId);
        final int displayWidth = layout.width();
        final Rect stableBounds = new Rect();
        layout.getStableBounds(stableBounds);
        return new Rect(
                determineMinX(leftButtonsWidth, rightButtonsWidth, requiredEmptySpace,
                        taskWidth),
                stableBounds.top,
                determineMaxX(leftButtonsWidth, rightButtonsWidth, requiredEmptySpace,
                        taskWidth, displayWidth),
                determineMaxY(requiredEmptySpace, stableBounds));
    }


    /**
     * Determine the lowest x coordinate of a freeform task. Used for restricting drag inputs.
     */
    private int determineMinX(int leftButtonsWidth, int rightButtonsWidth, int requiredEmptySpace,
            int taskWidth) {
        // Do not let apps with < 48dp empty header space go off the left edge at all.
        if (leftButtonsWidth + rightButtonsWidth + requiredEmptySpace > taskWidth) {
            return 0;
        }
        return -taskWidth + requiredEmptySpace + rightButtonsWidth;
    }

    /**
     * Determine the highest x coordinate of a freeform task. Used for restricting drag inputs.
     */
    private int determineMaxX(int leftButtonsWidth, int rightButtonsWidth, int requiredEmptySpace,
            int taskWidth, int displayWidth) {
        // Do not let apps with < 48dp empty header space go off the right edge at all.
        if (leftButtonsWidth + rightButtonsWidth + requiredEmptySpace > taskWidth) {
            return displayWidth - taskWidth;
        }
        return displayWidth - requiredEmptySpace - leftButtonsWidth;
    }

    /**
     * Determine the highest y coordinate of a freeform task. Used for restricting drag inputs.
     */
    private int determineMaxY(int requiredEmptySpace, Rect stableBounds) {
        return stableBounds.bottom - requiredEmptySpace;
    }


    /**
     * Create and display maximize menu window
     */
+19 −8
Original line number Diff line number Diff line
@@ -162,18 +162,29 @@ public class DragPositioningCallbackUtility {

    /**
     * Updates repositionTaskBounds to the final bounds of the task after the drag is finished. If
     * the bounds are outside of the stable bounds, they are shifted to place task at the top of the
     * stable bounds.
     * the bounds are outside of the valid drag area, the task is shifted back onto the edge of the
     * valid drag area.
     */
    static void onDragEnd(Rect repositionTaskBounds, Rect taskBoundsAtDragStart, Rect stableBounds,
            PointF repositionStartPoint, float x, float y)  {
    static void onDragEnd(Rect repositionTaskBounds, Rect taskBoundsAtDragStart,
            PointF repositionStartPoint, float x, float y, Rect validDragArea) {
        updateTaskBounds(repositionTaskBounds, taskBoundsAtDragStart, repositionStartPoint,
                x, y);

        // If task is outside of stable bounds (in the status bar area), shift the task down.
        if (stableBounds.top > repositionTaskBounds.top) {
            final int yShift =  stableBounds.top - repositionTaskBounds.top;
            repositionTaskBounds.offset(0, yShift);
        snapTaskBoundsIfNecessary(repositionTaskBounds, validDragArea);
    }

    private static void snapTaskBoundsIfNecessary(Rect repositionTaskBounds, Rect validDragArea) {
        // If we were never supplied a valid drag area, do not restrict movement.
        // Otherwise, we restrict deltas to keep task position inside the Rect.
        if (validDragArea.width() == 0) return;
        if (repositionTaskBounds.left < validDragArea.left) {
            repositionTaskBounds.offset(validDragArea.left - repositionTaskBounds.left, 0);
        } else if (repositionTaskBounds.left > validDragArea.right) {
            repositionTaskBounds.offset(validDragArea.right - repositionTaskBounds.left, 0);
        }
        if (repositionTaskBounds.top < validDragArea.top) {
            repositionTaskBounds.offset(0, validDragArea.top - repositionTaskBounds.top);
        } else if (repositionTaskBounds.top > validDragArea.bottom) {
            repositionTaskBounds.offset(0, validDragArea.bottom - repositionTaskBounds.top);
        }
    }

Loading