Skip to content

Commit

Permalink
feat: support windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Henri Devigne committed Jun 2, 2024
1 parent aee8624 commit d20a9d4
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 22 deletions.
Binary file added .DS_Store
Binary file not shown.
34 changes: 32 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
vendor
vendor
icons/*.go
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<https://support.apple.com/guide/mac-help/open-items-automatically-when-you-log-in-mh15189>

### Thresholds

Expand All @@ -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 !
8 changes: 8 additions & 0 deletions generate-icons.sh
Original file line number Diff line number Diff line change
@@ -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
Binary file added icons/green.ico
Binary file not shown.
Binary file added icons/orange.ico
Binary file not shown.
Binary file added icons/red.ico
Binary file not shown.
Binary file added icons/white.ico
Binary file not shown.
38 changes: 21 additions & 17 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,68 +3,63 @@ 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)
}

func onReady() {
systray.SetTitle("Initializing...")
systray.SetIcon(icons.White)

mLatencyLabel := systray.AddMenuItem("Latency", "Current Latency")
mLatencyLabel.Disable()

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()
}
}()
Expand All @@ -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()
}
22 changes: 22 additions & 0 deletions ping.go
Original file line number Diff line number Diff line change
@@ -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)
}
}

0 comments on commit d20a9d4

Please sign in to comment.