summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Fabio Muratori <muratori@google.com> 2025-02-11 00:49:38 -0800
committer Fabio Muratori <muratori@google.com> 2025-02-11 00:49:38 -0800
commit07d2f4be6e00a5494529152ee4a88882cfe71990 (patch)
tree1450f971e36767652bc7b618587c35172be4245a
parent51ff3146b7ad5b3dc22eee8cc9bed959b3a8df80 (diff)
Update menu details for desktop windowing:
- window info pill icon and chevron size/positioning - "windowing action" pill icons positioning - "more actions" pill icon size and margin to text Add Space component in "window actions" pill and logic to account for positioning of 3 and 4 icons. Create custom component for "more actions" and "open in" pills options to properly manage icon size and icon to text spacing. Fix: 369617114 Test: manual – verify that handle menu options and spacing are properly set for YouTube in app and browser. Verify "window action" icons spacing with 3 and 4 options. Flag: com.android.window.flags.enable_desktop_windowing_mode Change-Id: Iac777f33fc5325082d6754ac7816784d56b3bdf9
-rw-r--r--libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml147
-rw-r--r--libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml38
-rw-r--r--libs/WindowManager/Shell/res/values/attrs.xml7
-rw-r--r--libs/WindowManager/Shell/res/values/dimen.xml2
-rw-r--r--libs/WindowManager/Shell/res/values/styles.xml9
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt25
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt120
7 files changed, 239 insertions, 109 deletions
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
index 50c08732543a..477d207a5c7e 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
@@ -41,7 +41,7 @@
android:id="@+id/application_icon"
android:layout_width="@dimen/desktop_mode_caption_icon_radius"
android:layout_height="@dimen/desktop_mode_caption_icon_radius"
- android:layout_marginStart="12dp"
+ android:layout_marginStart="10dp"
android:layout_marginEnd="12dp"
android:contentDescription="@string/app_icon_text"
android:importantForAccessibility="no"/>
@@ -53,10 +53,9 @@
<com.android.wm.shell.windowdecor.HandleMenuImageButton
android:id="@+id/collapse_menu_button"
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:padding="4dp"
- android:layout_marginEnd="14dp"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
+ android:layout_marginEnd="16dp"
android:layout_marginStart="14dp"
android:contentDescription="@string/collapse_menu_text"
android:src="@drawable/ic_baseline_expand_more_24"
@@ -78,40 +77,55 @@
<ImageButton
android:id="@+id/fullscreen_button"
- android:layout_marginEnd="4dp"
+ android:paddingStart="16dp"
+ android:paddingEnd="12dp"
android:contentDescription="@string/fullscreen_text"
android:src="@drawable/desktop_mode_ic_handle_menu_fullscreen"
android:tint="@androidprv:color/materialColorOnSurface"
- android:layout_weight="1"
style="@style/DesktopModeHandleMenuWindowingButton"/>
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
<ImageButton
android:id="@+id/split_screen_button"
- android:layout_marginStart="4dp"
- android:layout_marginEnd="4dp"
+ android:paddingStart="14dp"
+ android:paddingEnd="14dp"
android:contentDescription="@string/split_screen_text"
android:src="@drawable/desktop_mode_ic_handle_menu_splitscreen"
android:tint="@androidprv:color/materialColorOnSurface"
- android:layout_weight="1"
style="@style/DesktopModeHandleMenuWindowingButton"/>
+ <Space
+ android:id="@+id/floating_button_space"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
<ImageButton
android:id="@+id/floating_button"
- android:layout_marginStart="4dp"
- android:layout_marginEnd="4dp"
+ android:paddingStart="14dp"
+ android:paddingEnd="14dp"
android:contentDescription="@string/float_button_text"
android:src="@drawable/desktop_mode_ic_handle_menu_floating"
android:tint="@androidprv:color/materialColorOnSurface"
- android:layout_weight="1"
style="@style/DesktopModeHandleMenuWindowingButton"/>
+ <Space
+ android:id="@+id/desktop_button_space"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
+
<ImageButton
android:id="@+id/desktop_button"
- android:layout_marginStart="4dp"
+ android:paddingStart="12dp"
+ android:paddingEnd="16dp"
android:contentDescription="@string/desktop_text"
android:src="@drawable/desktop_mode_ic_handle_menu_desktop"
android:tint="@androidprv:color/materialColorOnSurface"
- android:layout_weight="1"
style="@style/DesktopModeHandleMenuWindowingButton"/>
</LinearLayout>
@@ -126,77 +140,33 @@
android:elevation="@dimen/desktop_mode_handle_menu_pill_elevation"
android:background="@drawable/desktop_mode_decor_handle_menu_background">
- <LinearLayout
+ <com.android.wm.shell.windowdecor.HandleMenuActionButton
android:id="@+id/screenshot_button"
android:contentDescription="@string/screenshot_text"
- style="@style/DesktopModeHandleMenuActionButtonLayout">
-
- <ImageView
- android:id="@+id/image"
- android:src="@drawable/desktop_mode_ic_handle_menu_screenshot"
- android:importantForAccessibility="no"
- style="@style/DesktopModeHandleMenuActionButtonImage"/>
-
- <com.android.wm.shell.windowdecor.MarqueedTextView
- android:id="@+id/label"
- android:text="@string/screenshot_text"
- style="@style/DesktopModeHandleMenuActionButtonTextView"/>
+ android:text="@string/screenshot_text"
+ android:src="@drawable/desktop_mode_ic_handle_menu_screenshot"
+ style="@style/DesktopModeHandleMenuActionButton"/>
- </LinearLayout>
-
- <LinearLayout
+ <com.android.wm.shell.windowdecor.HandleMenuActionButton
android:id="@+id/new_window_button"
android:contentDescription="@string/new_window_text"
- style="@style/DesktopModeHandleMenuActionButtonLayout">
-
- <ImageView
- android:id="@+id/image"
- android:src="@drawable/desktop_mode_ic_handle_menu_new_window"
- android:importantForAccessibility="no"
- style="@style/DesktopModeHandleMenuActionButtonImage"/>
-
- <com.android.wm.shell.windowdecor.MarqueedTextView
- android:id="@+id/label"
- android:text="@string/new_window_text"
- style="@style/DesktopModeHandleMenuActionButtonTextView"/>
+ android:text="@string/new_window_text"
+ android:src="@drawable/desktop_mode_ic_handle_menu_new_window"
+ style="@style/DesktopModeHandleMenuActionButton"/>
- </LinearLayout>
-
- <LinearLayout
+ <com.android.wm.shell.windowdecor.HandleMenuActionButton
android:id="@+id/manage_windows_button"
android:contentDescription="@string/manage_windows_text"
- style="@style/DesktopModeHandleMenuActionButtonLayout">
-
- <ImageView
- android:id="@+id/image"
- android:src="@drawable/desktop_mode_ic_handle_menu_manage_windows"
- android:importantForAccessibility="no"
- style="@style/DesktopModeHandleMenuActionButtonImage"/>
-
- <com.android.wm.shell.windowdecor.MarqueedTextView
- android:id="@+id/label"
- android:text="@string/manage_windows_text"
- style="@style/DesktopModeHandleMenuActionButtonTextView"/>
-
- </LinearLayout>
+ android:text="@string/manage_windows_text"
+ android:src="@drawable/desktop_mode_ic_handle_menu_manage_windows"
+ style="@style/DesktopModeHandleMenuActionButton"/>
- <LinearLayout
+ <com.android.wm.shell.windowdecor.HandleMenuActionButton
android:id="@+id/change_aspect_ratio_button"
android:contentDescription="@string/change_aspect_ratio_text"
- style="@style/DesktopModeHandleMenuActionButtonLayout">
-
- <ImageView
- android:id="@+id/image"
- android:src="@drawable/desktop_mode_ic_handle_menu_change_aspect_ratio"
- android:importantForAccessibility="no"
- style="@style/DesktopModeHandleMenuActionButtonImage"/>
-
- <com.android.wm.shell.windowdecor.MarqueedTextView
- android:id="@+id/label"
- android:text="@string/change_aspect_ratio_text"
- style="@style/DesktopModeHandleMenuActionButtonTextView"/>
-
- </LinearLayout>
+ android:text="@string/change_aspect_ratio_text"
+ android:src="@drawable/desktop_mode_ic_handle_menu_change_aspect_ratio"
+ style="@style/DesktopModeHandleMenuActionButton"/>
</LinearLayout>
<LinearLayout
@@ -209,29 +179,14 @@
android:elevation="@dimen/desktop_mode_handle_menu_pill_elevation"
android:background="@drawable/desktop_mode_decor_handle_menu_background">
- <LinearLayout
+ <com.android.wm.shell.windowdecor.HandleMenuActionButton
android:id="@+id/open_in_app_or_browser_button"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:layout_marginEnd="8dp"
- android:gravity="start|center_vertical"
- android:paddingStart="16dp"
android:contentDescription="@string/open_in_browser_text"
- android:background="?android:selectableItemBackground">
-
- <ImageView
- android:id="@+id/image"
- android:src="@drawable/desktop_mode_ic_handle_menu_open_in_browser"
- android:importantForAccessibility="no"
- style="@style/DesktopModeHandleMenuActionButtonImage"/>
-
- <com.android.wm.shell.windowdecor.MarqueedTextView
- android:id="@+id/label"
- android:text="@string/open_in_browser_text"
- style="@style/DesktopModeHandleMenuActionButtonTextView"/>
-
- </LinearLayout>
+ android:text="@string/open_in_browser_text"
+ android:src="@drawable/desktop_mode_ic_handle_menu_open_in_browser"
+ style="@style/DesktopModeHandleMenuActionButton"
+ android:layout_width="0dp"
+ android:layout_weight="1"/>
<ImageButton
android:id="@+id/open_by_default_button"
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml
new file mode 100644
index 000000000000..379f4e984b73
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2025 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/action_button"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="start|center_vertical"
+ android:paddingHorizontal="16dp"
+ android:clickable="true"
+ android:focusable="true"
+ android:orientation="horizontal"
+ android:background="?android:attr/selectableItemBackground">
+
+ <ImageView
+ android:id="@+id/image"
+ android:contentDescription="@+id/label"
+ style="@style/DesktopModeHandleMenuActionButtonImage"/>
+
+ <com.android.wm.shell.windowdecor.MarqueedTextView
+ android:id="@+id/label"
+ style="@style/DesktopModeHandleMenuActionButtonTextView"/>
+</LinearLayout>
diff --git a/libs/WindowManager/Shell/res/values/attrs.xml b/libs/WindowManager/Shell/res/values/attrs.xml
index fbb5caa508de..4ba0468a740d 100644
--- a/libs/WindowManager/Shell/res/values/attrs.xml
+++ b/libs/WindowManager/Shell/res/values/attrs.xml
@@ -23,4 +23,11 @@
<declare-styleable name="MessageState">
<attr name="state_task_focused" format="boolean"/>
</declare-styleable>
+
+ <declare-styleable name="HandleMenuActionButton">
+ <attr name="android:text" format="string" />
+ <attr name="android:textColor" format="color" />
+ <attr name="android:src" format="reference" />
+ <attr name="android:drawableTint" format="color" />
+ </declare-styleable>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index e23d5725e9c3..96e008e42f1c 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -570,7 +570,7 @@
<dimen name="desktop_mode_handle_menu_corner_radius">26dp</dimen>
<!-- The radius of the caption menu icon. -->
- <dimen name="desktop_mode_caption_icon_radius">24dp</dimen>
+ <dimen name="desktop_mode_caption_icon_radius">32dp</dimen>
<!-- The radius of the caption menu shadow. -->
<dimen name="desktop_mode_handle_menu_shadow_radius">2dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index 035004bfd322..637b47ab3ace 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -40,13 +40,11 @@
<item name="android:activityCloseExitAnimation">@anim/forced_resizable_exit</item>
</style>
- <style name="DesktopModeHandleMenuActionButtonLayout">
+ <style name="DesktopModeHandleMenuActionButton">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">52dp</item>
- <item name="android:layout_weight">1</item>
- <item name="android:gravity">start|center_vertical</item>
- <item name="android:paddingHorizontal">16dp</item>
- <item name="android:background">?android:selectableItemBackground</item>
+ <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
+ <item name="android:drawableTint">@androidprv:color/materialColorOnSurface</item>
</style>
<style name="DesktopModeHandleMenuActionButtonImage">
@@ -71,7 +69,6 @@
<style name="DesktopModeHandleMenuWindowingButton">
<item name="android:layout_width">48dp</item>
<item name="android:layout_height">48dp</item>
- <item name="android:padding">14dp</item>
<item name="android:scaleType">fitCenter</item>
<item name="android:background">?android:selectableItemBackgroundBorderless</item>
</style>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
index a17bcb39f1a0..ff50672953c9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.kt
@@ -37,6 +37,9 @@ import android.view.WindowInsets.Type.systemBars
import android.view.WindowManager
import android.widget.ImageButton
import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.Space
+import android.widget.TextView
import android.window.DesktopModeFlags
import android.window.SurfaceSyncGroup
import androidx.annotation.StringRes
@@ -480,16 +483,23 @@ class HandleMenu(
private val splitscreenBtn = windowingPill.requireViewById<ImageButton>(
R.id.split_screen_button)
private val floatingBtn = windowingPill.requireViewById<ImageButton>(R.id.floating_button)
+ private val floatingBtnSpace = windowingPill.requireViewById<Space>(
+ R.id.floating_button_space)
+
private val desktopBtn = windowingPill.requireViewById<ImageButton>(R.id.desktop_button)
+ private val desktopBtnSpace = windowingPill.requireViewById<Space>(
+ R.id.desktop_button_space)
// More Actions Pill.
private val moreActionsPill = rootView.requireViewById<View>(R.id.more_actions_pill)
- private val screenshotBtn = moreActionsPill.requireViewById<View>(R.id.screenshot_button)
- private val newWindowBtn = moreActionsPill.requireViewById<View>(R.id.new_window_button)
+ private val screenshotBtn = moreActionsPill.requireViewById<HandleMenuActionButton>(
+ R.id.screenshot_button)
+ private val newWindowBtn = moreActionsPill.requireViewById<HandleMenuActionButton>(
+ R.id.new_window_button)
private val manageWindowBtn = moreActionsPill
- .requireViewById<View>(R.id.manage_windows_button)
+ .requireViewById<HandleMenuActionButton>(R.id.manage_windows_button)
private val changeAspectRatioBtn = moreActionsPill
- .requireViewById<View>(R.id.change_aspect_ratio_button)
+ .requireViewById<HandleMenuActionButton>(R.id.change_aspect_ratio_button)
// Open in Browser/App Pill.
private val openInAppOrBrowserPill = rootView.requireViewById<View>(
@@ -682,6 +692,7 @@ class HandleMenu(
if (!BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
floatingBtn.visibility = View.GONE
+ floatingBtnSpace.visibility = View.GONE
}
fullscreenBtn.isSelected = taskInfo.isFullscreen
@@ -710,8 +721,10 @@ class HandleMenu(
).forEach {
val button = it.first
val shouldShow = it.second
- val label = button.requireViewById<MarqueedTextView>(R.id.label)
- val image = button.requireViewById<ImageView>(R.id.image)
+
+ val buttonRoot = button.requireViewById<LinearLayout>(R.id.action_button)
+ val label = buttonRoot.requireViewById<MarqueedTextView>(R.id.label)
+ val image = buttonRoot.requireViewById<ImageView>(R.id.image)
button.isGone = !shouldShow
label.apply {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt
new file mode 100644
index 000000000000..4b2e473d6ec2
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.windowdecor
+
+import android.annotation.ColorInt
+import android.annotation.IdRes
+import android.content.Context
+import android.content.res.ColorStateList
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.core.content.withStyledAttributes
+import androidx.core.view.isGone
+import com.android.wm.shell.R
+
+/**
+ * Button-like component used to display the "Additional options" elements of the Handle menu window
+ * decoration.
+ *
+ * The possible options for which this button is used for are "Screenshot", "New Window", "Manage
+ * Windows" and "Change Aspect Ratio".
+ */
+class HandleMenuActionButton @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : LinearLayout(context, attrs, defStyleAttr) {
+
+ private val rootElement: LinearLayout
+ private val iconView: ImageView
+ private val textView: MarqueedTextView
+
+ init {
+ val view = LayoutInflater.from(context).inflate(
+ R.layout.desktop_mode_window_decor_handle_menu_action_button, this, true)
+ rootElement = findViewById(R.id.action_button)
+ iconView = findViewById(R.id.image)
+ textView = findViewById(R.id.label)
+
+ context.withStyledAttributes(attrs, R.styleable.HandleMenuActionButton) {
+ textView.text = getString(R.styleable.HandleMenuActionButton_android_text)
+ textView.setTextColor(getColor(R.styleable.HandleMenuActionButton_android_textColor, 0))
+ iconView.setImageResource(getResourceId(
+ R.styleable.HandleMenuActionButton_android_src, 0))
+ iconView.imageTintList = getColorStateList(
+ R.styleable.HandleMenuActionButton_android_drawableTint)
+ }
+ }
+
+ /**
+ * Sets a listener to be invoked when this view is clicked.
+ *
+ * @param l the [OnClickListener] that receives click events.
+ */
+ override fun setOnClickListener(l: OnClickListener?) {
+ rootElement.setOnClickListener(l)
+ }
+
+ /**
+ * Sets the text color for the text inside the button.
+ *
+ * @param color the color to set for the text, as a color integer.
+ */
+ fun setTextColor(@ColorInt color: Int) {
+ textView.setTextColor(color)
+ }
+
+ /**
+ * Sets the icon for the button using a resource ID.
+ *
+ * @param resourceId the resource ID of the drawable to set as the icon.
+ */
+ fun setIconResource(@IdRes resourceId: Int) {
+ iconView.setImageResource(resourceId)
+ }
+
+ /**
+ * Sets the text to display inside the button.
+ *
+ * @param text the text to display.
+ */
+ fun setText(text: CharSequence?) {
+ textView.text = text
+ }
+
+ /**
+ * Sets the tint color for the icon.
+ *
+ * @param color the color to use for the tint, as a color integer.
+ */
+ fun setDrawableTint(@ColorInt color: Int) {
+ iconView.imageTintList = ColorStateList.valueOf(color)
+ }
+
+ /**
+ * Gets or sets the tint applied to the icon.
+ *
+ * @return The [ColorStateList] representing the tint, or null if no tint is applied.
+ */
+ var compoundDrawableTintList: ColorStateList?
+ get() = iconView.imageTintList
+ set(value) {
+ iconView.imageTintList = value
+ }
+}