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

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

Make Manage Windows scrollable.

Adds the Manage Windows menu root view to a ScrollView that has a max
height of 2 rows. If the menu has more than 2 rows, it will be
scrollable.

Bug: 428203288
Test: Manual; open header and handle manage windows menus with 7+
instances of Drive open.
Flag: com.android.window.flags.enable_desktop_windowing_multi_instance_features

Change-Id: I1153ecd054baf858a16d080b09482a2977e793bc
parent b2ca6742
Loading
Loading
Loading
Loading
+29 −14
Original line number Diff line number Diff line
@@ -31,8 +31,11 @@ import android.view.View
import android.view.View.ALPHA
import android.view.View.SCALE_X
import android.view.View.SCALE_Y
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.view.ViewGroup.MarginLayoutParams
import android.view.WindowManager
import android.widget.LinearLayout
import android.widget.ScrollView
import android.window.TaskSnapshot
import com.android.wm.shell.shared.R

@@ -107,14 +110,21 @@ abstract class ManageWindowsViewContainer(
    ) {
        private val animators = mutableListOf<Animator>()
        private val iconViews = mutableListOf<SurfaceView>()
        val rootView: LinearLayout = LinearLayout(context)
        var menuHeight = 0
        val scrollableMenuView: ScrollView = ScrollView(context).apply {
            isVerticalScrollBarEnabled = false
        }
        private val menuBaseView: LinearLayout = LinearLayout(context)
        var scrollableMenuHeight = 0
        var menuWidth = 0
        var onIconClickListener: ((Int) -> Unit)? = null
        var onOutsideClickListener: (() -> Unit)? = null

        init {
            rootView.orientation = LinearLayout.VERTICAL
            val menuLayoutParams = WindowManager.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)
            menuLayoutParams.flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
            scrollableMenuView.addView(menuBaseView, menuLayoutParams)
            menuBaseView.orientation = LinearLayout.VERTICAL
            val menuBackground = ShapeDrawable()
            val menuRadius = getDimensionPixelSize(MENU_RADIUS_DP)
            menuBackground.shape = RoundRectShape(
@@ -123,13 +133,14 @@ abstract class ManageWindowsViewContainer(
                null
            )
            menuBackground.paint.color = menuBackgroundColor
            rootView.background = menuBackground
            rootView.elevation = getDimensionPixelSize(MENU_ELEVATION_DP)
            rootView.setOnTouchListener { _, event ->
            scrollableMenuView.background = menuBackground
            scrollableMenuView.elevation = getDimensionPixelSize(MENU_ELEVATION_DP)
            scrollableMenuView.setOnTouchListener { _, event ->
                if (event.actionMasked == ACTION_OUTSIDE) {
                    onOutsideClickListener?.invoke()
                }
                return@setOnTouchListener true
                // Do not consume a touch event that may be used for menu scrolling.
                return@setOnTouchListener false
            }
        }

@@ -142,8 +153,7 @@ abstract class ManageWindowsViewContainer(
            snapshotList: List<Pair<Int, Bitmap?>>
        ) {
            menuWidth = 0
            menuHeight = 0
            rootView.removeAllViews()
            menuBaseView.removeAllViews()
            val instanceIconHeight = getDimensionPixelSize(ICON_HEIGHT_DP)
            val instanceIconWidth = getDimensionPixelSize(ICON_WIDTH_DP)
            val iconRadius = getDimensionPixelSize(ICON_RADIUS_DP)
@@ -157,8 +167,12 @@ abstract class ManageWindowsViewContainer(
                if (iconCount % MENU_MAX_ICONS_PER_ROW == 0) {
                    rowLayout = LinearLayout(context)
                    rowLayout.orientation = LinearLayout.HORIZONTAL
                    rootView.addView(rowLayout)
                    menuHeight += (instanceIconHeight + iconMargin).toInt()
                    menuBaseView.addView(rowLayout)
                    val addedHeight = (instanceIconHeight + iconMargin).toInt()
                    // Increase ScrollView height up to the limit.
                    if (iconCount < MENU_MAX_ICONS_PER_ROW * MENU_MAX_ROWS_BEFORE_SCROLL) {
                        scrollableMenuHeight += addedHeight
                    }
                }

                val croppedBitmap = snapshotBitmap?.let { cropBitmap(it) }
@@ -201,7 +215,7 @@ abstract class ManageWindowsViewContainer(
            }
            // Add margin again for the right/bottom of the menu.
            menuWidth += iconMargin.toInt()
            menuHeight += iconMargin.toInt()
            scrollableMenuHeight += iconMargin.toInt()
        }

        private fun cropBitmap(
@@ -235,7 +249,7 @@ abstract class ManageWindowsViewContainer(

        /** Play the animation for opening the menu. */
        fun animateOpen() {
            animateView(rootView, MENU_BOUNDS_SHRUNK_SCALE, MENU_BOUNDS_FULL_SCALE,
            animateView(scrollableMenuView, MENU_BOUNDS_SHRUNK_SCALE, MENU_BOUNDS_FULL_SCALE,
                MENU_START_ALPHA, MENU_FULL_ALPHA
            )
            for (view in iconViews) {
@@ -248,7 +262,7 @@ abstract class ManageWindowsViewContainer(

        /** Play the animation for closing the menu. */
        fun animateClose(callback: () -> Unit) {
            animateView(rootView, MENU_BOUNDS_FULL_SCALE, MENU_BOUNDS_SHRUNK_SCALE,
            animateView(scrollableMenuView, MENU_BOUNDS_FULL_SCALE, MENU_BOUNDS_SHRUNK_SCALE,
                MENU_FULL_ALPHA, MENU_START_ALPHA
            )
            for (view in iconViews) {
@@ -317,6 +331,7 @@ abstract class ManageWindowsViewContainer(
            private const val ICON_MARGIN_DP = 16f
            private const val MENU_ELEVATION_DP = 1f
            private const val MENU_MAX_ICONS_PER_ROW = 3
            private const val MENU_MAX_ROWS_BEFORE_SCROLL = 2
            private const val MENU_BOUNDS_ANIM_DURATION = 200L
            private const val MENU_BOUNDS_SHRUNK_SCALE = 0.8f
            private const val MENU_BOUNDS_FULL_SCALE = 1f
+2 −2
Original line number Diff line number Diff line
@@ -82,10 +82,10 @@ class DesktopHandleManageWindowsMenu(
            x = menuPosition.x,
            y = menuPosition.y,
            width = menuView.menuWidth,
            height = menuView.menuHeight,
            height = menuView.scrollableMenuHeight,
            flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                    WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            view = menuView.rootView,
            view = menuView.scrollableMenuView,
            ignoreCutouts = desktopState.canEnterDesktopModeOrShowAppHandle,
        )
    }
+6 −6
Original line number Diff line number Diff line
@@ -66,8 +66,8 @@ class DesktopHeaderManageWindowsMenu(

    init {
        createMenu(snapshotList, onIconClickListener, onOutsideClickListener)
        menuView.rootView.pivotX = 0f
        menuView.rootView.pivotY = 0f
        menuView.scrollableMenuView.pivotX = 0f
        menuView.scrollableMenuView.pivotY = 0f
        animateOpen()
    }

@@ -95,10 +95,10 @@ class DesktopHeaderManageWindowsMenu(
            x = position.x,
            y = position.y,
            width = menuView.menuWidth,
            height = menuView.menuHeight,
            height = menuView.scrollableMenuHeight,
            flags = flags,
            forciblyShownTypes = systemBars(),
            view = menuView.rootView
            view = menuView.scrollableMenuView
        )
    }

@@ -111,7 +111,7 @@ class DesktopHeaderManageWindowsMenu(
            .build()
        val lp = WindowManager.LayoutParams(
            menuView.menuWidth,
            menuView.menuHeight,
            menuView.scrollableMenuHeight,
            WindowManager.LayoutParams.TYPE_APPLICATION,
            flags,
            PixelFormat.TRANSPARENT
@@ -126,7 +126,7 @@ class DesktopHeaderManageWindowsMenu(
            displayController.getDisplay(callerTaskInfo.displayId), windowManager,
            "MaximizeMenu"
        )
        menuView.let { viewHost.setView(it.rootView, lp) }
        menuView.let { viewHost.setView(it.scrollableMenuView, lp) }
        val t = surfaceControlTransactionSupplier.get()
        t.setLayer(leash, TaskConstants.TASK_CHILD_LAYER_FLOATING_MENU)
            .setPosition(leash, position.x.toFloat(), position.y.toFloat())