From 608d73706a247597ff8fe77adb54af95ac220f1a Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Sun, 26 Feb 2023 00:12:56 +0100 Subject: [PATCH] Add fake splash screen for launching apps by gestures --- .../ui/component/FakeSplashScreen.kt | 161 ++++++++++++++++++ .../launcher2/ui/gestures/GestureDetector.kt | 3 + .../launcher2/ui/gestures/GestureHandler.kt | 5 + .../ui/launcher/LauncherScaffoldVM.kt | 59 ++++--- .../ui/launcher/SharedLauncherActivity.kt | 3 +- .../gestures/LauncherGestureHandler.kt | 147 +++++++++++++++- .../search/common/SearchableItemVM.kt | 3 - .../mm20/launcher2/search/data/LauncherApp.kt | 3 + 8 files changed, 357 insertions(+), 27 deletions(-) create mode 100644 app/ui/src/main/java/de/mm20/launcher2/ui/component/FakeSplashScreen.kt diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/component/FakeSplashScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/component/FakeSplashScreen.kt new file mode 100644 index 00000000..f11ea1fc --- /dev/null +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/component/FakeSplashScreen.kt @@ -0,0 +1,161 @@ +package de.mm20.launcher2.ui.component + +import android.content.Context +import android.graphics.drawable.Drawable +import android.util.TypedValue +import androidx.compose.animation.animateColorAsState +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.core.content.ContextCompat +import coil.compose.AsyncImage +import de.mm20.launcher2.ktx.isAtLeastApiLevel +import de.mm20.launcher2.search.SavableSearchable +import de.mm20.launcher2.search.data.LauncherApp +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +@Composable +fun FakeSplashScreen( + modifier: Modifier = Modifier, + searchable: SavableSearchable? = null +) { + val splashScreenData = rememberSplashScreenData(searchable) + + val animatedBackgroundColor by animateColorAsState(splashScreenData.backgroundColor) + + Surface( + modifier = modifier + .fillMaxSize(), + shadowElevation = 4.dp, + color = animatedBackgroundColor, + ) { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center, + ) { + AsyncImage( + modifier = Modifier.size(288.dp), + model = splashScreenData.icon, + contentDescription = null + ) + AsyncImage( + modifier = Modifier + .padding(bottom = 60.dp) + .width(200.dp) + .height(80.dp) + .align(Alignment.BottomCenter), + model = splashScreenData.brandingIcon, + contentDescription = null + ) + } + } +} + +data class SplashScreenData( + val backgroundColor: Color, + val icon: Drawable? = null, + val brandingIcon: Drawable? = null, + val iconBackground: Color? = null, +) + +@Composable +fun rememberSplashScreenData(searchable: SavableSearchable?): SplashScreenData { + val context = LocalContext.current + val defaultBackgroundColor = MaterialTheme.colorScheme.background + val state = remember { + mutableStateOf(SplashScreenData(backgroundColor = defaultBackgroundColor)) + } + + LaunchedEffect(searchable) { + withContext(Dispatchers.IO) { + if (searchable is LauncherApp && isAtLeastApiLevel(31)) { + val activityInfo = searchable.launcherActivityInfo.activityInfo + val themeRes = activityInfo.themeResource + val ctx = context.createPackageContext( + searchable.`package`, + Context.CONTEXT_IGNORE_SECURITY + ) + ctx.setTheme(themeRes) + + val theme = ctx.theme + + val typedValue = TypedValue() + theme.resolveAttribute( + android.R.attr.windowSplashScreenBackground, + typedValue, + true + ) + if (!typedValue.isColorType || typedValue.data == 0) { + theme.resolveAttribute( + android.R.attr.windowBackground, + typedValue, + true + ) + } + if (!typedValue.isColorType || typedValue.data == 0) { + theme.resolveAttribute( + android.R.attr.colorBackground, + typedValue, + true + ) + } + if (!typedValue.isColorType || typedValue.data == 0) { + theme.resolveAttribute( + android.R.attr.background, + typedValue, + true + ) + } + val backgroundColor = typedValue.takeIf { it.isColorType && it.data != 0 }?.data + + theme.resolveAttribute( + android.R.attr.windowSplashScreenAnimatedIcon, + typedValue, + true + ) + + val icon = if (typedValue.resourceId != 0) { + ContextCompat.getDrawable(ctx, typedValue.resourceId) + } else { + null + } + + theme.resolveAttribute( + android.R.attr.windowSplashScreenBrandingImage, + typedValue, + true + ) + + val brandingIcon = if (typedValue.resourceId != 0) { + ContextCompat.getDrawable(ctx, typedValue.resourceId) + } else { + null + } + + state.value = SplashScreenData( + backgroundColor = backgroundColor?.let { Color(it) } ?: defaultBackgroundColor, + icon = icon, + brandingIcon = brandingIcon + ) + } + } + } + + return state.value +} \ No newline at end of file diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/gestures/GestureDetector.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/gestures/GestureDetector.kt index b95a7a29..fe333c4d 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/gestures/GestureDetector.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/gestures/GestureDetector.kt @@ -38,6 +38,7 @@ class GestureDetector { dragStart = null currentDrag = null hasDragEnded = false + gestureListener?.onDragEnd() } @@ -51,6 +52,8 @@ class GestureDetector { * The gesture detector will no longer track the drag gesture in this case. */ fun onDrag(offset: Offset): Boolean = false + + fun onDragEnd() {} } } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/gestures/GestureHandler.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/gestures/GestureHandler.kt index 3b6407f6..2c7de12d 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/gestures/GestureHandler.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/gestures/GestureHandler.kt @@ -11,6 +11,7 @@ fun GestureHandler( onLongPress: (Offset) -> Unit = {}, onDoubleTap: (Offset) -> Unit = {}, onDrag: (Offset) -> Boolean = { false }, + onDragEnd: () -> Unit = {}, ) { DisposableEffect(detector) { detector.gestureListener = object : GestureDetector.OnGestureListener { @@ -29,6 +30,10 @@ fun GestureHandler( override fun onDrag(offset: Offset): Boolean { return onDrag(offset) } + + override fun onDragEnd() { + onDragEnd() + } } onDispose { detector.gestureListener = null diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt index 43545dc7..110a0690 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt @@ -1,5 +1,6 @@ package de.mm20.launcher2.ui.launcher +import android.app.ActivityOptions import android.content.Context import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -15,6 +16,7 @@ import de.mm20.launcher2.permissions.PermissionsManager import de.mm20.launcher2.preferences.LauncherDataStore import de.mm20.launcher2.preferences.Settings import de.mm20.launcher2.preferences.Settings.GestureSettings.GestureAction +import de.mm20.launcher2.preferences.Settings.LayoutSettings.Layout import de.mm20.launcher2.search.SavableSearchable import de.mm20.launcher2.ui.gestures.Gesture import kotlinx.coroutines.flow.MutableStateFlow @@ -57,7 +59,8 @@ class LauncherScaffoldVM : ViewModel(), KoinComponent { isSystemInDarkMode.value = darkMode } - val baseLayout = dataStore.data.map { it.layout.baseLayout }.asLiveData() + val baseLayout = dataStore.data.map { it.layout.baseLayout } + .stateIn(viewModelScope, SharingStarted.Eagerly, null) val bottomSearchBar = dataStore.data.map { it.layout.bottomSearchBar }.asLiveData() val reverseSearchResults = dataStore.data.map { it.layout.reverseSearchResults }.asLiveData() val fixedSearchBar = dataStore.data.map { it.layout.fixedSearchBar }.asLiveData() @@ -109,18 +112,31 @@ class LauncherScaffoldVM : ViewModel(), KoinComponent { val gestureState: StateFlow = dataStore .data.map { it.gestures } .distinctUntilChanged() - .map { settings -> - val swipeLeftAction = settings?.swipeLeft ?: GestureAction.None - val swipeRightAction = settings?.swipeRight ?: GestureAction.None - val swipeDownAction = settings?.swipeDown ?: GestureAction.None + .combine(baseLayout) { settings, layout -> + val swipeLeftAction = + settings?.swipeLeft?.takeIf { layout != Layout.Pager } ?: GestureAction.None + val swipeRightAction = settings?.swipeRight?.takeIf { layout != Layout.PagerReversed } + ?: GestureAction.None + val swipeDownAction = + settings?.swipeDown?.takeIf { layout != Layout.PullDown } ?: GestureAction.None val longPressAction = settings?.longPress ?: GestureAction.None val doubleTapAction = settings?.doubleTap ?: GestureAction.None - val apps = listOfNotNull( - if (swipeLeftAction == GestureAction.LaunchApp) settings.swipeLeftApp else null, - if (swipeRightAction == GestureAction.LaunchApp) settings.swipeRightApp else null, - if (swipeDownAction == GestureAction.LaunchApp) settings.swipeDownApp else null, - if (longPressAction == GestureAction.LaunchApp) settings.longPressApp else null, + val swipeLeftAppKey = + if (swipeLeftAction == GestureAction.LaunchApp) settings.swipeLeftApp else null + val swipeRightAppKey = + if (swipeRightAction == GestureAction.LaunchApp) settings.swipeRightApp else null + val swipeDownAppKey = + if (swipeDownAction == GestureAction.LaunchApp) settings.swipeDownApp else null + val longPressAppKey = + if (longPressAction == GestureAction.LaunchApp) settings.longPressApp else null + val doubleTapAppKey = if (doubleTapAction == GestureAction.LaunchApp) settings.doubleTapApp else null + val apps = listOfNotNull( + swipeLeftAppKey, + swipeRightAppKey, + swipeDownAppKey, + longPressAppKey, + doubleTapAppKey ).let { favoritesRepository.getFromKeys(it) } GestureState( @@ -129,11 +145,11 @@ class LauncherScaffoldVM : ViewModel(), KoinComponent { swipeDownAction = swipeDownAction, longPressAction = longPressAction, doubleTapAction = doubleTapAction, - swipeLeftApp = apps.firstOrNull { it.key == settings?.swipeLeftApp }, - swipeRightApp = apps.firstOrNull { it.key == settings?.swipeRightApp }, - swipeDownApp = apps.firstOrNull { it.key == settings?.swipeDownApp }, - longPressApp = apps.firstOrNull { it.key == settings?.longPressApp }, - doubleTapApp = apps.firstOrNull { it.key == settings?.doubleTapApp } + swipeLeftApp = apps.firstOrNull { it.key == swipeLeftAppKey }, + swipeRightApp = apps.firstOrNull { it.key == swipeRightAppKey }, + swipeDownApp = apps.firstOrNull { it.key == swipeDownAppKey }, + longPressApp = apps.firstOrNull { it.key == longPressAppKey }, + doubleTapApp = apps.firstOrNull { it.key == doubleTapAppKey } ) }.stateIn(viewModelScope, SharingStarted.Eagerly, GestureState()) @@ -143,9 +159,9 @@ class LauncherScaffoldVM : ViewModel(), KoinComponent { val action = when (gesture) { Gesture.DoubleTap -> gestureState.value.doubleTapAction Gesture.LongPress -> gestureState.value.longPressAction - Gesture.SwipeDown -> gestureState.value.swipeDownAction?.takeIf { baseLayout.value != Settings.LayoutSettings.Layout.PullDown } - Gesture.SwipeLeft -> gestureState.value.swipeLeftAction?.takeIf { baseLayout.value != Settings.LayoutSettings.Layout.Pager } - Gesture.SwipeRight -> gestureState.value.swipeRightAction?.takeIf { baseLayout.value != Settings.LayoutSettings.Layout.PagerReversed } + Gesture.SwipeDown -> gestureState.value.swipeDownAction.takeIf { baseLayout.value != Settings.LayoutSettings.Layout.PullDown } + Gesture.SwipeLeft -> gestureState.value.swipeLeftAction.takeIf { baseLayout.value != Settings.LayoutSettings.Layout.Pager } + Gesture.SwipeRight -> gestureState.value.swipeRightAction.takeIf { baseLayout.value != Settings.LayoutSettings.Layout.PagerReversed } } val requiresAccessibilityService = action == GestureAction.OpenRecents @@ -195,13 +211,18 @@ class LauncherScaffoldVM : ViewModel(), KoinComponent { } GestureAction.LaunchApp -> { + val options = ActivityOptions.makeCustomAnimation( + context, + android.R.anim.fade_in, + android.R.anim.fade_out, + ) when (gesture) { Gesture.SwipeLeft -> gestureState.value.swipeLeftApp Gesture.SwipeRight -> gestureState.value.swipeRightApp Gesture.SwipeDown -> gestureState.value.swipeDownApp Gesture.LongPress -> gestureState.value.longPressApp Gesture.DoubleTap -> gestureState.value.doubleTapApp - }?.launch(context, null) + }?.launch(context, options.toBundle()) true } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt index df708034..c4b9c729 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt @@ -18,6 +18,7 @@ import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.key import androidx.compose.runtime.livedata.observeAsState @@ -126,7 +127,7 @@ abstract class SharedLauncherActivity( val hideStatus by viewModel.hideStatusBar.observeAsState(false) val hideNav by viewModel.hideNavBar.observeAsState(false) - val layout by viewModel.baseLayout.observeAsState(null) + val layout by viewModel.baseLayout.collectAsState(null) val bottomSearchBar by viewModel.bottomSearchBar.observeAsState(false) val reverseSearchResults by viewModel.reverseSearchResults.observeAsState(false) val fixedSearchBar by viewModel.fixedSearchBar.observeAsState(false) diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/gestures/LauncherGestureHandler.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/gestures/LauncherGestureHandler.kt index b2ef8bc2..14e2fc12 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/gestures/LauncherGestureHandler.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/gestures/LauncherGestureHandler.kt @@ -1,23 +1,37 @@ package de.mm20.launcher2.ui.launcher.gestures import android.app.WallpaperManager +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.offset import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import de.mm20.launcher2.preferences.Settings.GestureSettings.GestureAction +import de.mm20.launcher2.search.SavableSearchable +import de.mm20.launcher2.ui.component.FakeSplashScreen import de.mm20.launcher2.ui.gestures.Gesture import de.mm20.launcher2.ui.gestures.GestureHandler import de.mm20.launcher2.ui.gestures.LocalGestureDetector +import de.mm20.launcher2.ui.ktx.animateTo import de.mm20.launcher2.ui.ktx.toPixels import de.mm20.launcher2.ui.launcher.GestureState import de.mm20.launcher2.ui.launcher.LauncherScaffoldVM import de.mm20.launcher2.ui.launcher.sheets.FailedGestureSheet +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import kotlin.math.absoluteValue @Composable @@ -27,6 +41,7 @@ fun LauncherGestureHandler() { val gestureDetector = LocalGestureDetector.current val viewModel: LauncherScaffoldVM = viewModel() + val scope = rememberCoroutineScope() val gestureState by viewModel.gestureState.collectAsState(GestureState()) @@ -38,8 +53,13 @@ fun LauncherGestureHandler() { val windowToken = LocalView.current.windowToken + var launchingApp by remember { mutableStateOf(null) } + var swipeGestureProgress = remember { mutableStateOf(0f) } + var swipeGestureDirection by remember { mutableStateOf(null) } - val swipeThreshold = 150.dp.toPixels() + val swipeStartThreshold = 18.dp.toPixels() + val swipeActionThreshold = 150.dp.toPixels() + val swipeLaunchAppThreshold = 220.dp.toPixels() GestureHandler( detector = gestureDetector, onDoubleTap = { @@ -49,22 +69,98 @@ fun LauncherGestureHandler() { viewModel.handleGesture(context, Gesture.LongPress) }, onDrag = { + when { + gestureState.swipeRightApp != null && it.x > swipeStartThreshold && ( + swipeGestureDirection == SwipeDirection.Right || (swipeGestureDirection == null && it.x.absoluteValue > it.y.absoluteValue * 2f) + ) -> { + + swipeGestureDirection = SwipeDirection.Right + swipeGestureProgress.value = + ((it.x - swipeStartThreshold) / (swipeLaunchAppThreshold - swipeStartThreshold)).coerceIn( + 0f, + 1f + ) + launchingApp = gestureState.swipeRightApp + return@GestureHandler false + } + + gestureState.swipeLeftApp != null && it.x < -swipeStartThreshold && ( + swipeGestureDirection == SwipeDirection.Left || (swipeGestureDirection == null && it.x.absoluteValue > it.y.absoluteValue * 2f) + ) -> { + + swipeGestureDirection = SwipeDirection.Left + swipeGestureProgress.value = + ((-it.x - swipeStartThreshold) / (swipeLaunchAppThreshold - swipeStartThreshold)).coerceIn( + 0f, + 1f + ) + launchingApp = gestureState.swipeLeftApp + return@GestureHandler false + } + + gestureState.swipeDownApp != null && it.y > swipeStartThreshold && ( + swipeGestureDirection == SwipeDirection.Down || (swipeGestureDirection == null && it.y.absoluteValue > it.x.absoluteValue * 2f) + ) -> { + + swipeGestureDirection = SwipeDirection.Down + swipeGestureProgress.value = + ((it.y - swipeStartThreshold) / (swipeLaunchAppThreshold - swipeStartThreshold)).coerceIn( + 0f, + 1f + ) + launchingApp = gestureState.swipeDownApp + return@GestureHandler false + } + + else -> { + swipeGestureDirection = null + swipeGestureProgress.value = 0f + launchingApp = null + } + } + return@GestureHandler when { - it.x > swipeThreshold && it.x.absoluteValue > it.y.absoluteValue * 2f -> { + it.x > swipeActionThreshold && it.x.absoluteValue > it.y.absoluteValue * 2f -> { viewModel.handleGesture(context, Gesture.SwipeRight) } - it.x < -swipeThreshold && it.x.absoluteValue > it.y.absoluteValue * 2f -> { + it.x < -swipeActionThreshold && it.x.absoluteValue > it.y.absoluteValue * 2f -> { viewModel.handleGesture(context, Gesture.SwipeLeft) } - it.y > swipeThreshold && it.y.absoluteValue > it.x.absoluteValue * 2f -> { + it.y > swipeActionThreshold && it.y.absoluteValue > it.x.absoluteValue * 2f -> { viewModel.handleGesture(context, Gesture.SwipeDown) } else -> false } }, + onDragEnd = { + if (swipeGestureProgress.value > 0f) { + scope.launch { + val direction = swipeGestureDirection + if ((swipeGestureProgress.value * swipeLaunchAppThreshold) + swipeStartThreshold >= swipeActionThreshold + && direction != null + ) { + swipeGestureProgress.animateTo(1f) + viewModel.handleGesture( + context, + when (direction) { + SwipeDirection.Right -> Gesture.SwipeRight + SwipeDirection.Left -> Gesture.SwipeLeft + SwipeDirection.Down -> Gesture.SwipeDown + }, + ) + delay(500) + } else { + swipeGestureProgress.animateTo(0f) + } + swipeGestureDirection = null + swipeGestureProgress.value = 0f + launchingApp = null + } + } + }, onTap = { wallpaperManager.sendWallpaperCommand( windowToken, @@ -76,6 +172,43 @@ fun LauncherGestureHandler() { ) } ) + + if (launchingApp != null) { + BoxWithConstraints( + modifier = Modifier.fillMaxSize() + ) { + FakeSplashScreen( + modifier = Modifier + .offset { + val p = swipeGestureProgress.value + when (swipeGestureDirection) { + SwipeDirection.Right -> IntOffset( + (-swipeActionThreshold * (1f - p)).toInt(), + 0 + ) + + SwipeDirection.Left -> IntOffset( + (swipeActionThreshold * (1f - p)).toInt(), + 0 + ) + + SwipeDirection.Down -> IntOffset( + 0, + (-swipeActionThreshold * (1f - p)).toInt() + ) + + else -> IntOffset.Zero + } + } + .graphicsLayer { + alpha = (2f * swipeGestureProgress.value).coerceAtMost(1f) + }, + searchable = launchingApp, + ) + } + } + + if (viewModel.failedGestureState != null) { FailedGestureSheet( failedGesture = viewModel.failedGestureState!!, @@ -84,4 +217,10 @@ fun LauncherGestureHandler() { } ) } +} + +internal enum class SwipeDirection { + Left, + Right, + Down } \ No newline at end of file diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/SearchableItemVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/SearchableItemVM.kt index e9be7c7c..709f85b5 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/SearchableItemVM.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/SearchableItemVM.kt @@ -68,9 +68,6 @@ abstract class SearchableItemVM( ActivityOptionsCompat.makeBasic() } val bundle = options.toBundle() - if (isAtLeastApiLevel(31)) { - bundle?.putInt("android.activity.splashScreenStyle", 1) - } if (searchable.launch(context, bundle)) { favoritesRepository.incrementLaunchCounter(searchable) return true diff --git a/data/applications/src/main/java/de/mm20/launcher2/search/data/LauncherApp.kt b/data/applications/src/main/java/de/mm20/launcher2/search/data/LauncherApp.kt index 0fd92fb0..1b42ef4b 100644 --- a/data/applications/src/main/java/de/mm20/launcher2/search/data/LauncherApp.kt +++ b/data/applications/src/main/java/de/mm20/launcher2/search/data/LauncherApp.kt @@ -120,6 +120,9 @@ data class LauncherApp( override fun launch(context: Context, options: Bundle?): Boolean { val launcherApps = context.getSystemService()!! + if (isAtLeastApiLevel(31)) { + options?.putInt("android.activity.splashScreenStyle", 1) + } try { launcherApps.startMainActivity( ComponentName(`package`, activity),