Skip to content

Commit

Permalink
fix(focus-controller): resolve auto scroll issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Irineu333 committed Nov 9, 2023
1 parent 7b99241 commit d9a5768
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 28 deletions.
19 changes: 7 additions & 12 deletions app/src/main/java/com/neo/speaktouch/controller/FocusController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package com.neo.speaktouch.controller

import android.view.accessibility.AccessibilityNodeInfo
import com.neo.speaktouch.intercepter.CallbackInterceptor
import com.neo.speaktouch.model.NodeFilter
import com.neo.speaktouch.utils.extension.Direction
import com.neo.speaktouch.utils.extension.getFocusedOrNull
Expand Down Expand Up @@ -60,12 +61,9 @@ class FocusController(

if (current.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)) {

current.refresh()
child.refresh()

moveFocusToPrevious(
nodeFilter = nodeFilter
)
CallbackInterceptor.addCallback {
moveFocusToPrevious()
}

stop()
}
Expand Down Expand Up @@ -105,12 +103,9 @@ class FocusController(

if (current.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)) {

current.refresh()
child.refresh()

moveFocusToNext(
nodeFilter = nodeFilter
)
CallbackInterceptor.addCallback {
moveFocusToNext()
}

stop()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Global callbacks interceptor.
*
* Copyright (C) 2023 Irineu A. Silva.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.neo.speaktouch.intercepter

import android.view.accessibility.AccessibilityEvent
import com.neo.speaktouch.intercepter.interfece.Interceptor
import java.util.Stack

object CallbackInterceptor : Interceptor {

private val scroll = Stack<Scroll>()

override fun handle(event: AccessibilityEvent) {

if (event.eventType == AccessibilityEvent.TYPE_VIEW_SCROLLED) {

if (scroll.isNotEmpty()) {
scroll.pop().invoke()
}
}
}

fun addCallback(callback: Scroll) {
scroll.push(callback)
}

}

fun interface Scroll {
operator fun invoke()
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import android.accessibilityservice.AccessibilityServiceInfo
import android.os.Build
import android.view.accessibility.AccessibilityEvent
import com.neo.speaktouch.controller.FocusController
import com.neo.speaktouch.intercepter.CallbackInterceptor
import com.neo.speaktouch.intercepter.FocusInterceptor
import com.neo.speaktouch.intercepter.GestureInterceptor
import com.neo.speaktouch.intercepter.HapticInterceptor
Expand All @@ -47,6 +48,8 @@ class SpeakTouchService : AccessibilityService() {
accessibilityService = this
)

interceptors.add(CallbackInterceptor)

interceptors.add(FocusInterceptor())

interceptors.add(SpeechInterceptor.getInstance(this))
Expand Down
27 changes: 11 additions & 16 deletions app/src/main/java/com/neo/speaktouch/utils/extension/NodeScan.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ import android.view.accessibility.AccessibilityNodeInfo
* Open a nodes scan block.
* @see NodeScan
*/
fun nodeScan(block: NodeScan.() -> Unit) {
fun nodeScan(block: NodeScan.() -> Unit) : AccessibilityNodeInfo? {
try {
NodeScan().block()
} catch (_: NodeScanStop) {
// success finish
} catch (stop: NodeScanStop) {
return stop.result
}

return null
}

open class NodeScan {
Expand All @@ -49,11 +51,7 @@ open class NodeScan {

while (true) {

try {
scope.block()
} catch (_: NodeScanRepeat) {
continue
}
scope.block()

val current = scope.current
val parent = current.parent ?: return
Expand Down Expand Up @@ -121,10 +119,6 @@ sealed class NodeScanScope : NodeScan() {
fun indexOfChild() = current.indexOfChild(child)
fun leftIndexOfChild() = indexOfChild().dec()
fun rightIndexOfChild() = indexOfChild().inc()

fun repeat() {
throw NodeScanRepeat()
}
}

/**
Expand All @@ -139,8 +133,8 @@ sealed class NodeScanScope : NodeScan() {
val recursive: () -> Unit = {}
) : NodeScanScope()

fun stop() {
throw NodeScanStop()
fun stop(result: AccessibilityNodeInfo? = null) {
throw NodeScanStop(result)
}
}

Expand All @@ -160,5 +154,6 @@ sealed class Direction {
) : Direction()
}

class NodeScanStop : Exception()
class NodeScanRepeat : Exception()
class NodeScanStop(
val result: AccessibilityNodeInfo? = null
) : Exception()

0 comments on commit d9a5768

Please sign in to comment.