Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aerc for openSUSE:Factory checked in at 2024-07-30 11:55:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aerc (Old) and /work/SRC/openSUSE:Factory/.aerc.new.1882 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aerc" Tue Jul 30 11:55:15 2024 rev:13 rq:1190351 version:0.18.2 Changes: -------- --- /work/SRC/openSUSE:Factory/aerc/aerc.changes 2024-07-16 22:02:57.543040940 +0200 +++ /work/SRC/openSUSE:Factory/.aerc.new.1882/aerc.changes 2024-07-30 11:57:30.384895794 +0200 @@ -1,0 +2,9 @@ +Mon Jul 29 22:51:52 UTC 2024 - Hannes Braun <apple.han...@gmail.com> - 0.18.2 + +- Update to upstream version 0.18.2 + * Fixed builtin calendar filter error with non-GNU Awk. + * Fixed detection of unicode width measurements on tmux 3.4. + * Fixed dropping of events during large pastes. + * Fixed Home and End key decoding for the st terminal. + +------------------------------------------------------------------- Old: ---- aerc-0.18.1.tar.gz New: ---- aerc-0.18.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aerc.spec ++++++ --- /var/tmp/diff_new_pack.BoY9Yf/_old 2024-07-30 11:57:32.036962611 +0200 +++ /var/tmp/diff_new_pack.BoY9Yf/_new 2024-07-30 11:57:32.036962611 +0200 @@ -18,7 +18,7 @@ Name: aerc -Version: 0.18.1 +Version: 0.18.2 Release: 0 Summary: An email client for terminals License: GPL-3.0-or-later ++++++ aerc-0.18.1.tar.gz -> aerc-0.18.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aerc-0.18.1/CHANGELOG.md new/aerc-0.18.2/CHANGELOG.md --- old/aerc-0.18.1/CHANGELOG.md 2024-07-15 22:50:02.000000000 +0200 +++ new/aerc-0.18.2/CHANGELOG.md 2024-07-30 00:00:05.000000000 +0200 @@ -3,6 +3,15 @@ All notable changes to aerc will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [0.18.2](https://git.sr.ht/~rjarry/aerc/refs/0.18.2) - 2024-07-29 + +### Fixed + +- Builtin `calendar` filter error with non-GNU Awk. +- Detection of unicode width measurements on tmux 3.4. +- Dropping of events during large pastes. +- Home and End key decoding for the st terminal. + ## [0.18.1](https://git.sr.ht/~rjarry/aerc/refs/0.18.1) - 2024-07-15 ### Fixed diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aerc-0.18.1/GNUmakefile new/aerc-0.18.2/GNUmakefile --- old/aerc-0.18.1/GNUmakefile 2024-07-15 22:50:02.000000000 +0200 +++ new/aerc-0.18.2/GNUmakefile 2024-07-30 00:00:05.000000000 +0200 @@ -1,6 +1,6 @@ # variables that can be changed by users # -VERSION ?= $(shell git describe --long --abbrev=12 --tags --dirty 2>/dev/null || echo 0.18.1) +VERSION ?= $(shell git describe --long --abbrev=12 --tags --dirty 2>/dev/null || echo 0.18.2) DATE ?= $(shell date +%Y-%m-%d) PREFIX ?= /usr/local BINDIR ?= $(PREFIX)/bin diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aerc-0.18.1/contrib/depends-diff.py new/aerc-0.18.2/contrib/depends-diff.py --- old/aerc-0.18.1/contrib/depends-diff.py 2024-07-15 22:50:02.000000000 +0200 +++ new/aerc-0.18.2/contrib/depends-diff.py 2024-07-30 00:00:05.000000000 +0200 @@ -66,33 +66,36 @@ else: old_deps[name] = version - print("## New") - print() + once = False added = new_deps.keys() - old_deps.keys() if added: + print("## New") + print() for a in sorted(added): print("+", a, new_deps[a]) - else: - print("none") + once = True - print() - print("## Updated") - print() updated = old_deps.keys() & new_deps.keys() if updated: + if once: + print() + print("## Updated") + print() for u in sorted(updated): print("*", u, old_deps[u], "=>", new_deps[u]) - else: - print("none") + once = True - print() - print("## Removed") - print() removed = old_deps.keys() - new_deps.keys() if removed: + if once: + print() + print("## Removed") + print() for r in sorted(removed): print("-", r) - else: + once = True + + if not once: print("none") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aerc-0.18.1/doc/aerc-jmap.5.scd new/aerc-0.18.2/doc/aerc-jmap.5.scd --- old/aerc-0.18.1/doc/aerc-jmap.5.scd 2024-07-15 22:50:02.000000000 +0200 +++ new/aerc-0.18.2/doc/aerc-jmap.5.scd 2024-07-30 00:00:05.000000000 +0200 @@ -31,7 +31,7 @@ _jmap+oauthbearer_ JMAP over HTTPS using OAUTHBEARER authentication - The username is ignored any may be left empty. If specifying the + The username is ignored and may be left empty. If specifying the password, make sure to prefix it with _:_ to make it explicit that the username is empty. Or set the username to any random value. E.g.: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aerc-0.18.1/filters/calendar new/aerc-0.18.2/filters/calendar --- old/aerc-0.18.1/filters/calendar 2024-07-15 22:50:02.000000000 +0200 +++ new/aerc-0.18.2/filters/calendar 2024-07-30 00:00:05.000000000 +0200 @@ -205,7 +205,8 @@ } } -func prepare(line) { +function prepare(line) +{ gsub($1, "", line) gsub(/^[: ]/, "", line) return line diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aerc-0.18.1/filters/colorize.c new/aerc-0.18.2/filters/colorize.c --- old/aerc-0.18.1/filters/colorize.c 2024-07-15 22:50:02.000000000 +0200 +++ new/aerc-0.18.2/filters/colorize.c 2024-07-30 00:00:05.000000000 +0200 @@ -458,7 +458,7 @@ return false; if (isalnum(c)) return true; - if (strchr("-_.,~:;/?#@!$&%*+=\"'<>()[]", c) != NULL) + if (strchr("-_.,~:;/?#@!$&%*+=\"'|<>()[]", c) != NULL) return true; return false; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aerc-0.18.1/go.mod new/aerc-0.18.2/go.mod --- old/aerc-0.18.1/go.mod 2024-07-15 22:50:02.000000000 +0200 +++ new/aerc-0.18.2/go.mod 2024-07-30 00:00:05.000000000 +0200 @@ -5,7 +5,7 @@ require ( git.sr.ht/~rjarry/go-opt v1.4.0 git.sr.ht/~rockorager/go-jmap v0.5.0 - git.sr.ht/~rockorager/vaxis v0.9.2 + git.sr.ht/~rockorager/vaxis v0.10.3 github.com/ProtonMail/go-crypto v1.0.0 github.com/arran4/golang-ical v0.2.7 github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aerc-0.18.1/go.sum new/aerc-0.18.2/go.sum --- old/aerc-0.18.1/go.sum 2024-07-15 22:50:02.000000000 +0200 +++ new/aerc-0.18.2/go.sum 2024-07-30 00:00:05.000000000 +0200 @@ -2,8 +2,8 @@ git.sr.ht/~rjarry/go-opt v1.4.0/go.mod h1:oEPZUTJKGn1FVye0znaLoeskE/QTuyoJw5q+fjusdM4= git.sr.ht/~rockorager/go-jmap v0.5.0 h1:Xs8NeqpA631HUz4uIe6V+0CpWt6b+nnHF7S14U2BVPA= git.sr.ht/~rockorager/go-jmap v0.5.0/go.mod h1:aOTCtwpZSINpDDSOkLGpHU0Kbbm5lcSDMcobX3ZtOjY= -git.sr.ht/~rockorager/vaxis v0.9.2 h1:OKPaCG3S4b6jWnwUPC0zX+Zw16hhLcSgC2mLw/nwsV0= -git.sr.ht/~rockorager/vaxis v0.9.2/go.mod h1:h94aKek3frIV1hJbdXjqnBqaLkbWXvV+UxAsQHg9bns= +git.sr.ht/~rockorager/vaxis v0.10.3 h1:r9oHYKPfItWh05SQE/UJ4wDrmWRY9MDJKtA9HEl5nBI= +git.sr.ht/~rockorager/vaxis v0.10.3/go.mod h1:h94aKek3frIV1hJbdXjqnBqaLkbWXvV+UxAsQHg9bns= github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= ++++++ vendor.tar.zst ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/git.sr.ht/~rockorager/vaxis/event.go new/vendor/git.sr.ht/~rockorager/vaxis/event.go --- old/vendor/git.sr.ht/~rockorager/vaxis/event.go 2024-07-16 00:59:03.000000000 +0200 +++ new/vendor/git.sr.ht/~rockorager/vaxis/event.go 2024-07-30 00:54:32.000000000 +0200 @@ -18,6 +18,7 @@ notifyColorChange struct{} textAreaPix struct{} textAreaChar struct{} + inBandResizeEvents struct{} appID string terminalID string ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/git.sr.ht/~rockorager/vaxis/image.go new/vendor/git.sr.ht/~rockorager/vaxis/image.go --- old/vendor/git.sr.ht/~rockorager/vaxis/image.go 2024-07-16 00:59:03.000000000 +0200 +++ new/vendor/git.sr.ht/~rockorager/vaxis/image.go 2024-07-30 00:54:32.000000000 +0200 @@ -10,6 +10,8 @@ "io" "git.sr.ht/~rockorager/vaxis/log" + "git.sr.ht/~rockorager/vaxis/octreequant" + "github.com/mattn/go-sixel" "golang.org/x/image/draw" ) @@ -166,7 +168,7 @@ } fmt.Fprintf(k.buf, "\x1B_Gf=100,i=%d,m=%d;%s\x1B\\", k.id, m, string(b[:n])) } - k.vx.PostEvent(Redraw{}) + k.vx.PostEventBlocking(Redraw{}) }() } @@ -256,17 +258,27 @@ } // Re-encode the image s.buf.Reset() - err := sixel.NewEncoder(s.buf).Encode(img) + var paletted image.Image + if p, ok := img.(*image.Paletted); ok && len(p.Palette) < 255 { + // fast-path for paletted images: pass through to sixel + paletted = p + } else { + paletted = octreequant.Paletted(img, 254) + } + err := sixel.NewEncoder(s.buf).Encode(paletted) if err != nil { log.Error("couldn't encode sixel: %v", err) return } - s.vx.PostEvent(Redraw{}) + s.vx.PostEventBlocking(Redraw{}) }() } // CellSize is the current cell size of the encoded image func (s *Sixel) CellSize() (w int, h int) { + if atomicLoad(&s.encoding) { + return + } return s.w, s.h } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/git.sr.ht/~rockorager/vaxis/key.go new/vendor/git.sr.ht/~rockorager/vaxis/key.go --- old/vendor/git.sr.ht/~rockorager/vaxis/key.go 2024-07-16 00:59:03.000000000 +0200 +++ new/vendor/git.sr.ht/~rockorager/vaxis/key.go 2024-07-30 00:54:32.000000000 +0200 @@ -606,8 +606,10 @@ {5, '~'}: KeyPgUp, {6, '~'}: KeyPgDown, {1, 'F'}: KeyEnd, + {4, '~'}: KeyEnd, {8, '~'}: KeyEnd, {1, 'H'}: KeyHome, + {1, '~'}: KeyHome, {7, '~'}: KeyHome, {57358, 'u'}: KeyCapsLock, {57359, 'u'}: KeyScrollLock, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/git.sr.ht/~rockorager/vaxis/octreequant/ooctreequant.go new/vendor/git.sr.ht/~rockorager/vaxis/octreequant/ooctreequant.go --- old/vendor/git.sr.ht/~rockorager/vaxis/octreequant/ooctreequant.go 1970-01-01 01:00:00.000000000 +0100 +++ new/vendor/git.sr.ht/~rockorager/vaxis/octreequant/ooctreequant.go 2024-07-30 00:54:32.000000000 +0200 @@ -0,0 +1,260 @@ +// Package octreequant implements an image quantizer, for transforming bitmap +// images to palette images, before encoding them to SIXEL. +// +// This code was originally developed by delthas and taken from: https://github.com/delthas/octreequant +package octreequant + +import ( + "image" + imagecolor "image/color" +) + +const maxDepth = 8 + +type color struct { + r int + g int + b int + a0 bool // true if transparent +} + +func (c color) color() imagecolor.RGBA { + return imagecolor.RGBA{ + R: uint8(c.r), + G: uint8(c.g), + B: uint8(c.b), + A: 255, + } +} + +func newColor(c imagecolor.Color) color { + cr, cg, cb, ca := c.RGBA() + var r, g, b int + if ca == 0 { + return color{ + a0: true, + } + } + if ca == 0xFFFF { + r = int(cr) >> 8 + g = int(cg) >> 8 + b = int(cb) >> 8 + } else { + r = int(cr) * 255 / int(ca) + g = int(cg) * 255 / int(ca) + b = int(cb) * 255 / int(ca) + } + return color{ + r: r, + g: g, + b: b, + } +} + +type node struct { + c color + n int + i int + children []*node +} + +func (n *node) leaf() bool { + return n.n > 0 +} + +func (n *node) leafs() []*node { + nodes := make([]*node, 0, 8) + for _, n := range n.children { + if n == nil { + continue + } + if n.leaf() { + nodes = append(nodes, n) + } else { + nodes = append(nodes, n.leafs()...) + } + } + return nodes +} + +func (n *node) addColor(color color, level int, parent *tree) { + if level >= maxDepth { + n.c.r += color.r + n.c.g += color.g + n.c.b += color.b + n.n++ + return + } + i := n.colorIndex(color, level) + c := n.children[i] + if c == nil { + c = newNode(level, parent) + n.children[i] = c + } + c.addColor(color, level+1, parent) +} + +func (n *node) paletteIndex(color color, level int) int { + if n.leaf() { + return n.i + } + i := n.colorIndex(color, level) + if c := n.children[i]; c != nil { + return c.paletteIndex(color, level+1) + } + for _, n := range n.children { + if n == nil { + continue + } + return n.paletteIndex(color, level+1) + } + panic("unreachable") +} + +func (n *node) removeLeaves() int { + r := 0 + for _, c := range n.children { + if c == nil { + continue + } + n.c.r += c.c.r + n.c.g += c.c.g + n.c.b += c.c.b + n.n += c.n + r += 1 + } + return r - 1 +} + +func (n *node) colorIndex(color color, level int) int { + i := 0 + mask := 0x80 >> level + if color.r&mask != 0 { + i |= 4 + } + if color.g&mask != 0 { + i |= 2 + } + if color.b&mask != 0 { + i |= 1 + } + return i +} + +func (n *node) color() color { + return color{ + r: n.c.r / n.n, + g: n.c.g / n.n, + b: n.c.b / n.n, + } +} + +func newNode(level int, parent *tree) *node { + n := node{ + children: make([]*node, 8), + } + if level < maxDepth-1 { + parent.addNode(level, &n) + } + return &n +} + +type tree struct { + levels [][]*node + root *node + + count int // size of palette + a0 bool // true if any color is transparent +} + +func (t *tree) leaves() []*node { + return t.root.leafs() +} + +func (t *tree) addNode(level int, n *node) { + t.levels[level] = append(t.levels[level], n) +} + +func (t *tree) addColor(color color) { + t.a0 = t.a0 || color.a0 + t.root.addColor(color, 0, t) +} + +func (t *tree) makePalette(count int) imagecolor.Palette { + palette := make(imagecolor.Palette, 0, count) + i := 0 + c := len(t.leaves()) + + if t.a0 { + count-- + } + + for level := maxDepth - 1; level >= 0; level-- { + if len(t.levels[level]) == 0 { + continue + } + for _, n := range t.levels[level] { + c -= n.removeLeaves() + if c <= count { + break + } + } + if c <= count { + break + } + t.levels[level] = t.levels[level][:0] + } + + for _, n := range t.leaves() { + if i >= count { + break + } + if n.leaf() { + palette = append(palette, n.color().color()) + } + n.i = i + i++ + } + + if t.a0 { + palette = append(palette, imagecolor.RGBA{}) + } + t.count = len(palette) + return palette +} + +func (t *tree) paletteIndex(color color) int { + if color.a0 { + return t.count-1 + } + return t.root.paletteIndex(color, 0) +} + +func newTree() *tree { + t := tree{ + levels: make([][]*node, maxDepth), + } + t.root = newNode(0, &t) + return &t +} + +// Paletted quantizes an image and returns a paletted image, with +// a palette up to the specified color count. +func Paletted(img image.Image, colors int) *image.Paletted { + w := img.Bounds().Dx() + h := img.Bounds().Dy() + + t := newTree() + for y := 0; y < h; y++ { + for x := 0; x < w; x++ { + t.addColor(newColor(img.At(x, y))) + } + } + out := image.NewPaletted(img.Bounds(), t.makePalette(colors)) + for y := 0; y < h; y++ { + for x := 0; x < w; x++ { + out.SetColorIndex(x, y, uint8(t.paletteIndex(newColor(img.At(x, y))))) + } + } + return out +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/git.sr.ht/~rockorager/vaxis/quirks.go new/vendor/git.sr.ht/~rockorager/vaxis/quirks.go --- old/vendor/git.sr.ht/~rockorager/vaxis/quirks.go 2024-07-16 00:59:03.000000000 +0200 +++ new/vendor/git.sr.ht/~rockorager/vaxis/quirks.go 2024-07-30 00:54:32.000000000 +0200 @@ -13,15 +13,14 @@ case strings.HasPrefix(id, "kitty"): log.Debug("kitty identified. applying quirks") vx.caps.noZWJ = true + case id == "tmux 3.4": + // tmux 3.4 has unicode support, but doesn't advertise via 2027 + vx.caps.unicodeCore = true + } - // TODO: remove this when asciinema supports ':' delimiters in RGB if os.Getenv("ASCIINEMA_REC") != "" { - fgIndexSet = strings.ReplaceAll(fgIndexSet, ":", ";") - fgRGBSet = strings.ReplaceAll(fgRGBSet, ":", ";") - bgIndexSet = strings.ReplaceAll(bgIndexSet, ":", ";") - bgRGBSet = strings.ReplaceAll(bgRGBSet, ":", ";") - // Asciinema also doesn't support any advanced image protocols + // Asciinema doesn't support any advanced image protocols vx.graphicsProtocol = halfBlock } if os.Getenv("VAXIS_FORCE_LEGACY_SGR") != "" { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/git.sr.ht/~rockorager/vaxis/sequences.go new/vendor/git.sr.ht/~rockorager/vaxis/sequences.go --- old/vendor/git.sr.ht/~rockorager/vaxis/sequences.go 2024-07-16 00:59:03.000000000 +0200 +++ new/vendor/git.sr.ht/~rockorager/vaxis/sequences.go 2024-07-30 00:54:32.000000000 +0200 @@ -87,6 +87,7 @@ synchronizedUpdate = 2026 unicodeCore = 2027 colorThemeUpdates = 2031 + inBandResize = 2048 sixelScrolling = 8452 // dsr requests/responses diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/git.sr.ht/~rockorager/vaxis/vaxis.go new/vendor/git.sr.ht/~rockorager/vaxis/vaxis.go --- old/vendor/git.sr.ht/~rockorager/vaxis/vaxis.go 2024-07-16 00:59:03.000000000 +0200 +++ new/vendor/git.sr.ht/~rockorager/vaxis/vaxis.go 2024-07-30 00:54:32.000000000 +0200 @@ -34,6 +34,7 @@ reportSizePixels bool osc11 bool osc176 bool + inBandResize bool } type cursorState struct { @@ -269,6 +270,8 @@ log.Info("[capability] OSC 176 supported") case terminalID: vx.termID = ev + case inBandResizeEvents: + vx.caps.inBandResize = true } } } @@ -325,6 +328,13 @@ } } +// PostEventBlocking inserts an event into the [Vaxis] event loop. The call will +// block if the queue is full. This method should only be used from a different +// goroutine than the main thread. +func (vx *Vaxis) PostEventBlocking(ev Event) { + vx.queue <- ev +} + // SyncFunc queues a function to be called from the main thread. vaxis will call // the function when the event is received in the main thread either through // PollEvent or Events. A Redraw event will be sent to the host application @@ -697,25 +707,25 @@ if vx.pastePending { key.EventType = EventPaste } - vx.PostEvent(key) + vx.PostEventBlocking(key) case ansi.C0: key := decodeKey(seq) if vx.pastePending { key.EventType = EventPaste } - vx.PostEvent(key) + vx.PostEventBlocking(key) case ansi.ESC: key := decodeKey(seq) if vx.pastePending { key.EventType = EventPaste } - vx.PostEvent(key) + vx.PostEventBlocking(key) case ansi.SS3: key := decodeKey(seq) if vx.pastePending { key.EventType = EventPaste } - vx.PostEvent(key) + vx.PostEventBlocking(key) case ansi.CSI: switch seq.Final { case 'c': @@ -723,17 +733,17 @@ for _, ps := range seq.Parameters { switch ps[0] { case 4: - vx.PostEvent(capabilitySixel{}) + vx.PostEventBlocking(capabilitySixel{}) } } - vx.PostEvent(primaryDeviceAttribute{}) + vx.PostEventBlocking(primaryDeviceAttribute{}) return } case 'I': - vx.PostEvent(FocusIn{}) + vx.PostEventBlocking(FocusIn{}) return case 'O': - vx.PostEvent(FocusOut{}) + vx.PostEventBlocking(FocusOut{}) return case 'R': // KeyF1 or DSRCPR @@ -762,7 +772,7 @@ switch seq.Parameters[0][0] { case 2: if seq.Parameters[1][0] == 0 { - vx.PostEvent(capabilitySixel{}) + vx.PostEventBlocking(capabilitySixel{}) } } return @@ -775,7 +785,7 @@ switch seq.Parameters[0][0] { case colorThemeResp: // 997 m := ColorThemeMode(seq.Parameters[1][0]) - vx.PostEvent(ColorThemeUpdate{ + vx.PostEventBlocking(ColorThemeUpdate{ Mode: m, }) } @@ -795,7 +805,7 @@ } switch seq.Parameters[1][0] { case 1, 2: - vx.PostEvent(synchronizedUpdates{}) + vx.PostEventBlocking(synchronizedUpdates{}) } case 2027: if len(seq.Parameters) < 2 { @@ -804,7 +814,7 @@ } switch seq.Parameters[1][0] { case 1, 2: - vx.PostEvent(unicodeCoreCap{}) + vx.PostEventBlocking(unicodeCoreCap{}) } case 2031: if len(seq.Parameters) < 2 { @@ -813,13 +823,13 @@ } switch seq.Parameters[1][0] { case 1, 2: - vx.PostEvent(notifyColorChange{}) + vx.PostEventBlocking(notifyColorChange{}) } } return case 'u': if len(seq.Intermediate) == 1 && seq.Intermediate[0] == '?' { - vx.PostEvent(kittyKeyboard{}) + vx.PostEventBlocking(kittyKeyboard{}) return } case '~': @@ -831,22 +841,22 @@ switch seq.Parameters[0][0] { case 200: vx.pastePending = true - vx.PostEvent(PasteStartEvent{}) + vx.PostEventBlocking(PasteStartEvent{}) return case 201: vx.pastePending = false - vx.PostEvent(PasteEndEvent{}) + vx.PostEventBlocking(PasteEndEvent{}) return } } case 'M', 'm': mouse, ok := parseMouseEvent(seq) if ok { - vx.PostEvent(mouse) + vx.PostEventBlocking(mouse) } return case 't': - if len(seq.Parameters) != 3 { + if len(seq.Parameters) < 3 { log.Error("[CSI] unknown sequence: %s", seq) return } @@ -861,7 +871,7 @@ if !vx.caps.reportSizePixels { // Gate on this so we only report this // once at startup - vx.PostEvent(textAreaPix{}) + vx.PostEventBlocking(textAreaPix{}) return } case 8: @@ -872,10 +882,24 @@ // once at startup. This also means we // can set the size directly and won't // have race conditions - vx.PostEvent(textAreaChar{}) + vx.PostEventBlocking(textAreaChar{}) return } vx.chSizeDone <- true + case 48: + // CSI <type> ; <height> ; <width> ; <height_pix> ; <width_pix> t + switch len(seq.Parameters) { + case 5: + atomicStore(&vx.resize, true) + vx.nextSize.Cols = w + vx.nextSize.Rows = h + vx.nextSize.YPixel = seq.Parameters[3][0] + vx.nextSize.XPixel = seq.Parameters[4][0] + if !vx.caps.inBandResize { + vx.PostEventBlocking(inBandResizeEvents{}) + } + vx.Resize() + } } return } @@ -884,7 +908,7 @@ if vx.pastePending { key.EventType = EventPaste } - vx.PostEvent(key) + vx.PostEventBlocking(key) case ansi.DCS: switch seq.Final { case 'r': @@ -906,9 +930,9 @@ } switch vals[0] { case hexEncode("Smulx"): - vx.PostEvent(styledUnderlines{}) + vx.PostEventBlocking(styledUnderlines{}) case hexEncode("RGB"): - vx.PostEvent(truecolor{}) + vx.PostEventBlocking(truecolor{}) } } case '|': @@ -920,10 +944,10 @@ if string(seq.Data) == hexEncode("~VTE") { // VTE supports styled underlines but // doesn't respond to XTGETTCAP - vx.PostEvent(styledUnderlines{}) + vx.PostEventBlocking(styledUnderlines{}) } case '>': - vx.PostEvent(terminalID(seq.Data)) + vx.PostEventBlocking(terminalID(seq.Data)) } } case ansi.APC: @@ -931,7 +955,7 @@ return } if strings.HasPrefix(seq.Data, "G") { - vx.PostEvent(kittyGraphics{}) + vx.PostEventBlocking(kittyGraphics{}) } case ansi.OSC: if strings.HasPrefix(string(seq.Payload), "11") { @@ -943,7 +967,7 @@ if vx.CanReportBackgroundColor() { vx.chBg <- string(seq.Payload) } - vx.PostEvent(capabilityOsc11{}) + vx.PostEventBlocking(capabilityOsc11{}) } if strings.HasPrefix(string(seq.Payload), "52") { vals := strings.Split(string(seq.Payload), ";") @@ -982,7 +1006,7 @@ if !vx.CanReportBackgroundColor() { return Color(0) } - vx.tw.WriteString(osc11) + vx.tw.WriteStringLocked(osc11) resp := <-vx.chBg var r, g, b int _, err := fmt.Sscanf(resp, "11;rgb:%x/%x/%x", &r, &g, &b) @@ -1011,6 +1035,9 @@ _, _ = vx.tw.WriteString(decrqm(synchronizedUpdate)) _, _ = vx.tw.WriteString(decrqm(unicodeCore)) _, _ = vx.tw.WriteString(decrqm(colorThemeUpdates)) + // We blindly enable in band resize. We get a response immediately if it + // is supported + _, _ = vx.tw.WriteString(decset(inBandResize)) _, _ = vx.tw.WriteString(xtversion) _, _ = vx.tw.WriteString(kittyKBQuery) _, _ = vx.tw.WriteString(kittyGquery) @@ -1060,6 +1087,9 @@ // Let's query the current mode also _, _ = vx.tw.WriteString(tparm(dsr, colorThemeReq)) } + if vx.caps.inBandResize { + _, _ = vx.tw.WriteString(decset(inBandResize)) + } // TODO: query for bracketed paste support? _, _ = vx.tw.WriteString(decset(bracketedPaste)) // bracketed paste @@ -1105,6 +1135,9 @@ if vx.caps.osc176 { _, _ = vx.tw.WriteString(tparm(setAppID, vx.appIDLast)) } + if vx.caps.inBandResize { + _, _ = vx.tw.WriteString(decrst(inBandResize)) + } // Most terminals default to "text" mouse shape _, _ = vx.tw.WriteString(tparm(mouseShape, MouseShapeTextInput)) _, _ = vx.tw.Flush() @@ -1186,7 +1219,7 @@ } case <-vx.chSigWinSz: atomicStore(&vx.resize, true) - vx.PostEvent(Redraw{}) + vx.PostEventBlocking(Redraw{}) case <-vx.chSigKill: vx.Close() return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/git.sr.ht/~rockorager/vaxis/vaxis_unix.go new/vendor/git.sr.ht/~rockorager/vaxis/vaxis_unix.go --- old/vendor/git.sr.ht/~rockorager/vaxis/vaxis_unix.go 2024-07-16 00:59:03.000000000 +0200 +++ new/vendor/git.sr.ht/~rockorager/vaxis/vaxis_unix.go 2024-07-30 00:54:32.000000000 +0200 @@ -14,9 +14,11 @@ ) func (vx *Vaxis) setupSignals() { - signal.Notify(vx.chSigWinSz, - syscall.SIGWINCH, - ) + if !vx.caps.inBandResize { + signal.Notify(vx.chSigWinSz, + syscall.SIGWINCH, + ) + } signal.Notify(vx.chSigKill, // kill signals syscall.SIGABRT, @@ -32,6 +34,10 @@ // reportWinsize func (vx *Vaxis) reportWinsize() (Resize, error) { + if vx.caps.inBandResize { + // We already received the size if we have in band reports + return vx.nextSize, nil + } if vx.xtwinops && vx.caps.reportSizeChars && vx.caps.reportSizePixels { log.Trace("requesting screen size from terminal") io.WriteString(vx.console, textAreaSize) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/git.sr.ht/~rockorager/vaxis/writer.go new/vendor/git.sr.ht/~rockorager/vaxis/writer.go --- old/vendor/git.sr.ht/~rockorager/vaxis/writer.go 2024-07-16 00:59:03.000000000 +0200 +++ new/vendor/git.sr.ht/~rockorager/vaxis/writer.go 2024-07-30 00:54:32.000000000 +0200 @@ -4,6 +4,7 @@ "bytes" "fmt" "io" + "sync" ) // writer is a buffered writer for a terminal. If the terminal supports @@ -13,6 +14,7 @@ buf *bytes.Buffer w io.Writer vx *Vaxis + mut sync.Mutex } func newWriter(vx *Vaxis) *writer { @@ -66,6 +68,15 @@ return w.buf.Len() } +// WriteStringLocked writes to the underlying terminal while the mutex is held. +// This does not handle any mouse nor synchronization state and is intended to +// be used for one-off synchronized sequence writes to the terminal +func (w *writer) WriteStringLocked(s string) (n int, err error) { + w.mut.Lock() + defer w.mut.Unlock() + return w.w.Write([]byte(s)) +} + func (w *writer) Flush() (n int, err error) { if w.buf.Len() == 0 { // If we didn't write any visual changes, make sure we make any @@ -95,5 +106,7 @@ if w.vx.caps.synchronizedUpdate { w.buf.WriteString(decrst(synchronizedUpdate)) } + w.mut.Lock() + defer w.mut.Unlock() return w.w.Write(w.buf.Bytes()) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/modules.txt new/vendor/modules.txt --- old/vendor/modules.txt 2024-07-16 00:59:03.000000000 +0200 +++ new/vendor/modules.txt 2024-07-30 00:54:33.000000000 +0200 @@ -10,11 +10,12 @@ git.sr.ht/~rockorager/go-jmap/mail/emailsubmission git.sr.ht/~rockorager/go-jmap/mail/identity git.sr.ht/~rockorager/go-jmap/mail/mailbox -# git.sr.ht/~rockorager/vaxis v0.9.2 +# git.sr.ht/~rockorager/vaxis v0.10.3 ## explicit; go 1.18 git.sr.ht/~rockorager/vaxis git.sr.ht/~rockorager/vaxis/ansi git.sr.ht/~rockorager/vaxis/log +git.sr.ht/~rockorager/vaxis/octreequant git.sr.ht/~rockorager/vaxis/widgets/align git.sr.ht/~rockorager/vaxis/widgets/term # github.com/ProtonMail/go-crypto v1.0.0