From d20a9d4bf820cfcf1de8120bbcec9d132088e188 Mon Sep 17 00:00:00 2001 From: Henri Devigne Date: Sun, 2 Jun 2024 18:00:49 +0200 Subject: [PATCH] feat: support windows --- .DS_Store | Bin 0 -> 6148 bytes .github/workflows/main.yml | 34 +++++++++++++++++++++++++++++++-- .gitignore | 3 ++- README.md | 22 +++++++++++++++++++-- generate-icons.sh | 8 ++++++++ icons/green.ico | Bin 0 -> 105662 bytes icons/orange.ico | Bin 0 -> 105662 bytes icons/red.ico | Bin 0 -> 105662 bytes icons/white.ico | Bin 0 -> 105662 bytes main.go | 38 ++++++++++++++++++++----------------- ping.go | 22 +++++++++++++++++++++ 11 files changed, 105 insertions(+), 22 deletions(-) create mode 100644 .DS_Store create mode 100644 generate-icons.sh create mode 100644 icons/green.ico create mode 100644 icons/orange.ico create mode 100644 icons/red.ico create mode 100644 icons/white.ico create mode 100644 ping.go diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..fb4bc706581820e3f360ad645c335a095493254a GIT binary patch literal 6148 zcmeHKOG*Pl5PcmZjEE9&<3^YRs1Oj>V;C3ilz0FW15ruLAi8ij2k-!%zzcW;!JT`L z(-l>gMJay$j@#TXZ8nq-tGxw?Q0N-QK`XNjG%O`rxuqPmWoP8u;wG!lY@0AAwHe=Ph&Vjrs$(9;0lZ@u%eeW zssG2b`~Pv0U%3LVz`s%;RP$!uU`ke7Cz6v|o6;}nViH#>4k?_(Qp{K>#oP2~Tu)^} V%nVCKuF(9CK$O7;SKwC__yTVQXa4{I literal 0 HcmV?d00001 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fd3c2a1..45b89b3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,20 +2,45 @@ name: Release on: push: branches: - - main + - feat-support-windows permissions: contents: read jobs: + generate-icons: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.22' + - name: Compiled icons + run: | + GOPATH=$(go env GOPATH) + export GOPATH + go get github.com/cratonica/2goarray + go install github.com/cratonica/2goarray + bash generate-icons.sh + - uses: actions/upload-artifact@v4 + with: + name: icons + path: icons/*.go + windows-build: runs-on: windows-latest + needs: [ generate-icons ] steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1.22' - - run: go build -o ipingtray.exe + - uses: actions/download-artifact@v4 + with: + name: icons + path: icons + + - run: go build -ldflags -H=windowsgui -o ipingtray.exe - name: Set up NSIS run: choco install nsis @@ -33,11 +58,16 @@ jobs: macos-build: runs-on: macos-13 + needs: [ generate-icons ] steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1.22' + - uses: actions/download-artifact@v4 + with: + name: icons + path: icons - run: go build -o ipingtray - run: go install github.com/machinebox/appify@latest diff --git a/.gitignore b/.gitignore index 5657f6e..2068911 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -vendor \ No newline at end of file +vendor +icons/*.go \ No newline at end of file diff --git a/README.md b/README.md index bfbdc37..2de3edd 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,11 @@ this option cannot be configured at this time) ## Start app automatically on boot -###  MacOS +###  macOS You can follow the article from Apple which explain how to start the app automatically at boot: -https://support.apple.com/guide/mac-help/open-items-automatically-when-you-log-in-mh15189 + ### Thresholds @@ -41,6 +41,24 @@ https://support.apple.com/guide/mac-help/open-items-automatically-when-you-log-i ![./docs/screenshot.png](/docs/screenshot.png) +## Development + +### Generate icons + +If you wish to update the icons, you need to run the `generate-icons.sh` which gonna generate +golang []bytes array representing the icon. + +To generate icons, you also need to install [`2goarray`](https://github.com/cratonica/2goarray) + +```bash +go get github.com/cratonica/2goarray +go install github.com/cratonica/2goarray +``` + +> ⚠️ We use .ico file because it's the only supported format on windows, according to +> [@ZGGSONG](https://github.com/getlantern/systray/issues/154#issuecomment-1207607136) + + ## Contribution Feel free to contribute ! diff --git a/generate-icons.sh b/generate-icons.sh new file mode 100644 index 0000000..be0063f --- /dev/null +++ b/generate-icons.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -x + +for icon in icons/*.ico; do + icon_name="$(basename ${icon%.*})" + capitalized_name=$(echo "${icon_name:0:1}" | tr '[:lower:]' '[:upper:]')${icon_name:1} + ${GOPATH}/bin/2goarray "${capitalized_name}" icons <${icon} >"icons/${icon_name}.go" +done diff --git a/icons/green.ico b/icons/green.ico new file mode 100644 index 0000000000000000000000000000000000000000..7d32f7f18ce769e95043152497e9a33904b760a4 GIT binary patch literal 105662 zcmeI554>Gfb?4t9hWs%QN&pLO1Zh((iUKOswj>B`frgR+EQQgT=r|06GcwfCVTMO| zFT5lW;v9QI;6UNt$z!==X(&bjh%CgS( zD(mfdB1PY0&-J)2MZ6Y#?g(w5EwqWY6>X%gE!|J#cxp20e9wOAbRvE0_S}B8b>gzc z-<@h@z3KN()AiF8YvKVmU_@+fuw%*-mxAA%DPDbNjqv;;~(rMGZrdrppwsw|nW_o$E z>1o9D^<~rBjxZ)em)IEDHrXVx;2FEx&buZm*V^Z%a-G#Tm8Ns4i?7SQ#I|Qs?Gul( zkJv`~MBgs8p3&Fgj6Sz>)LBOD=Qe%6Q(eDw+Ub5%sqa@?+hx1Rba1BW)_8N28 zIoUVaHtF26=9v*w*V}hhHra7gxxwmHn*OdjU5CA{@9!x#J(D~ivXS(GzSLRV9{Nn* zhcjf*Vyj(7t-ty6CVJd2oldkJ-JIXAwzg#Z3X}Qyrh~hUyB90&&=a-;J0j*}!=+d6DVZ0Dp~F(>^u@pYqpKQ4b@b(1Oab@<$LPqjxjQtkCD z(kJ@Hvn89@;xG>~K{kbqdSmmv-utCfe~(@r_r9%+yWeBupGT@#BDQr+b}r@(J){4a zizc@Iqn+2w(sYlw9kfj>viCfC7G)Pw`F(z=}lXYH5uL%#&^h6aV*cgxYO7je}#Tz-@N|NX{=|@ zKtEaQ=Gwk3aXV?d?~7-VKCA!UH`h62e0a0*cifa2?2S(Q&mL?}t*!gp_tzMAPlhqJ z=MKNq$=0E#m^F0U4Fl8p9Qxq76qB9&GcuB2Ms`J<@??kK_Y8Nki<58b zNhYVe!#Kvr72e+Q+-0Q$7RTdI_Rz;Ej17_PaCXw97@WLL_bhvpvw!=V zY(~uHJr~9=Jh#Y>yn}3>xbr?%_71(o+e$XvOaA~yNBF}Sp&Eu0zr z9cljdzKT7@#rRvs%8Z%G;qlB;uy+(a-@Ve!Y`KnS5IIV&$XM|SvR7_xZviKK{D#x1x=~ z!RGIDWA8f^d$GSoCcE>siM#HfJ7nb<%{)JVDLM}-|0052baIIjlCaK zaYpQKo4C_+jGar|b&Nzx`}AWy#TcE~ zi{+R;Po6<9J2-4&PV} z+d=taba`oZTIGv1&p$o)$D7@IBCv?Q7A+Gh_AJ%h4^Fo^D&>>zV>#hQibz~4C* z>pmZHe8la_vG`cSv!~}S*}RvQJOA8!onRk4gFYrvZie++=$zk{n~Lq4`gf1Cc;nlF zJ=Qnwjy>P!bUc0di*>O(2GKPPqI=?zsdF?LJG#j3e@89WWnBfalOON#EMechz55gU zOo{uQKEE_FiS>c5&{=E;(JeZz=Vk6N{ub?V2G^JcCLUtUM|)!S$SG;8=ebf})4q5H zr;{AKo;Zd88t$ZYvfsz3_6MyXGi^-)aKaK8{n}&&Eox(AFVsNhc-CNr7e16R5*`xg` ziM_#m{-i&#*u!b|}t`+54#dEtSES0XD=l$aoN)qkD}7m6L&yA{M!z zEB@Bl8iw)8W!XWN-}zdVXZC(qa~s$`+C)1OZ!=p4=-9_2FaU${!^FenrC|nk#$&6y zzg-mO*tE6)&WXM8yBhP+9-fcH-t3S8y7mmh0!(-tc)5LEW4}keJH{?E``5V~Xyd*| zE8E8$n_>>Q_kK6ozS+SZHU?cY)`CG8@HSBM!`Q%)U;_^vhp+M2<8S8&+lNml&%-#A z+@p_oX@_U;zuD(hX08n6!wKLVvY&PLgV?km8 z{Gx0i%-}a+=(6mL3Gz3`Y~RftZ67vQe%CYhKde5LnJ)vcbMJ>c+rV3lzc~|N@Mz27 zJRA7Mm-}%aemAi<^BLQn9cf|^HoOhgI1rXD%Z~1vzY)vcjM=rct`wh6jt9PDzx&^< zZg*`>f1jB$Licd!{jhSn`+sFMW|1*_YDFf*r z2IYrk12r$Fd108k%;w~F&)}&xW_+PqUq!x8F|TYN_v7BOYag@YRA!$Hq<>g|3B@8B z2f~ilXTj8E_HWV0{Eb*#?8~T)_SV_=w8jOFm1}0)hpiR&vU`cW*~cC_m;S{AY`_RM z5N2S9yd5mT6l{6cIIi=!#Ju#@;CmH!#N$41`x1Avle<{&*g+VKZ6NF@A6=}?+G@Nl ziJ0>Yo*aBHbG?im8AEEG7vBrt+=KhU{>RG_w2i=D(?GMB8mHu8O1UjXOa55{!=w4dFwfCZR<4fulfpRXyH}IX+Rm3+2>S}48$aCzzD1;4v`OrDc)IwF<6t`lPw&{R#)?F^1Z|` za177#ySf+L-IPj_fiVCJ;zE8{HV}pw$H5fy8I12>t;JoDe;KuCW4-;2xL3ZHF{I*- zn7_ncdj32EF@HV|(fVlEf-zW={TsC$%&7U}wb_?tpQzcZ(gTl4KwTJcIaP#UYA=VG6c3 zS{ci}8<=bHx6=Ib3sv65=bYh>F{NkkX8WxBrhSqH48VkE5N0$6R2?a(up%1>L&`G~ zV?XkUo7{4D8^8H3rn0z$>k8ZFXD9-Vz%RZmsgpj1%$K*iGe}<$Jk4 z%*XdlpOZ{r05)KRaT?4p22?H@rnDZWh(R7T{+5^xJi=m+r)seW{u=&#&JWwi^*>=H z@s?!J!~kr-2&~8l!;r>+#I>y$jmLmE z3GssXQw-eB-=~bf%~kFXHhu1eu^;2e()I?O(2)V2tI7t#4h+E(O!+yG7Jm-}7GwTc zzg6-VY#(FG#9v3br{}V;OMyRQ1!k%k7?zs(!~fn}`CsOTW&aX?iM2`C`Q7rTH3)_M zyT|z3+{hn!Yv+Gu`{sORPM%7VK_>?A1F#ZeVEJEIlKrdmx7ql+wTgc`*uQYC()V)T zmwonSsU#V+F#sEl{CWQ?{x%wuus3FNARIF%67xs?5QaZl#2sR9?rn4PRFVv02Cz#N zgT_o?2Zmz)U=8MAZ_LQM(vHO+F*3H2@9Z7u8wYDJH)iV(#%%qS_*4El;*VGc{YC8MHAV2Is{5!II|>)?g0y#_av04fg&Kb*v3!jUea7{FzM^ zdkZ%&%u`7+h#3$c9r^R?Phk%B#_S!q4fg&eYw~X>`O~{^W&SVNKjRO($30*E`Io1X zWYER{Y`{o0{v&q+L)bEyf0rwy??&m-ar3f`8UpK;E%ix*M_}CUs#k% zl0h2-umK~mQXBulpVr^QAFQpn_s?N(%zgu5o&6TVRaU1tVBUXY&Gg5u7{lROpU%Ry z_qlVQoU-p-`=*j)P%$7b;4d>)D*j*ymSBqa-(U>ZU=H>Q{w`{p1L6H6-v6-mSK(SV z|ABw^+%4X+I8PG%x#DKVfk!t;w&ppFbEBCk4*jwrNTV~_I?^Zb&-V;#{(D66- z_PK$-pSkB}^8N4KKb0hdiUF8_K^Up=r`#V*k>4ZF0&8R8H%|-yJ7&Lyy1{-EmAFJX z7$1XJ9-C_tS96agUtE$(l0h2-un}@EyaU4AM;!aYRuTJdG5+QU`?oH{A4A69jn!|! z@EZukD~ubtM#&#>4dcuMzH~siH~UnQ46sLV02?9p_58sQEWs492eB`#i97Ar+i&7; zw7;=7Ut>TQgM|5Hi$REQ4!rNcP!78Ppgfh?Ed#N@KE%GpNMI$7Jzxs9U<}s8U2A`& z#URgw--y;coYo=m4xGgxwpuH!L4fsFJn)LZ9{W^guMDt1=pQDS`-PFAPniFO8Lhiw zO#w_@YX!#E*}p&2;*R_ur5FSHc{s*^j30?XGzPSJ5XPDZKX`EdvtRz%us`H0hvccu zJ{fohU?R+W$oIkw>}cMDv0o8;+!a`B=WodD;`(X~NUl(0z%maF+vIle^YF&~+5g;M z{ah-uPzIg>m@5EN zm5;nK+<)oAOLGdJQ3CD+gO!KT zS}bxp#5bi6=H7>X_0Z4;_J{rTVc|2!smweXc>Q|aSH2fEU_^O8#&31syJ#G8H>{FRNGJr+&4Fe(WH6{WZjQyDNjo-J#_rlir zwh#Umn-6}d%?B$ECJ*!J;(a*sj=%7=U&s%C^zf?iIhC0y1FvU}(K8H?bFO@^;@)=O z`%qwO_xv#zGFtiII1Y9`nDvG{2fz3?zZlxWp0ezJElXvF$w0dGx<>afpfOqSy;^S- z`(BvphP~pPqb&~J9`c3ct@Tc3xgLu=49qj;BnSBFufIC*_Dlc!m-19*whUxj&^fw? zfnfj0yD09(_reV9Tx;dZ>{*L>kFLeN%E2@d4s!F!sH5m}+P7pgon_Ia zH&~<|UF)}ALhPZOU;Lg2^KBcl^T*+R5GYU&v;<%E9YQEYenVjIKl6VY&}%0^+!%wbtcpX7>*4X!|<*Uh#)* zyr{B)@q9>`3)Hi~Jm4|kJ|^%+`;Y$C(N&?|e@@3O*-R%{pr=?@=#oM`YYyb|$ODJC z!_RlX$R;a=?Yn47>=k?-WO2yXDjTSAAalZSU;1F$#QHpb>rjSH{HE~w>V7zb)j*lZx< zP<{)JHZd11-n4)7ci)_+GI%n8Iq8tS))}Dd5PRVNWc&1fuW~Lh(+ykQowKjKGkkyb zex`mSOY34R7Xy2=i@8ANW`5=SzY>@`_ItR=n|cxTgLj;xKDF!b=&uX@pM*~Om)j1=gqZo;4O_dkTF1M19?Vh zBku*!585y8IR3S#e=U`1Dg*Qr>kA#COLU5E@pECFiy!xS+Xo}C(w$A42!EV=jKwui zxBX5GV*qTR#Ug4a&k8pC`0dA6y#4w!zn-g5pUU)+f%M|-1NuRS=u&p2vVG{hJ>U0q zV5C3n6|8Q|*0jaK%!x1-u(j8WOKB^GwGrf4-}=M1)>vEq?D9O7=_P~M7N9e9hYryt z42GD)bR2Yz&f8<&HGQ&s-cByI@#U8q=Y=CbOq=w3uU}wr``w9}_Pt%m)6j zibYuKZM ze(NW{mH+0Cf3xC^V~XnaIqeI%^jZ#H&iur73w<|wP9*Ff{QBF|(VeW?YJE!hAH9z^MCkN)(`*Od+0*!?S0$cL07do4*xDMYpc-pRoQ}R#NUv$=@9e7 z_l2>b;t{>K9_0l!#*i;wm9MHesq!q0|q(8hTz&Zu{9ck=642r{Lf3qxKwPRKOd$z&cS+>2+w%@hw?6gfv z0>};-B1>e7Y>_dt7I(-WU7(Y&rV1UQEB$sFIxO;hPZ%S|_mGob@z!*m(~QBVtC(27 zBgmXJ{d4OS=)cCk{HD#yzh9ZZ!!~54?cDs_{2!-nLJ~k`k{^3yifoZFydiUBk1q;& z7IJ+4JtA~QKBHjoY2)s+0b#G;@tW*+EkC(EyaP|JoYfvm7k`+<(fg|2ayYYVV}G9$=~?+8}qmCdVBtE+dOmc%!}<^`MdIe zmbM@PWFfhDSs^=Qh%Aw*#@pk9s8-`Qpde-NG} z`sL?H%DC9)sP$~lzhi!W_}0VoGyd+3{CwN~xou(&x$>FqJlp=oEZyk4unn2BAzy9Ov%P1QZ0fK2&t7ujZ^#OnAv^DH zk*#ve)p`PSpm{afJ#>Z6q*t#?)lK)kZ*y_H+>zV|9L!ZU4qLTW%NT7lwNN#>RQ^roT=y^^-o+cj`Frojcx{ANTliK}PdTR>&-jr$0Bp$Sarml_6vdd&pe#8m$})zxPw* z_oOrQ>5rw~>AqK++1HPk8iOATze&wpo!;eSO(WwFjR~DU*0_1WX3JG=w%^|W%E9@G z-#als|Hbq3_uKaSwnrqV3=2({qd4N!#Q8sGt0ez9R!tE9G0K@)T#MIB&`GQ-aVA~r^C0Zi=D1IMzShchp}gJJ zEPS&Tm&hNJCoJdew0=ghiF`6~-NHK;=C69>Rrx7To|0d%^Mat8OY%$d57>r%VDDMG zIKMdm_v38nwqM(L_vLT2&9~L}fj-eL`bb~tGkr$}^0kcj+H4*&M3(Zm#C{s33Ug?AM32^?Yz=6`;Ee!zVPeVTL->q?wS zm-;*id$l?46Q7&l{t2q;Lg>Xo&iZL|#LVPkYo#hMzhnBl$%&nXk zx}pRYEiT;W?tSv5f3-A!(>LCfuloL~{Jfu>mtVZ=;(Wxmb+)ayZOpc{wowOdFeE0~ zdjdJfZ~kxkju_-`oXfSj2lwKh)X@goLYrtCZKSQlvhz0=V>{0seGGn+p5*Ij1HP3uDSuLHv-N?oZpEFA zfkRBovq#^N0eLHAf^3ixW9TBU@?wzTb=k4O=6TsS=^)mXIHO+2gR)nf<391ZsqgLl z4Vk~#%jEVpli@v8&KlVwWAaywt4n(rVrAY@E#nl%L)eKX7OOmk*_WX6I~U}OzqmL* z=I`6_zWf6(d?3Ggr^V4b zEt0UpF?IZnb2t~q&UxmXa1E}-HMutT;9d*tp0aVo^R%gYP9o;$OSMjgJ`&TCLsmWo zS%^F3l93s*D`Z$a(_Z#XI*4^8)~MIU%SPvW5GZEH5xW@^CdaRE#1H z%kg2zUz6`L`+%KbY!p~5$BEdI*hg1-FZ0`h3mfZ`-(dU&FH7!Uk{|r#gY%_dS(+dA z&|&%E58J;v_DEUmm^%K(Ih@OP_%56gH*n3sdO42MJ-u(GZ9bl$?Uk*gPl_uvz7u!I zLSwuevPXifuFH@a&#+`zavG3|S;tg9z;TaHb@~xGfE5~)A?esxDmcA*MLZ9h-i@S$|Y><)U$KJ~j zJxKQ2>s&s^x)Nv7pFR)5UTu#1#OJ2IBL~SqGV!vbZc|lWVaMkihs4Uo_z)X_PFS}q zn;5Ye=G_@LnUB_Z5uLy6HuKeHAK^euic8r_aie|3n6aihzvp`@;*4uotl2%qTd;A~ zrVvZ;@8>o#N1y1M;tGxLkO8vTlp&KsMv@QjUjFE zh3`_}Om>ZXa4+u3y=jB|s&Xf?bF`g4VC(1;eWQ=`byJoF?yzs-PW!~)p60LcGleep zGkvTyUEN^0o3C2_>-nHR&mys+{4_d;M{Euph)HY_j8L$bFr!j(DqgF-{?4B7==)sD zv&Ox+r?+vmNn<)ON89NGeW6dAET*83o;iP<_-l<5_Kg2+J^Qg<3SAsvIy=S62Gii3 zW zR@z*&oj!E#XX3BLoFAJ`5B^$u+hpsDuD9Q6+LW!fa-)^I?Ek!{yd%sJcqU;2-zPS) zOEBXL9Qoq^CcgL{*Wg-Q)3e6B1ox&5o3brsn^u=?TwtGl+gr!+bC&oU6#nXdYg4w+ z?94JN_%(7mA2JqhGbXlL`Mxpv|jFW6MUR*hG59(%qEXIzVGa&7Lxy^4D>PFQBg z3oG85c=9YJ{+fC7wokE!_OUJOef;6ae=S?#^~Q0m+Z(KoqVsOZ_O{PUtQ=wGtya#l z@_sAVTKTAzTaBO1R_?X(fRzW!!ZCH5!#Tyde24FH4X(vCx%S@fe)an|wNY);eunXv zm;Y@W8k(o$a=&xP{##M6+(O-)THP+HhK5Fb<#R>dVqZ5})Mc)&{A%sXKP^rh8alLf z;x^T}CXTAEb;0U#?t-Bc#i=WF!LoJKRxR9CoWuXCn~b*Vs++W`hK9=Px!YDZu6n`w zhZZNg+g3N;=C4=Yc#E$qWj*Ta%EtJrvN5%$l#Ou`;2SGwOs#ok18dDI8@R20kI=v^ z^}5i&(Ry8IU{hWFw9x3N$)V9vlS8AM>Y{FhjzrxE9cilD7PrMZwUCkv5OpMsx}uI8%6+3oub?h!^ayoPqeE4_(V@wa_YTd=^I8K#^CC%?gTh(^ z4=wIdYs^SdS8GgJqynZc^RC4fhVMzSvEOe-Q}tlR;}X_Wo!IbOIepP<|O_LU0D$hTmLf!RE_%w@rhP> literal 0 HcmV?d00001 diff --git a/icons/orange.ico b/icons/orange.ico new file mode 100644 index 0000000000000000000000000000000000000000..b0f3d2e6b5e9decf78aa6d563110787ef18287ff GIT binary patch literal 105662 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 literal 0 HcmV?d00001 diff --git a/icons/red.ico b/icons/red.ico new file mode 100644 index 0000000000000000000000000000000000000000..2b6ff1d17d0e156bd6cb5593e80a3f99c47df782 GIT binary patch literal 105662 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 J_p*}D{{cO4ms|h< literal 0 HcmV?d00001 diff --git a/main.go b/main.go index 34de3a1..2b91af2 100644 --- a/main.go +++ b/main.go @@ -3,13 +3,14 @@ package main import ( "fmt" "log" + "runtime" "strings" "fyne.io/systray" probing "github.com/prometheus-community/pro-bing" -) -var pinger *probing.Pinger + "ipingtray/icons" +) func main() { systray.Run(onReady, onExit) @@ -17,6 +18,7 @@ func main() { func onReady() { systray.SetTitle("Initializing...") + systray.SetIcon(icons.White) mLatencyLabel := systray.AddMenuItem("Latency", "Current Latency") mLatencyLabel.Disable() @@ -24,47 +26,40 @@ func onReady() { systray.AddSeparator() mQuit := systray.AddMenuItem("Quit", "Quit the app") - var err error - pinger, err = probing.NewPinger("8.8.8.8") - if err != nil { - panic(err) - } - pinger.SetLogger(nil) - // Update tray title pinger.OnRecv = func(pkt *probing.Packet) { latency := pkt.Rtt.Milliseconds() + icon := icons.Red switch { case latency < 50: - systray.SetTitle(fmt.Sprintf("🟢 %d ms", latency)) + icon = icons.Green case latency < 75: - systray.SetTitle(fmt.Sprintf("🟠 %d ms", latency)) - default: - systray.SetTitle(fmt.Sprintf("🔴 %d ms", latency)) + icon = icons.Orange } + updateTray(fmt.Sprintf("%d ms", latency), icon) mLatencyLabel.SetTitle(fmt.Sprintf("%s: %d ms", pinger.IPAddr().String(), latency)) } pinger.OnSendError = func(_ *probing.Packet, err error) { - systray.SetTitle("🔴 Network unavailable") + updateTray("Network Unavailable", icons.Red) if strings.Contains(err.Error(), "sendto") { parts := strings.Split(err.Error(), ": ") if len(parts) >= 2 { - mLatencyLabel.SetTitle(fmt.Sprintf("8.8.8.8: %s", parts[len(parts)-1])) + mLatencyLabel.SetTitle(fmt.Sprintf("%s: %s", pinger.Addr(), parts[len(parts)-1])) return } } - mLatencyLabel.SetTitle(fmt.Sprintf("8.8.8.8: %s", err.Error())) + mLatencyLabel.SetTitle(fmt.Sprintf("%s: %s", pinger.Addr(), err.Error())) } // Running the ping go func() { if err := pinger.Run(); err != nil { - log.Println("Pinger has crashed") + log.Printf("pinger has crashed: %v\n", err) systray.Quit() } }() @@ -76,6 +71,15 @@ func onReady() { }() } +func updateTray(title string, icon []byte) { + systray.SetTitle(title) + systray.SetIcon(icon) + + if runtime.GOOS == "windows" { + systray.SetTooltip(title) + } +} + func onExit() { pinger.Stop() } diff --git a/ping.go b/ping.go new file mode 100644 index 0000000..71a4f69 --- /dev/null +++ b/ping.go @@ -0,0 +1,22 @@ +package main + +import ( + probing "github.com/prometheus-community/pro-bing" + "runtime" +) + +var pinger *probing.Pinger + +func init() { + var err error + pinger, err = probing.NewPinger("8.8.8.8") + if err != nil { + panic(err) + } + + pinger.SetLogger(nil) + + if runtime.GOOS == "windows" { + pinger.SetPrivileged(true) + } +}