Skip to content

Commit b06b40d

Browse files
committed
Merge branch 'develop' into copilot/mute-microphone-action
2 parents 2774038 + 24b4cf9 commit b06b40d

File tree

54 files changed

+719
-633
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+719
-633
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
- #1818 the Key Mapper GUI Keyboard is no longer mentioned in the app. It still works but PRO mode
4343
and the auto switching feature are the preferred way to work around the limitations of the Key
4444
Mapper keyboard.
45-
- Allow selecting notification and alarm sound and not just ringtones for Sound action
45+
- Allow selecting notification and alarm sound and not just ringtones for Sound action.
46+
- #1064 wait for switch keyboard action to complete before doing next action.
4647

4748
## [3.2.1](https://github.com/sds100/KeyMapper/releases/tag/v3.2.1)
4849

app/src/main/java/io/github/sds100/keymapper/trigger/ConfigTriggerViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ class ConfigTriggerViewModel @Inject constructor(
5151

5252
override fun onEditFloatingLayoutClick() {}
5353

54-
override fun showTriggerSetup(shortcut: TriggerSetupShortcut) {
54+
override fun showTriggerSetup(shortcut: TriggerSetupShortcut, forceProMode: Boolean) {
5555
when (shortcut) {
5656
TriggerSetupShortcut.ASSISTANT -> viewModelScope.launch {
5757
navigateToAdvancedTriggers("purchase_assistant_trigger")
5858
}
5959

60-
else -> super.showTriggerSetup(shortcut)
60+
else -> super.showTriggerSetup(shortcut, forceProMode)
6161
}
6262
}
6363
}

base/build.gradle.kts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ dependencies {
9393
implementation(libs.google.flexbox)
9494
implementation(libs.squareup.okhttp)
9595
coreLibraryDesugaring(libs.desugar.jdk.libs)
96-
implementation(libs.canopas.introshowcaseview)
9796
implementation(libs.dagger.hilt.android)
9897
ksp(libs.dagger.hilt.android.compiler)
9998
implementation(libs.bundles.splitties)

base/src/main/java/io/github/sds100/keymapper/base/actions/ActionDataEntityMapper.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ object ActionDataEntityMapper {
274274

275275
ActionId.VOLUME_INCREASE_STREAM,
276276
ActionId.VOLUME_DECREASE_STREAM,
277-
-> {
277+
-> {
278278
val stream =
279279
entity.extras.getData(ActionEntity.EXTRA_STREAM_TYPE).then {
280280
VOLUME_STREAM_MAP.getKey(it)!!.success()
@@ -299,7 +299,7 @@ object ActionDataEntityMapper {
299299
ActionId.VOLUME_TOGGLE_MUTE,
300300
ActionId.VOLUME_UNMUTE,
301301
ActionId.VOLUME_MUTE,
302-
-> {
302+
-> {
303303
val showVolumeUi =
304304
entity.flags.hasFlag(ActionEntity.ACTION_FLAG_SHOW_VOLUME_UI)
305305

@@ -324,7 +324,7 @@ object ActionDataEntityMapper {
324324
ActionId.TOGGLE_FLASHLIGHT,
325325
ActionId.ENABLE_FLASHLIGHT,
326326
ActionId.CHANGE_FLASHLIGHT_STRENGTH,
327-
-> {
327+
-> {
328328
val lens = entity.extras.getData(ActionEntity.EXTRA_LENS).then {
329329
LENS_MAP.getKey(it)!!.success()
330330
}.valueOrNull() ?: return null
@@ -350,7 +350,7 @@ object ActionDataEntityMapper {
350350
}
351351

352352
ActionId.DISABLE_FLASHLIGHT,
353-
-> {
353+
-> {
354354
val lens = entity.extras.getData(ActionEntity.EXTRA_LENS).then {
355355
LENS_MAP.getKey(it)!!.success()
356356
}.valueOrNull() ?: return null
@@ -359,7 +359,7 @@ object ActionDataEntityMapper {
359359

360360
ActionId.TOGGLE_DND_MODE,
361361
ActionId.ENABLE_DND_MODE,
362-
-> {
362+
-> {
363363
val dndMode = entity.extras.getData(ActionEntity.EXTRA_DND_MODE).then {
364364
DND_MODE_MAP.getKey(it)!!.success()
365365
}.valueOrNull() ?: return null
@@ -389,7 +389,7 @@ object ActionDataEntityMapper {
389389
ActionId.STOP_MEDIA_PACKAGE,
390390
ActionId.STEP_FORWARD_PACKAGE,
391391
ActionId.STEP_BACKWARD_PACKAGE,
392-
-> {
392+
-> {
393393
val packageName =
394394
entity.extras.getData(ActionEntity.EXTRA_PACKAGE_NAME).valueOrNull()
395395
?: return null

base/src/main/java/io/github/sds100/keymapper/base/actions/ChooseActionViewModel.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,16 +199,16 @@ class ChooseActionViewModel @Inject constructor(
199199
val messageToShow: Int? = when (id) {
200200
ActionId.FAST_FORWARD_PACKAGE,
201201
ActionId.FAST_FORWARD,
202-
-> R.string.action_fast_forward_message
202+
-> R.string.action_fast_forward_message
203203

204204
ActionId.REWIND_PACKAGE,
205205
ActionId.REWIND,
206-
-> R.string.action_rewind_message
206+
-> R.string.action_rewind_message
207207

208208
ActionId.TOGGLE_KEYBOARD,
209209
ActionId.SHOW_KEYBOARD,
210210
ActionId.HIDE_KEYBOARD,
211-
-> R.string.action_toggle_keyboard_message
211+
-> R.string.action_toggle_keyboard_message
212212

213213
ActionId.SECURE_LOCK_DEVICE -> R.string.action_secure_lock_device_message
214214

base/src/main/java/io/github/sds100/keymapper/base/actions/ConfigActionsUseCase.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ class ConfigActionsUseCaseImpl @Inject constructor(
2727
private val preferenceRepository: PreferenceRepository,
2828
private val configConstraints: ConfigConstraintsUseCase,
2929
defaultKeyMapOptionsUseCase: GetDefaultKeyMapOptionsUseCase,
30-
) : ConfigActionsUseCase, GetDefaultKeyMapOptionsUseCase by defaultKeyMapOptionsUseCase {
30+
) : ConfigActionsUseCase,
31+
GetDefaultKeyMapOptionsUseCase by defaultKeyMapOptionsUseCase {
3132

3233
override val keyMap: StateFlow<State<KeyMap>> = state.keyMap
3334

base/src/main/java/io/github/sds100/keymapper/base/actions/ConfigActionsViewModel.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import io.github.sds100.keymapper.base.R
77
import io.github.sds100.keymapper.base.actions.keyevent.FixKeyEventActionDelegate
88
import io.github.sds100.keymapper.base.keymaps.KeyMap
99
import io.github.sds100.keymapper.base.keymaps.ShortcutModel
10+
import io.github.sds100.keymapper.base.onboarding.OnboardingTapTarget
1011
import io.github.sds100.keymapper.base.onboarding.OnboardingTipDelegate
12+
import io.github.sds100.keymapper.base.onboarding.OnboardingUseCase
1113
import io.github.sds100.keymapper.base.onboarding.SetupAccessibilityServiceDelegate
1214
import io.github.sds100.keymapper.base.utils.getFullMessage
1315
import io.github.sds100.keymapper.base.utils.isFixable
@@ -47,6 +49,7 @@ class ConfigActionsViewModel @Inject constructor(
4749
private val createAction: CreateActionUseCase,
4850
private val testAction: TestActionUseCase,
4951
private val config: ConfigActionsUseCase,
52+
private val onboardingUseCase: OnboardingUseCase,
5053
setupAccessibilityServiceDelegate: SetupAccessibilityServiceDelegate,
5154
fixKeyEventActionDelegate: FixKeyEventActionDelegate,
5255
onboardingTipDelegate: OnboardingTipDelegate,
@@ -153,6 +156,9 @@ class ConfigActionsViewModel @Inject constructor(
153156
val actionData = navigate("add_action", NavDestination.ChooseAction) ?: return@launch
154157

155158
config.addAction(actionData)
159+
160+
// Never show the tap target to add an action again.
161+
onboardingUseCase.completedTapTarget(OnboardingTapTarget.CHOOSE_ACTION)
156162
}
157163
}
158164

@@ -178,6 +184,9 @@ class ConfigActionsViewModel @Inject constructor(
178184
override fun onEditClick() {
179185
val actionUid = actionOptionsUid.value ?: return
180186
viewModelScope.launch {
187+
// Clear the bottom sheet so navigating back with predicted-back works
188+
actionOptionsUid.update { null }
189+
181190
val keyMap = config.keyMap.first().dataOrNull() ?: return@launch
182191

183192
val oldAction = keyMap.actionList.find { it.uid == actionUid } ?: return@launch
@@ -188,6 +197,7 @@ class ConfigActionsViewModel @Inject constructor(
188197
override fun onReplaceClick() {
189198
val actionUid = actionOptionsUid.value ?: return
190199
viewModelScope.launch {
200+
// Clear the bottom sheet so navigating back with predicted-back works
191201
actionOptionsUid.update { null }
192202

193203
val newActionData =

base/src/main/java/io/github/sds100/keymapper/base/actions/ConfigShellCommandViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,11 @@ class ConfigShellCommandViewModel @Inject constructor(
101101
executeShellCommandUseCase.executeWithStreamingOutput(
102102
command = state.command,
103103
executionMode = state.executionMode,
104-
timeoutMillis = state.timeoutSeconds * 1000L
104+
timeoutMillis = state.timeoutSeconds * 1000L,
105105
).collect { result ->
106106
val isRunning = result.handle(
107107
onSuccess = { it.isExecuting() },
108-
onError = { false }
108+
onError = { false },
109109
)
110110

111111
state = state.copy(isRunning = isRunning, testResult = result)

base/src/main/java/io/github/sds100/keymapper/base/actions/ExecuteShellCommandUseCase.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class ExecuteShellCommandUseCase @Inject constructor(
4040
return when (executionMode) {
4141
ShellExecutionMode.STANDARD -> shellAdapter.executeWithStreamingOutput(
4242
command,
43-
timeoutMillis
43+
timeoutMillis,
4444
)
4545

4646
ShellExecutionMode.ROOT -> suAdapter.executeWithStreamingOutput(command, timeoutMillis)
@@ -56,7 +56,7 @@ class ExecuteShellCommandUseCase @Inject constructor(
5656
*/
5757
private suspend fun executeCommandSystemBridge(
5858
command: String,
59-
timeoutMillis: Long
59+
timeoutMillis: Long,
6060
): KMResult<ShellResult> {
6161
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
6262
runInterruptible(Dispatchers.IO) {

base/src/main/java/io/github/sds100/keymapper/base/actions/PerformActionsUseCase.kt

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import io.github.sds100.keymapper.common.utils.onSuccess
3636
import io.github.sds100.keymapper.common.utils.otherwise
3737
import io.github.sds100.keymapper.common.utils.success
3838
import io.github.sds100.keymapper.common.utils.then
39-
import io.github.sds100.keymapper.common.utils.valueOrNull
4039
import io.github.sds100.keymapper.common.utils.withFlag
4140
import io.github.sds100.keymapper.data.Keys
4241
import io.github.sds100.keymapper.data.PreferenceDefaults
@@ -77,10 +76,12 @@ import kotlinx.coroutines.delay
7776
import kotlinx.coroutines.flow.Flow
7877
import kotlinx.coroutines.flow.SharingStarted
7978
import kotlinx.coroutines.flow.StateFlow
79+
import kotlinx.coroutines.flow.filterNotNull
8080
import kotlinx.coroutines.flow.first
8181
import kotlinx.coroutines.flow.map
8282
import kotlinx.coroutines.flow.stateIn
8383
import kotlinx.coroutines.runBlocking
84+
import kotlinx.coroutines.withTimeoutOrNull
8485
import timber.log.Timber
8586

8687
class PerformActionsUseCaseImpl @AssistedInject constructor(
@@ -203,7 +204,8 @@ class PerformActionsUseCaseImpl @AssistedInject constructor(
203204
}
204205
} else {
205206
result = inputEventHub.injectKeyEvent(
206-
model, useSystemBridgeIfAvailable = injectKeyEventsWithSystemBridge.value,
207+
model,
208+
useSystemBridgeIfAvailable = injectKeyEventsWithSystemBridge.value,
207209
)
208210
}
209211
}
@@ -309,19 +311,18 @@ class PerformActionsUseCaseImpl @AssistedInject constructor(
309311
}
310312

311313
is ActionData.SwitchKeyboard -> {
312-
result = switchImeInterface
313-
.switchIme(action.imeId)
314-
.onSuccess { imeId ->
315-
val imeInfo = inputMethodAdapter.getInfoById(action.imeId).valueOrNull()
316-
?: return@onSuccess
317-
318-
val message = resourceProvider.getString(
319-
R.string.toast_chose_keyboard,
320-
imeInfo.label,
321-
)
314+
switchImeInterface.switchIme(action.imeId)
322315

323-
toastAdapter.show(message)
324-
}
316+
// See issue #1064. Wait for the input method to finish switching before returning.
317+
val chosenIme = withTimeoutOrNull(2000) {
318+
inputMethodAdapter.chosenIme.filterNotNull().first { it.id == action.imeId }
319+
}
320+
321+
if (chosenIme == null) {
322+
result = KMError.SwitchImeFailed
323+
} else {
324+
result = Success(Unit)
325+
}
325326
}
326327

327328
is ActionData.Volume.Down -> {

0 commit comments

Comments
 (0)