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

Commit 429d9a23 authored by Graciela Wissen Putri's avatar Graciela Wissen Putri
Browse files

[3/n] Reuse default center position for new window if free

If the last focused window is in the center and overlap with new window
exceeds minimum touch target, reuse the center position for the new
window and don't cascade.

Flag: com.android.window.flags.enable_cascading_windows
Test: atest DesktopTasksControllerTest
Bug: 280496681
Change-Id: Id593ae23ec5b0806f71461e3393c1dea16ba6345
parent 31668bc3
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.wm.shell.desktopmode

import android.app.TaskInfo
import android.content.res.Resources
import android.graphics.Point
import android.graphics.Rect
import android.view.Gravity
@@ -26,6 +27,7 @@ import com.android.wm.shell.desktopmode.DesktopTaskPosition.BottomRight
import com.android.wm.shell.desktopmode.DesktopTaskPosition.Center
import com.android.wm.shell.desktopmode.DesktopTaskPosition.TopLeft
import com.android.wm.shell.desktopmode.DesktopTaskPosition.TopRight
import com.android.wm.shell.R

/**
 * The position of a task window in desktop mode.
@@ -122,9 +124,28 @@ fun Rect.getDesktopTaskPosition(bounds: Rect): DesktopTaskPosition {
    }
}

internal fun cascadeWindow(frame: Rect, prev: Rect, dest: Rect) {
internal fun cascadeWindow(res: Resources, frame: Rect, prev: Rect, dest: Rect) {
    val candidateBounds = Rect(dest)
    val lastPos = frame.getDesktopTaskPosition(prev)
    val candidatePos = lastPos.next()
    val destCoord = candidatePos.getTopLeftCoordinates(frame, dest)
    var destCoord = Center.getTopLeftCoordinates(frame, candidateBounds)
    candidateBounds.offsetTo(destCoord.x, destCoord.y)
    // If the default center position is not free or if last focused window is not at the
    // center, get the next cascading window position.
    if (!prevBoundsMovedAboveThreshold(res, prev, candidateBounds) || Center != lastPos) {
        val nextCascadingPos = lastPos.next()
        destCoord = nextCascadingPos.getTopLeftCoordinates(frame, dest)
    }
    dest.offsetTo(destCoord.x, destCoord.y)
}

internal fun prevBoundsMovedAboveThreshold(res: Resources, prev: Rect, newBounds: Rect): Boolean {
    // This is the required minimum dp for a task to be touchable.
    val moveThresholdPx = res.getDimensionPixelSize(
        R.dimen.freeform_required_visible_empty_space_in_header)
    val leftFar = newBounds.left - prev.left > moveThresholdPx
    val topFar = newBounds.top - prev.top > moveThresholdPx
    val rightFar = prev.right - newBounds.right > moveThresholdPx
    val bottomFar = prev.bottom - newBounds.bottom > moveThresholdPx

    return leftFar || topFar || rightFar || bottomFar
}
+1 −1
Original line number Diff line number Diff line
@@ -1099,7 +1099,7 @@ class DesktopTasksController(
                .getActiveNonMinimizedOrderedTasks(taskInfo.displayId)
            activeTasks.firstOrNull()?.let { activeTask ->
                shellTaskOrganizer.getRunningTaskInfo(activeTask)?.let {
                    cascadeWindow(stableBounds,
                    cascadeWindow(context.resources, stableBounds,
                        it.configuration.windowConfiguration.bounds, initialBounds)
                }
            }
+25 −2
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ import com.android.internal.jank.InteractionJankMonitor
import com.android.window.flags.Flags
import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
import com.android.wm.shell.MockToken
import com.android.wm.shell.R
import com.android.wm.shell.RootTaskDisplayAreaOrganizer
import com.android.wm.shell.ShellTaskOrganizer
import com.android.wm.shell.ShellTestCase
@@ -724,6 +725,27 @@ class DesktopTasksControllerTest : ShellTestCase() {
      .isEqualTo(DesktopTaskPosition.Center)
  }

  @Test
  @EnableFlags(Flags.FLAG_ENABLE_CASCADING_WINDOWS)
  fun addMoveToDesktopChanges_defaultToCenterIfFree() {
    setUpLandscapeDisplay()
    val stableBounds = Rect()
    displayLayout.getStableBoundsForDesktopMode(stableBounds)

    val minTouchTarget = context.resources.getDimensionPixelSize(
      R.dimen.freeform_required_visible_empty_space_in_header)
    addFreeformTaskAtPosition(DesktopTaskPosition.Center, stableBounds,
      Rect(0, 0, 1600, 1200), Point(0, minTouchTarget + 1))

    val task = setUpFullscreenTask()
    val wct = WindowContainerTransaction()
    controller.addMoveToDesktopChanges(wct, task)

    val finalBounds = findBoundsChange(wct, task)
    assertThat(stableBounds.getDesktopTaskPosition(finalBounds!!))
      .isEqualTo(DesktopTaskPosition.Center)
  }

  @Test
  fun moveToDesktop_tdaFullscreen_windowingModeSetToFreeform() {
    val task = setUpFullscreenTask()
@@ -2544,11 +2566,12 @@ class DesktopTasksControllerTest : ShellTestCase() {
  private fun addFreeformTaskAtPosition(
    pos: DesktopTaskPosition,
    stableBounds: Rect,
    bounds: Rect = DEFAULT_LANDSCAPE_BOUNDS
    bounds: Rect = DEFAULT_LANDSCAPE_BOUNDS,
    offsetPos: Point = Point(0, 0)
  ): RunningTaskInfo {
    val offset = pos.getTopLeftCoordinates(stableBounds, bounds)
    val prevTaskBounds = Rect(bounds)
    prevTaskBounds.offsetTo(offset.x, offset.y)
    prevTaskBounds.offsetTo(offset.x + offsetPos.x, offset.y + offsetPos.y)
    return setUpFreeformTask(bounds = prevTaskBounds)
  }