// pkg/window/window.go package window import ( "sort" "sync" ) // Window is CoreGUI's own window descriptor, not a Wails type alias. type Window struct { 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. func (w *Window) ToPlatformOptions() PlatformWindowOptions { return PlatformWindowOptions{ Name: w.Name, Title: w.Title, URL: w.URL, Width: w.Width, Height: w.Height, X: w.X, Y: w.Y, MinWidth: w.MinWidth, MinHeight: w.MinHeight, MaxWidth: w.MaxWidth, MaxHeight: w.MaxHeight, Frameless: w.Frameless, Hidden: w.Hidden, AlwaysOnTop: w.AlwaysOnTop, BackgroundColour: w.BackgroundColour, DisableResize: w.DisableResize, EnableFileDrop: w.EnableFileDrop, } } // Manager manages window lifecycle through a Platform backend. type Manager struct { platform Platform state *StateManager layout *LayoutManager windows map[string]PlatformWindow defaultWidth int defaultHeight int mu sync.RWMutex } // NewManager creates a window Manager with the given platform backend. func NewManager(platform Platform) *Manager { return &Manager{ platform: platform, state: NewStateManager(), layout: NewLayoutManager(), windows: make(map[string]PlatformWindow), } } // NewManagerWithDir creates a window Manager with a custom config directory for state/layout persistence. // Useful for testing or when the default config directory is not appropriate. func NewManagerWithDir(platform Platform, configDir string) *Manager { return &Manager{ platform: platform, state: NewStateManagerWithDir(configDir), layout: NewLayoutManagerWithDir(configDir), windows: make(map[string]PlatformWindow), } } func (m *Manager) SetDefaultWidth(width int) { if width > 0 { m.defaultWidth = width } } func (m *Manager) SetDefaultHeight(height int) { if height > 0 { m.defaultHeight = height } } // Create opens a window from a declarative spec. // Example: m.Create(Window{Name: "editor", Title: "Editor", URL: "/"}) // Saved position, size, and maximized state are restored when available. func (m *Manager) Create(spec Window) (PlatformWindow, error) { w := spec if w.Name == "" { w.Name = "main" } if w.Title == "" { w.Title = "Core" } if w.Width == 0 { if m.defaultWidth > 0 { w.Width = m.defaultWidth } else { w.Width = 1280 } } if w.Height == 0 { if m.defaultHeight > 0 { w.Height = m.defaultHeight } else { w.Height = 800 } } if w.URL == "" { w.URL = "/" } // Apply saved state if available. if m.state != nil { m.state.ApplyState(&w) } pw := m.platform.CreateWindow(w.ToPlatformOptions()) if m.state != nil { if state, ok := m.state.GetState(w.Name); ok && state.Maximized { pw.Maximise() } } m.mu.Lock() m.windows[w.Name] = pw m.mu.Unlock() return pw, nil } // Get returns a tracked window by name. func (m *Manager) Get(name string) (PlatformWindow, bool) { m.mu.RLock() defer m.mu.RUnlock() pw, ok := m.windows[name] return pw, ok } // List returns all tracked window names. func (m *Manager) List() []string { m.mu.RLock() defer m.mu.RUnlock() names := make([]string, 0, len(m.windows)) for name := range m.windows { names = append(names, name) } sort.Strings(names) return names } // Remove stops tracking a window by name. func (m *Manager) Remove(name string) { m.mu.Lock() delete(m.windows, name) m.mu.Unlock() } // Platform returns the underlying platform for direct access. func (m *Manager) Platform() Platform { return m.platform } // State returns the state manager for window persistence. func (m *Manager) State() *StateManager { return m.state } // Layout returns the layout manager. func (m *Manager) Layout() *LayoutManager { return m.layout }