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

Reply via email to