Skip to content

Commit 106416a

Browse files
committed
#2174 feat: add default do not remap preference
Add a "Do not remap by default" toggle to the Change Default Options settings page. When enabled, new trigger keys will have consumeEvent = false by default, letting the original key event pass through to other apps.
1 parent bc11b09 commit 106416a

9 files changed

Lines changed: 66 additions & 23 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
## Added
1717

1818
- #2140 Add monochrome app icon layer for themed icon support on Android 13+.
19+
- #2174 Add "Do not remap by default" preference to the default options settings page.
1920

2021
## Fixed
2122

base/src/main/java/io/github/sds100/keymapper/base/keymaps/GetDefaultKeyMapOptionsUseCase.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ class GetDefaultKeyMapOptionsUseCaseImpl @Inject constructor(
5555
preferenceRepository.get(Keys.defaultVibrateDuration)
5656
.map { it ?: PreferenceDefaults.VIBRATION_DURATION }
5757
.stateIn(coroutineScope, SharingStarted.Lazily, PreferenceDefaults.VIBRATION_DURATION)
58+
59+
override val defaultDoNotRemap: StateFlow<Boolean> =
60+
preferenceRepository.get(Keys.defaultDoNotRemap)
61+
.map { it ?: PreferenceDefaults.DO_NOT_REMAP }
62+
.stateIn(coroutineScope, SharingStarted.Lazily, PreferenceDefaults.DO_NOT_REMAP)
5863
}
5964

6065
interface GetDefaultKeyMapOptionsUseCase {
@@ -65,4 +70,5 @@ interface GetDefaultKeyMapOptionsUseCase {
6570
val defaultDoublePressDelay: StateFlow<Int>
6671
val defaultSequenceTriggerTimeout: StateFlow<Int>
6772
val defaultVibrateDuration: StateFlow<Int>
73+
val defaultDoNotRemap: StateFlow<Boolean>
6874
}

base/src/main/java/io/github/sds100/keymapper/base/settings/DefaultOptionsSettingsScreen.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import androidx.compose.foundation.rememberScrollState
1313
import androidx.compose.foundation.verticalScroll
1414
import androidx.compose.material.icons.Icons
1515
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
16+
import androidx.compose.material.icons.rounded.Keyboard
1617
import androidx.compose.material3.BottomAppBar
1718
import androidx.compose.material3.ExperimentalMaterial3Api
1819
import androidx.compose.material3.Icon
@@ -35,6 +36,7 @@ import io.github.sds100.keymapper.base.utils.ui.SliderMaximums
3536
import io.github.sds100.keymapper.base.utils.ui.SliderMinimums
3637
import io.github.sds100.keymapper.base.utils.ui.SliderStepSizes
3738
import io.github.sds100.keymapper.base.utils.ui.compose.SliderOptionText
39+
import io.github.sds100.keymapper.base.utils.ui.compose.SwitchPreferenceCompose
3840

3941
@Composable
4042
fun DefaultOptionsSettingsScreen(modifier: Modifier = Modifier, viewModel: SettingsViewModel) {
@@ -209,6 +211,16 @@ private fun Content(
209211
stepSize = SliderStepSizes.TRIGGER_SEQUENCE_TRIGGER_TIMEOUT,
210212
)
211213
Spacer(Modifier.height(8.dp))
214+
215+
// Do not remap
216+
SwitchPreferenceCompose(
217+
title = stringResource(R.string.title_pref_default_do_not_remap),
218+
text = stringResource(R.string.summary_pref_default_do_not_remap),
219+
icon = Icons.Rounded.Keyboard,
220+
isChecked = state.doNotRemap,
221+
onCheckedChange = { callback.onDefaultDoNotRemapChanged(it) },
222+
)
223+
Spacer(Modifier.height(8.dp))
212224
}
213225
}
214226

@@ -219,6 +231,7 @@ interface DefaultOptionsSettingsCallback {
219231
fun onRepeatDelayChanged(delay: Int) = run { }
220232
fun onRepeatRateChanged(rate: Int) = run { }
221233
fun onSequenceTriggerTimeoutChanged(timeout: Int) = run { }
234+
fun onDefaultDoNotRemapChanged(doNotRemap: Boolean) = run { }
222235
}
223236

224237
@Preview

base/src/main/java/io/github/sds100/keymapper/base/settings/SettingsViewModel.kt

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -72,27 +72,32 @@ class SettingsViewModel @Inject constructor(
7272
}.stateIn(viewModelScope, SharingStarted.Lazily, MainSettingsState())
7373

