fix(focus): sync StackedView visibility on stack navigation
- commit
- 05af9591e877b9b1019c19480696d8c2fe81b9d6
- author
- brice · · 2025-12-15 22:39 UTC
- committer
- brice · · 2025-12-15 19:52 UTC
- parent
- 8cb6471
- signature
- unsigned
1 file · +39 -0
M internal/ui/app.go +39 -0
| @@ -710,11 +710,50 @@ func (a *App) handlePaneFocus(ctx context.Context, direction usecase.NavigateDir | |||
| 710 | 710 | wsView.FocusPane(newPane.Pane.ID) | |
| 711 | 711 | } | |
| 712 | 712 | ||
| 713 | + | // Sync StackedView visibility if new pane is in a stack | |
| 714 | + | if newPane.Parent != nil && newPane.Parent.IsStacked { | |
| 715 | + | a.syncStackedViewActive(ctx, wsView, newPane) | |
| 716 | + | } | |
| 717 | + | ||
| 713 | 718 | log.Debug().Str("direction", string(direction)).Str("new_pane_id", newPane.ID).Msg("focus navigated") | |
| 714 | 719 | ||
| 715 | 720 | return nil | |
| 716 | 721 | } | |
| 717 | 722 | ||
| 723 | + | // syncStackedViewActive updates the StackedView's visibility to match the domain model. | |
| 724 | + | // Call this after navigating focus to a pane inside a stack. | |
| 725 | + | func (a *App) syncStackedViewActive(ctx context.Context, wsView *component.WorkspaceView, paneNode *entity.PaneNode) { | |
| 726 | + | log := logging.FromContext(ctx) | |
| 727 | + | ||
| 728 | + | if paneNode == nil || paneNode.Parent == nil || !paneNode.Parent.IsStacked { | |
| 729 | + | return | |
| 730 | + | } | |
| 731 | + | ||
| 732 | + | tr := wsView.TreeRenderer() | |
| 733 | + | if tr == nil { | |
| 734 | + | return | |
| 735 | + | } | |
| 736 | + | ||
| 737 | + | // Get the StackedView for this pane | |
| 738 | + | stackedView := tr.GetStackedViewForPane(string(paneNode.Pane.ID)) | |
| 739 | + | if stackedView == nil { | |
| 740 | + | log.Warn().Str("pane_id", string(paneNode.Pane.ID)).Msg("stacked view not found for pane") | |
| 741 | + | return | |
| 742 | + | } | |
| 743 | + | ||
| 744 | + | // Use the parent's ActiveStackIndex which was set by the focus manager | |
| 745 | + | stackIndex := paneNode.Parent.ActiveStackIndex | |
| 746 | + | ||
| 747 | + | log.Debug(). | |
| 748 | + | Str("pane_id", string(paneNode.Pane.ID)). | |
| 749 | + | Int("stack_index", stackIndex). | |
| 750 | + | Msg("syncing stacked view visibility") | |
| 751 | + | ||
| 752 | + | if err := stackedView.SetActive(ctx, stackIndex); err != nil { | |
| 753 | + | log.Warn().Err(err).Msg("failed to set stacked view active index") | |
| 754 | + | } | |
| 755 | + | } | |
| 756 | + | ||
| 718 | 757 | // handleStackPane adds a new pane stacked on top of the active pane. | |
| 719 | 758 | // This modifies both the domain tree and the UI StackedView. | |
| 720 | 759 | func (a *App) handleStackPane(ctx context.Context) error { | |
| @@ -710,11 +710,50 @@ func (a *App) handlePaneFocus(ctx context.Context, direction usecase.NavigateDir | |||||
| 710 | wsView.FocusPane(newPane.Pane.ID) | 710 | wsView.FocusPane(newPane.Pane.ID) | ||
| 711 | } | 711 | } | ||
| 712 | 712 | ||||
| 713 | + | // Sync StackedView visibility if new pane is in a stack | |||
| 714 | + | if newPane.Parent != nil && newPane.Parent.IsStacked { | |||
| 715 | + | a.syncStackedViewActive(ctx, wsView, newPane) | |||
| 716 | + | } | |||
| 717 | + | ||||
| 713 | log.Debug().Str("direction", string(direction)).Str("new_pane_id", newPane.ID).Msg("focus navigated") | 718 | log.Debug().Str("direction", string(direction)).Str("new_pane_id", newPane.ID).Msg("focus navigated") | ||
| 714 | 719 | ||||
| 715 | return nil | 720 | return nil | ||
| 716 | } | 721 | } | ||
| 717 | 722 | ||||
| 723 | + | // syncStackedViewActive updates the StackedView's visibility to match the domain model. | |||
| 724 | + | // Call this after navigating focus to a pane inside a stack. | |||
| 725 | + | func (a *App) syncStackedViewActive(ctx context.Context, wsView *component.WorkspaceView, paneNode *entity.PaneNode) { | |||
| 726 | + | log := logging.FromContext(ctx) | |||
| 727 | + | ||||
| 728 | + | if paneNode == nil || paneNode.Parent == nil || !paneNode.Parent.IsStacked { | |||
| 729 | + | return | |||
| 730 | + | } | |||
| 731 | + | ||||
| 732 | + | tr := wsView.TreeRenderer() | |||
| 733 | + | if tr == nil { | |||
| 734 | + | return | |||
| 735 | + | } | |||
| 736 | + | ||||
| 737 | + | // Get the StackedView for this pane | |||
| 738 | + | stackedView := tr.GetStackedViewForPane(string(paneNode.Pane.ID)) | |||
| 739 | + | if stackedView == nil { | |||
| 740 | + | log.Warn().Str("pane_id", string(paneNode.Pane.ID)).Msg("stacked view not found for pane") | |||
| 741 | + | return | |||
| 742 | + | } | |||
| 743 | + | ||||
| 744 | + | // Use the parent's ActiveStackIndex which was set by the focus manager | |||
| 745 | + | stackIndex := paneNode.Parent.ActiveStackIndex | |||
| 746 | + | ||||
| 747 | + | log.Debug(). | |||
| 748 | + | Str("pane_id", string(paneNode.Pane.ID)). | |||
| 749 | + | Int("stack_index", stackIndex). | |||
| 750 | + | Msg("syncing stacked view visibility") | |||
| 751 | + | ||||
| 752 | + | if err := stackedView.SetActive(ctx, stackIndex); err != nil { | |||
| 753 | + | log.Warn().Err(err).Msg("failed to set stacked view active index") | |||
| 754 | + | } | |||
| 755 | + | } | |||
| 756 | + | ||||
| 718 | // handleStackPane adds a new pane stacked on top of the active pane. | 757 | // handleStackPane adds a new pane stacked on top of the active pane. | ||
| 719 | // This modifies both the domain tree and the UI StackedView. | 758 | // This modifies both the domain tree and the UI StackedView. | ||
| 720 | func (a *App) handleStackPane(ctx context.Context) error { | 759 | func (a *App) handleStackPane(ctx context.Context) error { | ||