From 962bd5a824feebcd5a05bca4e0df7505162b42bd Mon Sep 17 00:00:00 2001 From: Junya Hayashi Date: Tue, 13 Feb 2024 21:20:20 +0900 Subject: [PATCH] shiny/x11driver: handle the case of X server connection closed --- shiny/driver/x11driver/screen.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/shiny/driver/x11driver/screen.go b/shiny/driver/x11driver/screen.go index c0dc9a412..20b6ee5b0 100644 --- a/shiny/driver/x11driver/screen.go +++ b/shiny/driver/x11driver/screen.go @@ -5,6 +5,7 @@ package x11driver import ( + "errors" "fmt" "image" "image/color" @@ -28,6 +29,8 @@ import ( // For example, its Conn.WaitForEvent concept is a method, not a channel, so // it's not obvious how to interrupt it to service a NewWindow request. +var XConnectionClosed = errors.New("x11driver: X server connection closed") + type screenImpl struct { xc *xgb.Conn xsi *xproto.ScreenInfo @@ -125,6 +128,11 @@ func (s *screenImpl) run() { noWindowFound := false switch ev := ev.(type) { + case nil: + s.xc = nil + log.Printf("x11driver: X server connection closed") + return + case xproto.DestroyNotifyEvent: s.mu.Lock() delete(s.windows, ev.Window) @@ -284,6 +292,9 @@ const ( ) func (s *screenImpl) NewBuffer(size image.Point) (retBuf screen.Buffer, retErr error) { + if s.xc == nil { + return nil, XConnectionClosed + } w, h := int64(size.X), int64(size.Y) if w < 0 || maxShmSide < w || h < 0 || maxShmSide < h || maxShmSize < 4*w*h { @@ -354,6 +365,9 @@ func (s *screenImpl) NewBuffer(size image.Point) (retBuf screen.Buffer, retErr e } func (s *screenImpl) NewTexture(size image.Point) (screen.Texture, error) { + if s.xc == nil { + return nil, XConnectionClosed + } w, h := int64(size.X), int64(size.Y) if w < 0 || maxShmSide < w || h < 0 || maxShmSide < h || maxShmSize < 4*w*h { return nil, fmt.Errorf("x11driver: invalid texture size %v", size) @@ -391,6 +405,10 @@ func (s *screenImpl) NewTexture(size image.Point) (screen.Texture, error) { } func (s *screenImpl) NewWindow(opts *screen.NewWindowOptions) (screen.Window, error) { + if s.xc == nil { + return nil, XConnectionClosed + } + width, height := 1024, 768 if opts != nil { if opts.Width > 0 { @@ -654,6 +672,10 @@ func (s *screenImpl) setProperty(xw xproto.Window, prop xproto.Atom, values ...x } func (s *screenImpl) drawUniform(xp render.Picture, src2dst *f64.Aff3, src color.Color, sr image.Rectangle, op draw.Op, opts *screen.DrawOptions) { + if s.xc == nil { + return + } + if sr.Empty() { return }