7474
val defaultSettingsScreenState: StateFlow<DefaultSettingsState> = combine(
75-
useCase.getPreference(Keys.defaultLongPressDelay),
76-
useCase.getPreference(Keys.defaultDoublePressDelay),
77-
useCase.getPreference(Keys.defaultVibrateDuration),
78-
useCase.getPreference(Keys.defaultRepeatDelay),
79-
useCase.getPreference(Keys.defaultRepeatRate),
80-
useCase.getPreference(Keys.defaultSequenceTriggerTimeout),
81-
) { values ->
82-
DefaultSettingsState(
83-
longPressDelay = values[0] ?: PreferenceDefaults.LONG_PRESS_DELAY,
84-
defaultLongPressDelay = PreferenceDefaults.LONG_PRESS_DELAY,
85-
doublePressDelay = values[1] ?: PreferenceDefaults.DOUBLE_PRESS_DELAY,
86-
defaultDoublePressDelay = PreferenceDefaults.DOUBLE_PRESS_DELAY,
87-
vibrateDuration = values[2] ?: PreferenceDefaults.VIBRATION_DURATION,
88-
defaultVibrateDuration = PreferenceDefaults.VIBRATION_DURATION,
89-
repeatDelay = values[3] ?: PreferenceDefaults.REPEAT_DELAY,
90-
defaultRepeatDelay = PreferenceDefaults.REPEAT_DELAY,
91-
repeatRate = values[4] ?: PreferenceDefaults.REPEAT_RATE,
92-
defaultRepeatRate = PreferenceDefaults.REPEAT_RATE,
93-
sequenceTriggerTimeout = values[5] ?: PreferenceDefaults.SEQUENCE_TRIGGER_TIMEOUT,
94-
defaultSequenceTriggerTimeout = PreferenceDefaults.SEQUENCE_TRIGGER_TIMEOUT,
95-
)
75+
combine(
76+
useCase.getPreference(Keys.defaultLongPressDelay),
77+
useCase.getPreference(Keys.defaultDoublePressDelay),
78+
useCase.getPreference(Keys.defaultVibrateDuration),
79+
useCase.getPreference(Keys.defaultRepeatDelay),
80+
useCase.getPreference(Keys.defaultRepeatRate),
81+
useCase.getPreference(Keys.defaultSequenceTriggerTimeout),
82+
) { values ->
83+
DefaultSettingsState(
84+
longPressDelay = values[0] ?: PreferenceDefaults.LONG_PRESS_DELAY,
85+
defaultLongPressDelay = PreferenceDefaults.LONG_PRESS_DELAY,
86+
doublePressDelay = values[1] ?: PreferenceDefaults.DOUBLE_PRESS_DELAY,
87+
defaultDoublePressDelay = PreferenceDefaults.DOUBLE_PRESS_DELAY,
88+
vibrateDuration = values[2] ?: PreferenceDefaults.VIBRATION_DURATION,
89+
defaultVibrateDuration = PreferenceDefaults.VIBRATION_DURATION,
90+
repeatDelay = values[3] ?: PreferenceDefaults.REPEAT_DELAY,
91+
defaultRepeatDelay = PreferenceDefaults.REPEAT_DELAY,
92+
repeatRate = values[4] ?: PreferenceDefaults.REPEAT_RATE,
93+
defaultRepeatRate = PreferenceDefaults.REPEAT_RATE,
94+
sequenceTriggerTimeout = values[5] ?: PreferenceDefaults.SEQUENCE_TRIGGER_TIMEOUT,
95+
defaultSequenceTriggerTimeout = PreferenceDefaults.SEQUENCE_TRIGGER_TIMEOUT,
96+
)
97+
},
98+
useCase.getPreference(Keys.defaultDoNotRemap),
99+
) { state, doNotRemap ->
100+
state.copy(doNotRemap = doNotRemap ?: PreferenceDefaults.DO_NOT_REMAP)
96101
}.stateIn(viewModelScope, SharingStarted.Lazily, DefaultSettingsState())
97102

98103
val automaticChangeImeSettingsState: StateFlow<AutomaticChangeImeSettingsState> = combine(
@@ -241,6 +246,12 @@ class SettingsViewModel @Inject constructor(
241246
}
242247
}
243248

