mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-27 23:36:47 +00:00
Merge "Show a persistent toast when selecting desktop apps on home screen" into udc-qpr-dev
This commit is contained in:
23
quickstep/res/drawable/bg_floating_desktop_select.xml
Normal file
23
quickstep/res/drawable/bg_floating_desktop_select.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright (C) 2023 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.
|
||||
-->
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<corners android:radius="@dimen/rounded_button_radius" />
|
||||
<solid android:color="?androidprv:attr/materialColorPrimaryContainer" />
|
||||
</shape>
|
||||
56
quickstep/res/layout/floating_desktop_app_select.xml
Normal file
56
quickstep/res/layout/floating_desktop_app_select.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright (C) 2023 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.
|
||||
-->
|
||||
|
||||
<com.android.quickstep.views.DesktopAppSelectView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/desktop_mode_floating_app_select_height"
|
||||
android:layout_gravity="top|center_horizontal"
|
||||
android:background="@drawable/bg_floating_desktop_select"
|
||||
android:elevation="@dimen/desktop_mode_floating_app_select_elevation"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/desktop_app_select_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/desktop_mode_floating_app_select_text_margin"
|
||||
android:layout_marginStart="@dimen/desktop_mode_floating_app_select_margin"
|
||||
android:drawablePadding="@dimen/desktop_mode_floating_app_select_text_margin"
|
||||
android:drawableStart="@drawable/ic_desktop"
|
||||
android:drawableTint="?androidprv:attr/materialColorOnPrimaryContainer"
|
||||
android:fontFamily="google-sans-medium"
|
||||
android:gravity="center_vertical"
|
||||
android:text="@string/desktop_select_app_toast"
|
||||
android:textColor="?androidprv:attr/materialColorOnPrimaryContainer"
|
||||
android:textSize="@dimen/desktop_mode_floating_app_select_text_size" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/close_button"
|
||||
style="@android:style/Widget.DeviceDefault.Button.Borderless"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/desktop_mode_floating_app_select_margin"
|
||||
android:minWidth="0dp"
|
||||
android:fontFamily="google-sans-medium"
|
||||
android:text="@string/desktop_button_close_app_toast"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="?androidprv:attr/materialColorPrimary"
|
||||
android:textSize="@dimen/desktop_mode_floating_app_select_text_size" />
|
||||
|
||||
</com.android.quickstep.views.DesktopAppSelectView>
|
||||
@@ -383,4 +383,12 @@
|
||||
<dimen name="keyboard_quick_switch_task_view_radius">16dp</dimen>
|
||||
<dimen name="keyboard_quick_switch_no_recent_items_icon_size">24dp</dimen>
|
||||
<dimen name="keyboard_quick_switch_no_recent_items_icon_margin">8dp</dimen>
|
||||
|
||||
<!-- Desktop mode -->
|
||||
<dimen name="desktop_mode_floating_app_select_height">56dp</dimen>
|
||||
<dimen name="desktop_mode_floating_app_select_elevation">4dp</dimen>
|
||||
<dimen name="desktop_mode_floating_app_select_margin">16dp</dimen>
|
||||
<dimen name="desktop_mode_floating_app_select_text_size">14sp</dimen>
|
||||
<dimen name="desktop_mode_floating_app_select_text_margin">8dp</dimen>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -298,4 +298,10 @@
|
||||
|
||||
<!-- Accessibility label for quick switch tiles showing split tasks [CHAR LIMIT=NONE] -->
|
||||
<string name="quick_switch_split_task"><xliff:g id="app_name_1" example="Chrome">%1$s</xliff:g> and <xliff:g id="app_name_2" example="Gmail">%2$s</xliff:g></string>
|
||||
|
||||
<!-- ******* Desktop ******* -->
|
||||
<!-- Text shown in popup to choose a desktop app. [CHAR LIMIT=60] -->
|
||||
<string name="desktop_select_app_toast">Adding app to Desktop</string>
|
||||
<!-- Text shown on a button that closes the popup for choosing a desktop app. [CHAR_LIMIT=40] -->
|
||||
<string name="desktop_button_close_app_toast">Cancel</string>
|
||||
</resources>
|
||||
|
||||
@@ -17,11 +17,9 @@ package com.android.launcher3.statehandlers;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -30,6 +28,7 @@ import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.views.DesktopAppSelectView;
|
||||
import com.android.wm.shell.desktopmode.IDesktopTaskListener;
|
||||
|
||||
/**
|
||||
@@ -49,6 +48,7 @@ public class DesktopVisibilityController {
|
||||
|
||||
@Nullable
|
||||
private IDesktopTaskListener mDesktopTaskListener;
|
||||
private DesktopAppSelectView mSelectAppToast;
|
||||
|
||||
public DesktopVisibilityController(Launcher launcher) {
|
||||
mLauncher = launcher;
|
||||
@@ -60,17 +60,22 @@ public class DesktopVisibilityController {
|
||||
public void registerSystemUiListener() {
|
||||
mDesktopTaskListener = new IDesktopTaskListener.Stub() {
|
||||
@Override
|
||||
public void onVisibilityChanged(int displayId, boolean visible) throws RemoteException {
|
||||
public void onVisibilityChanged(int displayId, boolean visible) {
|
||||
// TODO(b/261234402): move visibility from sysui state to listener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStashedChanged(int displayId, boolean stashed) throws RemoteException {
|
||||
// TODO(b/261234402): show a persistent toast
|
||||
public void onStashedChanged(int displayId, boolean stashed) {
|
||||
MAIN_EXECUTOR.execute(() -> {
|
||||
if (stashed && displayId == mLauncher.getDisplayId()) {
|
||||
Toast.makeText(mLauncher, "Adding app to Desktop",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
if (displayId == mLauncher.getDisplayId()) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "desktop stashed changed value=" + stashed);
|
||||
}
|
||||
if (stashed) {
|
||||
showSelectAppToast();
|
||||
} else {
|
||||
hideSelectAppToast();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -110,6 +115,7 @@ public class DesktopVisibilityController {
|
||||
if (!isDesktopModeSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (freeformTasksVisible != mFreeformTasksVisible) {
|
||||
mFreeformTasksVisible = freeformTasksVisible;
|
||||
if (mFreeformTasksVisible) {
|
||||
@@ -219,4 +225,28 @@ public class DesktopVisibilityController {
|
||||
activity.setResumed();
|
||||
}
|
||||
}
|
||||
|
||||
private void showSelectAppToast() {
|
||||
if (mSelectAppToast != null) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "show toast to select desktop apps");
|
||||
}
|
||||
Runnable onCloseCallback = () -> {
|
||||
SystemUiProxy.INSTANCE.get(mLauncher).hideStashedDesktopApps(mLauncher.getDisplayId());
|
||||
};
|
||||
mSelectAppToast = DesktopAppSelectView.show(mLauncher, onCloseCallback);
|
||||
}
|
||||
|
||||
private void hideSelectAppToast() {
|
||||
if (mSelectAppToast == null) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "hide toast to select desktop apps");
|
||||
}
|
||||
mSelectAppToast.hide();
|
||||
mSelectAppToast = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1161,6 +1161,17 @@ public class SystemUiProxy implements ISystemUiProxy {
|
||||
}
|
||||
}
|
||||
|
||||
/** Call shell to hide desktop apps that may be stashed */
|
||||
public void hideStashedDesktopApps(int displayId) {
|
||||
if (mDesktopMode != null) {
|
||||
try {
|
||||
mDesktopMode.hideStashedDesktopApps(displayId);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed call hideStashedDesktopApps", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Call shell to get number of visible freeform tasks */
|
||||
public int getVisibleDesktopTaskCount(int displayId) {
|
||||
if (mDesktopMode != null) {
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.quickstep.views;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
|
||||
/**
|
||||
* Floating view show on launcher home screen that notifies the user that an app will be launched to
|
||||
* the desktop.
|
||||
*/
|
||||
public class DesktopAppSelectView extends LinearLayout {
|
||||
|
||||
private static final int HIDE_DURATION = 83;
|
||||
|
||||
private final Launcher mLauncher;
|
||||
|
||||
@Nullable
|
||||
private Runnable mOnCloseCallback = null;
|
||||
private boolean mIsHideAnimationRunning;
|
||||
|
||||
public DesktopAppSelectView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public DesktopAppSelectView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public DesktopAppSelectView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public DesktopAppSelectView(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
mLauncher = Launcher.getLauncher(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the popup on launcher home screen
|
||||
*
|
||||
* @param onCloseCallback optional callback that is called when user clicks the close button
|
||||
* @return the created view
|
||||
*/
|
||||
public static DesktopAppSelectView show(Launcher launcher, @Nullable Runnable onCloseCallback) {
|
||||
DesktopAppSelectView view = (DesktopAppSelectView) launcher.getLayoutInflater().inflate(
|
||||
R.layout.floating_desktop_app_select, launcher.getDragLayer(), false);
|
||||
view.setOnCloseClickCallback(onCloseCallback);
|
||||
launcher.getDragLayer().addView(view);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
findViewById(R.id.close_button).setOnClickListener(v -> {
|
||||
if (!mIsHideAnimationRunning) {
|
||||
hide();
|
||||
if (mOnCloseCallback != null) {
|
||||
mOnCloseCallback.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the floating view
|
||||
*/
|
||||
public void hide() {
|
||||
if (!mIsHideAnimationRunning) {
|
||||
mIsHideAnimationRunning = true;
|
||||
animate().alpha(0).setDuration(HIDE_DURATION).setInterpolator(LINEAR).withEndAction(
|
||||
() -> {
|
||||
mLauncher.getDragLayer().removeView(this);
|
||||
mIsHideAnimationRunning = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a callback that is called when close button is clicked
|
||||
*/
|
||||
public void setOnCloseClickCallback(@Nullable Runnable callback) {
|
||||
mOnCloseCallback = callback;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user