refactor(ax): replace window option chains with declarative specs
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
089bdacadb
commit
f0a1f9027b
10 changed files with 143 additions and 305 deletions
|
|
@ -115,7 +115,7 @@ func (s *Service) HandleIPCEvents(c *core.Core, msg core.Message) error {
|
|||
case window.ActionWindowResized:
|
||||
if s.events != nil {
|
||||
s.events.Emit(Event{Type: EventWindowResize, Window: m.Name,
|
||||
Data: map[string]any{"w": m.Width, "h": m.Height}})
|
||||
Data: map[string]any{"width": m.Width, "height": m.Height}})
|
||||
}
|
||||
case window.ActionWindowFocused:
|
||||
if s.events != nil {
|
||||
|
|
@ -474,13 +474,16 @@ func (s *Service) handleWSMessage(msg WSMessage) (any, bool, error) {
|
|||
func (s *Service) handleTrayAction(actionID string) {
|
||||
switch actionID {
|
||||
case "open-desktop":
|
||||
// Show all windows
|
||||
infos := s.ListWindowInfos()
|
||||
for _, info := range infos {
|
||||
_, _, _ = s.Core().PERFORM(window.TaskSetVisibility{Name: info.Name, Visible: true})
|
||||
_, _, _ = s.Core().PERFORM(window.TaskFocus{Name: info.Name})
|
||||
}
|
||||
case "close-desktop":
|
||||
// Hide all windows — future: add TaskHideWindow
|
||||
infos := s.ListWindowInfos()
|
||||
for _, info := range infos {
|
||||
_, _, _ = s.Core().PERFORM(window.TaskSetVisibility{Name: info.Name, Visible: false})
|
||||
}
|
||||
case "env-info":
|
||||
// Query environment info via IPC and show as dialog
|
||||
result, handled, _ := s.Core().QUERY(environment.QueryInfo{})
|
||||
|
|
@ -586,13 +589,9 @@ func (s *Service) windowService() *window.Service {
|
|||
|
||||
// --- Window Management (delegates via IPC) ---
|
||||
|
||||
// OpenWindow creates a new window via IPC.
|
||||
func (s *Service) OpenWindow(options ...window.WindowOption) error {
|
||||
spec, err := window.ApplyOptions(options...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _, err = s.Core().PERFORM(window.TaskOpenWindow{Window: spec})
|
||||
// OpenWindow creates a new window from a declarative Window spec.
|
||||
func (s *Service) OpenWindow(spec window.Window) error {
|
||||
_, _, err := s.Core().PERFORM(window.TaskOpenWindow{Window: spec})
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -749,32 +748,13 @@ func (s *Service) GetSavedWindowStates() map[string]window.WindowState {
|
|||
return result
|
||||
}
|
||||
|
||||
// CreateWindowOptions contains options for creating a new window.
|
||||
type CreateWindowOptions struct {
|
||||
Name string `json:"name"`
|
||||
Title string `json:"title,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
X int `json:"x,omitempty"`
|
||||
Y int `json:"y,omitempty"`
|
||||
Width int `json:"width,omitempty"`
|
||||
Height int `json:"height,omitempty"`
|
||||
}
|
||||
|
||||
// CreateWindow creates a new window with the specified options.
|
||||
func (s *Service) CreateWindow(options CreateWindowOptions) (*window.WindowInfo, error) {
|
||||
if options.Name == "" {
|
||||
// CreateWindow creates a new named window from a declarative Window spec.
|
||||
func (s *Service) CreateWindow(spec window.Window) (*window.WindowInfo, error) {
|
||||
if spec.Name == "" {
|
||||
return nil, coreerr.E("display.CreateWindow", "window name is required", nil)
|
||||
}
|
||||
result, _, err := s.Core().PERFORM(window.TaskOpenWindow{
|
||||
Window: &window.Window{
|
||||
Name: options.Name,
|
||||
Title: options.Title,
|
||||
URL: options.URL,
|
||||
Width: options.Width,
|
||||
Height: options.Height,
|
||||
X: options.X,
|
||||
Y: options.Y,
|
||||
},
|
||||
Window: spec,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -897,7 +877,7 @@ func ptr[T any](v T) *T { return &v }
|
|||
|
||||
func (s *Service) handleNewWorkspace() {
|
||||
_, _, _ = s.Core().PERFORM(window.TaskOpenWindow{
|
||||
Window: &window.Window{
|
||||
Window: window.Window{
|
||||
Name: "workspace-new",
|
||||
Title: "New Workspace",
|
||||
URL: "/workspace/new",
|
||||
|
|
@ -921,7 +901,7 @@ func (s *Service) handleListWorkspaces() {
|
|||
|
||||
func (s *Service) handleNewFile() {
|
||||
_, _, _ = s.Core().PERFORM(window.TaskOpenWindow{
|
||||
Window: &window.Window{
|
||||
Window: window.Window{
|
||||
Name: "editor",
|
||||
Title: "New File - Editor",
|
||||
URL: "/#/developer/editor?new=true",
|
||||
|
|
@ -946,7 +926,7 @@ func (s *Service) handleOpenFile() {
|
|||
return
|
||||
}
|
||||
_, _, _ = s.Core().PERFORM(window.TaskOpenWindow{
|
||||
Window: &window.Window{
|
||||
Window: window.Window{
|
||||
Name: "editor",
|
||||
Title: paths[0] + " - Editor",
|
||||
URL: "/#/developer/editor?file=" + paths[0],
|
||||
|
|
@ -959,7 +939,7 @@ func (s *Service) handleOpenFile() {
|
|||
func (s *Service) handleSaveFile() { _ = s.Core().ACTION(ActionIDECommand{Command: "save"}) }
|
||||
func (s *Service) handleOpenEditor() {
|
||||
_, _, _ = s.Core().PERFORM(window.TaskOpenWindow{
|
||||
Window: &window.Window{
|
||||
Window: window.Window{
|
||||
Name: "editor",
|
||||
Title: "Editor",
|
||||
URL: "/#/developer/editor",
|
||||
|
|
@ -970,7 +950,7 @@ func (s *Service) handleOpenEditor() {
|
|||
}
|
||||
func (s *Service) handleOpenTerminal() {
|
||||
_, _, _ = s.Core().PERFORM(window.TaskOpenWindow{
|
||||
Window: &window.Window{
|
||||
Window: window.Window{
|
||||
Name: "terminal",
|
||||
Title: "Terminal",
|
||||
URL: "/#/developer/terminal",
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ func TestServiceConclave_Good(t *testing.T) {
|
|||
|
||||
// Open a window via IPC
|
||||
result, handled, err := c.PERFORM(window.TaskOpenWindow{
|
||||
Window: &window.Window{Name: "main"},
|
||||
Window: window.Window{Name: "main"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, handled)
|
||||
|
|
@ -167,8 +167,8 @@ func TestOpenWindow_Good(t *testing.T) {
|
|||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
|
||||
t.Run("creates window with default options", func(t *testing.T) {
|
||||
err := svc.OpenWindow()
|
||||
t.Run("creates window with default spec", func(t *testing.T) {
|
||||
err := svc.OpenWindow(window.Window{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Verify via IPC query
|
||||
|
|
@ -176,13 +176,14 @@ func TestOpenWindow_Good(t *testing.T) {
|
|||
assert.GreaterOrEqual(t, len(infos), 1)
|
||||
})
|
||||
|
||||
t.Run("creates window with custom options", func(t *testing.T) {
|
||||
err := svc.OpenWindow(
|
||||
window.WithName("custom-window"),
|
||||
window.WithTitle("Custom Title"),
|
||||
window.WithSize(640, 480),
|
||||
window.WithURL("/custom"),
|
||||
)
|
||||
t.Run("creates window with custom spec", func(t *testing.T) {
|
||||
err := svc.OpenWindow(window.Window{
|
||||
Name: "custom-window",
|
||||
Title: "Custom Title",
|
||||
Width: 640,
|
||||
Height: 480,
|
||||
URL: "/custom",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
result, _, _ := c.QUERY(window.QueryWindowByName{Name: "custom-window"})
|
||||
|
|
@ -195,10 +196,7 @@ func TestGetWindowInfo_Good(t *testing.T) {
|
|||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
|
||||
_ = svc.OpenWindow(
|
||||
window.WithName("test-win"),
|
||||
window.WithSize(800, 600),
|
||||
)
|
||||
_ = svc.OpenWindow(window.Window{Name: "test-win", Width: 800, Height: 600})
|
||||
|
||||
// Modify position via IPC
|
||||
_, _, _ = c.PERFORM(window.TaskSetPosition{Name: "test-win", X: 100, Y: 200})
|
||||
|
|
@ -226,8 +224,8 @@ func TestListWindowInfos_Good(t *testing.T) {
|
|||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
|
||||
_ = svc.OpenWindow(window.WithName("win-1"))
|
||||
_ = svc.OpenWindow(window.WithName("win-2"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "win-1"})
|
||||
_ = svc.OpenWindow(window.Window{Name: "win-2"})
|
||||
|
||||
infos := svc.ListWindowInfos()
|
||||
assert.Len(t, infos, 2)
|
||||
|
|
@ -236,7 +234,7 @@ func TestListWindowInfos_Good(t *testing.T) {
|
|||
func TestSetWindowPosition_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("pos-win"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "pos-win"})
|
||||
|
||||
err := svc.SetWindowPosition("pos-win", 300, 400)
|
||||
assert.NoError(t, err)
|
||||
|
|
@ -257,7 +255,7 @@ func TestSetWindowPosition_Bad(t *testing.T) {
|
|||
func TestSetWindowSize_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("size-win"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "size-win"})
|
||||
|
||||
err := svc.SetWindowSize("size-win", 1024, 768)
|
||||
assert.NoError(t, err)
|
||||
|
|
@ -270,7 +268,7 @@ func TestSetWindowSize_Good(t *testing.T) {
|
|||
func TestMaximizeWindow_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("max-win"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "max-win"})
|
||||
|
||||
err := svc.MaximizeWindow("max-win")
|
||||
assert.NoError(t, err)
|
||||
|
|
@ -282,7 +280,7 @@ func TestMaximizeWindow_Good(t *testing.T) {
|
|||
func TestRestoreWindow_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("restore-win"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "restore-win"})
|
||||
_ = svc.MaximizeWindow("restore-win")
|
||||
|
||||
err := svc.RestoreWindow("restore-win")
|
||||
|
|
@ -295,7 +293,7 @@ func TestRestoreWindow_Good(t *testing.T) {
|
|||
func TestFocusWindow_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("focus-win"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "focus-win"})
|
||||
|
||||
err := svc.FocusWindow("focus-win")
|
||||
assert.NoError(t, err)
|
||||
|
|
@ -307,7 +305,7 @@ func TestFocusWindow_Good(t *testing.T) {
|
|||
func TestCloseWindow_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("close-win"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "close-win"})
|
||||
|
||||
err := svc.CloseWindow("close-win")
|
||||
assert.NoError(t, err)
|
||||
|
|
@ -320,7 +318,7 @@ func TestCloseWindow_Good(t *testing.T) {
|
|||
func TestSetWindowVisibility_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("vis-win"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "vis-win"})
|
||||
|
||||
err := svc.SetWindowVisibility("vis-win", false)
|
||||
assert.NoError(t, err)
|
||||
|
|
@ -332,7 +330,7 @@ func TestSetWindowVisibility_Good(t *testing.T) {
|
|||
func TestSetWindowAlwaysOnTop_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("ontop-win"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "ontop-win"})
|
||||
|
||||
err := svc.SetWindowAlwaysOnTop("ontop-win", true)
|
||||
assert.NoError(t, err)
|
||||
|
|
@ -341,7 +339,7 @@ func TestSetWindowAlwaysOnTop_Good(t *testing.T) {
|
|||
func TestSetWindowTitle_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("title-win"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "title-win"})
|
||||
|
||||
err := svc.SetWindowTitle("title-win", "New Title")
|
||||
assert.NoError(t, err)
|
||||
|
|
@ -350,8 +348,8 @@ func TestSetWindowTitle_Good(t *testing.T) {
|
|||
func TestGetFocusedWindow_Good(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("win-a"))
|
||||
_ = svc.OpenWindow(window.WithName("win-b"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "win-a"})
|
||||
_ = svc.OpenWindow(window.Window{Name: "win-b"})
|
||||
_ = svc.FocusWindow("win-b")
|
||||
|
||||
focused := svc.GetFocusedWindow()
|
||||
|
|
@ -361,7 +359,7 @@ func TestGetFocusedWindow_Good(t *testing.T) {
|
|||
func TestGetFocusedWindow_NoneSelected(t *testing.T) {
|
||||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
_ = svc.OpenWindow(window.WithName("win-a"))
|
||||
_ = svc.OpenWindow(window.Window{Name: "win-a"})
|
||||
|
||||
focused := svc.GetFocusedWindow()
|
||||
assert.Equal(t, "", focused)
|
||||
|
|
@ -371,7 +369,7 @@ func TestCreateWindow_Good(t *testing.T) {
|
|||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
|
||||
info, err := svc.CreateWindow(CreateWindowOptions{
|
||||
info, err := svc.CreateWindow(window.Window{
|
||||
Name: "new-win",
|
||||
Title: "New Window",
|
||||
URL: "/new",
|
||||
|
|
@ -386,7 +384,7 @@ func TestCreateWindow_Bad(t *testing.T) {
|
|||
c := newTestConclave(t)
|
||||
svc := core.MustServiceFor[*Service](c, "display")
|
||||
|
||||
_, err := svc.CreateWindow(CreateWindowOptions{})
|
||||
_, err := svc.CreateWindow(window.Window{})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "window name is required")
|
||||
}
|
||||
|
|
@ -413,7 +411,7 @@ func TestHandleIPCEvents_WindowOpened_Good(t *testing.T) {
|
|||
// Open a window — this should trigger ActionWindowOpened
|
||||
// which HandleIPCEvents should convert to a WS event
|
||||
result, handled, err := c.PERFORM(window.TaskOpenWindow{
|
||||
Window: &window.Window{Name: "test"},
|
||||
Window: window.Window{Name: "test"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, handled)
|
||||
|
|
|
|||
|
|
@ -75,30 +75,13 @@ func (s *Subsystem) windowFocused(_ context.Context, _ *mcp.CallToolRequest, _ W
|
|||
|
||||
// --- window_create ---
|
||||
|
||||
type WindowCreateInput struct {
|
||||
Name string `json:"name"`
|
||||
Title string `json:"title,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
X int `json:"x,omitempty"`
|
||||
Y int `json:"y,omitempty"`
|
||||
Width int `json:"width,omitempty"`
|
||||
Height int `json:"height,omitempty"`
|
||||
}
|
||||
type WindowCreateOutput struct {
|
||||
Window window.WindowInfo `json:"window"`
|
||||
}
|
||||
|
||||
func (s *Subsystem) windowCreate(_ context.Context, _ *mcp.CallToolRequest, input WindowCreateInput) (*mcp.CallToolResult, WindowCreateOutput, error) {
|
||||
func (s *Subsystem) windowCreate(_ context.Context, _ *mcp.CallToolRequest, input window.Window) (*mcp.CallToolResult, WindowCreateOutput, error) {
|
||||
result, _, err := s.core.PERFORM(window.TaskOpenWindow{
|
||||
Window: &window.Window{
|
||||
Name: input.Name,
|
||||
Title: input.Title,
|
||||
URL: input.URL,
|
||||
Width: input.Width,
|
||||
Height: input.Height,
|
||||
X: input.X,
|
||||
Y: input.Y,
|
||||
},
|
||||
Window: input,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, WindowCreateOutput{}, err
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ type QueryWindowByName struct{ Name string }
|
|||
type QueryConfig struct{}
|
||||
|
||||
type TaskOpenWindow struct {
|
||||
Window *Window
|
||||
Options []WindowOption
|
||||
Window Window
|
||||
}
|
||||
|
||||
type TaskCloseWindow struct{ Name string }
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
// pkg/window/options.go
|
||||
package window
|
||||
|
||||
// WindowOption is a functional option applied to a Window descriptor.
|
||||
type WindowOption func(*Window) error
|
||||
|
||||
// ApplyOptions creates a Window and applies all options in order.
|
||||
func ApplyOptions(options ...WindowOption) (*Window, error) {
|
||||
w := &Window{}
|
||||
for _, option := range options {
|
||||
if option == nil {
|
||||
continue
|
||||
}
|
||||
if err := option(w); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return w, nil
|
||||
}
|
||||
|
||||
func WithName(name string) WindowOption {
|
||||
return func(w *Window) error { w.Name = name; return nil }
|
||||
}
|
||||
|
||||
func WithTitle(title string) WindowOption {
|
||||
return func(w *Window) error { w.Title = title; return nil }
|
||||
}
|
||||
|
||||
func WithURL(url string) WindowOption {
|
||||
return func(w *Window) error { w.URL = url; return nil }
|
||||
}
|
||||
|
||||
func WithSize(width, height int) WindowOption {
|
||||
return func(w *Window) error { w.Width = width; w.Height = height; return nil }
|
||||
}
|
||||
|
||||
func WithPosition(x, y int) WindowOption {
|
||||
return func(w *Window) error { w.X = x; w.Y = y; return nil }
|
||||
}
|
||||
|
||||
func WithMinSize(width, height int) WindowOption {
|
||||
return func(w *Window) error { w.MinWidth = width; w.MinHeight = height; return nil }
|
||||
}
|
||||
|
||||
func WithMaxSize(width, height int) WindowOption {
|
||||
return func(w *Window) error { w.MaxWidth = width; w.MaxHeight = height; return nil }
|
||||
}
|
||||
|
||||
func WithFrameless(frameless bool) WindowOption {
|
||||
return func(w *Window) error { w.Frameless = frameless; return nil }
|
||||
}
|
||||
|
||||
func WithHidden(hidden bool) WindowOption {
|
||||
return func(w *Window) error { w.Hidden = hidden; return nil }
|
||||
}
|
||||
|
||||
func WithAlwaysOnTop(alwaysOnTop bool) WindowOption {
|
||||
return func(w *Window) error { w.AlwaysOnTop = alwaysOnTop; return nil }
|
||||
}
|
||||
|
||||
func WithBackgroundColour(r, g, b, a uint8) WindowOption {
|
||||
return func(w *Window) error { w.BackgroundColour = [4]uint8{r, g, b, a}; return nil }
|
||||
}
|
||||
|
||||
func WithFileDrop(enabled bool) WindowOption {
|
||||
return func(w *Window) error { w.EnableFileDrop = enabled; return nil }
|
||||
}
|
||||
|
|
@ -187,15 +187,7 @@ func (s *Service) primaryScreenArea() (int, int, int, int) {
|
|||
}
|
||||
|
||||
func (s *Service) taskOpenWindow(t TaskOpenWindow) (any, bool, error) {
|
||||
var (
|
||||
pw PlatformWindow
|
||||
err error
|
||||
)
|
||||
if t.Window != nil {
|
||||
pw, err = s.manager.Create(t.Window)
|
||||
} else {
|
||||
pw, err = s.manager.Open(t.Options...)
|
||||
}
|
||||
pw, err := s.manager.Create(t.Window)
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
|
|
@ -227,8 +219,14 @@ func (s *Service) trackWindow(pw PlatformWindow) {
|
|||
}
|
||||
case "resize":
|
||||
if data := e.Data; data != nil {
|
||||
w, _ := data["w"].(int)
|
||||
h, _ := data["h"].(int)
|
||||
w, _ := data["width"].(int)
|
||||
if w == 0 {
|
||||
w, _ = data["w"].(int)
|
||||
}
|
||||
h, _ := data["height"].(int)
|
||||
if h == 0 {
|
||||
h, _ = data["h"].(int)
|
||||
}
|
||||
_ = s.Core().ACTION(ActionWindowResized{Name: e.Name, Width: w, Height: h})
|
||||
}
|
||||
case "close":
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ func TestTaskTileWindows_UsesPrimaryScreenSize(t *testing.T) {
|
|||
},
|
||||
})
|
||||
|
||||
_, _, err := c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("left"), WithSize(400, 400)}})
|
||||
_, _, err := c.PERFORM(TaskOpenWindow{Window: Window{Name: "left", Width: 400, Height: 400}})
|
||||
require.NoError(t, err)
|
||||
_, _, err = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("right"), WithSize(400, 400)}})
|
||||
_, _, err = c.PERFORM(TaskOpenWindow{Window: Window{Name: "right", Width: 400, Height: 400}})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, handled, err := c.PERFORM(TaskTileWindows{Mode: "left-right", Windows: []string{"left", "right"}})
|
||||
|
|
@ -82,7 +82,7 @@ func TestTaskSnapWindow_UsesPrimaryScreenSize(t *testing.T) {
|
|||
},
|
||||
})
|
||||
|
||||
_, _, err := c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("snap"), WithSize(400, 300)}})
|
||||
_, _, err := c.PERFORM(TaskOpenWindow{Window: Window{Name: "snap", Width: 400, Height: 300}})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, handled, err := c.PERFORM(TaskSnapWindow{Name: "snap", Position: "left"})
|
||||
|
|
@ -107,9 +107,9 @@ func TestTaskTileWindows_UsesPrimaryWorkAreaOrigin(t *testing.T) {
|
|||
},
|
||||
})
|
||||
|
||||
_, _, err := c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("left"), WithSize(400, 400)}})
|
||||
_, _, err := c.PERFORM(TaskOpenWindow{Window: Window{Name: "left", Width: 400, Height: 400}})
|
||||
require.NoError(t, err)
|
||||
_, _, err = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("right"), WithSize(400, 400)}})
|
||||
_, _, err = c.PERFORM(TaskOpenWindow{Window: Window{Name: "right", Width: 400, Height: 400}})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, handled, err := c.PERFORM(TaskTileWindows{Mode: "left-right", Windows: []string{"left", "right"}})
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ func TestRegister_Good(t *testing.T) {
|
|||
func TestTaskOpenWindow_Good(t *testing.T) {
|
||||
_, c := newTestWindowService(t)
|
||||
result, handled, err := c.PERFORM(TaskOpenWindow{
|
||||
Window: &Window{Name: "test", URL: "/"},
|
||||
Window: Window{Name: "test", URL: "/"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, handled)
|
||||
|
|
@ -39,10 +39,10 @@ func TestTaskOpenWindow_Good(t *testing.T) {
|
|||
assert.Equal(t, "test", info.Name)
|
||||
}
|
||||
|
||||
func TestTaskOpenWindow_OptionsFallback_Good(t *testing.T) {
|
||||
func TestTaskOpenWindow_Declarative_Good(t *testing.T) {
|
||||
_, c := newTestWindowService(t)
|
||||
result, handled, err := c.PERFORM(TaskOpenWindow{
|
||||
Options: []WindowOption{WithName("test-fallback"), WithURL("/")},
|
||||
Window: Window{Name: "test-fallback", URL: "/"},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.True(t, handled)
|
||||
|
|
@ -60,8 +60,8 @@ func TestTaskOpenWindow_Bad(t *testing.T) {
|
|||
|
||||
func TestQueryWindowList_Good(t *testing.T) {
|
||||
_, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("a")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("b")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "a"}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "b"}})
|
||||
|
||||
result, handled, err := c.QUERY(QueryWindowList{})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -72,7 +72,7 @@ func TestQueryWindowList_Good(t *testing.T) {
|
|||
|
||||
func TestQueryWindowByName_Good(t *testing.T) {
|
||||
_, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
result, handled, err := c.QUERY(QueryWindowByName{Name: "test"})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -91,7 +91,7 @@ func TestQueryWindowByName_Bad(t *testing.T) {
|
|||
|
||||
func TestTaskCloseWindow_Good(t *testing.T) {
|
||||
_, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskCloseWindow{Name: "test"})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -111,7 +111,7 @@ func TestTaskCloseWindow_Bad(t *testing.T) {
|
|||
|
||||
func TestTaskSetPosition_Good(t *testing.T) {
|
||||
_, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskSetPosition{Name: "test", X: 100, Y: 200})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -125,7 +125,7 @@ func TestTaskSetPosition_Good(t *testing.T) {
|
|||
|
||||
func TestTaskSetSize_Good(t *testing.T) {
|
||||
_, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskSetSize{Name: "test", Width: 800, Height: 600})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -139,7 +139,7 @@ func TestTaskSetSize_Good(t *testing.T) {
|
|||
|
||||
func TestTaskMaximise_Good(t *testing.T) {
|
||||
_, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskMaximise{Name: "test"})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -155,7 +155,7 @@ func TestFileDrop_Good(t *testing.T) {
|
|||
|
||||
// Open a window
|
||||
result, _, _ := c.PERFORM(TaskOpenWindow{
|
||||
Options: []WindowOption{WithName("drop-test")},
|
||||
Window: Window{Name: "drop-test"},
|
||||
})
|
||||
info := result.(WindowInfo)
|
||||
assert.Equal(t, "drop-test", info.Name)
|
||||
|
|
@ -190,7 +190,7 @@ func TestFileDrop_Good(t *testing.T) {
|
|||
|
||||
func TestTaskMinimise_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskMinimise{Name: "test"})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -213,7 +213,7 @@ func TestTaskMinimise_Bad(t *testing.T) {
|
|||
|
||||
func TestTaskFocus_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskFocus{Name: "test"})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -236,7 +236,7 @@ func TestTaskFocus_Bad(t *testing.T) {
|
|||
|
||||
func TestTaskRestore_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
// First maximise, then restore
|
||||
_, _, _ = c.PERFORM(TaskMaximise{Name: "test"})
|
||||
|
|
@ -267,7 +267,7 @@ func TestTaskRestore_Bad(t *testing.T) {
|
|||
|
||||
func TestTaskSetTitle_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskSetTitle{Name: "test", Title: "New Title"})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -289,7 +289,7 @@ func TestTaskSetTitle_Bad(t *testing.T) {
|
|||
|
||||
func TestTaskSetAlwaysOnTop_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskSetAlwaysOnTop{Name: "test", AlwaysOnTop: true})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -312,7 +312,7 @@ func TestTaskSetAlwaysOnTop_Bad(t *testing.T) {
|
|||
|
||||
func TestTaskSetBackgroundColour_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskSetBackgroundColour{
|
||||
Name: "test", Red: 10, Green: 20, Blue: 30, Alpha: 40,
|
||||
|
|
@ -337,7 +337,7 @@ func TestTaskSetBackgroundColour_Bad(t *testing.T) {
|
|||
|
||||
func TestTaskSetVisibility_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskSetVisibility{Name: "test", Visible: true})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -366,7 +366,7 @@ func TestTaskSetVisibility_Bad(t *testing.T) {
|
|||
|
||||
func TestTaskFullscreen_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("test")}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "test"}})
|
||||
|
||||
// Enter fullscreen
|
||||
_, handled, err := c.PERFORM(TaskFullscreen{Name: "test", Fullscreen: true})
|
||||
|
|
@ -396,8 +396,8 @@ func TestTaskFullscreen_Bad(t *testing.T) {
|
|||
|
||||
func TestTaskSaveLayout_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("editor"), WithSize(960, 1080), WithPosition(0, 0)}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("terminal"), WithSize(960, 1080), WithPosition(960, 0)}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "editor", Width: 960, Height: 1080, X: 0, Y: 0}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "terminal", Width: 960, Height: 1080, X: 960, Y: 0}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskSaveLayout{Name: "coding"})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -433,8 +433,8 @@ func TestTaskSaveLayout_Bad(t *testing.T) {
|
|||
func TestTaskRestoreLayout_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
// Open windows
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("editor"), WithSize(800, 600), WithPosition(0, 0)}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("terminal"), WithSize(800, 600), WithPosition(0, 0)}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "editor", Width: 800, Height: 600, X: 0, Y: 0}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "terminal", Width: 800, Height: 600, X: 0, Y: 0}})
|
||||
|
||||
// Save a layout with specific positions
|
||||
_, _, _ = c.PERFORM(TaskSaveLayout{Name: "coding"})
|
||||
|
|
@ -483,8 +483,8 @@ func TestTaskRestoreLayout_Bad(t *testing.T) {
|
|||
|
||||
func TestTaskStackWindows_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("s1"), WithSize(800, 600)}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("s2"), WithSize(800, 600)}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "s1", Width: 800, Height: 600}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "s2", Width: 800, Height: 600}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskStackWindows{Windows: []string{"s1", "s2"}, OffsetX: 25, OffsetY: 35})
|
||||
require.NoError(t, err)
|
||||
|
|
@ -501,8 +501,8 @@ func TestTaskStackWindows_Good(t *testing.T) {
|
|||
|
||||
func TestTaskApplyWorkflow_Good(t *testing.T) {
|
||||
svc, c := newTestWindowService(t)
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("editor"), WithSize(800, 600)}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Options: []WindowOption{WithName("terminal"), WithSize(800, 600)}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "editor", Width: 800, Height: 600}})
|
||||
_, _, _ = c.PERFORM(TaskOpenWindow{Window: Window{Name: "terminal", Width: 800, Height: 600}})
|
||||
|
||||
_, handled, err := c.PERFORM(TaskApplyWorkflow{Workflow: "side-by-side"})
|
||||
require.NoError(t, err)
|
||||
|
|
|
|||
|
|
@ -1,26 +1,27 @@
|
|||
// pkg/window/window.go
|
||||
package window
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
import "sync"
|
||||
|
||||
// Window is CoreGUI's own window descriptor — NOT a Wails type alias.
|
||||
type Window struct {
|
||||
Name string
|
||||
Title string
|
||||
URL string
|
||||
Width, Height int
|
||||
X, Y int
|
||||
MinWidth, MinHeight int
|
||||
MaxWidth, MaxHeight int
|
||||
Frameless bool
|
||||
Hidden bool
|
||||
AlwaysOnTop bool
|
||||
BackgroundColour [4]uint8
|
||||
DisableResize bool
|
||||
EnableFileDrop bool
|
||||
Name string `json:"name,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
Width int `json:"width,omitempty"`
|
||||
Height int `json:"height,omitempty"`
|
||||
X int `json:"x,omitempty"`
|
||||
Y int `json:"y,omitempty"`
|
||||
MinWidth int `json:"minWidth,omitempty"`
|
||||
MinHeight int `json:"minHeight,omitempty"`
|
||||
MaxWidth int `json:"maxWidth,omitempty"`
|
||||
MaxHeight int `json:"maxHeight,omitempty"`
|
||||
Frameless bool `json:"frameless,omitempty"`
|
||||
Hidden bool `json:"hidden,omitempty"`
|
||||
AlwaysOnTop bool `json:"alwaysOnTop,omitempty"`
|
||||
BackgroundColour [4]uint8 `json:"backgroundColour,omitempty"`
|
||||
DisableResize bool `json:"disableResize,omitempty"`
|
||||
EnableFileDrop bool `json:"enableFileDrop,omitempty"`
|
||||
}
|
||||
|
||||
// ToPlatformOptions converts a Window to PlatformWindowOptions for the backend.
|
||||
|
|
@ -80,17 +81,15 @@ func (m *Manager) SetDefaultHeight(height int) {
|
|||
}
|
||||
}
|
||||
|
||||
// Open creates a window using functional options, applies saved state, and tracks it.
|
||||
func (m *Manager) Open(options ...WindowOption) (PlatformWindow, error) {
|
||||
w, err := ApplyOptions(options...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("window.Manager.Open: %w", err)
|
||||
}
|
||||
return m.Create(w)
|
||||
// Open creates a window from a declarative Window spec, for example:
|
||||
// m.Open(Window{Name: "editor", Title: "Editor", URL: "/"})
|
||||
func (m *Manager) Open(spec Window) (PlatformWindow, error) {
|
||||
return m.Create(spec)
|
||||
}
|
||||
|
||||
// Create creates a window from a Window descriptor.
|
||||
func (m *Manager) Create(w *Window) (PlatformWindow, error) {
|
||||
func (m *Manager) Create(spec Window) (PlatformWindow, error) {
|
||||
w := spec
|
||||
if w.Name == "" {
|
||||
w.Name = "main"
|
||||
}
|
||||
|
|
@ -116,7 +115,7 @@ func (m *Manager) Create(w *Window) (PlatformWindow, error) {
|
|||
}
|
||||
|
||||
// Apply saved state if available
|
||||
m.state.ApplyState(w)
|
||||
m.state.ApplyState(&w)
|
||||
|
||||
pw := m.platform.CreateWindow(w.ToPlatformOptions())
|
||||
|
||||
|
|
|
|||
|
|
@ -14,71 +14,25 @@ func TestWindowDefaults(t *testing.T) {
|
|||
assert.Equal(t, 0, w.Width)
|
||||
}
|
||||
|
||||
func TestWindowOption_Name_Good(t *testing.T) {
|
||||
w := &Window{}
|
||||
err := WithName("main")(w)
|
||||
require.NoError(t, err)
|
||||
func TestWindowSpec_Good(t *testing.T) {
|
||||
w := Window{
|
||||
Name: "main",
|
||||
Title: "My App",
|
||||
URL: "/dashboard",
|
||||
Width: 1280,
|
||||
Height: 720,
|
||||
X: 100,
|
||||
Y: 200,
|
||||
}
|
||||
assert.Equal(t, "main", w.Name)
|
||||
}
|
||||
|
||||
func TestWindowOption_Title_Good(t *testing.T) {
|
||||
w := &Window{}
|
||||
err := WithTitle("My App")(w)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "My App", w.Title)
|
||||
}
|
||||
|
||||
func TestWindowOption_URL_Good(t *testing.T) {
|
||||
w := &Window{}
|
||||
err := WithURL("/dashboard")(w)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "/dashboard", w.URL)
|
||||
}
|
||||
|
||||
func TestWindowOption_Size_Good(t *testing.T) {
|
||||
w := &Window{}
|
||||
err := WithSize(1280, 720)(w)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 1280, w.Width)
|
||||
assert.Equal(t, 720, w.Height)
|
||||
}
|
||||
|
||||
func TestWindowOption_Position_Good(t *testing.T) {
|
||||
w := &Window{}
|
||||
err := WithPosition(100, 200)(w)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 100, w.X)
|
||||
assert.Equal(t, 200, w.Y)
|
||||
}
|
||||
|
||||
func TestApplyOptions_Good(t *testing.T) {
|
||||
w, err := ApplyOptions(
|
||||
WithName("test"),
|
||||
WithTitle("Test Window"),
|
||||
WithURL("/test"),
|
||||
WithSize(800, 600),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "test", w.Name)
|
||||
assert.Equal(t, "Test Window", w.Title)
|
||||
assert.Equal(t, "/test", w.URL)
|
||||
assert.Equal(t, 800, w.Width)
|
||||
assert.Equal(t, 600, w.Height)
|
||||
}
|
||||
|
||||
func TestApplyOptions_Bad(t *testing.T) {
|
||||
_, err := ApplyOptions(func(w *Window) error {
|
||||
return assert.AnError
|
||||
})
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestApplyOptions_Empty_Good(t *testing.T) {
|
||||
w, err := ApplyOptions()
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, w)
|
||||
}
|
||||
|
||||
// newTestManager creates a Manager with a mock platform and clean state for testing.
|
||||
func newTestManager() (*Manager, *mockPlatform) {
|
||||
p := newMockPlatform()
|
||||
|
|
@ -93,7 +47,7 @@ func newTestManager() (*Manager, *mockPlatform) {
|
|||
|
||||
func TestManager_Open_Good(t *testing.T) {
|
||||
m, p := newTestManager()
|
||||
pw, err := m.Open(WithName("test"), WithTitle("Test"), WithURL("/test"), WithSize(800, 600))
|
||||
pw, err := m.Open(Window{Name: "test", Title: "Test", URL: "/test", Width: 800, Height: 600})
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, pw)
|
||||
assert.Equal(t, "test", pw.Name())
|
||||
|
|
@ -102,7 +56,7 @@ func TestManager_Open_Good(t *testing.T) {
|
|||
|
||||
func TestManager_Open_Defaults_Good(t *testing.T) {
|
||||
m, _ := newTestManager()
|
||||
pw, err := m.Open()
|
||||
pw, err := m.Open(Window{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "main", pw.Name())
|
||||
w, h := pw.Size()
|
||||
|
|
@ -115,7 +69,7 @@ func TestManager_Open_CustomDefaults_Good(t *testing.T) {
|
|||
m.SetDefaultWidth(1440)
|
||||
m.SetDefaultHeight(900)
|
||||
|
||||
pw, err := m.Open()
|
||||
pw, err := m.Open(Window{})
|
||||
require.NoError(t, err)
|
||||
|
||||
w, h := pw.Size()
|
||||
|
|
@ -123,15 +77,9 @@ func TestManager_Open_CustomDefaults_Good(t *testing.T) {
|
|||
assert.Equal(t, 900, h)
|
||||
}
|
||||
|
||||
func TestManager_Open_Bad(t *testing.T) {
|
||||
m, _ := newTestManager()
|
||||
_, err := m.Open(func(w *Window) error { return assert.AnError })
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestManager_Get_Good(t *testing.T) {
|
||||
m, _ := newTestManager()
|
||||
_, _ = m.Open(WithName("findme"))
|
||||
_, _ = m.Open(Window{Name: "findme"})
|
||||
pw, ok := m.Get("findme")
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, "findme", pw.Name())
|
||||
|
|
@ -145,8 +93,8 @@ func TestManager_Get_Bad(t *testing.T) {
|
|||
|
||||
func TestManager_List_Good(t *testing.T) {
|
||||
m, _ := newTestManager()
|
||||
_, _ = m.Open(WithName("a"))
|
||||
_, _ = m.Open(WithName("b"))
|
||||
_, _ = m.Open(Window{Name: "a"})
|
||||
_, _ = m.Open(Window{Name: "b"})
|
||||
names := m.List()
|
||||
assert.Len(t, names, 2)
|
||||
assert.Contains(t, names, "a")
|
||||
|
|
@ -155,7 +103,7 @@ func TestManager_List_Good(t *testing.T) {
|
|||
|
||||
func TestManager_Remove_Good(t *testing.T) {
|
||||
m, _ := newTestManager()
|
||||
_, _ = m.Open(WithName("temp"))
|
||||
_, _ = m.Open(Window{Name: "temp"})
|
||||
m.Remove("temp")
|
||||
_, ok := m.Get("temp")
|
||||
assert.False(t, ok)
|
||||
|
|
@ -170,8 +118,8 @@ func TestTileMode_String_Good(t *testing.T) {
|
|||
|
||||
func TestManager_TileWindows_Good(t *testing.T) {
|
||||
m, _ := newTestManager()
|
||||
_, _ = m.Open(WithName("a"), WithSize(800, 600))
|
||||
_, _ = m.Open(WithName("b"), WithSize(800, 600))
|
||||
_, _ = m.Open(Window{Name: "a", Width: 800, Height: 600})
|
||||
_, _ = m.Open(Window{Name: "b", Width: 800, Height: 600})
|
||||
err := m.TileWindows(TileModeLeftRight, []string{"a", "b"}, 1920, 1080)
|
||||
require.NoError(t, err)
|
||||
a, _ := m.Get("a")
|
||||
|
|
@ -190,7 +138,7 @@ func TestManager_TileWindows_Bad(t *testing.T) {
|
|||
|
||||
func TestManager_SnapWindow_Good(t *testing.T) {
|
||||
m, _ := newTestManager()
|
||||
_, _ = m.Open(WithName("snap"), WithSize(800, 600))
|
||||
_, _ = m.Open(Window{Name: "snap", Width: 800, Height: 600})
|
||||
err := m.SnapWindow("snap", SnapLeft, 1920, 1080)
|
||||
require.NoError(t, err)
|
||||
w, _ := m.Get("snap")
|
||||
|
|
@ -202,8 +150,8 @@ func TestManager_SnapWindow_Good(t *testing.T) {
|
|||
|
||||
func TestManager_StackWindows_Good(t *testing.T) {
|
||||
m, _ := newTestManager()
|
||||
_, _ = m.Open(WithName("s1"), WithSize(800, 600))
|
||||
_, _ = m.Open(WithName("s2"), WithSize(800, 600))
|
||||
_, _ = m.Open(Window{Name: "s1", Width: 800, Height: 600})
|
||||
_, _ = m.Open(Window{Name: "s2", Width: 800, Height: 600})
|
||||
err := m.StackWindows([]string{"s1", "s2"}, 30, 30)
|
||||
require.NoError(t, err)
|
||||
s2, _ := m.Get("s2")
|
||||
|
|
@ -244,7 +192,7 @@ func TestTileWindows_AllModes_Good(t *testing.T) {
|
|||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
m, _ := newTestManager()
|
||||
_, err := m.Open(WithName("win"), WithSize(800, 600))
|
||||
_, err := m.Open(Window{Name: "win", Width: 800, Height: 600})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = m.TileWindows(tc.mode, []string{"win"}, screenW, screenH)
|
||||
|
|
@ -290,7 +238,7 @@ func TestSnapWindow_AllPositions_Good(t *testing.T) {
|
|||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
m, _ := newTestManager()
|
||||
_, err := m.Open(WithName("snap"), WithSize(tc.initW, tc.initH))
|
||||
_, err := m.Open(Window{Name: "snap", Width: tc.initW, Height: tc.initH})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = m.SnapWindow("snap", tc.pos, screenW, screenH)
|
||||
|
|
@ -313,7 +261,7 @@ func TestStackWindows_ThreeWindows_Good(t *testing.T) {
|
|||
m, _ := newTestManager()
|
||||
names := []string{"s1", "s2", "s3"}
|
||||
for _, name := range names {
|
||||
_, err := m.Open(WithName(name), WithSize(800, 600))
|
||||
_, err := m.Open(Window{Name: name, Width: 800, Height: 600})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
|
@ -369,9 +317,9 @@ func TestApplyWorkflow_AllLayouts_Good(t *testing.T) {
|
|||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
m, _ := newTestManager()
|
||||
_, err := m.Open(WithName("editor"), WithSize(800, 600))
|
||||
_, err := m.Open(Window{Name: "editor", Width: 800, Height: 600})
|
||||
require.NoError(t, err)
|
||||
_, err = m.Open(WithName("terminal"), WithSize(800, 600))
|
||||
_, err = m.Open(Window{Name: "terminal", Width: 800, Height: 600})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = m.ApplyWorkflow(tc.workflow, []string{"editor", "terminal"}, screenW, screenH)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue