Skip to content

Commit 0f5436c

Browse files
authored
Merge pull request #2144 from keymapperorg/claude/issue-262-talkback-gestures
Add support for accessibility navigation gestures (TalkBack)
2 parents a04e738 + 6a79767 commit 0f5436c

19 files changed

Lines changed: 1084 additions & 1 deletion

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Changed
44

55
- #1369 Add content descriptions to drag handles and custom "Move up"/"Move down" accessibility actions for trigger and action list items, improving TalkBack support for reordering.
6+
- #262 Add "TalkBack gesture" action to simulate TalkBack navigation gestures (swipes, multi-finger taps, and multi-directional swipes).
67

78
## [4.1.1](https://github.com/sds100/KeyMapper/releases/tag/v4.1.1)
89

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.github.sds100.keymapper.base.actions
22

3+
import io.github.sds100.keymapper.base.actions.talkback.TalkBackGestureType
34
import io.github.sds100.keymapper.common.models.ShellExecutionMode
45
import io.github.sds100.keymapper.common.utils.NodeInteractionType
56
import io.github.sds100.keymapper.common.utils.Orientation
@@ -95,6 +96,7 @@ sealed class ActionData : Comparable<ActionData> {
9596
{ it.showVolumeUi },
9697
{ it.volumeStream },
9798
)
99+
98100
else -> super.compareTo(other)
99101
}
100102
}
@@ -111,6 +113,7 @@ sealed class ActionData : Comparable<ActionData> {
111113
{ it.showVolumeUi },
112114
{ it.volumeStream },
113115
)
116+
114117
else -> super.compareTo(other)
115118
}
116119
}
@@ -1040,6 +1043,17 @@ sealed class ActionData : Comparable<ActionData> {
10401043
{ it.settingKey },
10411044
{ it.value },
10421045
)
1046+
1047+
else -> super.compareTo(other)
1048+
}
1049+
}
1050+
1051+
@Serializable
1052+
data class TalkBackGesture(val gesture: TalkBackGestureType) : ActionData() {
1053+
override val id: ActionId = ActionId.TALKBACK_GESTURE
1054+
1055+
override fun compareTo(other: ActionData) = when (other) {
1056+
is TalkBackGesture -> gesture.compareTo(other.gesture)
10431057
else -> super.compareTo(other)
10441058
}
10451059
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package io.github.sds100.keymapper.base.actions
22

33
import android.util.Base64
44
import androidx.core.net.toUri
5+
import io.github.sds100.keymapper.base.actions.talkback.TalkBackGestureType
56
import io.github.sds100.keymapper.common.models.ShellExecutionMode
67
import io.github.sds100.keymapper.common.utils.KMError
78
import io.github.sds100.keymapper.common.utils.KMResult
@@ -69,6 +70,7 @@ object ActionDataEntityMapper {
6970
ActionEntity.Type.MODIFY_SETTING -> ActionId.MODIFY_SETTING
7071

7172
ActionEntity.Type.CREATE_NOTIFICATION -> ActionId.CREATE_NOTIFICATION
73+
7274
ActionEntity.Type.TOAST -> ActionId.TOAST
7375
}
7476

@@ -874,6 +876,20 @@ object ActionDataEntityMapper {
874876

875877
ActionId.CLEAR_RECENT_APP -> ActionData.ClearRecentApp
876878

879+
ActionId.TALKBACK_GESTURE -> {
880+
val gestureTypeString =
881+
entity.extras.getData(ActionEntity.EXTRA_TALKBACK_GESTURE_TYPE)
882+
.valueOrNull() ?: return null
883+
884+
val gestureType = try {
885+
TalkBackGestureType.valueOf(gestureTypeString)
886+
} catch (_: IllegalArgumentException) {
887+
return null
888+
}
889+
890+
ActionData.TalkBackGesture(gesture = gestureType)
891+
}
892+
877893
ActionId.MODIFY_SETTING -> {
878894
val value = entity.extras.getData(ActionEntity.EXTRA_SETTING_VALUE)
879895
.valueOrNull() ?: return null
@@ -1324,6 +1340,10 @@ object ActionDataEntityMapper {
13241340
EntityExtra(ActionEntity.EXTRA_TOAST_DURATION, data.duration.name),
13251341
)
13261342

1343+
is ActionData.TalkBackGesture -> listOf(
1344+
EntityExtra(ActionEntity.EXTRA_TALKBACK_GESTURE_TYPE, data.gesture.name),
1345+
)
1346+
13271347
else -> emptyList()
13281348
}
13291349

@@ -1510,5 +1530,7 @@ object ActionDataEntityMapper {
15101530
ActionId.CLEAR_RECENT_APP to "clear_recent_app",
15111531

15121532
ActionId.MODIFY_SETTING to "modify_setting",
1533+
1534+
ActionId.TALKBACK_GESTURE to "talkback_gesture",
15131535
)
15141536
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ class LazyActionErrorSnapshot(
265265
}
266266
}
267267

268+
is ActionData.TalkBackGesture -> {
269+
return getAppError(TALKBACK_PACKAGE_NAME)
270+
}
271+
268272
else -> {}
269273
}
270274

@@ -317,3 +321,5 @@ interface ActionErrorSnapshot {
317321
fun getError(action: ActionData): KMError?
318322
fun getErrors(actions: List<ActionData>): Map<ActionData, KMError?>
319323
}
324+
325+
private const val TALKBACK_PACKAGE_NAME = "com.google.android.marvin.talkback"

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,6 @@ enum class ActionId {
161161
CLEAR_RECENT_APP,
162162

163163
MODIFY_SETTING,
164+
165+
TALKBACK_GESTURE,
164166
}

0 commit comments

Comments
 (0)