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>
116 lines
3.3 KiB
Markdown
116 lines
3.3 KiB
Markdown
# 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:
|
|
```zig
|
|
.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:
|
|
```zig
|
|
// 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:
|
|
|
|
1. Usuario presiona flecha abajo
|
|
2. `handleKeyboard` detecta la tecla y ejecuta `selectCell(new_row, new_col)`
|
|
3. `selected_row` cambia de 1 a 2 ✓
|
|
4. `result.selection_changed = true` ✓
|
|
5. **PERO** `result.selected_row` es `null` ✗
|
|
6. zsimifactu verifica `if (result.selected_row) |row_idx|` → es null → no actualiza DataManager
|
|
7. Siguiente frame: zsimifactu sincroniza desde DataManager → `selected_row` vuelve a 1
|
|
|
|
---
|
|
|
|
## Solución
|
|
|
|
Añadir `result.selected_row` y `result.selected_col` a todas las teclas de navegación en `handleKeyboard`:
|
|
|
|
```zig
|
|
.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
|
|
|
|
1. **El resultado de un widget debe ser completo** - Si `selection_changed = true`, también debe informar QUÉ cambió (`selected_row`, `selected_col`).
|
|
|
|
2. **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.
|
|
|
|
3. **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*
|