From 9dbb1aaf7316d46fba6b48221fb4cbe4487b4149 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=97=A0=E5=BF=A7?=
<69062567+wuyou-123@users.noreply.github.com>
Date: Thu, 27 Jun 2024 19:13:56 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E:=201.=E7=A6=81=E7=94=A8?=
=?UTF-8?q?=E6=97=A0=E6=9E=81=E7=BC=A9=E6=94=BE(=E5=B9=B3=E6=9D=BF)=202.?=
=?UTF-8?q?=E5=B0=8F=E7=AA=97-=E8=AE=B0=E4=BD=8F=E7=8A=B6=E6=80=81=20?=
=?UTF-8?q?=E6=94=B9=E4=B8=BA=20=E8=AE=B0=E4=BD=8F=E7=8A=B6=E6=80=81?=
=?UTF-8?q?=E5=8F=8A=E4=BD=8D=E7=BD=AE=20(#709)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: disable infinitymode gesture for pad
* feat: freeform - Remember state function adds remember location
* refactor: hide "disable infinitymode gesture" switch on phone
---
.../module/app/SystemUI/Phone/SystemUIT.java | 4 +
.../StickyFloatingWindows.java | 110 ++++++++----
.../systemui/DisableInfinitymodeGesture.kt | 17 ++
.../StickyFloatingWindowsForSystemUI.kt | 168 ++++++++++++++++++
.../systemui/SystemUIOtherSettings.java | 3 +
app/src/main/res/values-zh-rCN/strings.xml | 4 +-
app/src/main/res/values/strings.xml | 4 +-
app/src/main/res/xml/system_ui_other.xml | 8 +-
8 files changed, 279 insertions(+), 39 deletions(-)
create mode 100644 app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemui/DisableInfinitymodeGesture.kt
create mode 100644 app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemui/StickyFloatingWindowsForSystemUI.kt
diff --git a/app/src/main/java/com/sevtinge/hyperceiler/module/app/SystemUI/Phone/SystemUIT.java b/app/src/main/java/com/sevtinge/hyperceiler/module/app/SystemUI/Phone/SystemUIT.java
index d1ff595375..1765dc4ad6 100644
--- a/app/src/main/java/com/sevtinge/hyperceiler/module/app/SystemUI/Phone/SystemUIT.java
+++ b/app/src/main/java/com/sevtinge/hyperceiler/module/app/SystemUI/Phone/SystemUIT.java
@@ -31,6 +31,7 @@
import com.sevtinge.hyperceiler.module.hook.systemui.BrightnessPct;
import com.sevtinge.hyperceiler.module.hook.systemui.ChargeAnimationStyle;
import com.sevtinge.hyperceiler.module.hook.systemui.DisableBottomBar;
+import com.sevtinge.hyperceiler.module.hook.systemui.DisableInfinitymodeGesture;
import com.sevtinge.hyperceiler.module.hook.systemui.DisableMiuiMultiWinSwitch;
import com.sevtinge.hyperceiler.module.hook.systemui.DisableTransparent;
import com.sevtinge.hyperceiler.module.hook.systemui.MediaButton;
@@ -42,6 +43,7 @@
import com.sevtinge.hyperceiler.module.hook.systemui.RemoveMiuiMultiWinSwitch;
import com.sevtinge.hyperceiler.module.hook.systemui.SquigglyProgress;
import com.sevtinge.hyperceiler.module.hook.systemui.StatusBarActions;
+import com.sevtinge.hyperceiler.module.hook.systemui.StickyFloatingWindowsForSystemUI;
import com.sevtinge.hyperceiler.module.hook.systemui.UiLockApp;
import com.sevtinge.hyperceiler.module.hook.systemui.UnimportantNotification;
import com.sevtinge.hyperceiler.module.hook.systemui.UnlockClipboard;
@@ -183,6 +185,7 @@ public void handleLoadPackage() {
initHook(StatusBarSimIcon.INSTANCE, isHideSim);
initHook(HideVoWiFiIcon.INSTANCE, mPrefsMap.getBoolean("system_ui_status_bar_icon_vowifi") || mPrefsMap.getBoolean("system_ui_status_bar_icon_volte"));
initHook(UseNewHD.INSTANCE, mPrefsMap.getBoolean("system_ui_status_bar_use_new_hd"));
+ initHook(new StickyFloatingWindowsForSystemUI(), mPrefsMap.getBoolean("system_framework_freeform_sticky"));
// 移动网络图标
boolean isEnableMobilePublic = mPrefsMap.getBoolean("system_ui_status_bar_icon_mobile_network_hide_card_1") ||
@@ -333,6 +336,7 @@ public void handleLoadPackage() {
initHook(new BrightnessPct(), mPrefsMap.getBoolean("system_showpct_title"));
initHook(DisableMiuiMultiWinSwitch.INSTANCE, mPrefsMap.getBoolean("system_ui_disable_miui_multi_win_switch"));
initHook(RemoveMiuiMultiWinSwitch.INSTANCE, mPrefsMap.getBoolean("system_ui_remove_miui_multi_win_switch"));
+ initHook(DisableInfinitymodeGesture.INSTANCE, mPrefsMap.getBoolean("system_ui_disable_infinitymode_gesture"));
initHook(DisableBottomBar.INSTANCE, mPrefsMap.getBoolean("system_ui_disable_bottombar"));
initHook(UnlockClipboard.INSTANCE, mPrefsMap.getBoolean("system_ui_unlock_clipboard"));
diff --git a/app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemframework/StickyFloatingWindows.java b/app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemframework/StickyFloatingWindows.java
index cc707326dc..1bf05fe5cb 100644
--- a/app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemframework/StickyFloatingWindows.java
+++ b/app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemframework/StickyFloatingWindows.java
@@ -1,21 +1,21 @@
/*
- * This file is part of HyperCeiler.
+ * This file is part of HyperCeiler.
- * HyperCeiler is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License.
+ * HyperCeiler is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
- * Copyright (C) 2023-2024 HyperCeiler Contributions
-*/
+ * Copyright (C) 2023-2024 HyperCeiler Contributions
+ */
package com.sevtinge.hyperceiler.module.hook.systemframework;
import android.annotation.SuppressLint;
@@ -44,7 +44,6 @@ public class StickyFloatingWindows extends BaseHook {
@Override
public void init() {
-
final List fwBlackList = new ArrayList<>();
fwBlackList.add("com.miui.securitycenter");
fwBlackList.add("com.miui.home");
@@ -54,9 +53,16 @@ public void init() {
protected void after(MethodHookParam param) {
if (param.args.length != 8) return;
Intent intent = (Intent) param.args[5];
+ Object activityRecord = param.args[7];
+ Intent recordIntent = (Intent) XposedHelpers.getObjectField(activityRecord, "intent");
+ String recordPackageName = recordIntent.getComponent().getPackageName();
+ String packageName = intent.getComponent().getPackageName();
+ if (recordPackageName.equals(packageName)) {
+ // 如果是相同应用跳转就忽略,防止出现全屏应用跳转页面之后变成小窗的情况
+ return;
+ }
if (intent == null || intent.getComponent() == null) return;
ActivityOptions options = (ActivityOptions) param.getResult();
- int windowingMode = options == null ? -1 : (int) XposedHelpers.callMethod(options, "getLaunchWindowingMode");
String pkgName = intent.getComponent().getPackageName();
if (fwBlackList.contains(pkgName)) return;
Context mContext;
@@ -65,7 +71,7 @@ protected void after(MethodHookParam param) {
} catch (Throwable ignore) {
mContext = (Context) XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.args[0], "mService"), "mContext");
}
- if (windowingMode != 5 && fwApps.containsKey(pkgName)) {
+ if (fwApps.containsKey(pkgName)) {
try {
if (MiuiMultiWindowUtils == null) {
logE(TAG, StickyFloatingWindows.this.lpparam.packageName, "Cannot find MiuiMultiWindowUtils class");
@@ -76,36 +82,19 @@ protected void after(MethodHookParam param) {
} catch (Throwable t) {
logW(TAG, "", t);
}
- } else if (windowingMode == 5 && !fwApps.containsKey(pkgName)) {
- fwApps.put(pkgName, new Pair<>(0f, null));
- storeFwAppsInSetting(mContext);
}
}
});
hookAllMethods("com.android.server.wm.ActivityTaskSupervisor", "startActivityFromRecents", new MethodHook() {
- @Override
- protected void after(MethodHookParam param) {
- Object safeOptions = param.args[3];
- ActivityOptions options = (ActivityOptions) XposedHelpers.callMethod(safeOptions, "getOptions", param.thisObject);
- int windowingMode = options == null ? -1 : (int) XposedHelpers.callMethod(options, "getLaunchWindowingMode");
- String pkgName = getTaskPackageName(param.thisObject, (int) param.args[2], options);
- if (fwBlackList.contains(pkgName)) return;
- if (windowingMode == 5 && pkgName != null) {
- fwApps.put(pkgName, new Pair<>(0f, null));
- Context mContext = (Context) XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mService"), "mContext");
- storeFwAppsInSetting(mContext);
- }
- }
@Override
protected void before(MethodHookParam param) {
Object safeOptions = param.args[3];
ActivityOptions options = (ActivityOptions) XposedHelpers.callMethod(safeOptions, "getOptions", param.thisObject);
- int windowingMode = options == null ? -1 : (int) XposedHelpers.callMethod(options, "getLaunchWindowingMode");
String pkgName = getTaskPackageName(param.thisObject, (int) param.args[2], options);
if (fwBlackList.contains(pkgName)) return;
- if (windowingMode != 5 && fwApps.containsKey(pkgName)) {
+ if (fwApps.containsKey(pkgName)) {
Context mContext = (Context) XposedHelpers.getObjectField(XposedHelpers.getObjectField(param.thisObject, "mService"), "mContext");
options = patchActivityOptions(mContext, options, pkgName, MiuiMultiWindowUtils);
XposedHelpers.setObjectField(safeOptions, "mOriginalOptions", options);
@@ -184,6 +173,47 @@ public void onReceive(Context context, Intent intent) {
}
}
}, new IntentFilter("miui.intent.action_launch_fullscreen_from_freeform"));
+
+ IntentFilter mFilter = new IntentFilter();
+ mFilter.addAction(ACTION_PREFIX + "updateFwApps");
+ mFilter.addAction(ACTION_PREFIX + "getFwApps");
+ mFilter.addAction(ACTION_PREFIX + "removeFwApps");
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String pkgName = intent.getStringExtra("package");
+ switch (intent.getAction()) {
+ case ACTION_PREFIX + "updateFwApps":
+ float scale = intent.getFloatExtra("scale", 0f);
+ Rect rect = intent.getParcelableExtra("rect");
+ if (!fwApps.containsKey(pkgName)) {
+ fwApps.put(pkgName, new Pair<>(scale, rect));
+ storeFwAppsInSetting(context);
+ return;
+ }
+ Pair oldPair = fwApps.get(pkgName);
+ if (scale == 0f) {
+ scale = oldPair.first;
+ }
+ if (rect == null) {
+ rect = oldPair.second;
+ }
+ fwApps.put(pkgName, new Pair<>(scale, rect));
+ storeFwAppsInSetting(context);
+ break;
+ case ACTION_PREFIX + "getFwApps":
+ syncFwApps(context);
+ break;
+ case ACTION_PREFIX + "removeFwApps":
+ if (pkgName != null && fwApps.remove(pkgName) != null) {
+ storeFwAppsInSetting(context);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }, mFilter);
}
});
@@ -228,8 +258,8 @@ public static String getTaskPackageName(Object thisObject, int taskId, boolean w
Object mRootWindowContainer = XposedHelpers.getObjectField(thisObject, "mRootWindowContainer");
if (mRootWindowContainer == null) return null;
Object task = withOptions ?
- XposedHelpers.callMethod(mRootWindowContainer, "anyTaskForId", taskId, 2, options, true) :
- XposedHelpers.callMethod(mRootWindowContainer, "anyTaskForId", taskId, 0);
+ XposedHelpers.callMethod(mRootWindowContainer, "anyTaskForId", taskId, 2, options, true) :
+ XposedHelpers.callMethod(mRootWindowContainer, "anyTaskForId", taskId, 0);
if (task == null) return null;
Intent intent = (Intent) XposedHelpers.getObjectField(task, "intent");
return intent == null ? null : intent.getComponent().getPackageName();
@@ -260,7 +290,15 @@ public static void unserializeFwApps(String data) {
}
}
+ public static void syncFwApps(Context context) {
+ if (context == null) return;
+ Intent intent = new Intent(ACTION_PREFIX + "syncFwApps");
+ intent.putExtra("fwApps", serializeFwApps());
+ context.sendBroadcast(intent);
+ }
+
public static void storeFwAppsInSetting(Context context) {
+ syncFwApps(context);
Settings.Global.putString(context.getContentResolver(), ProjectApi.mAppModulePkg + ".fw.apps", serializeFwApps());
}
diff --git a/app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemui/DisableInfinitymodeGesture.kt b/app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemui/DisableInfinitymodeGesture.kt
new file mode 100644
index 0000000000..147176f700
--- /dev/null
+++ b/app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemui/DisableInfinitymodeGesture.kt
@@ -0,0 +1,17 @@
+package com.sevtinge.hyperceiler.module.hook.systemui
+
+import com.github.kyuubiran.ezxhelper.ClassUtils.loadClass
+import com.github.kyuubiran.ezxhelper.HookFactory.`-Static`.createHook
+import com.github.kyuubiran.ezxhelper.finders.MethodFinder.`-Static`.methodFinder
+import com.sevtinge.hyperceiler.module.base.*
+
+
+object DisableInfinitymodeGesture : BaseHook() {
+ override fun init() {
+ loadClass(
+ "com.android.wm.shell.miuifreeform.MiuiInfinityModeSizesPolicy",
+ ).methodFinder().filterByName("isForbiddenWindow").single().createHook {
+ returnConstant(true)
+ }
+ }
+}
diff --git a/app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemui/StickyFloatingWindowsForSystemUI.kt b/app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemui/StickyFloatingWindowsForSystemUI.kt
new file mode 100644
index 0000000000..abae863d90
--- /dev/null
+++ b/app/src/main/java/com/sevtinge/hyperceiler/module/hook/systemui/StickyFloatingWindowsForSystemUI.kt
@@ -0,0 +1,168 @@
+package com.sevtinge.hyperceiler.module.hook.systemui
+
+import android.annotation.*
+import android.app.*
+import android.content.*
+import android.graphics.*
+import android.util.*
+import com.github.kyuubiran.ezxhelper.ClassUtils.loadClass
+import com.github.kyuubiran.ezxhelper.HookFactory.`-Static`.createHook
+import com.github.kyuubiran.ezxhelper.finders.MethodFinder.`-Static`.methodFinder
+import com.sevtinge.hyperceiler.module.base.*
+import com.sevtinge.hyperceiler.module.base.tool.OtherTool.*
+import com.sevtinge.hyperceiler.utils.*
+import java.util.concurrent.*
+
+
+class StickyFloatingWindowsForSystemUI : BaseHook() {
+ private val fwApps: ConcurrentHashMap> = ConcurrentHashMap()
+
+ private fun updateFwApps(context: Context, pkgName: String?, scale: Float?, rect: Rect?) {
+ val intent = Intent(ACTION_PREFIX + "updateFwApps")
+ if (pkgName != null) {
+ intent.putExtra("package", pkgName)
+ }
+ if (scale != null) {
+ intent.putExtra("scale", scale)
+ }
+ if (rect != null) {
+ intent.putExtra("rect", rect)
+ }
+ context.sendBroadcast(intent)
+ }
+
+ private fun addFwApps(context: Context, pkgName: String) {
+ updateFwApps(context, pkgName, null, null)
+ }
+
+ private fun removeFwApps(context: Context, pkgName: String) {
+ val intent = Intent(ACTION_PREFIX + "removeFwApps")
+ intent.putExtra("package", pkgName)
+ context.sendBroadcast(intent)
+ }
+
+
+ fun unserializeFwApps(data: String?) {
+ if (data.isNullOrEmpty()) return
+ fwApps.clear()
+ val dataArr = data.split("|")
+ for (appData in dataArr) {
+ if ("" == appData) continue
+ val appDataArr = appData.split(":")
+ fwApps[appDataArr[0]] = Pair(
+ appDataArr[1].toFloat(),
+ if ("-" == appDataArr[2]) null else Rect.unflattenFromString(appDataArr[2])
+ )
+ }
+ }
+ private val fwBlackList: List = listOf("com.miui.securitycenter", "com.miui.home")
+
+ @SuppressLint("UnspecifiedRegisterReceiverFlag")
+ override fun init() {
+
+ findContext(FLAG_ALL).registerReceiver(
+ object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ val extra = intent.getStringExtra("fwApps")
+ unserializeFwApps(extra)
+ logI(TAG, lpparam.packageName, "unserializeFwApps: $extra")
+ }
+ },
+ IntentFilter(ACTION_PREFIX + "syncFwApps")
+ )
+
+ loadClass(
+ "com.android.wm.shell.miuifreeform.MiuiInfinityModeTaskOperations",
+ ).methodFinder().filterByName("resizedTask").single().createHook {
+ after {
+ val taskWrapperInfo = it.args[0]
+ val scale = taskWrapperInfo.callMethod("getDestinationNormalScale") as Float
+ val rect = taskWrapperInfo.callMethod("getDestinationBounds") as Rect
+ val taskInfo = taskWrapperInfo.callMethod("getTaskInfo") as TaskInfo
+ val pkgName = taskInfo.baseIntent.component!!.packageName
+ val context = it.thisObject.getObjectField("mContext") as Context
+ logI(TAG, lpparam.packageName, "resizedTask: $pkgName, $scale, $rect")
+ if (fwApps.containsKey(pkgName)) {
+ updateFwApps(context, pkgName, scale, rect)
+ }
+ }
+ }
+ loadClass(
+ "com.android.wm.shell.miuifreeform.MiuiInfinityModeTaskOperations",
+ ).methodFinder().filterByName("setFreeformDestBoundsAndScale").single().createHook {
+ after {
+ val pkgName = it.args[0].getObjectField("mPackageName").toString()
+ val rect = it.args[1] as Rect
+ val scale = it.args[2] as Float
+ val context = it.thisObject.getObjectField("mContext") as Context
+ logI(
+ TAG,
+ lpparam.packageName,
+ "setFreeformDestBoundsAndScale: $pkgName, $scale, $rect"
+ )
+ updateFwApps(context, pkgName, scale, rect)
+ }
+ }
+ loadClass(
+ "com.android.wm.shell.miuifreeform.MiuiFreeformModeTaskInfo",
+ ).methodFinder().filterByName("setBounds").single().createHook {
+ after {
+ val rect = it.args[0] as Rect? ?: return@after
+ val mMode = it.thisObject.getObjectField("mMode") as Int
+ if (mMode != 0) return@after
+ val taskInfo =
+ it.thisObject.callMethod("getState")!!.getObjectField("mTaskInfo") as TaskInfo
+ val pkgName = taskInfo.baseIntent.component!!.packageName
+ val context = it.thisObject.getObjectField("mContext") as Context
+ logI(TAG, lpparam.packageName, "setBounds: $pkgName, $rect")
+ updateFwApps(context, pkgName, null, rect)
+ }
+ }
+ loadClass(
+ "com.android.wm.shell.miuifreeform.MiuiFreeformModeTaskInfo",
+ ).methodFinder().filterByName("setScale").single().createHook {
+ after {
+ val scale = it.args[0] as Float
+ if (scale.isNaN()) return@after
+ val mMode = it.thisObject.getObjectField("mMode") as Int
+ if (mMode != 0) return@after
+ if (!(it.thisObject.callMethod("isExiting") as Boolean)) return@after
+ val taskInfo =
+ it.thisObject.callMethod("getState")!!.getObjectField("mTaskInfo") as TaskInfo
+ val pkgName = taskInfo.baseIntent.component!!.packageName
+ val context = it.thisObject.getObjectField("mContext") as Context
+ logI(TAG, lpparam.packageName, "setScale: $pkgName, $scale")
+
+ updateFwApps(context, pkgName, scale, null)
+ }
+ }
+ loadClass(
+ "com.android.wm.shell.miuimultiwinswitch.miuiwindowdecor.MiuiBaseWindowDecoration",
+ ).methodFinder().filterByName("updateViews").single().createHook {
+ before {
+ val taskInfo =
+ it.thisObject.getObjectField("mTaskInfo") as ActivityManager.RunningTaskInfo
+
+ val pkgName = taskInfo.baseActivity?.packageName
+ if (pkgName.isNullOrBlank()) return@before
+ if (fwBlackList.contains(pkgName)) return@before
+ if (!taskInfo.getBooleanField("isFocused")) return@before
+ val windowingMode = taskInfo.callMethod("getWindowingMode") as Int
+ val context = it.thisObject.getObjectField("mContext") as Context
+ if (windowingMode == 5) {
+ // 小窗
+ if (!fwApps.containsKey(pkgName)) {
+ logI(TAG, lpparam.packageName, "shouldHideCaption: add $pkgName")
+ addFwApps(context, pkgName)
+ }
+ } else if (windowingMode == 1) {
+ // 全屏
+ if (fwApps.containsKey(pkgName)) {
+ logI(TAG, lpparam.packageName, "shouldHideCaption: remove $pkgName")
+ removeFwApps(context, pkgName)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/sevtinge/hyperceiler/ui/fragment/systemui/SystemUIOtherSettings.java b/app/src/main/java/com/sevtinge/hyperceiler/ui/fragment/systemui/SystemUIOtherSettings.java
index e6170a54e6..9aeb75de2a 100644
--- a/app/src/main/java/com/sevtinge/hyperceiler/ui/fragment/systemui/SystemUIOtherSettings.java
+++ b/app/src/main/java/com/sevtinge/hyperceiler/ui/fragment/systemui/SystemUIOtherSettings.java
@@ -44,6 +44,7 @@ public class SystemUIOtherSettings extends SettingsPreferenceFragment {
PreferenceCategory mChargeAnimationTitle;
SwitchPreference mMiuiMultiWinSwitch;
SwitchPreference mMiuiMultiWinSwitchRemove;
+ SwitchPreference mDisableInfinitymodeGesture;
SwitchPreference mBottomBar;
SwitchPreference mVolume;
SwitchPreference mPower;
@@ -70,6 +71,7 @@ public void initPrefs() {
mDisableBluetoothRestrict = findPreference("prefs_key_system_ui_disable_bluetooth_restrict");
mMiuiMultiWinSwitch = findPreference("prefs_key_system_ui_disable_miui_multi_win_switch");
mMiuiMultiWinSwitchRemove = findPreference("prefs_key_system_ui_remove_miui_multi_win_switch");
+ mDisableInfinitymodeGesture = findPreference("prefs_key_system_ui_disable_infinitymode_gesture");
mBottomBar = findPreference("prefs_key_system_ui_disable_bottombar");
mVolume = findPreference("prefs_key_system_ui_disable_volume");
mPower = findPreference("prefs_key_system_ui_disable_power");
@@ -79,6 +81,7 @@ public void initPrefs() {
mDisableBluetoothRestrict.setVisible(isMiuiVersion(14f) && isMoreAndroidVersion(31));
mMiuiMultiWinSwitch.setVisible(isMoreHyperOSVersion(1f) && isMoreAndroidVersion(34));
mMiuiMultiWinSwitchRemove.setVisible(isMoreHyperOSVersion(1f) && isMoreAndroidVersion(34) && isPad());
+ mDisableInfinitymodeGesture.setVisible(isMoreHyperOSVersion(1f) && isMoreAndroidVersion(34) && isPad());
mBottomBar.setVisible(isMoreHyperOSVersion(1f) && isMoreAndroidVersion(34));
mPctUseBlur.setVisible(isMoreHyperOSVersion(1f));
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 5879194f2f..c51969aa7d 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -356,7 +356,7 @@
多小窗
强制允许小窗
忽略系统黑名单与软件禁用小窗
- 记住状态
+ 记住状态及位置
小窗气泡
将所有小窗转为迷你小窗
在最近任务中将所有小窗转为迷你小窗显示\n此功能为实验性功能,具有较高不稳定性
@@ -909,6 +909,8 @@
禁用蓝牙临时关闭
隐藏快捷窗口按钮
禁用快捷窗口按钮
+ 禁用无极缩放手势
+ 仅供平板使用
隐藏常驻的三个小点,包括小窗顶部和 HyperOS for Pad 横屏顶部中间的按钮 (不影响功能使用)
隐藏小窗的手势提示线
更多应用通知栏下拉打开小窗
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 82fead650f..5286174006 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -352,7 +352,7 @@
Multiple freeform
Force small freeform to be allowed
Ignore the system blacklist and software ban freeform
- Remember state
+ Remember state and position
Bubble freeform
Turn all freeform into mini freeform
Turn all freeform into mini freeform in recent tasks\nThis feature is an experimental feature with high instability
@@ -889,6 +889,8 @@
Hide the Convenience Window button
Hide the three permanent dots, including the top of the small window and the button in the middle of the top of the HyperOS for Pad horizontal screen (does not affect the use of functions)
Disable the Convenience Window button
+ Disable infinite zoom gestures
+ For tablet use only
Hide the bottom gesture of the small window
Data display
Displays the brightness percentage
diff --git a/app/src/main/res/xml/system_ui_other.xml b/app/src/main/res/xml/system_ui_other.xml
index 80fa966ee3..4c678bc82e 100644
--- a/app/src/main/res/xml/system_ui_other.xml
+++ b/app/src/main/res/xml/system_ui_other.xml
@@ -86,10 +86,16 @@
android:title="@string/system_ui_disable_miui_multi_win_switch" />
+
+