diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 10d3d5c1fd..6830609dd0 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -4,7 +4,6 @@
-keep class com.sevtinge.hyperceiler.utils.Helpers{boolean isModuleActive;}
-keep class com.sevtinge.hyperceiler.utils.Helpers{int XposedVersion;}
-keep class * extends com.sevtinge.hyperceiler.module.base.BaseHook
--keep class * extends com.sevtinge.hyperceiler.utils.hook.HookUtils
-keep class com.sevtinge.hyperceiler.ui.HideAppActivity
-keep class * extends com.sevtinge.hyperceiler.ui.fragment.base.*
-keep class miui.drm.**{*;}
diff --git a/app/src/main/java/com/sevtinge/hyperceiler/module/app/Home.java b/app/src/main/java/com/sevtinge/hyperceiler/module/app/Home.java
index f08b4f5dec..1127bfab06 100644
--- a/app/src/main/java/com/sevtinge/hyperceiler/module/app/Home.java
+++ b/app/src/main/java/com/sevtinge/hyperceiler/module/app/Home.java
@@ -45,6 +45,7 @@
import com.sevtinge.hyperceiler.module.hook.home.folder.SmallFolderIconBlur;
import com.sevtinge.hyperceiler.module.hook.home.gesture.DoubleTap;
import com.sevtinge.hyperceiler.module.hook.home.gesture.HotSeatSwipe;
+import com.sevtinge.hyperceiler.module.hook.home.gesture.QuickBack;
import com.sevtinge.hyperceiler.module.hook.home.gesture.ShakeDevice;
import com.sevtinge.hyperceiler.module.hook.home.layout.HotSeatsHeight;
import com.sevtinge.hyperceiler.module.hook.home.layout.HotSeatsMarginBottom;
@@ -116,6 +117,7 @@ public void handleLoadPackage() {
initHook(LoadHostDir.INSTANCE);
// 手势
+ initHook(new QuickBack(), mPrefsMap.getBoolean("home_navigation_quick_back"));
initHook(new DoubleTap(), mPrefsMap.getInt("home_gesture_double_tap_action", 0) > 0);
initHook(new ScreenSwipe(), mPrefsMap.getInt("home_gesture_up_swipe_action", 0) > 0 ||
mPrefsMap.getInt("home_gesture_down_swipe_action", 0) > 0 ||
diff --git a/app/src/main/java/com/sevtinge/hyperceiler/module/hook/home/gesture/QuickBack.java b/app/src/main/java/com/sevtinge/hyperceiler/module/hook/home/gesture/QuickBack.java
new file mode 100644
index 0000000000..74e4fdac8c
--- /dev/null
+++ b/app/src/main/java/com/sevtinge/hyperceiler/module/hook/home/gesture/QuickBack.java
@@ -0,0 +1,116 @@
+package com.sevtinge.hyperceiler.module.hook.home.gesture;
+
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.content.Context;
+
+import com.sevtinge.hyperceiler.module.base.BaseHook;
+
+import java.util.ArrayList;
+
+import de.robv.android.xposed.XposedHelpers;
+
+public class QuickBack extends BaseHook {
+ @Override
+ public void init() {
+ findAndHookMethod("com.miui.home.recents.GestureStubView",
+ "isDisableQuickSwitch", new MethodHook() {
+ @Override
+ protected void before(MethodHookParam param) {
+ param.setResult(false);
+ }
+ }
+ );
+
+ findAndHookMethod("com.miui.home.recents.GestureStubView",
+ "getNextTask", Context.class, boolean.class, int.class,
+ new MethodHook() {
+ @Override
+ protected void before(MethodHookParam param) {
+ Context context = (Context) param.args[0];
+ ActivityManager.RunningTaskInfo runningTask;
+ Object recentsModel = XposedHelpers.callStaticMethod(findClass("com.miui.home.recents.RecentsModel"), "getInstance", context);
+ Object taskLoader = XposedHelpers.callMethod(recentsModel, "getTaskLoader");
+ Object createLoadPlan = XposedHelpers.callMethod(taskLoader, "createLoadPlan", context);
+ XposedHelpers.callMethod(taskLoader, "preloadTasks", createLoadPlan, -1);
+ Object taskStack = XposedHelpers.callMethod(createLoadPlan, "getTaskStack");
+ ActivityOptions activityOptions = null;
+ if (taskStack == null || (int) XposedHelpers.callMethod(taskStack, "getTaskCount") == 0 || (runningTask = (ActivityManager.RunningTaskInfo) XposedHelpers.callMethod(recentsModel, "getRunningTask")) == null) {
+ param.setResult(null);
+ return;
+ }
+ ArrayList> stackTasks = (ArrayList>) XposedHelpers.callMethod(taskStack, "getStackTasks");
+ int size = stackTasks.size();
+ Object task = null;
+ int i2 = 0;
+ while (true) {
+ if (i2 >= size - 1) {
+ break;
+ } else if ((int) XposedHelpers.getObjectField(XposedHelpers.getObjectField(stackTasks.get(i2), "key"), "id") == runningTask.id) {
+ task = stackTasks.get(i2 + 1);
+ break;
+ } else {
+ i2++;
+ }
+ }
+ if (task == null && size >= 1 && "com.miui.home".equals(runningTask.baseActivity.getPackageName())) {
+ task = stackTasks.get(0);
+ }
+ if (task != null && XposedHelpers.getObjectField(task, "icon") == null) {
+ XposedHelpers.setObjectField(task, "icon", XposedHelpers.callMethod(taskLoader, "getAndUpdateActivityIcon",
+ XposedHelpers.getObjectField(task, "key"),
+ XposedHelpers.getObjectField(task, "taskDescription"),
+ context.getResources(), true
+ ));
+ }
+ if (!(boolean) param.args[1] || task == null) {
+ param.setResult(task);
+ return;
+ }
+ int i = (int) param.args[2];
+ if (i == 0) {
+ activityOptions = ActivityOptions.makeCustomAnimation(context,
+ (int) XposedHelpers.callStaticMethod(
+ findClass("com.miui.home.recents.GestureStubView"),
+ "getAnimId", context, "recents_quick_switch_left_enter"),
+ (int) XposedHelpers.callStaticMethod(
+ findClass("com.miui.home.recents.GestureStubView"),
+ "getAnimId", context, "recents_quick_switch_left_exit"));
+ } else if (i == 1) {
+ activityOptions = ActivityOptions.makeCustomAnimation(context,
+ (int) XposedHelpers.callStaticMethod(
+ findClass("com.miui.home.recents.GestureStubView"),
+ "getAnimId", context, "recents_quick_switch_right_enter"),
+ (int) XposedHelpers.callStaticMethod(
+ findClass("com.miui.home.recents.GestureStubView"),
+ "getAnimId", context, "recents_quick_switch_right_exit"));
+ }
+ Object iActivityManager = XposedHelpers.callStaticMethod(findClass("android.app.ActivityManagerNative"), "getDefault");
+ if (iActivityManager != null) {
+ try {
+ if ((int) XposedHelpers.getObjectField(XposedHelpers.getObjectField(task, "key"), "windowingMode") == 3) {
+ if (activityOptions == null) {
+ activityOptions = ActivityOptions.makeBasic();
+ }
+ activityOptions.getClass().getMethod("setLaunchWindowingMode", Integer.class).invoke(activityOptions, 4);
+ }
+ XposedHelpers.callMethod(iActivityManager, "startActivityFromRecents",
+ XposedHelpers.getObjectField(
+ XposedHelpers.getObjectField(task, "key"),
+ "id"),
+ activityOptions == null ? null : activityOptions.toBundle());
+ param.setResult(task);
+ return;
+ } catch (Exception e) {
+ logE(TAG, "Error :" + e);
+ param.setResult(task);
+ return;
+ }
+ }
+ param.setResult(task);
+ }
+ }
+ );
+
+ }
+}
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index c40a7e0d8b..bc2dbb401d 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -806,6 +806,8 @@
系统桌面
手势与导航
导航
+ 切换上一个应用
+ 从屏幕两侧向内滑动并停顿,快速切换上一个应用
返回手势区域高度
返回手势区域宽度
手势
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3d9f2b524e..e4b6e65bed 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -790,6 +790,8 @@
System launcher
Gesture and Navigation
Navigation
+ Go back to previous app
+ Swipe across the screen starting from the edge to go back to previous app
Back gesture area height
Back gesture area width
Gesture
diff --git a/app/src/main/res/xml/home_gesture.xml b/app/src/main/res/xml/home_gesture.xml
index 2646decbca..bb9ae27134 100644
--- a/app/src/main/res/xml/home_gesture.xml
+++ b/app/src/main/res/xml/home_gesture.xml
@@ -2,78 +2,84 @@
+
+
+ app:maxValue="100"
+ app:minValue="10"
+ app:showSeekBarValue="true"
+ app:stepValue="5" />
+ app:maxValue="400"
+ app:minValue="100"
+ app:showSeekBarValue="true"
+ app:stepValue="5" />
+ android:title="@string/home_gesture_double_tap" />
+ android:title="@string/home_gesture_shake" />
+ android:title="@string/home_gesture_left_swipe" />
+ android:title="@string/home_gesture_right_swipe" />
+ android:title="@string/home_gesture_up_swipe" />
+ android:title="@string/home_gesture_down_swipe" />
+ android:title="@string/home_gesture_up_swipe2" />
+ android:title="@string/home_gesture_down_swipe2" />