fix(window): use detected screen size for tiling
Some checks failed
Security Scan / security (push) Failing after 35s
Test / test (push) Successful in 1m4s

This commit is contained in:
Virgil 2026-04-02 14:47:40 +00:00
parent 4f4a4eb8e4
commit 54d77d85cd
5 changed files with 80 additions and 6 deletions

View file

@ -58,7 +58,8 @@ type TaskOpenWindow struct {
Opts []WindowOption
}
// TaskCloseWindow closes a window. Handler persists state BEFORE emitting ActionWindowClosed.
// TaskCloseWindow closes a window after persisting state.
// Platform close events emit ActionWindowClosed through the tracked window handler.
type TaskCloseWindow struct{ Name string }
// TaskSetPosition moves a window.

View file

@ -63,7 +63,10 @@ func (w *MockWindow) Maximise() { w.maximised = true;
func (w *MockWindow) Restore() { w.maximised = false; w.minimised = false; w.visible = true }
func (w *MockWindow) Minimise() { w.minimised = true; w.maximised = false; w.visible = false }
func (w *MockWindow) Focus() { w.focused = true }
func (w *MockWindow) Close() { w.closed = true }
func (w *MockWindow) Close() {
w.closed = true
w.emit(WindowEvent{Type: "close", Name: w.name})
}
func (w *MockWindow) Show() { w.visible = true }
func (w *MockWindow) Hide() { w.visible = false }
func (w *MockWindow) Fullscreen() {}
@ -76,3 +79,15 @@ func (w *MockWindow) OnWindowEvent(handler func(WindowEvent)) {
func (w *MockWindow) OnFileDrop(handler func(paths []string, targetID string)) {
w.fileDropHandlers = append(w.fileDropHandlers, handler)
}
func (w *MockWindow) emit(e WindowEvent) {
for _, h := range w.eventHandlers {
h(e)
}
}
func (w *MockWindow) emitFileDrop(paths []string, targetID string) {
for _, h := range w.fileDropHandlers {
h(paths, targetID)
}
}

View file

@ -63,7 +63,10 @@ func (w *mockWindow) Maximise() { w.maximised = true;
func (w *mockWindow) Restore() { w.maximised = false; w.minimised = false; w.visible = true }
func (w *mockWindow) Minimise() { w.minimised = true; w.maximised = false; w.visible = false }
func (w *mockWindow) Focus() { w.focused = true }
func (w *mockWindow) Close() { w.closed = true }
func (w *mockWindow) Close() {
w.closed = true
w.emit(WindowEvent{Type: "close", Name: w.name})
}
func (w *mockWindow) Show() { w.visible = true }
func (w *mockWindow) Hide() { w.visible = false }
func (w *mockWindow) Fullscreen() {}

View file

@ -274,7 +274,6 @@ func (s *Service) taskCloseWindow(name string) error {
s.manager.State().CaptureState(pw)
pw.Close()
s.manager.Remove(name)
_ = s.Core().ACTION(ActionWindowClosed{Name: name})
return nil
}
@ -454,8 +453,8 @@ func (s *Service) taskTileWindows(mode string, names []string) error {
if len(names) == 0 {
names = s.manager.List()
}
// Default screen size — callers can query screen_primary for actual values.
return s.manager.TileWindows(tm, names, 1920, 1080)
screenW, screenH := s.primaryScreenSize()
return s.manager.TileWindows(tm, names, screenW, screenH)
}
var snapPosMap = map[string]SnapPosition{

View file

@ -6,6 +6,7 @@ import (
"testing"
"forge.lthn.ai/core/go/pkg/core"
"forge.lthn.ai/core/gui/pkg/screen"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -22,6 +23,41 @@ func newTestWindowService(t *testing.T) (*Service, *core.Core) {
return svc, c
}
type testScreenPlatform struct {
screens []screen.Screen
}
func (p *testScreenPlatform) GetAll() []screen.Screen { return p.screens }
func (p *testScreenPlatform) GetPrimary() *screen.Screen {
for i := range p.screens {
if p.screens[i].IsPrimary {
return &p.screens[i]
}
}
return nil
}
func newTestWindowServiceWithScreen(t *testing.T) (*Service, *core.Core) {
t.Helper()
c, err := core.New(
core.WithService(Register(newMockPlatform())),
core.WithService(screen.Register(&testScreenPlatform{
screens: []screen.Screen{{
ID: "primary", Name: "Primary", IsPrimary: true,
Size: screen.Size{Width: 2560, Height: 1440},
Bounds: screen.Rect{X: 0, Y: 0, Width: 2560, Height: 1440},
WorkArea: screen.Rect{X: 0, Y: 0, Width: 2560, Height: 1440},
}},
})),
core.WithServiceLock(),
)
require.NoError(t, err)
require.NoError(t, c.ServiceStartup(context.Background(), nil))
svc := core.MustServiceFor[*Service](c, "window")
return svc, c
}
func TestRegister_Good(t *testing.T) {
svc, _ := newTestWindowService(t)
assert.NotNil(t, svc)
@ -218,6 +254,26 @@ func TestTaskSetBackgroundColour_Good(t *testing.T) {
assert.Equal(t, [4]uint8{10, 20, 30, 40}, pw.(*mockWindow).backgroundColor)
}
func TestTaskTileWindows_UsesPrimaryScreenSize(t *testing.T) {
_, c := newTestWindowServiceWithScreen(t)
_, _, _ = c.PERFORM(TaskOpenWindow{Opts: []WindowOption{WithName("left")}})
_, _, _ = c.PERFORM(TaskOpenWindow{Opts: []WindowOption{WithName("right")}})
_, handled, err := c.PERFORM(TaskTileWindows{Mode: "left-right", Windows: []string{"left", "right"}})
require.NoError(t, err)
assert.True(t, handled)
left, _, _ := c.QUERY(QueryWindowByName{Name: "left"})
right, _, _ := c.QUERY(QueryWindowByName{Name: "right"})
leftInfo := left.(*WindowInfo)
rightInfo := right.(*WindowInfo)
assert.Equal(t, 1280, leftInfo.Width)
assert.Equal(t, 1280, rightInfo.Width)
assert.Equal(t, 0, leftInfo.X)
assert.Equal(t, 1280, rightInfo.X)
}
func TestTaskSetOpacity_Good(t *testing.T) {
_, c := newTestWindowService(t)
_, _, _ = c.PERFORM(TaskOpenWindow{Opts: []WindowOption{WithName("test")}})