From 552b0751b9194df5fe78a0530e5455defb2d9f8d Mon Sep 17 00:00:00 2001 From: Virgil Date: Tue, 31 Mar 2026 06:10:54 +0000 Subject: [PATCH] refactor(ax): route saved window state via ipc --- pkg/display/display.go | 32 +++++++++++--------------------- pkg/display/display_test.go | 16 +++++++++++++++- pkg/window/messages.go | 4 ++++ pkg/window/service.go | 16 ++++++++++++++++ pkg/window/service_test.go | 29 +++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 22 deletions(-) diff --git a/pkg/display/display.go b/pkg/display/display.go index 3789e4b..99d73ba 100644 --- a/pkg/display/display.go +++ b/pkg/display/display.go @@ -578,15 +578,6 @@ func (s *Service) persistSection(key string, value map[string]any) { // --- Service accessors --- -// windowService returns the window service from Core, or nil if not registered. -func (s *Service) windowService() *window.Service { - svc, err := core.ServiceFor[*window.Service](s.Core(), "window") - if err != nil { - return nil - } - return svc -} - // --- Window Management (delegates via IPC) --- // OpenWindow creates a new window from a declarative Window spec. @@ -726,26 +717,25 @@ func (s *Service) GetWindowTitle(name string) (string, error) { // ResetWindowState clears saved window positions. func (s *Service) ResetWindowState() error { - ws := s.windowService() - if ws != nil { - ws.Manager().State().Clear() - } + _, _, _ = s.Core().PERFORM(window.TaskResetWindowState{}) return nil } // GetSavedWindowStates returns all saved window states. func (s *Service) GetSavedWindowStates() map[string]window.WindowState { - ws := s.windowService() - if ws == nil { + result, handled, _ := s.Core().QUERY(window.QuerySavedWindowStates{}) + if !handled { return nil } - result := make(map[string]window.WindowState) - for _, name := range ws.Manager().State().ListStates() { - if state, ok := ws.Manager().State().GetState(name); ok { - result[name] = state - } + saved, _ := result.(map[string]window.WindowState) + if saved == nil { + return nil } - return result + out := make(map[string]window.WindowState, len(saved)) + for name, state := range saved { + out[name] = state + } + return out } // CreateWindow creates a new named window from a declarative Window spec. diff --git a/pkg/display/display_test.go b/pkg/display/display_test.go index e666c68..d67c26f 100644 --- a/pkg/display/display_test.go +++ b/pkg/display/display_test.go @@ -393,16 +393,30 @@ func TestResetWindowState_Good(t *testing.T) { c := newTestConclave(t) svc := core.MustServiceFor[*Service](c, "display") - err := svc.ResetWindowState() + _ = svc.OpenWindow(window.Window{Name: "reset-win"}) + err := svc.SetWindowPosition("reset-win", 42, 84) + require.NoError(t, err) + + err = svc.ResetWindowState() assert.NoError(t, err) + + states := svc.GetSavedWindowStates() + assert.Empty(t, states) } func TestGetSavedWindowStates_Good(t *testing.T) { c := newTestConclave(t) svc := core.MustServiceFor[*Service](c, "display") + _ = svc.OpenWindow(window.Window{Name: "saved-win"}) + err := svc.SetWindowPosition("saved-win", 12, 34) + require.NoError(t, err) + states := svc.GetSavedWindowStates() assert.NotNil(t, states) + require.Contains(t, states, "saved-win") + assert.Equal(t, 12, states["saved-win"].X) + assert.Equal(t, 34, states["saved-win"].Y) } func TestHandleIPCEvents_WindowOpened_Good(t *testing.T) { diff --git a/pkg/window/messages.go b/pkg/window/messages.go index 9a79612..bdb3791 100644 --- a/pkg/window/messages.go +++ b/pkg/window/messages.go @@ -17,6 +17,8 @@ type QueryWindowByName struct{ Name string } type QueryConfig struct{} +type QuerySavedWindowStates struct{} + type TaskOpenWindow struct { Window Window } @@ -79,6 +81,8 @@ type TaskRestoreLayout struct{ Name string } type TaskDeleteLayout struct{ Name string } +type TaskResetWindowState struct{} + type TaskTileWindows struct { Mode string // "left-right", "grid", "left-half", "right-half", etc. Windows []string // window names; empty = all diff --git a/pkg/window/service.go b/pkg/window/service.go index 6192a89..14bd0fa 100644 --- a/pkg/window/service.go +++ b/pkg/window/service.go @@ -59,6 +59,8 @@ func (s *Service) handleQuery(c *core.Core, q core.Query) (any, bool, error) { return s.queryWindowList(), true, nil case QueryWindowByName: return s.queryWindowByName(q.Name), true, nil + case QuerySavedWindowStates: + return s.querySavedWindowStates(), true, nil case QueryLayoutList: return s.manager.Layout().ListLayouts(), true, nil case QueryLayoutGet: @@ -103,6 +105,17 @@ func (s *Service) queryWindowByName(name string) *WindowInfo { } } +func (s *Service) querySavedWindowStates() map[string]WindowState { + stateNames := s.manager.State().ListStates() + result := make(map[string]WindowState, len(stateNames)) + for _, name := range stateNames { + if state, ok := s.manager.State().GetState(name); ok { + result[name] = state + } + } + return result +} + // --- Task Handlers --- func (s *Service) handleTask(c *core.Core, t core.Task) (any, bool, error) { @@ -140,6 +153,9 @@ func (s *Service) handleTask(c *core.Core, t core.Task) (any, bool, error) { case TaskDeleteLayout: s.manager.Layout().DeleteLayout(t.Name) return nil, true, nil + case TaskResetWindowState: + s.manager.State().Clear() + return nil, true, nil case TaskTileWindows: return nil, true, s.taskTileWindows(t.Mode, t.Windows) case TaskStackWindows: diff --git a/pkg/window/service_test.go b/pkg/window/service_test.go index 64a332d..d39bde7 100644 --- a/pkg/window/service_test.go +++ b/pkg/window/service_test.go @@ -89,6 +89,21 @@ func TestQueryWindowByName_Bad(t *testing.T) { assert.Nil(t, result) } +func TestQuerySavedWindowStates_Good(t *testing.T) { + _, c := newTestWindowService(t) + _, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}}) + _, _, _ = c.PERFORM(TaskSetPosition{Name: "test", X: 120, Y: 240}) + + result, handled, err := c.QUERY(QuerySavedWindowStates{}) + require.NoError(t, err) + assert.True(t, handled) + + states := result.(map[string]WindowState) + require.Contains(t, states, "test") + assert.Equal(t, 120, states["test"].X) + assert.Equal(t, 240, states["test"].Y) +} + func TestTaskCloseWindow_Good(t *testing.T) { _, c := newTestWindowService(t) _, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}}) @@ -109,6 +124,20 @@ func TestTaskCloseWindow_Bad(t *testing.T) { assert.Error(t, err) } +func TestTaskResetWindowState_Good(t *testing.T) { + _, c := newTestWindowService(t) + _, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}}) + _, _, _ = c.PERFORM(TaskSetPosition{Name: "test", X: 80, Y: 90}) + + _, handled, err := c.PERFORM(TaskResetWindowState{}) + require.NoError(t, err) + assert.True(t, handled) + + result, _, err := c.QUERY(QuerySavedWindowStates{}) + require.NoError(t, err) + assert.Empty(t, result.(map[string]WindowState)) +} + func TestTaskSetPosition_Good(t *testing.T) { _, c := newTestWindowService(t) _, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})