From ddfce0efbf4ea1c03effe4fb70c11f9687b6cc62 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Fri, 13 Mar 2026 13:17:33 -0400 Subject: [PATCH 1/3] Fix checkbox state rendering for nested task list items. Filter list item spans by nesting level in isChecked() so the line index aligns with direct children only, matching how getIndexOfProcessedLine() counts them. Without this, nested items shift the index and cause checkboxes to render the wrong state. --- .../kotlin/org/wordpress/aztec/spans/AztecTaskListSpan.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/spans/AztecTaskListSpan.kt b/aztec/src/main/kotlin/org/wordpress/aztec/spans/AztecTaskListSpan.kt index 3cbae340a..43a5ce126 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/spans/AztecTaskListSpan.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/spans/AztecTaskListSpan.kt @@ -139,9 +139,9 @@ open class AztecTaskListSpan( private fun isChecked(text: CharSequence, lineIndex: Int): Boolean { val spanStart = (text as Spanned).getSpanStart(this) val spanEnd = text.getSpanEnd(this) - val sortedSpans = text.getSpans(spanStart, spanEnd, AztecListItemSpan::class.java).sortedBy { - text.getSpanStart(it) - } + val sortedSpans = text.getSpans(spanStart, spanEnd, AztecListItemSpan::class.java) + .filter { it.nestingLevel == nestingLevel + 1 } + .sortedBy { text.getSpanStart(it) } return sortedSpans.getOrNull(lineIndex - 1)?.attributes?.getValue("checked") == "true" } From a4bcfd5f75ac1dc2b22003033caf986995d4a774 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Fri, 13 Mar 2026 13:18:28 -0400 Subject: [PATCH 2/3] Fix checkbox toggle for nested task list items Select the innermost AztecTaskListSpan at the tap position instead of an arbitrary one, and compute the x-coordinate boundary based on nesting depth so taps on indented checkboxes are recognized. --- .../org/wordpress/aztec/TaskListClickHandler.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/TaskListClickHandler.kt b/aztec/src/main/kotlin/org/wordpress/aztec/TaskListClickHandler.kt index d0545bbff..af8387b32 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/TaskListClickHandler.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/TaskListClickHandler.kt @@ -7,15 +7,18 @@ import org.wordpress.aztec.spans.AztecTaskListSpan class TaskListClickHandler(val listStyle: BlockFormatter.ListStyle) { fun handleTaskListClick(text: Spannable, off: Int, x: Int, startMargin: Int): Boolean { - // We want to make sure that text click will not trigger the checked change - if (x + startMargin > (listStyle.leadingMargin() + AztecTaskListSpan.PADDING_SPACE)) return false - val clickedList = text.getSpans(off, off, AztecTaskListSpan::class.java).firstOrNull() + val clickedList = text.getSpans(off, off, AztecTaskListSpan::class.java).maxByOrNull { it.nestingLevel } + ?: return false + // Account for nested leading margins: each nesting level adds one leadingMargin width + val depthMultiplier = (clickedList.nestingLevel / 2) + 1 + val effectiveMargin = listStyle.leadingMargin() * depthMultiplier + if (x + startMargin > (effectiveMargin + AztecTaskListSpan.PADDING_SPACE)) return false val clickedLines = text.getSpans(off, off, AztecListItemSpan::class.java) val clickedLine = clickedLines.find { val spanStart = text.getSpanStart(it) spanStart == off || (spanStart == off - 1 && text.getSpanEnd(it) == off) } - if (clickedList != null && clickedLine != null && clickedList.canToggle()) { + if (clickedLine != null && clickedList.canToggle()) { clickedLine.toggleCheck() clickedList.refresh() return true From 59b2013254b333fb6d8b60cd4c91ac9c4fa0d978 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Fri, 13 Mar 2026 13:18:45 -0400 Subject: [PATCH 3/3] Remove fixed-depth x-coordinate gate for task list taps The previous check rejected taps beyond a single leading margin width, preventing interaction with indented checkboxes. The handler now performs its own nesting-aware check, so the outer gate only needs to verify the editor is enabled. --- .../src/main/kotlin/org/wordpress/aztec/AztecText.kt | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt index b33cc9b3e..cd2f51bcd 100644 --- a/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt +++ b/aztec/src/main/kotlin/org/wordpress/aztec/AztecText.kt @@ -751,16 +751,11 @@ open class AztecText : AppCompatEditText, TextWatcher, UnknownHtmlSpan.OnUnknown x += scrollX y += scrollY - // We check whether the user tap on a checkbox of a task list. The aztec text field should be enabled and we - // check whether the tap event was on the leading margin which is where the checkbox is located plus a padding - // space used to increase the target size for the tap event. - if (isEnabled && - x + totalPaddingStart <= (blockFormatter.listStyleLeadingMargin() + AztecTaskListSpan.PADDING_SPACE)) { + // We check whether the user tap on a checkbox of a task list. The handler performs its + // own nesting-aware x-coordinate check, so we only need a rough gate here. + if (isEnabled) { val line = layout.getLineForVertical(y) val off = layout.getOffsetForHorizontal(line, x.toFloat()) - // If the tap event was on the leading margin, we double check whether we are tapping on a task list item. - // If that is true, then we return false because we don't want to propagate the tap event to stop moving - // the cursor to the item tapped. if (getTaskListHandler()?.handleTaskListClick( text, off,