Skip to content

Commit 1a4bef4

Browse files
Implement Disable{Snap,Fling}ToDismiss
1 parent f905676 commit 1a4bef4

File tree

8 files changed

+141
-0
lines changed

8 files changed

+141
-0
lines changed

SplitScreenMods/Readme.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ Keep the split ratio while swapping sides.
2525

2626
Disable the swapping animation.
2727

28+
## DisableSnapToDismiss / DisableFlingToDismiss
29+
30+
Disable leaving the split by dragging the divider to the edge.
31+
2832
## SnapMode
2933

3034
Change the snap mode used by the system:

SplitScreenMods/src/main/assets/xposed_init

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ com.programminghoch10.SplitScreenMods.AdditionalSnapTargetsHook
22
com.programminghoch10.SplitScreenMods.AlwaysAllowMultiInstanceSplitHook
33
com.programminghoch10.SplitScreenMods.CalculateRatiosHook
44
com.programminghoch10.SplitScreenMods.CustomFixedRatioHook
5+
com.programminghoch10.SplitScreenMods.DisableFlingToDismissHook
6+
com.programminghoch10.SplitScreenMods.DisableSnapToDismissHook
57
com.programminghoch10.SplitScreenMods.DisableSwapAnimationHook
68
com.programminghoch10.SplitScreenMods.FreeSnapHook
79
com.programminghoch10.SplitScreenMods.KeepSplitScreenRatioHook
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.programminghoch10.SplitScreenMods
2+
3+
import android.os.Build
4+
import com.programminghoch10.SplitScreenMods.BuildConfig.SHARED_PREFERENCES_NAME
5+
import com.programminghoch10.SplitScreenMods.DisableFlingToDismissHookConfig.enabled
6+
import de.binarynoise.logger.Logger.log
7+
import de.robv.android.xposed.IXposedHookLoadPackage
8+
import de.robv.android.xposed.XC_MethodHook
9+
import de.robv.android.xposed.XSharedPreferences
10+
import de.robv.android.xposed.XposedBridge
11+
import de.robv.android.xposed.XposedHelpers
12+
import de.robv.android.xposed.callbacks.XC_LoadPackage
13+
14+
object DisableFlingToDismissHookConfig {
15+
val enabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
16+
}
17+
18+
class DisableFlingToDismissHook : IXposedHookLoadPackage {
19+
20+
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
21+
if (lpparam.packageName != "com.android.systemui") return
22+
if (!enabled) return
23+
log("handleLoadPackage(${lpparam.packageName} in process ${lpparam.processName})")
24+
val preferences = XSharedPreferences(BuildConfig.APPLICATION_ID, SHARED_PREFERENCES_NAME)
25+
val enabled = preferences.getBoolean("DisableFlingToDismiss", false)
26+
if (!enabled) return
27+
28+
val DividerSnapAlgorithmClass = XposedHelpers.findClass("com.android.wm.shell.common.split.DividerSnapAlgorithm", lpparam.classLoader)
29+
XposedBridge.hookAllConstructors(DividerSnapAlgorithmClass, object : XC_MethodHook() {
30+
override fun afterHookedMethod(param: MethodHookParam) {
31+
log("disabling dismiss targets")
32+
XposedHelpers.setObjectField(
33+
param.thisObject,
34+
"mDismissStartTarget",
35+
XposedHelpers.getObjectField(param.thisObject, "mFirstSplitTarget"),
36+
)
37+
XposedHelpers.setObjectField(
38+
param.thisObject,
39+
"mDismissEndTarget",
40+
XposedHelpers.getObjectField(param.thisObject, "mLastSplitTarget"),
41+
)
42+
}
43+
})
44+
}
45+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.programminghoch10.SplitScreenMods
2+
3+
import android.os.Build
4+
import com.programminghoch10.SplitScreenMods.BuildConfig.SHARED_PREFERENCES_NAME
5+
import com.programminghoch10.SplitScreenMods.DisableSnapToDismissHookConfig.enabled
6+
import de.binarynoise.logger.Logger.log
7+
import de.robv.android.xposed.IXposedHookLoadPackage
8+
import de.robv.android.xposed.XC_MethodHook
9+
import de.robv.android.xposed.XSharedPreferences
10+
import de.robv.android.xposed.XposedBridge
11+
import de.robv.android.xposed.XposedHelpers
12+
import de.robv.android.xposed.callbacks.XC_LoadPackage
13+
14+
object DisableSnapToDismissHookConfig {
15+
val enabled = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE
16+
}
17+
18+
class DisableSnapToDismissHook : IXposedHookLoadPackage {
19+
20+
fun isDismissTarget(snapPosition: Int): Boolean {
21+
log("isDismissTarget($snapPosition) = ${snapPosition == SNAP_TO_START_AND_DISMISS || snapPosition == SNAP_TO_END_AND_DISMISS}")
22+
return snapPosition == SNAP_TO_START_AND_DISMISS || snapPosition == SNAP_TO_END_AND_DISMISS
23+
}
24+
25+
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
26+
if (lpparam.packageName != "com.android.systemui") return
27+
if (!enabled) return
28+
log("handleLoadPackage(${lpparam.packageName} in process ${lpparam.processName})")
29+
val preferences = XSharedPreferences(BuildConfig.APPLICATION_ID, SHARED_PREFERENCES_NAME)
30+
val enabled = preferences.getBoolean("DisableSnapToDismiss", false)
31+
if (!enabled) return
32+
33+
val DividerSnapAlgorithmClass = XposedHelpers.findClass("com.android.wm.shell.common.split.DividerSnapAlgorithm", lpparam.classLoader)
34+
XposedBridge.hookAllConstructors(DividerSnapAlgorithmClass, object : XC_MethodHook() {
35+
override fun afterHookedMethod(param: MethodHookParam) {
36+
val mTargets = XposedHelpers.getObjectField(param.thisObject, "mTargets") as ArrayList<Any?>
37+
if (mTargets.isEmpty()) return
38+
log("filtering snap targets")
39+
val filteredTargets = mTargets.filter { !isDismissTarget(XposedHelpers.getIntField(it, "snapPosition")) }
40+
XposedHelpers.setObjectField(param.thisObject, "mTargets", filteredTargets)
41+
}
42+
})
43+
}
44+
}