249+
override fun onDefaultDoNotRemapChanged(doNotRemap: Boolean) {
250+
viewModelScope.launch {
251+
useCase.setPreference(Keys.defaultDoNotRemap, doNotRemap)
252+
}
253+
}
254+
244255
fun onShowToastWhenAutoChangingImeToggled(enabled: Boolean) {
245256
viewModelScope.launch {
246257
useCase.setPreference(Keys.showToastWhenAutoChangingIme, enabled)
@@ -387,6 +398,8 @@ data class DefaultSettingsState(
387398

388399
val sequenceTriggerTimeout: Int = PreferenceDefaults.SEQUENCE_TRIGGER_TIMEOUT,
389400
val defaultSequenceTriggerTimeout: Int = PreferenceDefaults.SEQUENCE_TRIGGER_TIMEOUT,
401+
402+
val doNotRemap: Boolean = PreferenceDefaults.DO_NOT_REMAP,
390403
)
391404

392405
data class AutomaticChangeImeSettingsState(

base/src/main/java/io/github/sds100/keymapper/base/trigger/ConfigTriggerDelegate.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class ConfigTriggerDelegate {
6666
device: KeyEventTriggerDevice,
6767
requiresIme: Boolean,
6868
otherTriggerKeys: List<KeyCodeTriggerKey> = emptyList(),
69+
defaultDoNotRemap: Boolean = false,
6970
): Trigger {
7071
val isPowerKey = KeyEventUtils.isPowerButtonKey(keyCode, scanCode)
7172

@@ -79,7 +80,7 @@ class ConfigTriggerDelegate {
7980
}
8081
}
8182

82-
var consumeKeyEvent = true
83+
var consumeKeyEvent = !defaultDoNotRemap
8384

8485
// Issue #753
8586
if (KeyEventUtils.isModifierKey(keyCode)) {
@@ -130,6 +131,7 @@ class ConfigTriggerDelegate {
130131
scanCode: Int,
131132
device: EvdevDeviceInfo,
132133
otherTriggerKeys: List<KeyCodeTriggerKey> = emptyList(),
134+
defaultDoNotRemap: Boolean = false,
133135
): Trigger {
134136
val isPowerKey = KeyEventUtils.isPowerButtonKey(keyCode, scanCode)
135137

@@ -158,7 +160,7 @@ class ConfigTriggerDelegate {
158160
scanCode = scanCode,
159161
device = device,
160162
clickType = clickType,
161-
consumeEvent = true,
163+
consumeEvent = !defaultDoNotRemap,
162164
detectWithScanCodeUserSetting = conflictingKeys.isNotEmpty(),
163165
)
164166

base/src/main/java/io/github/sds100/keymapper/base/trigger/ConfigTriggerUseCase.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ class ConfigTriggerUseCaseImpl @Inject constructor(
118118
device,
119119
requiresIme,
120120
otherTriggerKeys = otherTriggerKeys,
121+
defaultDoNotRemap = defaultDoNotRemap.value,
121122
)
122123
}
123124

@@ -129,6 +130,7 @@ class ConfigTriggerUseCaseImpl @Inject constructor(
129130
scanCode,
130131
device,
131132
otherTriggerKeys = otherTriggerKeys,
133+
defaultDoNotRemap = defaultDoNotRemap.value,
132134
)
133135
}
134136

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,9 @@
674674
<string name="title_pref_default_options">Change default options</string>
675675
<string name="summary_pref_default_options">For triggers and actions</string>
676676

677+
<string name="title_pref_default_do_not_remap">Do not remap by default</string>
678+
<string name="summary_pref_default_do_not_remap">New trigger keys will not consume the key event by default</string>
679+
677680
<string name="title_pref_reset_settings">Reset all</string>
678681
<string name="dialog_title_reset_settings">DANGER!</string>
679682
<string name="dialog_message_reset_settings">Are you sure you want to reset all settings in the app to the default? Your existing key maps will not be affected. The introductions and warning pop ups will show again.</string>

data/src/main/java/io/github/sds100/keymapper/data/Keys.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ object Keys {
4040
val defaultRepeatRate = intPreferencesKey("pref_repeat_delay")
4141
val defaultSequenceTriggerTimeout = intPreferencesKey("pref_sequence_trigger_timeout")
4242
val defaultHoldDownDuration = intPreferencesKey("pref_hold_down_duration")
43+
val defaultDoNotRemap = booleanPreferencesKey("pref_default_do_not_remap")
4344
val toggleKeyboardOnToggleKeymaps =
4445
booleanPreferencesKey("key_toggle_keyboard_on_pause_resume_keymaps")
4546
val automaticBackupLocation = stringPreferencesKey("pref_automatic_backup_location")

data/src/main/java/io/github/sds100/keymapper/data/PreferenceDefaults.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ object PreferenceDefaults {
2222
// It is false by default and the first time they turn on the system bridge,
2323
// the preference will be set to true.
2424
const val KEY_EVENT_ACTIONS_USE_SYSTEM_BRIDGE = false
25+
26+
const val DO_NOT_REMAP = false
2527
}

0 commit comments

Comments
 (0)