fix swipe gestures not working after double tap to sleep

fix #1879
This commit is contained in:
MM20
2026-05-31 13:11:59 +02:00
parent fb7fe9d399
commit b071668743
10 changed files with 37 additions and 68 deletions

View File

@@ -114,9 +114,11 @@ import dev.chrisbanes.haze.hazeEffect
import dev.chrisbanes.haze.hazeSource import dev.chrisbanes.haze.hazeSource
import dev.chrisbanes.haze.rememberHazeState import dev.chrisbanes.haze.rememberHazeState
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.roundToInt import kotlin.math.roundToInt
@@ -808,16 +810,16 @@ internal class LauncherScaffoldState(
targetPage: ScaffoldPage, targetPage: ScaffoldPage,
component: ScaffoldComponent, component: ScaffoldComponent,
animate: suspend () -> Unit, animate: suspend () -> Unit,
) { ) = withContext(NonCancellable) {
when (targetPage) { when (targetPage) {
ScaffoldPage.Secondary -> { ScaffoldPage.Secondary -> {
config.homeComponent.onPreDismiss(this) config.homeComponent.onPreDismiss(this@LauncherScaffoldState)
component.onPreActivate(this) component.onPreActivate(this@LauncherScaffoldState)
} }
ScaffoldPage.Home -> { ScaffoldPage.Home -> {
component.onPreDismiss(this) component.onPreDismiss(this@LauncherScaffoldState)
config.homeComponent.onPreActivate(this) config.homeComponent.onPreActivate(this@LauncherScaffoldState)
} }
} }
@@ -825,24 +827,14 @@ internal class LauncherScaffoldState(
when (targetPage) { when (targetPage) {
ScaffoldPage.Secondary -> { ScaffoldPage.Secondary -> {
component.onActivate(this) component.onActivate(this@LauncherScaffoldState)
if (!component.permanent) { config.homeComponent.onDismiss(this@LauncherScaffoldState)
delay(component.resetDelay.milliseconds) homePageSearchBarOffset = 0f
isSettledOnSecondaryPage = false
currentOffset3D = Offset3D.Zero
component.onPreDismiss(this)
component.onDismiss(this)
currentGesture = null
unlock()
} else {
config.homeComponent.onDismiss(this)
homePageSearchBarOffset = 0f
}
} }
ScaffoldPage.Home -> { ScaffoldPage.Home -> {
config.homeComponent.onActivate(this) config.homeComponent.onActivate(this@LauncherScaffoldState)
component.onDismiss(this) component.onDismiss(this@LauncherScaffoldState)
currentGesture = null currentGesture = null
secondaryPageSearchBarOffset = 0f secondaryPageSearchBarOffset = 0f
} }

View File

@@ -42,8 +42,6 @@ internal object FeedComponent : ScaffoldComponent(), KoinComponent {
private val feedSettings: FeedSettings by inject() private val feedSettings: FeedSettings by inject()
private val feedService: FeedService by inject() private val feedService: FeedService by inject()
override val permanent: Boolean = true
override val survivesPause: Boolean = true override val survivesPause: Boolean = true
private var state = mutableIntStateOf(0) private var state = mutableIntStateOf(0)
@@ -186,7 +184,7 @@ internal object FeedComponent : ScaffoldComponent(), KoinComponent {
.alpha(1f - state.currentProgress) .alpha(1f - state.currentProgress)
} }
override suspend fun onPreActivate(state: LauncherScaffoldState) { override fun onPreActivate(state: LauncherScaffoldState) {
super.onPreActivate(state) super.onPreActivate(state)
this.state.intValue = 2 this.state.intValue = 2
} }
@@ -201,7 +199,7 @@ internal object FeedComponent : ScaffoldComponent(), KoinComponent {
this.state.intValue = 0 this.state.intValue = 0
} }
override suspend fun onPreDismiss(state: LauncherScaffoldState) { override fun onPreDismiss(state: LauncherScaffoldState) {
super.onPreDismiss(state) super.onPreDismiss(state)
this.state.intValue = 1 this.state.intValue = 1
} }

View File

@@ -15,13 +15,13 @@ import de.mm20.launcher2.search.SavableSearchable
import de.mm20.launcher2.ui.component.FakeSplashScreen import de.mm20.launcher2.ui.component.FakeSplashScreen
import de.mm20.launcher2.ui.ktx.toIntOffset import de.mm20.launcher2.ui.ktx.toIntOffset
import de.mm20.launcher2.ui.launcher.scaffold.LauncherScaffoldState import de.mm20.launcher2.ui.launcher.scaffold.LauncherScaffoldState
import kotlinx.coroutines.delay
import kotlin.time.Duration.Companion.milliseconds
internal class LaunchComponent( internal class LaunchComponent(
private val activity: Activity, private val activity: Activity,
private val searchable: SavableSearchable, private val searchable: SavableSearchable,
): ScaffoldComponent() { ): ScaffoldComponent() {
override val permanent: Boolean = false
override val resetDelay: Long = 500L
override val showSearchBar = false override val showSearchBar = false
override val isAtTop: State<Boolean?> = mutableStateOf(true) override val isAtTop: State<Boolean?> = mutableStateOf(true)
@@ -51,6 +51,9 @@ internal class LaunchComponent(
) )
searchable.launch(activity, options.toBundle()) searchable.launch(activity, options.toBundle())
delay(500.milliseconds)
state.reset()
} }
override fun homePageModifier( override fun homePageModifier(

View File

@@ -36,8 +36,6 @@ internal object NotificationsComponent : ScaffoldComponent(), KoinComponent {
private val globalActionService: GlobalActionsService by inject() private val globalActionService: GlobalActionsService by inject()
override val permanent: Boolean = false
override val showSearchBar: Boolean = false override val showSearchBar: Boolean = false
override val drawBackground: Boolean = false override val drawBackground: Boolean = false
@@ -84,14 +82,14 @@ internal object NotificationsComponent : ScaffoldComponent(), KoinComponent {
} }
} }
override suspend fun onPreActivate(state: LauncherScaffoldState) { override fun onPreActivate(state: LauncherScaffoldState) {
super.onPreActivate(state) super.onPreActivate(state)
globalActionService.openNotificationDrawer() globalActionService.openNotificationDrawer()
} }
override suspend fun onActivate(state: LauncherScaffoldState) { override suspend fun onActivate(state: LauncherScaffoldState) {
super.onActivate(state) super.onActivate(state)
state.navigateBack(false) state.navigateBack()
} }
@SuppressLint("ModifierFactoryExtensionFunction") @SuppressLint("ModifierFactoryExtensionFunction")

View File

@@ -48,9 +48,6 @@ internal object PowerMenuComponent : ScaffoldComponent(), KoinComponent {
private val permissionsManager: PermissionsManager by inject() private val permissionsManager: PermissionsManager by inject()
private val globalActionService: GlobalActionsService by inject() private val globalActionService: GlobalActionsService by inject()
override val permanent: Boolean
get() = !permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)
override val showSearchBar: Boolean = false override val showSearchBar: Boolean = false
override val drawBackground: Boolean = false override val drawBackground: Boolean = false
@@ -166,7 +163,7 @@ internal object PowerMenuComponent : ScaffoldComponent(), KoinComponent {
} }
} }
override suspend fun onPreActivate(state: LauncherScaffoldState) { override fun onPreActivate(state: LauncherScaffoldState) {
super.onPreActivate(state) super.onPreActivate(state)
if (permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)) { if (permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)) {
globalActionService.openPowerDialog() globalActionService.openPowerDialog()
@@ -175,9 +172,7 @@ internal object PowerMenuComponent : ScaffoldComponent(), KoinComponent {
override suspend fun onActivate(state: LauncherScaffoldState) { override suspend fun onActivate(state: LauncherScaffoldState) {
super.onActivate(state) super.onActivate(state)
if (!permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)) { state.navigateBack(true)
state.navigateBack(true)
}
} }
@SuppressLint("ModifierFactoryExtensionFunction") @SuppressLint("ModifierFactoryExtensionFunction")

View File

@@ -36,8 +36,6 @@ internal object QuickSettingsComponent : ScaffoldComponent(), KoinComponent {
private val globalActionService: GlobalActionsService by inject() private val globalActionService: GlobalActionsService by inject()
override val permanent: Boolean = false
override val showSearchBar: Boolean = false override val showSearchBar: Boolean = false
override val drawBackground: Boolean = false override val drawBackground: Boolean = false
@@ -84,16 +82,15 @@ internal object QuickSettingsComponent : ScaffoldComponent(), KoinComponent {
} }
} }
override suspend fun onPreActivate(state: LauncherScaffoldState) { override fun onPreActivate(state: LauncherScaffoldState) {
super.onPreActivate(state) super.onPreActivate(state)
globalActionService.openQuickSettings() globalActionService.openQuickSettings()
} }
override suspend fun onActivate(state: LauncherScaffoldState) { override suspend fun onActivate(state: LauncherScaffoldState) {
super.onActivate(state) super.onActivate(state)
state.navigateBack(false) state.navigateBack()
} }
@SuppressLint("ModifierFactoryExtensionFunction") @SuppressLint("ModifierFactoryExtensionFunction")

