From ebc33c721b5edccaffcb963a110bd9bd709e64c5 Mon Sep 17 00:00:00 2001 From: yetone Date: Mon, 28 Sep 2026 16:15:40 +0800 Subject: [PATCH] =?UTF-8?q?tray:=20a=20click=20on=20the=20bird=20flaps=20i?= =?UTF-8?q?t=20=E2=80=94=20the=20wing=20beats=20twice=20and=20the=20tail?= =?UTF-8?q?=20flicks=20up=20once,=2016=20frames=20over=20about=20half=20a?= =?UTF-8?q?=20second=20(build/icon/gen.go=20tray-flap=20bends=20the=20outl?= =?UTF-8?q?ine=20about=20the=20tail's=20root=20and=20the=20shoulder,=20eas?= =?UTF-8?q?ed,=20so=20it=20stays=20one=20line);=20and=20the=20usage=20besi?= =?UTF-8?q?de=20it=20no=20longer=20sits=20hard=20against=20it,=20a=20thin?= =?UTF-8?q?=20space=20between=20(Image=20#13:=20=E5=9B=BE=E6=A0=87?= =?UTF-8?q?=E4=B8=8E=E7=94=A8=E9=87=8F=E4=B9=8B=E9=97=B4=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E4=BB=BB=E4=BD=95=E7=9A=84=E9=97=B4=E8=B7=9D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 1 + build/icon/gen.go | 94 ++++++++++++++++++++++++++++++ internal/gui/app.go | 34 ++++++++++- internal/gui/trayflap/flap-01.png | Bin 0 -> 829 bytes internal/gui/trayflap/flap-02.png | Bin 0 -> 854 bytes internal/gui/trayflap/flap-03.png | Bin 0 -> 851 bytes internal/gui/trayflap/flap-04.png | Bin 0 -> 830 bytes internal/gui/trayflap/flap-05.png | Bin 0 -> 833 bytes internal/gui/trayflap/flap-06.png | Bin 0 -> 853 bytes internal/gui/trayflap/flap-07.png | Bin 0 -> 870 bytes internal/gui/trayflap/flap-08.png | Bin 0 -> 835 bytes internal/gui/trayflap/flap-09.png | Bin 0 -> 854 bytes internal/gui/trayflap/flap-10.png | Bin 0 -> 859 bytes internal/gui/trayflap/flap-11.png | Bin 0 -> 843 bytes internal/gui/trayflap/flap-12.png | Bin 0 -> 837 bytes internal/gui/trayflap/flap-13.png | Bin 0 -> 833 bytes internal/gui/trayflap/flap-14.png | Bin 0 -> 845 bytes internal/gui/trayflap/flap-15.png | Bin 0 -> 835 bytes internal/gui/trayflap/flap-16.png | Bin 0 -> 830 bytes internal/gui/trayusage_tray.go | 5 ++ 20 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 internal/gui/trayflap/flap-01.png create mode 100644 internal/gui/trayflap/flap-02.png create mode 100644 internal/gui/trayflap/flap-03.png create mode 100644 internal/gui/trayflap/flap-04.png create mode 100644 internal/gui/trayflap/flap-05.png create mode 100644 internal/gui/trayflap/flap-06.png create mode 100644 internal/gui/trayflap/flap-07.png create mode 100644 internal/gui/trayflap/flap-08.png create mode 100644 internal/gui/trayflap/flap-09.png create mode 100644 internal/gui/trayflap/flap-10.png create mode 100644 internal/gui/trayflap/flap-11.png create mode 100644 internal/gui/trayflap/flap-12.png create mode 100644 internal/gui/trayflap/flap-13.png create mode 100644 internal/gui/trayflap/flap-14.png create mode 100644 internal/gui/trayflap/flap-15.png create mode 100644 internal/gui/trayflap/flap-16.png diff --git a/Makefile b/Makefile index ca6bc2f5..41becc30 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,7 @@ app: build icons: @go run build/icon/gen.go tray internal/gui/tray.png + @go run build/icon/gen.go tray-flap internal/gui/trayflap @go run build/icon/gen.go app 64 internal/gui/icon.png @go run build/icon/gen.go app 1024 internal/gui/icon-1024.png @rm -rf build/darwin/magpie.iconset && mkdir -p build/darwin/magpie.iconset diff --git a/build/icon/gen.go b/build/icon/gen.go index 78e0bfb6..d51b678c 100644 --- a/build/icon/gen.go +++ b/build/icon/gen.go @@ -9,6 +9,7 @@ // internal/gui/assets/index.html. // // go run build/icon/gen.go tray internal/gui/tray.png # 44px black template icon (macOS menu bar) +// go run build/icon/gen.go tray-flap internal/gui/trayflap # its frames when clicked (a size after the folder for a bigger look) // go run build/icon/gen.go app 64 internal/gui/icon.png # app icon at a given size // make icons # regenerates all of them plus magpie.icns package main @@ -38,6 +39,19 @@ func main() { switch { case len(os.Args) == 3 && os.Args[1] == "tray": img = tray() + case len(os.Args) == 3 && os.Args[1] == "tray-flap": + if err := trayFlap(os.Args[2], 44); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + return + case len(os.Args) == 4 && os.Args[1] == "tray-flap": + n, _ := strconv.Atoi(os.Args[3]) + if err := trayFlap(os.Args[2], n); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + return case len(os.Args) == 4 && os.Args[1] == "glyph": n, _ := strconv.Atoi(os.Args[2]) img = glyph(n) @@ -71,6 +85,86 @@ func tray() image.Image { return img } +// flapFrames is how many pictures one flap of the tray bird is drawn in. +const flapFrames = 16 + +// trayFlap writes the frames the tray icon plays when it is clicked, +// flap-01.png to flap-16.png: the wing beats twice and the tail flicks up +// once, both easing out of and back into the still bird. The drawing is +// bent, not cut: every point of the outline near the tail turns about the +// tail's root, and every point near the wing about the shoulder, by less +// the nearer it is to the pivot, so the outline stays whole. +func trayFlap(dir string, S int) error { + base := parse(smallSVG) + for f := 1; f <= flapFrames; f++ { + t := float64(f) / (flapFrames + 1) + env := math.Sin(math.Pi * t) // 0 at both ends + tail := 14 * env * math.Sin(math.Pi*t) + wing := 8 * env * math.Sin(4*math.Pi*t) + if wing < 0 { + wing /= 2 // a beat is mostly up; down only a little, into the belly + } + rings := make([][][2]float64, len(base)) + for i, r := range base { + rings[i] = make([][2]float64, len(r)) + for j, p := range r { + // Tail and wing meet in a notch of the outline (ring 0): above + // it the outline bends with the tail, below it with the wing, + // eased across it so it stays one line. The holes, the + // shoulder and the belly, move only where they meet the wing. + up, down := 0.0, smooth((p[1]-25)/3) + if i == 0 { + up = 1 - smooth((p[1]-24)/2.5) + } + p = bend(p, [2]float64{12, 24}, [2]float64{2, 6}, 5, tail*up) + p = bend(p, [2]float64{29, 19.5}, [2]float64{8, 30}, 3.5, wing*down) + rings[i][j] = p + } + } + k := float64(S) / 44 + cov := coverage(rings, S, 8, k, 0, 0) + img := image.NewNRGBA(image.Rect(0, 0, S, S)) + for i, a := range cov { + img.SetNRGBA(i%S, i/S, color.NRGBA{0, 0, 0, uint8(a*255 + 0.5)}) + } + out, err := os.Create(fmt.Sprintf("%s/flap-%02d.png", dir, f)) + if err != nil { + return err + } + err = png.Encode(out, img) + out.Close() + if err != nil { + return err + } + } + return nil +} + +// bend turns p about pivot by deg degrees (clockwise on screen, which +// raises what points left), by all of it at tip's end of the axis from pivot +// to tip and by none at the pivot or behind it, fading too with p's distance +// from that axis past width. +func bend(p, pivot, tip [2]float64, width, deg float64) [2]float64 { + ax, ay := tip[0]-pivot[0], tip[1]-pivot[1] + l := math.Hypot(ax, ay) + dx, dy := p[0]-pivot[0], p[1]-pivot[1] + along := (dx*ax + dy*ay) / (l * l) + across := math.Abs(dx*ay-dy*ax) / l + w := smooth(along/0.45) * (1 - smooth((across-width)/width)) + if w <= 0 { + return p + } + a := deg * w * math.Pi / 180 + s, c := math.Sin(a), math.Cos(a) + return [2]float64{pivot[0] + dx*c - dy*s, pivot[1] + dx*s + dy*c} +} + +// smooth eases 0..1 (clamped) in and out. +func smooth(x float64) float64 { + x = math.Max(0, math.Min(1, x)) + return x * x * (3 - 2*x) +} + // glyph is the bird alone, black on clear, as big on an n-pixel canvas as // app draws it on its tile: the layer of build/darwin/AppIcon.icon, which // macOS 26 lays on a tile of its own, light or dark (#117). diff --git a/internal/gui/app.go b/internal/gui/app.go index 74568a2d..359af6a7 100644 --- a/internal/gui/app.go +++ b/internal/gui/app.go @@ -4,8 +4,9 @@ package gui import ( "crypto/sha256" - _ "embed" + "embed" "encoding/hex" + "io/fs" "log" "net/http" "os" @@ -26,6 +27,12 @@ import ( //go:embed tray.png var trayIcon []byte // black glyph, tinted by the macOS menu bar +// trayFlap is the bird beating its wing and flicking its tail, played on +// the tray icon when it is clicked (build/icon/gen.go tray-flap). +// +//go:embed trayflap/*.png +var trayFlap embed.FS + //go:embed icon.png var appIcon []byte // coloured, for other trays @@ -56,6 +63,9 @@ type host struct { panel *application.WebviewWindow main *application.WebviewWindow tray *application.SystemTray + // flapping is set while the tray bird plays its flap, so a second + // click in it doesn't start another over it + flapping atomic.Bool panelHeight int glides atomic.Int64 // the newest panel glide; older ones stop @@ -302,6 +312,9 @@ func Run(version string, showMain bool, link string) error { // the quick panel by the icon, or the main window if the user would // rather (Settings → Tray icon) h.tray.OnClick(func() { + if runtime.GOOS == "darwin" { + go h.flap() + } if settings.Load().Tray == "window" { h.ShowMain("") return @@ -375,3 +388,22 @@ func abs(n int) int { } return n } + +// flap plays trayFlap on the tray icon, about half a second, and ends on the +// still bird. +func (h *host) flap() { + if !h.flapping.CompareAndSwap(false, true) { + return + } + defer h.flapping.Store(false) + names, _ := fs.Glob(trayFlap, "trayflap/*.png") + for _, n := range names { + b, err := trayFlap.ReadFile(n) + if err != nil { + break + } + h.tray.SetTemplateIcon(b) + time.Sleep(28 * time.Millisecond) + } + h.tray.SetTemplateIcon(trayIcon) +} diff --git a/internal/gui/trayflap/flap-01.png b/internal/gui/trayflap/flap-01.png new file mode 100644 index 0000000000000000000000000000000000000000..530d13e7395faeb36aa51f1cac1251cb5290c604 GIT binary patch literal 829 zcmV-D1H$}?P)E|_3MpUUi z(SA7M(l>WA!0tN09>y6An?{dEuQm)s63#O;m0?QQ+a!Z^tq%GOfhFT+p&2@MfIWBc z?!?CMM2puedQ^RcsvI*@iHVRW68MIvHek5PY9wwJ z@%AnYFbEY0PcJNEe90zMNq9$#x1Vb!va>t^n|2LS&eh??;Y}7`mziLxl`pG%nx?Kk zu%}hq5jMy$M_;+zq`?H4F(CrOoE&xh4M$M$Bb{$KdrSmBVZu_)APcC{g++44YKyb* zWkhEhvApG>8V9G`RANHt-p=#C0?r%~)JnVBM0b#r%~$GHT$Czozhl>o*3`){tYYOc zNrsNlRp!P@V0ASJ-M0Mw7IVQ*aZkM012;aSN{qv&0KNnG1mLUoyv*2t2H*#Px8nKA zfpt|mu!n$;3HXg4@fpDHg5LZ8X>I?;u{PQO7p*@500960S>)SuoTNtD00000NkvXX Hu0mjfg-&@a literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-02.png b/internal/gui/trayflap/flap-02.png new file mode 100644 index 0000000000000000000000000000000000000000..888a1aaa0a2ceb9ca3f0fd3b0caa65dc059bbad6 GIT binary patch literal 854 zcmV-c1F8IpP)D4dh>D4ciiwDdh>3}cjfyfVA}ThhC}UzG zq9Sr4BBFzc6ecP%D5D!U$e^Nw47!o=#`oaYm%DrKUfyL3Fyv6+g$X@(9>4;CyJ;t`2w*jO0G6_0{0q0k zXUJ!s0jL7V*%(nb^&fD1bk!(tB-2{?*UY#u`nE7admRSxoun}sN@K%#sEMEz*_)|p}|9OL!GPg>E)&a zsCpx70P?!AJjny`3J$f&?J;2W3S={$BpEC)bE^V6VBAO}B}d?PO4z=Q(M#T}Jo}OV zU$C?d#kI8BbMS80#_+C~a3ZROO1LW#{I<;gX~0 z0t~H!q=hZ83CLQkD#R+UR}8kDl#6)awJ3o(?cOq9cU;5R)9fd`MQ1G&GGHy0b$OL> z*^Eh0IXW?MUXIu&55@rop<0@!FD+wy$gXMn^jc>}J!2v}t7_rBq|r?I-S&`MT_0R6#G1X4Baeo2e9+S(o#rz52HGr1@zB$6G zPWc7E56Ag@s(ZobuLn5BIvOD9=`cPEpX%HRTZsbEPAxP>v8cnv@FgT zHa*$g^1S#F71(||E@xw!Y8f7l-B6B6(sqO{va?MDR%(sV8x~7aD|11g+&Sr z2`MC4SXiX6kYHip3KJ|07zjavg@FrLm|)0-k#EB=?Cs9Z?OiMU79w}pDkyPJ&6{yaJ$m% z$oAwnDapJ7Q?^J)I(AFkk;h3is^6YSVwIRN4^yIC^$g7A3A5vncAeD{em|u}JxhsF zF@n1Y6%C%qT{>T4Z>xS zJh7_Cx&D7ly4;E>gRV8&=zJokPd@L2FpAoa6X~X>##`!5N-1-g`n;;K2cblxQ!A-r zq}gW1@3u+cMJVBV2Sg859ZP)o6>dYm&$tRmvmLV@~THdMMP_= zv7s30pq0JEj5L@;*kt(AobED~J(AN4gIc+pd`ZnvR*a}|$`zANw0)W#U(|gsQnI3K zHTFT-9D`ZsP9%4fR5=khL)`(o>$}hjcisWG#UMVf8t<%002ovPDHLkV1gGOl#2iW literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-04.png b/internal/gui/trayflap/flap-04.png new file mode 100644 index 0000000000000000000000000000000000000000..e76506e0ee2611fad04bbb78bad1b79ffa379919 GIT binary patch literal 830 zcmV-E1Ht@>P)ExcRuK^qQBe_5F*#9DF)3|z-P%Sb}&j40-7MAay z6x=R=D{HJVfL8!YQb#QSJC+k=uLHu?9H6$181+mggtHx91E>UmEn6vab=#v z34j{_`wj<30f0}0u(m0t4*<4ohdO^%gk$TbNx`mB_k>k81uz6~3SiB2+BSZ4>6pHk z1%NL+K-G*i=LPBofI|RXmIN>Sx$9ydyKBmolC>XZ_l*o=Y*X|oK~4D z>W0tkzq(q@)M)2~J@AO`Na}psYAb!?Z~eV=At_nu^@Fq5{!qvhqJ7n zyhf;mEwb+T%|=F)J5pe!P3F;z>2Pg1ODn!M+v1yyC`B2-N#1&?8L5y6A`meJhQeia zPms&G+i1-ZUDM9lCtEDkSQwSJ>^ND_CwYOv^hhfZZLwgNRp%0`A9lq^J(pei0K+Q8 zys#B60%k8(0ci00R)%kH*#qjR4=mUcQ)Dk?!8phf5O388nHZa-DZg(pFE5yzX%QRF z$@7+DTRSZR3_`_Lq|=Jhwy~gxZ}2=hW+8j42G?1f)9DTJxd&dfmJaxD00030|C*=VTALR3UjP6A07*qo IM6N<$f@x-XQUCw| literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-05.png b/internal/gui/trayflap/flap-05.png new file mode 100644 index 0000000000000000000000000000000000000000..f04dc5f6d07aadcba4897a2ed96e86b2dd986ec2 GIT binary patch literal 833 zcmV-H1HSx;P)@htEk9eu)-=LDk35#DhjQvsFD7ch{86A=%6Bl4#F5CB7=yCh?H%-@qOd$?ESg#-uJqN^$Q2um)vtd@4R!*x%cIN z%$e?hv)0@J-wU|b1n>aBYXD#W08=6@0Qg4h^8deD%L3Sk&Sf~?5`Y!gz>F01^Yr+B z$b+i^xK{J@0qiFUP?2!Q%8_TKlwgYipxQ1O^;m6jz#)KXKx(+kd;EhKSl@;Ko&hKW zSPXMm=9eb`8W}|S)DTwN3_yng{iP1S18~C}TLti5O}OmuceHN-e31}# zWa_vk26aUFxf0i#31NduWSm`^I?t(Gdjnw15;qZfY*N^BYCU{ns&(mi76Cks%3G}k zmA5*FJ*&j{SS6Hqb4RQYT9ue6S51Na=rlQS98l~#5o0%*N(V7f${REe<0$*k=K@+g zJP82sQlMwpR_g}2yqg3VOpktq!#3+=nG3UJ7?ne=i8$!fq`+YQO$?&ZGFXgjVokK! zz4Xpd+O-WZSj25%mpNY6;+fc&Y{mGtR##0p6QxhW=9nV&h=y^jd{?soE)sGm;HSJ^ zVqTsZq)#s-&&vV(qD;O=3t00000 LNkvXXu0mjf1SN$y literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-06.png b/internal/gui/trayflap/flap-06.png new file mode 100644 index 0000000000000000000000000000000000000000..501b20e25fe3353b145500f82bf8af80e05039b9 GIT binary patch literal 853 zcmV-b1FHOqP)7{~t`5fK#;5fOn!R74CG*hB{r5fu{=5fu{?6%!K`5fv2`fr^NUh=_`bGAbq_ zA}YqHsEEiQgA5`fGALt=3^J&Qi0Gi>;D7M#_1)cj?=D$3`iDnKbN9VpzxRLN_wITh z|CsK8m#rY+{E9hZ$%DNHa10>zw_!}Q1K@_^Y~7%Bme>$KR{^w_IDZyEL7CG^IRHhG zVSiK;g!JGJ0Zf!R#sFT~uIL*8bpU-O*d!rq6g8mg7&7ZdI_HKv(gfO#3F|HYWdy80 zrU3Q;Q~+ecf_8a>2R=}O^kM>^7{aRKnmjdK&^>YCvF66CBW%eL)*A~Z?-anM3|iyn z8u7v_0PmHXUpNAvIe>aAQU;I?3ff>6z0bL*!*da&>q5f75xfWwZBT9$slr5Zcbp?IoRL3=DsaaAxl4Mxg;JENZ3V)gt09VPv0%OPY86^xym!X>D}} fylnjr00960rR>lBwslMr00000NkvXXu0mjffxL=9 literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-07.png b/internal/gui/trayflap/flap-07.png new file mode 100644 index 0000000000000000000000000000000000000000..aa03e34a3a7fe99fe80cee27703045f7aa7d7c98 GIT binary patch literal 870 zcmV-s1DX7ZP)dW4Np{tg2kc!N z!!^c>ny|-17KqPqlpTS)jXo2RfC=blB zl08W9QqiJtIC)uVHpbwF0iez5Xj4{KEn<1m6&QvlNRAEW9gNLJQGRKn?As0 zW{M2ZNV@t?Q5_FhRAA6 z!Dwl=m-7G)t6*Q`<{`hIW?b%Q`Pwvk5pmu$^vT0Cz+nDuYn~oh#CIUlVW|SX=)9-OigJu$uLT# z@a@b&mNh>@YZ<<IgzfZ7&-2(6hz*Ft_u>(t0nU59VH3EL% wO}qv0GpBXWp8lJ^BAr=X0Oze=0RRC1|B@)f2etsu1^@s607*qoM6N<$g73JI+yDRo literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-08.png b/internal/gui/trayflap/flap-08.png new file mode 100644 index 0000000000000000000000000000000000000000..7d0a2c7334ab797ed85b1ca10073c1645611d994 GIT binary patch literal 835 zcmV-J1HAl+P)7{~t`5fv2?6%mC^R74CG*hED{M8rfyL_|eJ#Kc5JL`6kKprT?TqGF;VjEahg zii(PgiHHm$I+%#aV2m;%GKi>%=pf^b|G~%G-Mx43-DTP6A0CX|z3+bczxTfHyX#~8 zV|oD2T5-TT0CG!Y@lqAQ0>B3V>wg=@Mr{JCalJ}T+w5WG_F+cP-vIE`cNKR5)P%!o z+ymH3338nVjJ0Qs0K9Qo%{xwIVjtyJKo8GutQ(45y@rI!Dz0X7&D z0DAx`0P?25bK&S*3$*6}+_i+&$2|{zJ<5d(;i&HNnImk;5jNl$^4Wi!qgwz??qhZH zmH2nCR4%%7097ke2Cxb)Br3Ffwf?hhnzP1UxP6rn}$(Q2PN|(zCf%^$z zr%8gp((+=EfxmsMhkU9g(wLmDhO z#xB504G-7?i-63Xzl|H=G3m{^ejOI8(H+zRc4?OtE-o`4He24R!X%9?|gyvif22{ z96G$isD|BEI}V^@I_08spEqe!zSPIeqBO@zRm!)nu;Ano58OpeCYUju8DAO=>Uh5F z{%&aMAupsd{iFd3x@*(E8ug6eZMrRiecq&X9cA@dtRZ@gMoKZ8DSllFRe|Mqn8Fv% z7OQ6F%JGo&9icZ_*_Hw;RVH-J^8O7Lhm)j-^^qH2sMfd-p9A;~;3I%9;(DInC|&^g z0pPuMed)kbn{3z>;1dFV3`ZiiwJdiHeGdii(Pii83Z4DmJJHW1=Er zBBG+AA|iu`4kjWp7^52*WKhw;4LZnp)Kd&?#~|D_B&)6~CVnGKg*TF-s>-h&$(9|-`aDKF`&u5I186di#mmRi z&%Uc%(03pzJW>I$5@s~d7X`tNwDDLmWLtvP9mqa5F`T7>b7pd1%34|FiY4KJCE1yc z@rO!X^h?lt>Gw?wd;1RRo>>Zlr_$yDvsA7YI|epH@jsCEoO3P_Ye<_>NfsKnVdzRF zWvCcD((GO1o+&@R9Pmy}qjJlZaE7j#2Xv-cgaUQGzoSuUMMHS%qH>uE2f6PsfIx@! z(xk1n4PtrImN1k!R9BA`qe^e|3{}}>)zOi5nq6{C7@ZnDgDI=b7CUD*%>@it@|w61 z7TAbEw!kJJ*J2T35BR*HvF(f#5KhYHyYL!=$iF!mMOtuzRiNOHetH>)!Joe zywoT*3W@V-KsEB>5C%z|DoS5ibg;3(JY8c28ne4PW6MCjsMWU|n#73k!j-Hp>7v%e zbn;TL7dEi#P?X$0vj_o?iD%udh@&u%=xV2!%$@+a!{iE@3uOEN@Dji?0AC%+ica|% zz<0;}zpt#u8bzl}%Dn3#5;`&e*!_bd6G0{WJi(ixRm1Vs3Js-VBz3_8j-#nui`|v( z7&a2J*-ZH3uc5&9J4)b&v&F8NIxfg|Z6JKI9Y%BYZZ-SGW9o5O+0Rg{cdZu|nV z!Z^GK;0u7a06s|1bG)Ot58xYsSIYB+6P8hAlUZle5d=T+Bi;e{nbNt-hyUuoNK1(u g!fE4I00030|9R@sk0emw&;S4c07*qoM6N<$f&@{EQUCw| literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-10.png b/internal/gui/trayflap/flap-10.png new file mode 100644 index 0000000000000000000000000000000000000000..1ede17e63f5d898e43a3cb3615f0624fc785ea50 GIT binary patch literal 859 zcmV-h1EltP7@5{^D(jN}llK0O0-nr+VbKdJs zTryn)XRS%VB>;D4%#uni01<#k{~N?r?*WWymjb#cfK{XyGrCR@z&wCLsDnI!I)E1f zc+80BrUa?rHURXsYn*a5y{=OQFa)rsIa9Vi1=xxKRJRjG-AQ$xbf~38>?n=Y@}DKZ z#x?-(m^^bfr%U3bw!u-FQn%{}t6RhXK2T0>X-=z&BTjInco*Xf<@%J?kf7=1k^{PfW=Bb2MpWi*}vGTJc z&N-(qWyfMAO*XRStw{y3j6*HDV}jVUK&Sy%tZF!>kr3sk4=`A)&&5U?Ytfn%ffaVL zCkau?J2VcjC@U>n9JUPrEp|tjwz}z%%WJ;CFbqM`I^2MDZj_E=RGxBABth?n02f&) zlA_UZn6j#DvFiAJrk%}qKLl85H3e*mO+eP-h%*Z~AJ}{c>rlI3T$YYC*c?-2)6y`u zHQ&uFfa5MW5Vd*4@0XaD2U@*0S#Ls~*9~*>C=_;;FlXAcUgQ8M?Sv^}Q-d4*RG-XT zRZr+jE*7!m`P9{AL+MOZkxinf;!V5*@GGP1UOZiy lzam{&T?1#W-vIys|Npdo$Ux&uzajtt002ovPDHLkV1n&pgE;^I literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-11.png b/internal/gui/trayflap/flap-11.png new file mode 100644 index 0000000000000000000000000000000000000000..eaf54d2e47ba4269d94912189da1d548f48231f1 GIT binary patch literal 843 zcmV-R1GM~!P)Y|$;r)q@7;UhG1l}?PH4(|=YBo++;h%*eT@H1 z55Q?F3b?poj+LZfmjHSIGXEOJM!Nv+XqVdtZAytJ;^!uSZi?&Y0hF{gom2o&5fKip zxkg9@cLZRft#Je3t?Q1y2havE)SOM$lo}NSsBR-h-AY$HaK{Emdn>}K?Y~Wc4Q&cw zA3z;IF3xG6Hz@Exb23;F_{~mQGtdTw`AN z3&1Ds=GUIUmmZ*MM`{4FQBFIIqWYYRIy@InPCZ~>dceN1aeOGYzRS-rpF>B12k^iV zc4q51Cr@W&r&Dl66Et>3P2MJNiCIC-eqYN&3 z7qNZ%K$K+#2`t-c$0C=#O6XOL!#>le&Zu8lM&*zxmjr$016(rXu*ohgsz+4>pwFr_ zi}5+}0S1R2U)TbhfULzT#di38E5Wz7uC)cjydG+>8Ky`lreU0DzT0U4R|q*3@C*Ka zhk2>DagzlRd0scn$qQfDUBcXIC2nZ}sCTeJ!deYJMBH#KXVnwBl8r4{@?7fbD~`8L z%Cn^g95eNS-UhU1*~)btMGfq6D$~wAqTFYG`|6|blXQV)&1L{!u-Kbs2N$W@|87Me zf7OU6^b#Xc-L=+xqHTC2j+CV{lYS0G|@@8~=ze0Dh;m?)K^4{1<6!^#Gi<{saI3|NqEA V)i&OC+-m>;002ovPDHLkV1lrlcsu|A literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-12.png b/internal/gui/trayflap/flap-12.png new file mode 100644 index 0000000000000000000000000000000000000000..a8496aa866a1c45a47db99035c0ea430a2945700 GIT binary patch literal 837 zcmV-L1G@Z)P)D6PKvFT1ijtIMA%s+vq@tpt3y@3xM=mF?@11wwdxK{Clbb->d+yiM|D1d8+g&V~ zZh_O*(gEM|d94ZH0f2V^e*6QbNLm5#lcU4`|JTY}z#eoa#r0MJ6yqjlETCT|$M;(X zt_ENz))@deh?1ZZ;f_QgGs+3UmV7|vxM0>pwZjRA0A@bch%58+UxvVXV+7zifC_-z zqJR~CcnaVog)E;cVdaJwHvnW81-)d^bvR+npTZ7OaDaX60Q*c6*ei$@Ta5X4pPBUn9XJ4YBf^fg zfos;Jw$*<6*6YoPuzoEvY+PuAXN1?@1DLSIO)Vd58hb|6!&h3Z!?^PR;8~DwrB;M* zrH9Sf42iKuDD&kS>=06$Az7|!fxYZBIdS6C?Arlzw`rvpAz8{QHV$=`J?OUpRBMj&y-m?WKD!YpGE}+{Wn!)<4jSE>sC#)xO>Ty zp*@B!z+e-1h0Sxm-HYeexnw6KwzE27!MWA?Y}gDfQV-ZLjzsKg8o(t&jx6{YUoX>_ z=L-Au7Wlm4b55Sc0S2=sGws(w7L5Td5+u`~U-PqlS5R-)3fi5*Ml0gIZ41CFSKvkr zP?M=Whc#>7fjz1!*5=XWnLqyzqIh;gofp^^ae3hjS9|HIW-~)iq*84d= zqj&`1JAgOh{c8udRp5c$0Ny9y7k&xvk=V`9(*0597C3D!9q_LJ00960ByGt_*D^o^ P00000NkvXXu0mjf!_I|G literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-13.png b/internal/gui/trayflap/flap-13.png new file mode 100644 index 0000000000000000000000000000000000000000..b504df5e0120b952c5668673e135846cd5852ccb GIT binary patch literal 833 zcmV-H1HSx;P)5QX3W*Wf@wfPqy-YCwQlEw#WPz#yQ&AfO;1z#yQYz#yO?z*0d#K!8C(K~xz8 z7z6|u6c`w!l7TA)7^G5LRn-Ak3Mep0C0850lUCF9-R|Bxsiiz=rP$}2{cd(RwR0FUpjHvM{AZ*zHD#wUk&s0n}Y48d_DFAFygk0K4Sd{NPc!n%Gb{#Z zEUPB36DnqjtQdZ?nc?N8EwIva#?g%7a3zeTC10IoaWBJ5Q3i1AnlEK76k-bxL=1tU z<+j?gh-K$8S~hrBAE&I7H707;(kri7ak8L~U4g;yNK24pbS+L<6>hP~!>(wdXBwA2 zzz~V(3R~hPpx0vMfGV$VW!UzXoG|hFxqvM&L|Q2u#({%Fyj3P-tR0f3{JzS#JY#I8 zd2Bc*&TEEa?KBTC*d=s?r_+*BjST!fS&-~ zi|e-ztZS7Ab_MvDfZzBKp8)(`(7gYimhPW2_rQzR(gFVo00960;bPrNbmyh;00000 LNkvXXu0mjfeqVhs literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-14.png b/internal/gui/trayflap/flap-14.png new file mode 100644 index 0000000000000000000000000000000000000000..355202f4c74df196392364b6f2fc35259175e81d GIT binary patch literal 845 zcmV-T1G4;yP)FknD}1PcQOEH1&23w!(=?LVEf+!4-&?e zfLY)ta0mDf{ICaAwYnAH(pvFpPSV&+h-^E%0(OCE)7iXUUPfp+u!W3d%bsKdYXEiN zmAU&RBeH?Uwj&ZE3v7Qb7VOA)yWO2phK7R=MACHd(39+_2ie3O-Bot3She`V`1hJ8 z;r*0k&t06ZYj8ktL%L~7JE5a9kK|kRi0+|_m8uR-pEow0#O2q`i zspVHSaLnwQgSN{m zpW$Nr+w7j1FJ4&AK(?eso3%LDwK2V)PVnswd%`OtDNV8kNu(OnFjg(!l}->I5y>;7 ziZt~9W76ezL>aWL-bUvW5$EJa7Q(2ezOW*F;i&PZ&L*XVIVLs7krFu*MiZ(=RMWQGjJ_5e# z8}n!5eZSiKW8fR`(t6)@!X^fFU=Il17r`%D#CzaZhvvP0=;=So^aO4QcN%{J00960 X5nt2i^F8yB00000NkvXXu0mjfXW@sP literal 0 HcmV?d00001 diff --git a/internal/gui/trayflap/flap-15.png b/internal/gui/trayflap/flap-15.png new file mode 100644 index 0000000000000000000000000000000000000000..dbd0900a187e0219197945433b2e4a2fa90e7214 GIT binary patch literal 835 zcmV-J1HAl+P)&D6?55+4u)+YBd!0HvqWxP!?SY_sJ3+Rw>BaPHNfqN-ouU(9ed9(8DSN^_Y zX`6~`X?5V?-GPhYeKFx&R11}GHzN35n~6%&BVqH39rTR0^&HWY>|WfO)Y0mo9ulr~ zd6iHh9bpQk4U3nXu3mZ16-LklgRz|i8x7{euEk4b3vlS_Wza)WqTGm(Nb*3LA<%be zt8|PlmfyGngWf*07(8X`449}LN3Xo26Kv4!G{BLXj+xzY=!P|s7pL4K=o>CMMn1sM zDo9$`Dw}|;#i~Nod41Dj+e;}mDd19U`B`RJ3+Njj3PUg~4)(3+F9!lvb|L&jj61wXD5j9Jc%hsG3YW&JMF zU_4D?KqonYg5KTD!OmSBZV+s!0VnO=(rQ141Fuo9xGA6VcOKf3r{W@1W&7=C$!Mxs z;HR;_RAQ3!JfWA_*=7POwNB`UP)-6fjV*NtqmdmMq72_WACzMan0c^v=(}dwzfH<}sE` zE8wEF0xnt-xB=i8K3g8aFs|BvR24Dlgle81x5m=5^F?=%#xDJ4^w&o3h zBLIPmkwa~AQP5ikP<@Q(^+Y2ZF^2LC53&8X7FanV=2Q(pSvSrlU+QfS!6&=UBLyLQQN)2or5GuGW)S0JT#$4Xg|e-9mCHwh)| zz2*+;s$0D5)U+yEvW;U3{eFUt2IsXcUMg9DQ{~Jaw@^;}WhmrF27r(|<5B{<4zZl% zm^qaV^;jQ$w$2*sci+(~Cv<`hx|ar6>dY~-`wpk9DqHN7&M32l#n~MD0J}gZ!B*G= z23kmM^ZBmDwwD6Kg0ga4X|Mr9q?^z%PBr_jyn%(D5i(*emGyFq-a6rVK~GS93}fQF zW;otHWB~@x6X%+zCyp^bWfQ7c)~NILbHhZ=r2Q0dCePYnRf&tk+bpn^l-^W#A@sOp zcGLsAk3M;Nb=z~j3!j^`R8xV796&|#9QZEAPU(HiDX~0tnQ+$*pibBH1f8Xf_c`Fe za)FF;0tLO>&cV)1C1$UF#%SiX0FR@2eE6Jd%870-Cz}WIR$P=SjPGHVjHX)bnuRN1 zk__R(`4L|M{3&SN|4&Q%8^_XU1zfcL1^@v6|Dd1TW9Ajk=>Px#07*qo IM6N<$f;psn9smFU literal 0 HcmV?d00001 diff --git a/internal/gui/trayusage_tray.go b/internal/gui/trayusage_tray.go index 10651adb..4af996ff 100644 --- a/internal/gui/trayusage_tray.go +++ b/internal/gui/trayusage_tray.go @@ -4,6 +4,7 @@ package gui import ( "context" + "runtime" "time" "github.com/yetone/magpie/internal/provider" @@ -35,6 +36,10 @@ func (h *host) watchTrayUsage() { } } cancel() + if label != "" && runtime.GOOS == "darwin" { + // the menu bar sets the text hard against the icon + label = "\u2009" + label + } if label+"\x00"+tip != shown { shown = label + "\x00" + tip h.tray.SetLabel(label)