Loading quickstep/src/com/android/launcher3/taskbar/NewWindowTaskbarShortcut.kt 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.launcher3.taskbar import android.content.Context import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK import android.view.View import com.android.launcher3.AbstractFloatingView import com.android.launcher3.R import com.android.launcher3.model.data.ItemInfo import com.android.launcher3.popup.SystemShortcut import com.android.launcher3.views.ActivityContext /** * A single menu item shortcut to execute creating a new instance of an app. Default interaction for * [onClick] is to launch the app in full screen or as a floating window in Desktop Mode. */ class NewWindowTaskbarShortcut<T>(target: T, itemInfo: ItemInfo?, originalView: View?) : SystemShortcut<T>( R.drawable.desktop_mode_ic_taskbar_menu_new_window, R.string.new_window_option_taskbar, target, itemInfo, originalView ) where T : Context?, T : ActivityContext? { override fun onClick(v: View?) { val intent = mItemInfo.intent ?: return intent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK) mTarget?.startActivitySafely(v, intent, mItemInfo) AbstractFloatingView.closeAllOpenViews(mTarget) } } quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java +1 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,7 @@ public class TaskbarModelCallbacks implements Map<PackageUserKey, Integer> packageUserKeytoUidMap) { Preconditions.assertUIThread(); mControllers.taskbarAllAppsController.setApps(apps, flags, packageUserKeytoUidMap); mControllers.taskbarPopupController.setApps(apps); } protected void dumpLogs(String prefix, PrintWriter pw) { Loading quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java +59 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.launcher3.taskbar; import static com.android.launcher3.model.data.AppInfo.COMPONENT_KEY_COMPARATOR; import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition; import android.content.Intent; Loading @@ -29,11 +30,13 @@ import androidx.annotation.NonNull; import com.android.internal.logging.InstanceId; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BubbleTextView; import com.android.launcher3.Flags; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.dot.FolderDotInfo; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; Loading @@ -51,9 +54,11 @@ import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.views.ActivityContext; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.util.LogUtils; import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Objects; Loading @@ -79,6 +84,7 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba // Initialized in init. private TaskbarControllers mControllers; private boolean mAllowInitialSplitSelection; private AppInfo[] mAppInfosList; public TaskbarPopupController(TaskbarActivityContext context) { mContext = context; Loading Loading @@ -195,6 +201,10 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba if (com.android.wm.shell.Flags.enableBubbleAnything()) { shortcuts.add(BUBBLE); } if (Flags.enableMultiInstanceMenuTaskbar() && DesktopModeStatus.canEnterDesktopMode(mContext)) { shortcuts.addAll(getMultiInstanceMenuOptions().toList()); } return shortcuts.stream(); } Loading Loading @@ -258,6 +268,54 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba originalView, position, mAllowInitialSplitSelection); } /** * Set the list of AppInfos to be able to pull from later */ public void setApps(AppInfo[] apps) { mAppInfosList = apps; } /** * Finds and returns an AppInfo object from a list, using its ComponentKey for identification. * Based off of {@link com.android.launcher3.allapps.AllAppsStore#getApp(ComponentKey)} * since we cannot access AllAppsStore from here. */ public AppInfo getApp(ComponentKey key) { if (key == null) { return null; } AppInfo tempInfo = new AppInfo(); tempInfo.componentName = key.componentName; tempInfo.user = key.user; int index = Arrays.binarySearch(mAppInfosList, tempInfo, COMPONENT_KEY_COMPARATOR); return index < 0 ? null : mAppInfosList[index]; } /** * Returns a stream of Multi Instance menu options if an app supports it. */ Stream<SystemShortcut.Factory<BaseTaskbarContext>> getMultiInstanceMenuOptions() { SystemShortcut.Factory<BaseTaskbarContext> factory = createNewWindowShortcutFactory(); return factory != null ? Stream.of(factory) : Stream.empty(); } /** * Creates a factory function representing a "New Window" menu item only if the calling app * supports multi-instance. * @return A factory function to be used in populating the long-press menu. */ SystemShortcut.Factory<BaseTaskbarContext> createNewWindowShortcutFactory() { return (context, itemInfo, originalView) -> { ComponentKey key = itemInfo.getComponentKey(); AppInfo app = getApp(key); if (app != null && app.supportsMultiInstance()) { return new NewWindowTaskbarShortcut<>(context, itemInfo, originalView); } return null; }; } /** * A single menu item ("Split left," "Split right," or "Split top") that executes a split * from the taskbar, as if the user performed a drag and drop split. Loading res/drawable/desktop_mode_ic_taskbar_menu_new_window.xml 0 → 100644 +25 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2024 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. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20"> <path android:pathData="M15 16V14H13V12.5H15V10.5H16.5V12.5H18.5V14H16.5V16H15ZM3.5 17C3.09722 17 2.74306 16.8542 2.4375 16.5625C2.14583 16.2569 2 15.9028 2 15.5V4.5C2 4.08333 2.14583 3.72917 2.4375 3.4375C2.74306 3.14583 3.09722 3 3.5 3H14.5C14.9167 3 15.2708 3.14583 15.5625 3.4375C15.8542 3.72917 16 4.08333 16 4.5V9H14.5V7H3.5V15.5H13.625V17H3.5ZM3.5 5.5H14.5V4.5H3.5V5.5ZM3.5 5.5V4.5V5.5Z" android:fillColor="#1C1C14"/> </vector> res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ <string name="split_app_info_accessibility">App info for %1$s</string> <string name="split_app_usage_settings">Usage settings for %1$s</string> <!-- Title for an option to open a new window for a given app --> <string name="new_window_option_taskbar">New Window</string> <!-- App pairs --> <string name="save_app_pair">Save app pair</string> <!-- App pair default title --> Loading Loading
quickstep/src/com/android/launcher3/taskbar/NewWindowTaskbarShortcut.kt 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.launcher3.taskbar import android.content.Context import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK import android.view.View import com.android.launcher3.AbstractFloatingView import com.android.launcher3.R import com.android.launcher3.model.data.ItemInfo import com.android.launcher3.popup.SystemShortcut import com.android.launcher3.views.ActivityContext /** * A single menu item shortcut to execute creating a new instance of an app. Default interaction for * [onClick] is to launch the app in full screen or as a floating window in Desktop Mode. */ class NewWindowTaskbarShortcut<T>(target: T, itemInfo: ItemInfo?, originalView: View?) : SystemShortcut<T>( R.drawable.desktop_mode_ic_taskbar_menu_new_window, R.string.new_window_option_taskbar, target, itemInfo, originalView ) where T : Context?, T : ActivityContext? { override fun onClick(v: View?) { val intent = mItemInfo.intent ?: return intent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK) mTarget?.startActivitySafely(v, intent, mItemInfo) AbstractFloatingView.closeAllOpenViews(mTarget) } }
quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java +1 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,7 @@ public class TaskbarModelCallbacks implements Map<PackageUserKey, Integer> packageUserKeytoUidMap) { Preconditions.assertUIThread(); mControllers.taskbarAllAppsController.setApps(apps, flags, packageUserKeytoUidMap); mControllers.taskbarPopupController.setApps(apps); } protected void dumpLogs(String prefix, PrintWriter pw) { Loading
quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java +59 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ package com.android.launcher3.taskbar; import static com.android.launcher3.model.data.AppInfo.COMPONENT_KEY_COMPARATOR; import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition; import android.content.Intent; Loading @@ -29,11 +30,13 @@ import androidx.annotation.NonNull; import com.android.internal.logging.InstanceId; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BubbleTextView; import com.android.launcher3.Flags; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.dot.FolderDotInfo; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; Loading @@ -51,9 +54,11 @@ import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.views.ActivityContext; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.util.LogUtils; import com.android.wm.shell.shared.desktopmode.DesktopModeStatus; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Objects; Loading @@ -79,6 +84,7 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba // Initialized in init. private TaskbarControllers mControllers; private boolean mAllowInitialSplitSelection; private AppInfo[] mAppInfosList; public TaskbarPopupController(TaskbarActivityContext context) { mContext = context; Loading Loading @@ -195,6 +201,10 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba if (com.android.wm.shell.Flags.enableBubbleAnything()) { shortcuts.add(BUBBLE); } if (Flags.enableMultiInstanceMenuTaskbar() && DesktopModeStatus.canEnterDesktopMode(mContext)) { shortcuts.addAll(getMultiInstanceMenuOptions().toList()); } return shortcuts.stream(); } Loading Loading @@ -258,6 +268,54 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba originalView, position, mAllowInitialSplitSelection); } /** * Set the list of AppInfos to be able to pull from later */ public void setApps(AppInfo[] apps) { mAppInfosList = apps; } /** * Finds and returns an AppInfo object from a list, using its ComponentKey for identification. * Based off of {@link com.android.launcher3.allapps.AllAppsStore#getApp(ComponentKey)} * since we cannot access AllAppsStore from here. */ public AppInfo getApp(ComponentKey key) { if (key == null) { return null; } AppInfo tempInfo = new AppInfo(); tempInfo.componentName = key.componentName; tempInfo.user = key.user; int index = Arrays.binarySearch(mAppInfosList, tempInfo, COMPONENT_KEY_COMPARATOR); return index < 0 ? null : mAppInfosList[index]; } /** * Returns a stream of Multi Instance menu options if an app supports it. */ Stream<SystemShortcut.Factory<BaseTaskbarContext>> getMultiInstanceMenuOptions() { SystemShortcut.Factory<BaseTaskbarContext> factory = createNewWindowShortcutFactory(); return factory != null ? Stream.of(factory) : Stream.empty(); } /** * Creates a factory function representing a "New Window" menu item only if the calling app * supports multi-instance. * @return A factory function to be used in populating the long-press menu. */ SystemShortcut.Factory<BaseTaskbarContext> createNewWindowShortcutFactory() { return (context, itemInfo, originalView) -> { ComponentKey key = itemInfo.getComponentKey(); AppInfo app = getApp(key); if (app != null && app.supportsMultiInstance()) { return new NewWindowTaskbarShortcut<>(context, itemInfo, originalView); } return null; }; } /** * A single menu item ("Split left," "Split right," or "Split top") that executes a split * from the taskbar, as if the user performed a drag and drop split. Loading
res/drawable/desktop_mode_ic_taskbar_menu_new_window.xml 0 → 100644 +25 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2024 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. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20"> <path android:pathData="M15 16V14H13V12.5H15V10.5H16.5V12.5H18.5V14H16.5V16H15ZM3.5 17C3.09722 17 2.74306 16.8542 2.4375 16.5625C2.14583 16.2569 2 15.9028 2 15.5V4.5C2 4.08333 2.14583 3.72917 2.4375 3.4375C2.74306 3.14583 3.09722 3 3.5 3H14.5C14.9167 3 15.2708 3.14583 15.5625 3.4375C15.8542 3.72917 16 4.08333 16 4.5V9H14.5V7H3.5V15.5H13.625V17H3.5ZM3.5 5.5H14.5V4.5H3.5V5.5ZM3.5 5.5V4.5V5.5Z" android:fillColor="#1C1C14"/> </vector>
res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ <string name="split_app_info_accessibility">App info for %1$s</string> <string name="split_app_usage_settings">Usage settings for %1$s</string> <!-- Title for an option to open a new window for a given app --> <string name="new_window_option_taskbar">New Window</string> <!-- App pairs --> <string name="save_app_pair">Save app pair</string> <!-- App pair default title --> Loading