View File

@@ -39,9 +39,6 @@ internal object RecentsComponent : ScaffoldComponent(), KoinComponent {
private val permissionsManager: PermissionsManager by inject() private val permissionsManager: PermissionsManager by inject()
private val globalActionService: GlobalActionsService by inject() private val globalActionService: GlobalActionsService by inject()
override val permanent: Boolean
get() = !permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)
override val showSearchBar: Boolean = false override val showSearchBar: Boolean = false
override val drawBackground: Boolean = false override val drawBackground: Boolean = false
@@ -69,7 +66,7 @@ internal object RecentsComponent : ScaffoldComponent(), KoinComponent {
} }
} }
override suspend fun onPreActivate(state: LauncherScaffoldState) { override fun onPreActivate(state: LauncherScaffoldState) {
super.onPreActivate(state) super.onPreActivate(state)
if (permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)) { if (permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)) {
globalActionService.openRecents() globalActionService.openRecents()
@@ -78,7 +75,7 @@ internal object RecentsComponent : ScaffoldComponent(), KoinComponent {
override suspend fun onActivate(state: LauncherScaffoldState) { override suspend fun onActivate(state: LauncherScaffoldState) {
super.onActivate(state) super.onActivate(state)
state.navigateBack(true) state.navigateBack()
} }
@SuppressLint("ModifierFactoryExtensionFunction") @SuppressLint("ModifierFactoryExtensionFunction")

View File

@@ -12,17 +12,6 @@ import de.mm20.launcher2.ui.launcher.scaffold.LauncherScaffoldState
internal abstract class ScaffoldComponent { internal abstract class ScaffoldComponent {
/**
* If true, the component stays open. I.e. widgets, search.
* If false, the component is immediately dismissed after running its onMount function,
* returning to the home screen. I.e. turn off screen, launch app.
*/
open val permanent: Boolean = true
/**
* For non-permanent components, this is the delay before the component is dismissed.
*/
open val resetDelay: Long = 0L
/** /**
* If true, a semi-transparent background is drawn behind the page. * If true, a semi-transparent background is drawn behind the page.
@@ -87,7 +76,7 @@ internal abstract class ScaffoldComponent {
/** /**
* Called when the component is about to be activated, but before the animation is completed. * Called when the component is about to be activated, but before the animation is completed.
*/ */
open suspend fun onPreActivate(state: LauncherScaffoldState) { open fun onPreActivate(state: LauncherScaffoldState) {
} }
@@ -102,7 +91,7 @@ internal abstract class ScaffoldComponent {
/** /**
* Called when the component is about to be dismissed, but before the animation is completed. * Called when the component is about to be dismissed, but before the animation is completed.
*/ */
open suspend fun onPreDismiss(state: LauncherScaffoldState) { open fun onPreDismiss(state: LauncherScaffoldState) {
} }

View File

@@ -23,21 +23,18 @@ import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.preferences.GestureAction import de.mm20.launcher2.preferences.GestureAction
import de.mm20.launcher2.ui.launcher.scaffold.LauncherScaffoldState import de.mm20.launcher2.ui.launcher.scaffold.LauncherScaffoldState
import de.mm20.launcher2.ui.launcher.sheets.LocalBottomSheetManager import de.mm20.launcher2.ui.launcher.sheets.LocalBottomSheetManager
import kotlinx.coroutines.delay
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.inject import org.koin.core.component.inject
import kotlin.time.Duration.Companion.milliseconds
internal object ScreenOffComponent : ScaffoldComponent(), KoinComponent { internal object ScreenOffComponent : ScaffoldComponent(), KoinComponent {
private val permissionsManager: PermissionsManager by inject() private val permissionsManager: PermissionsManager by inject()
private val globalActionService: GlobalActionsService by inject() private val globalActionService: GlobalActionsService by inject()
override val permanent: Boolean
get() = !permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)
override val showSearchBar: Boolean = false override val showSearchBar: Boolean = false
override val resetDelay: Long = 1000L
override val drawBackground: Boolean = false override val drawBackground: Boolean = false
override val isAtTop: State<Boolean?> = mutableStateOf(true) override val isAtTop: State<Boolean?> = mutableStateOf(true)
@@ -96,7 +93,7 @@ internal object ScreenOffComponent : ScaffoldComponent(), KoinComponent {
.alpha(1f - (state.currentProgress * 0.1f)) then defaultModifier .alpha(1f - (state.currentProgress * 0.1f)) then defaultModifier
} }
override suspend fun onPreActivate(state: LauncherScaffoldState) { override fun onPreActivate(state: LauncherScaffoldState) {
super.onPreActivate(state) super.onPreActivate(state)
if (permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)) { if (permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)) {
globalActionService.lockScreen() globalActionService.lockScreen()
@@ -107,6 +104,9 @@ internal object ScreenOffComponent : ScaffoldComponent(), KoinComponent {
super.onActivate(state) super.onActivate(state)
if (!permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)) { if (!permissionsManager.checkPermissionOnce(PermissionGroup.Accessibility)) {
state.navigateBack(true) state.navigateBack(true)
} else {
delay(500.milliseconds)
state.reset()
} }
} }
} }

View File

@@ -103,14 +103,14 @@ internal class SearchComponent(
super.onDismiss(state) super.onDismiss(state)
} }
override suspend fun onPreActivate(state: LauncherScaffoldState) { override fun onPreActivate(state: LauncherScaffoldState) {
super.onPreActivate(state) super.onPreActivate(state)
if (openKeyboard) { if (openKeyboard) {
state.isSearchBarFocused = true state.isSearchBarFocused = true
} }
} }
override suspend fun onPreDismiss(state: LauncherScaffoldState) { override fun onPreDismiss(state: LauncherScaffoldState) {
super.onPreDismiss(state) super.onPreDismiss(state)
state.isSearchBarFocused = false state.isSearchBarFocused = false
} }