From 6b4cf27e025eca3d4fc66eb8eecff885c6d45c7c Mon Sep 17 00:00:00 2001 From: maelstrom Date: Sat, 11 Jul 2026 16:09:53 +0200 Subject: [PATCH] feat: disable expressive motion springs and animations for quick tiles --- .../drdisagree/iconify/data/keys/XposedKey.kt | 1 + .../main/screens/QuickSettingsScreen.kt | 7 ++++ .../modules/quicksettings/QuickSettings.kt | 40 +++++++++++++++++++ app/src/main/res/values/strings.xml | 2 + 4 files changed, 50 insertions(+) diff --git a/app/src/main/java/com/drdisagree/iconify/data/keys/XposedKey.kt b/app/src/main/java/com/drdisagree/iconify/data/keys/XposedKey.kt index e6dcd58df..85f399eab 100644 --- a/app/src/main/java/com/drdisagree/iconify/data/keys/XposedKey.kt +++ b/app/src/main/java/com/drdisagree/iconify/data/keys/XposedKey.kt @@ -102,6 +102,7 @@ enum class XposedKey(override val default: Any?) : Key { COMPACT_MEDIA_PLAYER(false), BLUR_MEDIA_PLAYER_ARTWORK(false), BLUR_MEDIA_PLAYER_ARTWORK_RADIUS(60f), + DISABLE_QS_EXPRESSIVE_EFFECTS(false), HIDE_QS_SILENT_TEXT(false), HIDE_QS_FOOTER_BUTTONS(false), QS_PANEL_HIDE_CARRIER(false), diff --git a/app/src/main/java/com/drdisagree/iconify/features/xposed/quicksettings/main/screens/QuickSettingsScreen.kt b/app/src/main/java/com/drdisagree/iconify/features/xposed/quicksettings/main/screens/QuickSettingsScreen.kt index f3cd628c9..e2246ff73 100644 --- a/app/src/main/java/com/drdisagree/iconify/features/xposed/quicksettings/main/screens/QuickSettingsScreen.kt +++ b/app/src/main/java/com/drdisagree/iconify/features/xposed/quicksettings/main/screens/QuickSettingsScreen.kt @@ -164,6 +164,12 @@ val quickSettingsPreferences = preferenceScreen { } category(title = stringRes(R.string.section_title_qs_elements)) { + switch( + key = XposedKey.DISABLE_QS_EXPRESSIVE_EFFECTS, + title = stringRes(R.string.disable_qs_expressive_effects_title), + summary = { stringRes(R.string.disable_qs_expressive_effects_desc) }, + ) + switch( key = XposedKey.HIDE_QS_SILENT_TEXT, title = stringRes(R.string.hide_qs_silent_text_title), @@ -222,6 +228,7 @@ fun QuickSettingsScreen( XposedKey.NOTIFICATION_HEADS_UP_BLUR.name, XposedKey.COMPACT_MEDIA_PLAYER.name, XposedKey.BLUR_MEDIA_PLAYER_ARTWORK.name, + XposedKey.DISABLE_QS_EXPRESSIVE_EFFECTS.name, XposedKey.HIDE_QS_SILENT_TEXT.name, XposedKey.HIDE_QS_FOOTER_BUTTONS.name, XposedKey.QS_PANEL_HIDE_CARRIER.name, diff --git a/app/src/main/java/com/drdisagree/iconify/xposed/modules/quicksettings/QuickSettings.kt b/app/src/main/java/com/drdisagree/iconify/xposed/modules/quicksettings/QuickSettings.kt index 636ee4636..6e295306e 100644 --- a/app/src/main/java/com/drdisagree/iconify/xposed/modules/quicksettings/QuickSettings.kt +++ b/app/src/main/java/com/drdisagree/iconify/xposed/modules/quicksettings/QuickSettings.kt @@ -36,6 +36,7 @@ import com.drdisagree.iconify.xposed.modules.extras.utils.toolkit.setExtraField import com.drdisagree.iconify.xposed.modules.extras.utils.toolkit.setField import com.drdisagree.iconify.xposed.modules.extras.utils.toolkit.setFieldSilently import com.drdisagree.iconify.xposed.utils.XPrefs.Xprefs +import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam @SuppressLint("DiscouragedApi") @@ -44,6 +45,7 @@ class QuickSettings(context: Context) : ModPack(context) { private var fixNotificationColor = true private var fixNotificationFooterButtonsColor = true private var fixNotificationExpandButtonColor = true + private var disableExpressiveEffects = false private var hideSilentText = false private var hideFooterButtons = false private var qqsTopMarginPort = 100 @@ -68,6 +70,7 @@ class QuickSettings(context: Context) : ModPack(context) { getBoolean(XposedKey.FIX_NOTIFICATION_FOOTER_BUTTON_COLOR) fixNotificationExpandButtonColor = getBoolean(XposedKey.FIX_NOTIFICATION_EXPAND_BUTTON_COLOR) + disableExpressiveEffects = getBoolean(XposedKey.DISABLE_QS_EXPRESSIVE_EFFECTS) hideSilentText = getBoolean(XposedKey.HIDE_QS_SILENT_TEXT) hideFooterButtons = getBoolean(XposedKey.HIDE_QS_FOOTER_BUTTONS) compactMediaPlayerEnabled = getBoolean(XposedKey.COMPACT_MEDIA_PLAYER) @@ -84,6 +87,43 @@ class QuickSettings(context: Context) : ModPack(context) { manageQsElementVisibility() compactMediaPlayer() blurMediaPlayerArtwork() + setQsExpressiveness() + } + + private fun setQsExpressiveness() { + val inTileBounceableLambda = ThreadLocal() + inTileBounceableLambda.set(false) + + val tileBounceableLambdaClass = findClass("$SYSTEMUI_PACKAGE.qs.panels.ui.compose.infinitegrid.TileKt\$\$ExternalSyntheticLambda2") + tileBounceableLambdaClass.hookMethod("invoke").runBefore { + if (!disableExpressiveEffects) return@runBefore + inTileBounceableLambda.set(true) + }.runAfter { + inTileBounceableLambda.set(false) + } + + val bounceableClass = + findClass("com.android.compose.animation.BounceableKt") + bounceableClass.hookMethod($$"bounceable$default") + .runAfter { param -> + if (!inTileBounceableLambda.get()!!) return@runAfter + param.result = param.args[0] + } + + val tileDefaultsClass = findClass("$SYSTEMUI_PACKAGE.qs.panels.ui.compose.infinitegrid.TileDefaults") + tileDefaultsClass.hookMethod("animateTileShapeAsState") + .run(object : XC_MethodHook() { + private val prevState = ThreadLocal() + + override fun beforeHookedMethod(param: MethodHookParam) { + prevState.set(param.args[0].getFieldSilently("visualState") as? Int ?: return) + param.args[0].setFieldSilently("visualState", 1 /* STATE_INACTIVE */) + } + + override fun afterHookedMethod(param: MethodHookParam) { + param.args[0].setFieldSilently("visualState", prevState.get() ?: return) + } + }) } private fun setQsMargin() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a08ffbdc7..c992b219d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -659,6 +659,8 @@ Disable quick settings panel on secured lockscreen Disable QS on Lockscreen Disable quick settings tiles on secured lockscreen + Disable Expressive Effects + Disables the rounding and bounce effects when a tile is pressed Hide Silent Text Hide silent text shown as header of silent notifications Hide Footer Buttons