Harden display IPC failure handling
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run

This commit is contained in:
Snider 2026-04-17 17:45:33 +01:00
parent 5cb446db3b
commit d549a5a122
2 changed files with 105 additions and 11 deletions

View file

@ -32,6 +32,10 @@ import (
type Options struct{}
func failedAction(method, action string) error {
return coreerr.E(method, action+" action failed", nil)
}
// WindowInfo is an alias for window.WindowInfo (backward compatibility).
type WindowInfo = window.WindowInfo
@ -1083,9 +1087,18 @@ func (s *Service) OpenWindow(options ...window.WindowOption) error {
func (s *Service) GetWindowInfo(name string) (*window.WindowInfo, error) {
r := s.Core().QUERY(window.QueryWindowByName{Name: name})
if !r.OK {
return nil, coreerr.E("display.GetWindowInfo", "window service not available", nil)
if err, ok := r.Value.(error); ok {
return nil, err
}
return nil, failedAction("display.GetWindowInfo", "window.queryWindowByName")
}
if r.Value == nil {
return nil, nil
}
info, ok := r.Value.(*window.WindowInfo)
if !ok {
return nil, coreerr.E("display.GetWindowInfo", "unexpected result type", nil)
}
info, _ := r.Value.(*window.WindowInfo)
return info, nil
}
@ -1108,6 +1121,7 @@ func (s *Service) SetWindowPosition(name string, x, y int) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.SetWindowPosition", "window.setPosition")
}
return nil
}
@ -1121,6 +1135,7 @@ func (s *Service) SetWindowSize(name string, width, height int) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.SetWindowSize", "window.setSize")
}
return nil
}
@ -1142,6 +1157,7 @@ func (s *Service) MaximizeWindow(name string) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.MaximizeWindow", "window.maximise")
}
return nil
}
@ -1155,6 +1171,7 @@ func (s *Service) MinimizeWindow(name string) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.MinimizeWindow", "window.minimise")
}
return nil
}
@ -1168,6 +1185,7 @@ func (s *Service) FocusWindow(name string) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.FocusWindow", "window.focus")
}
return nil
}
@ -1181,6 +1199,7 @@ func (s *Service) CloseWindow(name string) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.CloseWindow", "window.close")
}
return nil
}
@ -1194,6 +1213,7 @@ func (s *Service) RestoreWindow(name string) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.RestoreWindow", "window.restore")
}
return nil
}
@ -1207,6 +1227,7 @@ func (s *Service) SetWindowVisibility(name string, visible bool) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.SetWindowVisibility", "window.setVisibility")
}
return nil
}
@ -1220,6 +1241,7 @@ func (s *Service) SetWindowAlwaysOnTop(name string, alwaysOnTop bool) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.SetWindowAlwaysOnTop", "window.setAlwaysOnTop")
}
return nil
}
@ -1233,6 +1255,7 @@ func (s *Service) SetWindowTitle(name string, title string) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.SetWindowTitle", "window.setTitle")
}
return nil
}
@ -1246,6 +1269,7 @@ func (s *Service) SetWindowFullscreen(name string, fullscreen bool) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.SetWindowFullscreen", "window.fullscreen")
}
return nil
}
@ -1261,6 +1285,7 @@ func (s *Service) SetWindowBackgroundColour(name string, r, g, b, a uint8) error
if e, ok := result.Value.(error); ok {
return e
}
return failedAction("display.SetWindowBackgroundColour", "window.setBackgroundColour")
}
return nil
}
@ -1362,6 +1387,7 @@ func (s *Service) SaveLayout(name string) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.SaveLayout", "window.saveLayout")
}
return nil
}
@ -1375,6 +1401,7 @@ func (s *Service) RestoreLayout(name string) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.RestoreLayout", "window.restoreLayout")
}
return nil
}
@ -1398,6 +1425,7 @@ func (s *Service) DeleteLayout(name string) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.DeleteLayout", "window.deleteLayout")
}
return nil
}
@ -1408,7 +1436,13 @@ func (s *Service) GetLayout(name string) *window.Layout {
if !r.OK {
return nil
}
layout, _ := r.Value.(*window.Layout)
if r.Value == nil {
return nil
}
layout, ok := r.Value.(*window.Layout)
if !ok {
return nil
}
return layout
}
@ -1423,6 +1457,7 @@ func (s *Service) TileWindows(mode window.TileMode, windowNames []string) error
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.TileWindows", "window.tileWindows")
}
return nil
}
@ -1436,6 +1471,7 @@ func (s *Service) SnapWindow(name string, position window.SnapPosition) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.SnapWindow", "window.snapWindow")
}
return nil
}
@ -1449,6 +1485,7 @@ func (s *Service) StackWindows(windowNames []string, offsetX, offsetY int) error
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.StackWindows", "window.stackWindows")
}
return nil
}
@ -1462,6 +1499,7 @@ func (s *Service) ApplyWorkflowLayout(workflow window.WorkflowLayout) error {
if e, ok := r.Value.(error); ok {
return e
}
return failedAction("display.ApplyWorkflowLayout", "window.applyWorkflow")
}
return nil
}
@ -1479,9 +1517,12 @@ func (s *Service) LayoutBesideEditor(name, editor, side string, ratio float64) (
if e, ok := r.Value.(error); ok {
return window.LayoutBesideEditorResult{}, e
}
return window.LayoutBesideEditorResult{}, nil
return window.LayoutBesideEditorResult{}, failedAction("display.LayoutBesideEditor", "window.layoutBesideEditor")
}
result, ok := r.Value.(window.LayoutBesideEditorResult)
if !ok {
return window.LayoutBesideEditorResult{}, coreerr.E("display.LayoutBesideEditor", "unexpected result type", nil)
}
result, _ := r.Value.(window.LayoutBesideEditorResult)
return result, nil
}
@ -1498,9 +1539,12 @@ func (s *Service) LayoutSuggest(screenID string, windowCount int) (window.Layout
if e, ok := r.Value.(error); ok {
return window.LayoutSuggestion{}, e
}
return window.LayoutSuggestion{}, nil
return window.LayoutSuggestion{}, failedAction("display.LayoutSuggest", "window.layoutSuggest")
}
result, ok := r.Value.(window.LayoutSuggestion)
if !ok {
return window.LayoutSuggestion{}, coreerr.E("display.LayoutSuggest", "unexpected result type", nil)
}
result, _ := r.Value.(window.LayoutSuggestion)
return result, nil
}
@ -1517,9 +1561,12 @@ func (s *Service) FindScreenSpace(screenID string, width, height, padding int) (
if e, ok := r.Value.(error); ok {
return window.ScreenSpace{}, e
}
return window.ScreenSpace{}, nil
return window.ScreenSpace{}, failedAction("display.FindScreenSpace", "window.findSpace")
}
result, ok := r.Value.(window.ScreenSpace)
if !ok {
return window.ScreenSpace{}, coreerr.E("display.FindScreenSpace", "unexpected result type", nil)
}
result, _ := r.Value.(window.ScreenSpace)
return result, nil
}
@ -1536,9 +1583,12 @@ func (s *Service) ArrangeWindowPair(primary, secondary, screenID string, ratio f
if e, ok := r.Value.(error); ok {
return window.PairArrangement{}, e
}
return window.PairArrangement{}, nil
return window.PairArrangement{}, failedAction("display.ArrangeWindowPair", "window.arrangePair")
}
result, ok := r.Value.(window.PairArrangement)
if !ok {
return window.PairArrangement{}, coreerr.E("display.ArrangeWindowPair", "unexpected result type", nil)
}
result, _ := r.Value.(window.PairArrangement)
return result, nil
}

