Bug: Las flechas no movían la selección en AdvancedTable. Causa raíz: - handleKeyboard seteaba result.selection_changed = true - PERO NO seteaba result.selected_row / result.selected_col - zsimifactu sincroniza selección desde DataManager cada frame - Sin esos valores, DataManager no se actualizaba - Siguiente frame: selección se reseteaba al valor anterior Solución: - Añadir result.selected_row y result.selected_col a todas las teclas de navegación (up, down, left, right, page_up, page_down, home, end) Cambios visuales: - Celda seleccionada: borde + tinte sutil (15%) en lugar de fondo sólido azul 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.3 KiB
Bug: AdvancedTable Keyboard Navigation No Funciona
Fecha: 2025-12-17 Estado: ✅ RESUELTO Severidad: ALTA
Síntoma
Las flechas de teclado no mueven la selección en AdvancedTable cuando se usa en zsimifactu.
Causa Raíz (ENCONTRADA)
El problema era una combinación de dos factores:
1. handleKeyboard no seteaba result.selected_row / result.selected_col
En el código original:
.down => {
if (table_state.selected_row < row_count - 1) {
table_state.selectCell(...);
result.selection_changed = true;
// FALTABA: result.selected_row = new_row;
// FALTABA: result.selected_col = new_col;
}
},
2. zsimifactu sincroniza la selección desde DataManager cada frame
En who_list_advanced.zig líneas 199-205:
// Sincronizar selección con DataManager
if (dm.getSelectedWhoIndex()) |idx| {
const idx_i32: i32 = @intCast(idx);
if (self.table_state.selected_row != idx_i32) {
self.table_state.selected_row = idx_i32; // ← RESETEA cada frame
}
}
Flujo del bug:
- Usuario presiona flecha abajo
handleKeyboarddetecta la tecla y ejecutaselectCell(new_row, new_col)selected_rowcambia de 1 a 2 ✓result.selection_changed = true✓- PERO
result.selected_rowesnull✗ - zsimifactu verifica
if (result.selected_row) |row_idx|→ es null → no actualiza DataManager - Siguiente frame: zsimifactu sincroniza desde DataManager →
selected_rowvuelve a 1
Solución
Añadir result.selected_row y result.selected_col a todas las teclas de navegación en handleKeyboard:
.down => {
if (table_state.selected_row < @as(i32, @intCast(row_count)) - 1) {
const new_row: usize = @intCast(table_state.selected_row + 1);
const new_col: usize = @intCast(@max(0, table_state.selected_col));
table_state.selectCell(new_row, new_col);
result.selection_changed = true;
result.selected_row = new_row; // ← AÑADIDO
result.selected_col = new_col; // ← AÑADIDO
}
},
Teclas corregidas:
.up.down.left.right.page_up.page_down.home(y Ctrl+Home).end(y Ctrl+End)
Verificación
Debug añadido temporalmente mostró:
[ADV-TABLE] DOWN: after selectCell, selected_row=2 ← SÍ cambia
[ADV-TABLE] navKey detected: down, selected_row=1 ← Pero vuelve a 1 en siguiente frame
Después del fix, las flechas funcionan correctamente.
Archivos modificados
src/widgets/advanced_table/advanced_table.zig- handleKeyboard corregido
Lecciones aprendidas
-
El resultado de un widget debe ser completo - Si
selection_changed = true, también debe informar QUÉ cambió (selected_row,selected_col). -
Cuidado con la sincronización bidireccional - Cuando un widget y un data manager ambos pueden modificar el mismo estado, hay que asegurar que los cambios del widget se propaguen al data manager antes de que éste resetee el estado.
-
Debug incremental - Añadir debug DENTRO de la función problemática (no antes) para ver el flujo real.
Documentado por: Claude Code (Opus 4.5) Fecha resolución: 2025-12-17 ~19:30