SplitScreenMods/src/main/java/com/programminghoch10/SplitScreenMods/SettingsActivity.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ class SettingsActivity : FragmentActivity() {
4141
val keepSplitScreenRatioPreference = preferenceScreen.findPreference<SwitchPreference>("KeepSplitScreenRatio")!!
4242
val keepSwapRatioPreference = preferenceScreen.findPreference<SwitchPreference>("KeepSwapRatio")!!
4343
val disableSwapAnimationPreference = preferenceScreen.findPreference<SwitchPreference>("DisableSwapAnimation")!!
44+
val disableSnapToDismissPreference = preferenceScreen.findPreference<SwitchPreference>("DisableSnapToDismiss")!!
45+
val disableFlingToDismissPreference = preferenceScreen.findPreference<SwitchPreference>("DisableFlingToDismiss")!!
46+
val disabledEdgeDismissNoticePreference = preferenceScreen.findPreference<Preference>("DisabledEdgeDismissNotice")!!
4447
val snapModePreference = preferenceScreen.findPreference<ListPreference>("SnapMode")!!
4548
val freeSnapPreference = preferenceScreen.findPreference<SwitchPreference>("FreeSnap")!!
4649
val snapTargetsPreference = preferenceScreen.findPreference<ListPreference>("SnapTargets")!!
@@ -53,6 +56,10 @@ class SettingsActivity : FragmentActivity() {
5356
keepSplitScreenRatioPreference.setEnabledAndVisible(KeepSplitScreenRatioHookConfig.enabled)
5457
keepSwapRatioPreference.setEnabledAndVisible(KeepSwapRatioHookConfig.enabled)
5558
disableSwapAnimationPreference.setEnabledAndVisible(DisableSwapAnimationHookConfig.enabled || keepSwapRatioPreference.isEnabledAndChecked)
59+
disableSnapToDismissPreference.setEnabledAndVisible(DisableSnapToDismissHookConfig.enabled)
60+
disableFlingToDismissPreference.setEnabledAndVisible(DisableFlingToDismissHookConfig.enabled)
61+
disabledEdgeDismissNoticePreference.isVisible =
62+
listOf(disableFlingToDismissPreference, disableSnapToDismissPreference).filter { it.isEnabled }.allOrFalse { it.isChecked }
5663
snapModePreference.setEnabledAndVisible(SnapModeHookConfig.enabled)
5764
val is1_1SnapMode = snapModePreference.value == SNAP_MODE.SNAP_ONLY_1_1.key
5865
val isFixedRatioSnapMode = snapModePreference.value == SNAP_MODE.SNAP_FIXED_RATIO.key
@@ -99,3 +106,11 @@ fun Preference.setEnabledAndVisible(enabled: Boolean) {
99106
this.isEnabled = enabled
100107
this.isVisible = enabled
101108
}
109+
110+
/**
111+
* Same as [Iterable.all], but returns false on empty Collections
112+
*/
113+
inline fun <T> Iterable<T>.allOrFalse(predicate: (T) -> Boolean): Boolean {
114+
if (this is Collection && isEmpty()) return false
115+
return this.all(predicate)
116+
}

SplitScreenMods/src/main/res/values/strings.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,13 @@
4242
<string name="KeepSwapRatio_summary">Keep split ratio when swapping sides.</string>
4343
<string name="DisableSwapAnimation_title">DisableSwapAnimation</string>
4444
<string name="DisableSwapAnimation_summary">Disable swapping animation.</string>
45+
<string name="DisableSnapToDismiss_title">DisableSnapToDismiss</string>
46+
<string name="DisableSnapToDismiss_summary">Disable snap to dismiss.</string>
47+
<string name="DisableFlingToDismiss_title">DisableFlingToDismiss</string>
48+
<string name="DisableFlingToDismiss_summary">Disable fling to dismiss.</string>
49+
<string name="DisabledEdgeDismissNotice">
50+
Please note that you can only exit the SplitScreen
51+
by exiting the app by going back
52+
or by closing the SplitScreen entirely from the overview.
53+
</string>
4554
</resources>

SplitScreenMods/src/main/res/xml/root_preferences.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,24 @@
3030
app:summary="@string/DisableSwapAnimation_summary"
3131
app:title="@string/DisableSwapAnimation_title"
3232
/>
33+
<SwitchPreference
34+
app:iconSpaceReserved="false"
35+
app:key="DisableSnapToDismiss"
36+
app:summary="@string/DisableSnapToDismiss_summary"
37+
app:title="@string/DisableSnapToDismiss_title"
38+
/>
39+
<SwitchPreference
40+
app:iconSpaceReserved="false"
41+
app:key="DisableFlingToDismiss"
42+
app:summary="@string/DisableFlingToDismiss_summary"
43+
app:title="@string/DisableFlingToDismiss_title"
44+
/>
45+
<Preference
46+
app:iconSpaceReserved="false"
47+
app:key="DisabledEdgeDismissNotice"
48+
app:selectable="false"
49+
app:summary="@string/DisabledEdgeDismissNotice"
50+
/>
3351
</PreferenceCategory>
3452
<PreferenceCategory
3553
app:iconSpaceReserved="false"

metadata/com.programminghoch10.SplitScreenMods/en-US/full_description.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ Keep the split ratio while swapping sides.
3232

3333
Disable the swapping animation.
3434

35+
## DisableSnapToDismiss / DisableFlingToDismiss
36+
37+
Disable leaving the split by dragging the divider to the edge.
38+
3539
## SnapMode
3640

3741
Change the snap mode used by the system:

0 commit comments

Comments
 (0)