summaryrefslogtreecommitdiff
path: root/internal/tui
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-06 16:01:46 +0200
committerPaul Buetow <paul@buetow.org>2026-03-06 16:01:46 +0200
commitfcee8baac995b25ffb9ab06567f010df105c3db1 (patch)
treecaeba14673afcdc66698d63ccfee8d1b535a41ed /internal/tui
parentaca5e2205b4dd18a13706c725daa0f326e10000b (diff)
refactor: thread runtime flags through ior and tui (task 385)
Diffstat (limited to 'internal/tui')
-rw-r--r--internal/tui/tui.go61
-rw-r--r--internal/tui/tui_test.go29
2 files changed, 63 insertions, 27 deletions
diff --git a/internal/tui/tui.go b/internal/tui/tui.go
index 12c904d..c1ba700 100644
--- a/internal/tui/tui.go
+++ b/internal/tui/tui.go
@@ -65,6 +65,7 @@ type TraceRuntimeBindings interface {
}
type runtimeBindingsContextKey struct{}
+type traceFiltersContextKey struct{}
type runtimeBindings struct {
mu sync.RWMutex
@@ -75,6 +76,11 @@ type runtimeBindings struct {
probeManager ProbeManager
}
+type traceFilters struct {
+ pidFilter int
+ tidFilter int
+}
+
func newRuntimeBindings() *runtimeBindings {
return &runtimeBindings{}
}
@@ -152,6 +158,21 @@ func RuntimeBindingsFromContext(ctx context.Context) (TraceRuntimeBindings, bool
return bindings, true
}
+// ContextWithTraceFilters stores the active PID/TID filters for the trace starter.
+func ContextWithTraceFilters(ctx context.Context, pidFilter, tidFilter int) context.Context {
+ filters := traceFilters{pidFilter: pidFilter, tidFilter: tidFilter}
+ return context.WithValue(ctx, traceFiltersContextKey{}, filters)
+}
+
+// TraceFiltersFromContext returns the active PID/TID filters when provided by the TUI model.
+func TraceFiltersFromContext(ctx context.Context) (pidFilter, tidFilter int, ok bool) {
+ filters, ok := ctx.Value(traceFiltersContextKey{}).(traceFilters)
+ if !ok {
+ return 0, 0, false
+ }
+ return filters.pidFilter, filters.tidFilter, true
+}
+
// Run starts the TUI program in alternate screen mode.
func Run() error {
return RunWithTraceStarter(defaultTraceStarter)
@@ -159,8 +180,12 @@ func Run() error {
// RunWithTraceStarter starts the TUI program with a custom trace starter.
func RunWithTraceStarter(starter TraceStarter) error {
- cfg := flags.Get()
- model := newModelWithRuntimeConfig(cfg.PidFilter, cfg.PidFilter, cfg.TUIExportEnable, starter)
+ return RunWithTraceStarterConfig(flags.Get(), starter)
+}
+
+// RunWithTraceStarterConfig starts the TUI with explicit runtime flags.
+func RunWithTraceStarterConfig(cfg flags.Flags, starter TraceStarter) error {
+ model := newModelWithRuntimeConfig(cfg.PidFilter, cfg.PidFilter, cfg.TidFilter, cfg.TUIExportEnable, starter)
program := tea.NewProgram(model)
_, err := program.Run()
return err
@@ -169,8 +194,12 @@ func RunWithTraceStarter(starter TraceStarter) error {
// RunTestFlamesWithTraceStarter starts the TUI directly on dashboard/flame view
// with a synthetic static flamegraph source.
func RunTestFlamesWithTraceStarter(starter TraceStarter) error {
- cfg := flags.Get()
- model := newModelWithRuntimeConfig(1, 1, cfg.TUIExportEnable, starter)
+ return RunTestFlamesWithTraceStarterConfig(flags.Get(), starter)
+}
+
+// RunTestFlamesWithTraceStarterConfig starts test-flames mode with explicit runtime flags.
+func RunTestFlamesWithTraceStarterConfig(cfg flags.Flags, starter TraceStarter) error {
+ model := newModelWithRuntimeConfig(1, 1, -1, cfg.TUIExportEnable, starter)
program := tea.NewProgram(model)
_, err := program.Run()
return err
@@ -201,6 +230,7 @@ type Model struct {
traceStop context.CancelFunc
pidFilter int
+ tidFilter int
exportEnabled bool
isDark bool
focused bool
@@ -220,11 +250,15 @@ type Model struct {
// NewModel creates the top-level TUI model.
func NewModel(initialPID int, startTrace TraceStarter) Model {
- cfg := flags.Get()
- return newModelWithRuntimeConfig(initialPID, cfg.PidFilter, cfg.TUIExportEnable, startTrace)
+ return NewModelWithConfig(flags.Get(), initialPID, startTrace)
}
-func newModelWithRuntimeConfig(initialPID, startupPidFilter int, exportEnabled bool, startTrace TraceStarter) Model {
+// NewModelWithConfig creates the top-level TUI model with explicit runtime flags.
+func NewModelWithConfig(cfg flags.Flags, initialPID int, startTrace TraceStarter) Model {
+ return newModelWithRuntimeConfig(initialPID, cfg.PidFilter, cfg.TidFilter, cfg.TUIExportEnable, startTrace)
+}
+
+func newModelWithRuntimeConfig(initialPID, startupPidFilter, startupTidFilter int, exportEnabled bool, startTrace TraceStarter) Model {
common.ApplyPalette(true)
syncStylesFromCommon()
@@ -245,6 +279,10 @@ func newModelWithRuntimeConfig(initialPID, startupPidFilter int, exportEnabled b
if initialPID > 0 {
pidFilter = selectedPIDFilter(initialPID)
}
+ tidFilter := selectedPIDFilter(startupTidFilter)
+ if initialPID > 0 {
+ tidFilter = -1
+ }
dashboard.SetPidFilter(pidFilter)
model := Model{
@@ -258,13 +296,13 @@ func newModelWithRuntimeConfig(initialPID, startupPidFilter int, exportEnabled b
spin: spin,
startTrace: startTrace,
pidFilter: pidFilter,
+ tidFilter: tidFilter,
exportEnabled: exportEnabled,
isDark: true,
focused: true,
}
if initialPID > 0 {
- flags.SetPidFilter(initialPID)
model.screen = ScreenDashboard
model.attaching = true
}
@@ -529,9 +567,8 @@ func (m Model) updateActiveModel(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m Model) handlePidSelected(msg PidSelectedMsg) (tea.Model, tea.Cmd) {
pid := selectedPIDFilter(msg.Pid)
m.stopTrace()
- flags.SetPidFilter(pid)
- flags.SetTidFilter(-1)
m.pidFilter = pid
+ m.tidFilter = -1
m.dashboard.SetPidFilter(pid)
m.screen = ScreenDashboard
m.attaching = true
@@ -546,9 +583,8 @@ func (m Model) handleTidSelected(msg TidSelectedMsg) (tea.Model, tea.Cmd) {
pid = msg.Pid
}
m.stopTrace()
- flags.SetPidFilter(pid)
- flags.SetTidFilter(tid)
m.pidFilter = pid
+ m.tidFilter = tid
m.dashboard.SetPidFilter(pid)
m.screen = ScreenDashboard
m.attaching = true
@@ -607,6 +643,7 @@ func (m *Model) beginTraceCmd() tea.Cmd {
ctx, cancel := context.WithCancel(context.Background())
m.traceStop = cancel
ctx = context.WithValue(ctx, runtimeBindingsContextKey{}, m.runtime)
+ ctx = ContextWithTraceFilters(ctx, m.pidFilter, m.tidFilter)
return startTraceCmd(m.startTrace, ctx)
}
diff --git a/internal/tui/tui_test.go b/internal/tui/tui_test.go
index cd9e6cd..ad529fc 100644
--- a/internal/tui/tui_test.go
+++ b/internal/tui/tui_test.go
@@ -51,11 +51,11 @@ func TestPidSelectedTransitionsToDashboardAndSetsPIDFilter(t *testing.T) {
if !updated.attaching {
t.Fatalf("expected attaching state to be true")
}
- if got := flags.Get().PidFilter; got != 42 {
- t.Fatalf("expected pid filter 42, got %d", got)
+ if updated.pidFilter != 42 {
+ t.Fatalf("expected pid filter 42, got %d", updated.pidFilter)
}
- if got := flags.Get().TidFilter; got != -1 {
- t.Fatalf("expected tid filter reset to -1, got %d", got)
+ if updated.tidFilter != -1 {
+ t.Fatalf("expected tid filter reset to -1, got %d", updated.tidFilter)
}
}
@@ -80,10 +80,9 @@ func TestPidSelectedAllSetsNoFilter(t *testing.T) {
next, _ := m.Update(PidSelectedMsg{Pid: 0})
updated := next.(Model)
- if got := flags.Get().PidFilter; got != -1 {
- t.Fatalf("expected pid filter -1 for all pids, got %d", got)
+ if updated.pidFilter != -1 {
+ t.Fatalf("expected pid filter -1 for all pids, got %d", updated.pidFilter)
}
- _ = updated
}
func TestTracingErrorMessageClearsAttachingState(t *testing.T) {
@@ -623,11 +622,11 @@ func TestTidSelectedTransitionsToDashboardAndSetsTIDFilter(t *testing.T) {
if !updated.attaching {
t.Fatalf("expected attaching state to be true")
}
- if got := flags.Get().TidFilter; got != 3333 {
- t.Fatalf("expected tid filter 3333, got %d", got)
+ if updated.tidFilter != 3333 {
+ t.Fatalf("expected tid filter 3333, got %d", updated.tidFilter)
}
- if got := flags.Get().PidFilter; got != 2222 {
- t.Fatalf("expected pid filter to remain 2222, got %d", got)
+ if updated.pidFilter != 2222 {
+ t.Fatalf("expected pid filter to remain 2222, got %d", updated.pidFilter)
}
}
@@ -644,11 +643,11 @@ func TestTidSelectedFromAllPIDModeSetsOwningPID(t *testing.T) {
if updated.screen != ScreenDashboard {
t.Fatalf("expected dashboard screen, got %v", updated.screen)
}
- if got := flags.Get().PidFilter; got != 4444 {
- t.Fatalf("expected pid filter switched to owning pid 4444, got %d", got)
+ if updated.pidFilter != 4444 {
+ t.Fatalf("expected pid filter switched to owning pid 4444, got %d", updated.pidFilter)
}
- if got := flags.Get().TidFilter; got != 5555 {
- t.Fatalf("expected tid filter 5555, got %d", got)
+ if updated.tidFilter != 5555 {
+ t.Fatalf("expected tid filter 5555, got %d", updated.tidFilter)
}
}