View file

@ -248,6 +248,23 @@ func TestGetWindowInfo_Bad(t *testing.T) {
assert.Nil(t, info)
}
func TestGetWindowInfo_BadType(t *testing.T) {
svc, c := newTestDisplayService(t)
c.RegisterQuery(func(_ *core.Core, q core.Query) core.Result {
switch q.(type) {
case window.QueryWindowByName:
return core.Result{Value: "unexpected", OK: true}
default:
return core.Result{}
}
})
info, err := svc.GetWindowInfo("broken")
require.Error(t, err)
assert.Nil(t, info)
}
func TestListWindowInfos_Good(t *testing.T) {
c := newTestConclave(t)
svc := core.MustServiceFor[*Service](c, "display")
@ -280,6 +297,19 @@ func TestSetWindowPosition_Bad(t *testing.T) {
assert.Error(t, err)
}
func TestSetWindowPosition_ActionFailure(t *testing.T) {
c := newTestConclave(t)
svc := core.MustServiceFor[*Service](c, "display")
c.Action("window.setPosition", func(_ context.Context, _ core.Options) core.Result {
return core.Result{OK: false}
})
err := svc.SetWindowPosition("pos-win", 300, 400)
require.Error(t, err)
assert.Contains(t, err.Error(), "window.setPosition")
}
func TestSetWindowSize_Good(t *testing.T) {
c := newTestConclave(t)
svc := core.MustServiceFor[*Service](c, "display")
@ -435,6 +465,20 @@ func TestSetWindowFullscreen_Bad(t *testing.T) {
require.Error(t, err)
}
func TestLayoutBesideEditor_ActionFailure(t *testing.T) {
c := newTestConclave(t)
svc := core.MustServiceFor[*Service](c, "display")
c.Action("window.layoutBesideEditor", func(_ context.Context, _ core.Options) core.Result {
return core.Result{OK: false}
})
result, err := svc.LayoutBesideEditor("preview", "code", "right", 0.62)
require.Error(t, err)
assert.Zero(t, result)
assert.Contains(t, err.Error(), "window.layoutBesideEditor")
}
func TestSetWindowFullscreen_Ugly(t *testing.T) {
c := newTestConclave(t)
svc := core.MustServiceFor[*Service](c, "display")