diff --git a/Makefile b/Makefile index 0f1cd331ac..c51d52e48c 100644 --- a/Makefile +++ b/Makefile @@ -164,19 +164,19 @@ host-apps-windows: powershell 'Get-ChildItem .\cmd\apps | % { ${OPTS} go build ${BUILD_OPTS} -o ./apps $$_.FullName }' host-apps-systray: ## Build app - ${OPTS} go build ${BUILD_OPTS} -o ./apps/skychat ./cmd/apps/skychat - ${OPTS} go build ${BUILD_OPTS} -o ./apps/skysocks ./cmd/apps/skysocks - ${OPTS} go build ${BUILD_OPTS} -o ./apps/skysocks-client ./cmd/apps/skysocks-client - ${OPTS} go build ${BUILD_OPTS} -tags systray -o ./apps/vpn-server ./cmd/apps/vpn-server - ${OPTS} go build ${BUILD_OPTS} -tags systray -o ./apps/vpn-client ./cmd/apps/vpn-client + ${OPTS} go build ${BUILD_OPTS} -o ./apps/ ./cmd/apps/skychat + ${OPTS} go build ${BUILD_OPTS} -o ./apps/ ./cmd/apps/skysocks + ${OPTS} go build ${BUILD_OPTS} -o ./apps/ ./cmd/apps/skysocks-client + ${OPTS} go build ${BUILD_OPTS} -tags systray -o ./apps/ ./cmd/apps/vpn-server + ${OPTS} go build ${BUILD_OPTS} -tags systray -o ./apps/ ./cmd/apps/vpn-client host-apps-systray-windows: powershell -Command new-item .\apps -itemtype directory -force - powershell 'go build ${BUILD_OPTS} -o .\apps\skychat .\cmd\apps\skychat' - powershell 'go build ${BUILD_OPTS} -o .\apps\skysocks .\cmd\apps\skysocks' - powershell 'go build ${BUILD_OPTS} -o .\apps\skysocks-client .\cmd\apps\skysocks-client' - powershell 'go build ${BUILD_OPTS} -tags systray -o .\apps\vpn-server .\cmd\apps\vpn-server' - powershell 'go build ${BUILD_OPTS} -tags systray -o .\apps\vpn-client .\cmd\apps\vpn-client' + powershell 'go build ${BUILD_OPTS} -o .\apps\skychat.exe .\cmd\apps\skychat' + powershell 'go build ${BUILD_OPTS} -o .\apps\skysocks.exe .\cmd\apps\skysocks' + powershell 'go build ${BUILD_OPTS} -o .\apps\skysocks-client.exe .\cmd\apps\skysocks-client' + powershell 'go build ${BUILD_OPTS} -tags systray -o .\apps\vpn-server.exe .\cmd\apps\vpn-server' + powershell 'go build ${BUILD_OPTS} -tags systray -o .\apps\vpn-client.exe .\cmd\apps\vpn-client' # Static Apps host-apps-static: ## Build app @@ -200,9 +200,9 @@ bin-systray-windows: ## Build `skywire-visor` and `skywire-cli` with systray sup powershell 'Get-ChildItem .\cmd | % { ${OPTS} go build ${BUILD_OPTS} -tags systray -o ./ $$_.FullName }' bin-systray: ## Build `skywire-visor`, `skywire-cli` - ${OPTS} go build ${BUILD_OPTS} -tags systray -o ./skywire-visor ./cmd/skywire-visor - ${OPTS} go build ${BUILD_OPTS} -tags systray -o ./skywire-cli ./cmd/skywire-cli - ${OPTS} go build ${BUILD_OPTS} -o ./setup-node ./cmd/setup-node + ${OPTS} go build ${BUILD_OPTS} -tags systray -o ./ ./cmd/skywire-visor + ${OPTS} go build ${BUILD_OPTS} -tags systray -o ./ ./cmd/skywire-cli + ${OPTS} go build ${BUILD_OPTS} -o ./ ./cmd/setup-node # Static Bin bin-static: ## Build `skywire-visor`, `skywire-cli` diff --git a/apps b/apps deleted file mode 120000 index 5c1caf3e24..0000000000 --- a/apps +++ /dev/null @@ -1 +0,0 @@ -scripts/_apps \ No newline at end of file diff --git a/cmd/skywire-visor/commands/nosystray.go b/cmd/skywire-visor/commands/nosystray.go index f2c0e3be1e..86a050fa76 100644 --- a/cmd/skywire-visor/commands/nosystray.go +++ b/cmd/skywire-visor/commands/nosystray.go @@ -9,10 +9,6 @@ import ( "github.com/skycoin/skycoin/src/util/logging" ) -func extraFlags() { - -} - func runApp() { runVisor() } diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index d93a59b06e..18c2ec5064 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -97,8 +97,6 @@ func init() { for _, j := range hiddenflags { rootCmd.Flags().MarkHidden(j) //nolint } - - extraFlags() } var rootCmd = &cobra.Command{ diff --git a/cmd/skywire-visor/commands/systray.go b/cmd/skywire-visor/commands/systray.go index 0d9f4e01c0..cee11b4298 100644 --- a/cmd/skywire-visor/commands/systray.go +++ b/cmd/skywire-visor/commands/systray.go @@ -12,14 +12,6 @@ import ( "github.com/skycoin/skywire/internal/gui" ) -var ( - runSysTrayApp bool -) - -func extraFlags() { - rootCmd.Flags().BoolVar(&runSysTrayApp, "systray", false, "Run system tray app") -} - func runApp(args ...string) { l := logging.NewMasterLogger() sysTrayIcon, err := gui.ReadSysTrayIcon() @@ -33,7 +25,6 @@ func runApp(args ...string) { }() conf := initConfig(l, confPath) - systray.Run(gui.GetOnGUIReady(sysTrayIcon, conf), gui.OnGUIQuit) } diff --git a/docs/systray-builds.md b/docs/systray-builds.md index 377e77904c..553ec58f68 100644 --- a/docs/systray-builds.md +++ b/docs/systray-builds.md @@ -9,7 +9,7 @@ To build `skywire-visor` with systray feature enabled, you have to had these ins - Debian / Ubuntu and its derivations ```bash -$ sudo apt install libgtk-3-dev libappindicator3-dev +$ sudo apt-get install gcc libgtk-3-dev libayatana-appindicator3-dev libappindicator3-dev ``` - Fedora / RHEL and its derivations @@ -23,6 +23,7 @@ $ sudo dnf install gtk3-devel libappindicator-gtk3-devel ```bash $ sudo pacman -S libappindicator-gtk3 gtk3 ``` +also need install `libayatana-appindicator`. You can install it by [AUR](https://aur.archlinux.org/packages/libayatana-appindicator). Other distros might require the installation of said library in their own respective name. diff --git a/go.mod b/go.mod index 99f0e3488b..f5bf5fe041 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/getlantern/golog v0.0.0-20201105130739-9586b8bde3a9 // indirect github.com/getlantern/hidden v0.0.0-20201229170000-e66e7f878730 // indirect github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6 // indirect - github.com/getlantern/systray v1.1.0 + github.com/getlantern/systray v1.2.1 github.com/google/go-github v17.0.0+incompatible github.com/google/uuid v1.1.2 github.com/gorilla/securecookie v1.1.1 diff --git a/go.sum b/go.sum index 3aac97a303..317fe1510e 100644 --- a/go.sum +++ b/go.sum @@ -166,8 +166,8 @@ github.com/getlantern/hidden v0.0.0-20201229170000-e66e7f878730/go.mod h1:6mmzY2 github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6 h1:QthAQCekS1YOeYWSvoHI6ZatlG4B+GBDLxV/2ZkBsTA= github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= -github.com/getlantern/systray v1.1.0 h1:U0wCEqseLi2ok1fE6b88gJklzriavPJixZysZPkZd/Y= -github.com/getlantern/systray v1.1.0/go.mod h1:AecygODWIsBquJCJFop8MEQcJbWFfw/1yWbVabNgpCM= +github.com/getlantern/systray v1.2.1 h1:udsC2k98v2hN359VTFShuQW6GGprRprw6kD6539JikI= +github.com/getlantern/systray v1.2.1/go.mod h1:AecygODWIsBquJCJFop8MEQcJbWFfw/1yWbVabNgpCM= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= diff --git a/internal/gui/gui.go b/internal/gui/gui.go index b1b0fb3ac2..99b2f2d4df 100644 --- a/internal/gui/gui.go +++ b/internal/gui/gui.go @@ -4,10 +4,12 @@ package gui import ( + "context" "embed" "fmt" "io" "io/ioutil" + "net" "net/http" "strings" "sync" @@ -16,10 +18,19 @@ import ( "github.com/gen2brain/dlgs" "github.com/getlantern/systray" + "github.com/sirupsen/logrus" + "github.com/skycoin/dmsg/pkg/direct" + dmsgdisc "github.com/skycoin/dmsg/pkg/disc" + "github.com/skycoin/dmsg/pkg/dmsg" + "github.com/skycoin/dmsg/pkg/dmsgget" + "github.com/skycoin/dmsg/pkg/dmsghttp" "github.com/skycoin/skycoin/src/util/logging" "github.com/toqueteos/webbrowser" + "github.com/skycoin/skywire-utilities/pkg/cipher" + "github.com/skycoin/skywire/pkg/servicedisc" "github.com/skycoin/skywire/pkg/skyenv" + "github.com/skycoin/skywire/pkg/visor" "github.com/skycoin/skywire/pkg/visor/visorconfig" ) @@ -33,8 +44,8 @@ var log = logging.NewMasterLogger() var ( stopVisorFnMx sync.Mutex stopVisorFn func() - //vpnClientStatusMu sync.Mutex - //vpnClientStatus bool + closeDmsgDC func() + rpcC visor.API ) var ( @@ -44,27 +55,31 @@ var ( var ( mAdvancedButton *systray.MenuItem mOpenHypervisor *systray.MenuItem - //mVPNClient *systray.MenuItem - mVPNLink *systray.MenuItem - mUninstall *systray.MenuItem - mQuit *systray.MenuItem + mVPNClient *systray.MenuItem + mVPNStatus *systray.MenuItem + mVPNLink *systray.MenuItem + mVPNButton *systray.MenuItem + mUninstall *systray.MenuItem + mQuit *systray.MenuItem ) // GetOnGUIReady creates func to run on GUI startup. func GetOnGUIReady(icon []byte, conf *visorconfig.V1) func() { doneCh := make(chan bool, 1) + logger := logging.NewMasterLogger() + logger.SetLevel(logrus.InfoLevel) + + httpC := getHTTPClient(conf, context.Background(), logger) + return func() { systray.SetTemplateIcon(icon, icon) - systray.SetTooltip("Skywire") initOpenVPNLinkBtn(conf) initAdvancedButton(conf) - //initVpnClientBtn() + initVpnClientBtn(conf, httpC, logger) initQuitBtn() - //go updateVPNConnectionStatus(conf, doneCh) - go handleUserInteraction(conf, doneCh) } } @@ -96,7 +111,6 @@ func Stop() { if !atomic.CompareAndSwapInt32(&guiStopped, 0, 1) { return } - stopVisor() systray.Quit() } @@ -168,13 +182,111 @@ func initOpenVPNLinkBtn(vc *visorconfig.V1) { }() } -//func initVpnClientBtn() { -// mVPNClient = systray.AddMenuItem("VPN", "VPN Client Connection") -//} +func initVpnClientBtn(conf *visorconfig.V1, httpClient *http.Client, logger *logging.MasterLogger) { + + rpc_logger := logger.PackageLogger("systray:rpc_client") + hvAddr := getHVAddr(conf) + for !isHypervisorRunning(hvAddr) { + rpc_logger.Info("Waiting for RPC to get ready...") + time.Sleep(2 * time.Second) + } + rpcC = rpcClient(conf, rpc_logger) + + mVPNClient := systray.AddMenuItem("VPN", "VPN Client Submenu") + // VPN Status + mVPNStatus = mVPNClient.AddSubMenuItem("Status: Disconnect", "VPN Client Status") + mVPNStatus.Disable() + go vpnStatusBtn(conf, rpcC) + // VPN Connect/Disconnect Button + mVPNButton = mVPNClient.AddSubMenuItem("Connect", "VPN Client Switch Button") + // VPN Public Servers List + mVPNServersList := mVPNClient.AddSubMenuItem("Servers", "VPN Client Servers") + mVPNServers := []*systray.MenuItem{} + for _, server := range getAvailPublicVPNServers(conf, httpClient, logger.PackageLogger("systray:servers")) { + mVPNServers = append(mVPNServers, mVPNServersList.AddSubMenuItemCheckbox(server, "", false)) + } + go serversBtn(conf, mVPNServers, rpcC) +} + +func vpnStatusBtn(conf *visorconfig.V1, rpcClient visor.API) { + for { + stats, _ := rpcClient.GetAppConnectionsSummary(skyenv.VPNClientName) + if len(stats) == 1 { + if stats[0].IsAlive { + mVPNStatus.SetTitle("Status: Connected") + mVPNButton.SetTitle("Disconnect") + mVPNButton.Enable() + } else { + mVPNStatus.SetTitle("Status: Connecting...") + mVPNButton.SetTitle("Disconnect") + mVPNButton.Disable() + } + } else { + mVPNStatus.SetTitle("Status: Disconnected") + mVPNButton.SetTitle("Connect") + mVPNButton.Enable() + } + time.Sleep(3 * time.Second) + } +} + +func serversBtn(conf *visorconfig.V1, servers []*systray.MenuItem, rpcClient visor.API) { + btnChannel := make(chan int) + for index, server := range servers { + go func(chn chan int, server *systray.MenuItem, index int) { + + select { + case <-server.ClickedCh: + chn <- index + } + }(btnChannel, server, index) + } + + for { + selectedServer := servers[<-btnChannel] + serverTempValue := strings.Split(selectedServer.String(), ",")[2] + serverPK := serverTempValue[2 : len(serverTempValue)-5] + for _, server := range servers { + server.Uncheck() + server.Enable() + } + selectedServer.Check() + selectedServer.Disable() + pk := cipher.PubKey{} + if err := pk.UnmarshalText([]byte(serverPK)); err != nil { + continue + } + + rpcClient.StopApp(skyenv.VPNClientName) + rpcClient.SetAppPK(skyenv.VPNClientName, pk) + rpcClient.StartApp(skyenv.VPNClientName) + } +} -//func handleVpnClientButton(conf *visorconfig.V1) { -// //mVPNClient.AddSubMenuItem() -//} +func handleVPNButton(conf *visorconfig.V1, rpcClient visor.API) { + stats, _ := rpcClient.GetAppConnectionsSummary(skyenv.VPNClientName) + if len(stats) == 1 { + if stats[0].IsAlive { + mVPNStatus.SetTitle("Status: Disconnecting...") + mVPNButton.Disable() + mVPNButton.SetTitle("Connect") + if err := rpcClient.StopApp(skyenv.VPNClientName); err != nil { + mVPNStatus.SetTitle("Status: Connected") + mVPNButton.Enable() + mVPNButton.SetTitle("Disconnect") + } + } + } else { + mVPNStatus.SetTitle("Status: Connecting...") + mVPNButton.Disable() + mVPNButton.SetTitle("Disconnect") + if err := rpcClient.StartApp(skyenv.VPNClientName); err != nil { + mVPNStatus.SetTitle("Status: Disconnected") + mVPNButton.Enable() + mVPNButton.SetTitle("Connect") + } + } +} func handleVPNLinkButton(conf *visorconfig.V1) { vpnAddr := getVPNAddr(conf) @@ -190,26 +302,92 @@ func handleVPNLinkButton(conf *visorconfig.V1) { } } -// GetAvailPublicVPNServers gets all available public VPN server from service discovery URL -// func GetAvailPublicVPNServers(conf *visorconfig.V1) []string { -// sdClient := servicedisc.NewClient(log, servicedisc.Config{ -// Type: servicedisc.ServiceTypeVPN, -// PK: conf.PK, -// SK: conf.SK, -// DiscAddr: conf.Launcher.ServiceDisc, -// }) -// //ctx, _ := context.WithTimeout(context.Background(), 7*time.Second) -// vpnServers, err := sdClient.Services(context.Background(), 0) -// if err != nil { -// log.Error("Error getting public vpn servers: ", err) -// return nil -// } -// serverAddrs := make([]string, len(vpnServers)) -// for idx, server := range vpnServers { -// serverAddrs[idx] = server.Addr.PubKey().String() -// } -// return serverAddrs -// } +// getAvailPublicVPNServers gets all available public VPN server from service discovery URL +func getAvailPublicVPNServers(conf *visorconfig.V1, httpC *http.Client, logger *logging.Logger) []string { + + svrConfig := servicedisc.Config{ + Type: servicedisc.ServiceTypeVPN, + PK: conf.PK, + SK: conf.SK, + DiscAddr: conf.Launcher.ServiceDisc, + } + sdClient := servicedisc.NewClient(log, log, svrConfig, httpC, "") + vpnServers, err := sdClient.Services(context.Background(), 0) + if err != nil { + logger.Error("Error getting vpn servers: ", err) + return nil + } + serverAddrs := make([]string, len(vpnServers)) + for idx, server := range vpnServers { + serverAddrs[idx] = server.Addr.PubKey().String() + ";" + server.Geo.Country + } + return serverAddrs +} + +func getHTTPClient(conf *visorconfig.V1, ctx context.Context, logger *logging.MasterLogger) *http.Client { + var serviceURL dmsgget.URL + serviceURL.Fill(conf.Launcher.ServiceDisc) + if serviceURL.Scheme == "dmsg" { + var keys cipher.PubKeys + servers := conf.Dmsg.Servers + var delegatedServers []cipher.PubKey + + if len(servers) == 0 { + return &http.Client{} + } + + pk, sk := cipher.GenerateKeyPair() + keys = append(keys, pk) + entries := direct.GetAllEntries(keys, servers) + dClient := direct.NewClient(entries, logger.PackageLogger("systray:dmsghttp_direct_client")) + dmsgDC, closeDmsg, err := direct.StartDmsg(ctx, logger.PackageLogger("systray:dsmghttp_dmsgDC"), + pk, sk, dClient, dmsg.DefaultConfig()) + if err != nil { + return &http.Client{} + } + dmsgHTTP := http.Client{Transport: dmsghttp.MakeHTTPTransport(ctx, dmsgDC)} + + servers, err = dClient.AvailableServers(ctx) + if err != nil { + closeDmsg() + return &http.Client{} + } + + for _, server := range servers { + delegatedServers = append(delegatedServers, server.Static) + } + + clientEntry := &dmsgdisc.Entry{ + Client: &dmsgdisc.Client{ + DelegatedServers: delegatedServers, + }, + Static: serviceURL.Addr.PK, + } + + err = dClient.PostEntry(ctx, clientEntry) + if err != nil { + closeDmsg() + return &http.Client{} + } + closeDmsgDC = closeDmsg + return &dmsgHTTP + } + closeDmsgDC = func() {} + return &http.Client{} +} + +func isSetVPNClientPKExist(conf *visorconfig.V1) bool { + for _, v := range conf.Launcher.Apps { + if v.Name == skyenv.VPNClientName { + for index := range v.Args { + if v.Args[index] == "-srv" { + return true + } + } + } + } + return false +} func initUninstallBtn() { if !checkIsPackage() { @@ -226,8 +404,8 @@ func handleUserInteraction(conf *visorconfig.V1, doneCh chan<- bool) { select { case <-mOpenHypervisor.ClickedCh: handleOpenHypervisor(conf) - //case <-mVPNClient.ClickedCh: - // handleVpnClientButton(conf) + case <-mVPNButton.ClickedCh: + handleVPNButton(conf, rpcC) case <-mVPNLink.ClickedCh: handleVPNLinkButton(conf) case <-mUninstall.ClickedCh: @@ -269,6 +447,7 @@ func handleUninstall() { func stopVisor() { stopVisorFnMx.Lock() + closeDmsgDC() stop := stopVisorFn stopVisorFnMx.Unlock() @@ -279,7 +458,7 @@ func stopVisor() { func isHypervisorRunning(addr string) bool { // we check if it's up by querying `health` endpoint - resp, err := http.Get(addr + "/api/health") + resp, err := http.Get(addr) if err != nil { // hypervisor is not running in this case return false @@ -346,3 +525,12 @@ func getVPNAddr(conf *visorconfig.V1) string { return hvAddr + "/#/vpn/" + conf.PK.Hex() + "/status" } + +func rpcClient(conf *visorconfig.V1, logger *logging.Logger) visor.API { + const rpcDialTimeout = time.Second * 5 + conn, err := net.DialTimeout("tcp", conf.CLIAddr, rpcDialTimeout) + if err != nil { + logger.Fatal("RPC connection failed:", err) + } + return visor.NewRPCClient(logger, conn, visor.RPCPrefix, 0) +} diff --git a/pkg/app/launcher/launcher.go b/pkg/app/launcher/launcher.go index 2ac8950dad..cc65c8fe2d 100644 --- a/pkg/app/launcher/launcher.go +++ b/pkg/app/launcher/launcher.go @@ -239,7 +239,6 @@ func (l *Launcher) startApp(cmd string, args, envs []string) error { if err != nil { return err } - // Start proc and persist pid. pid, err := l.procM.Start(procConf) if err != nil { diff --git a/pkg/skyenv/values.go b/pkg/skyenv/values.go index 77168eef34..736cfd0d5e 100644 --- a/pkg/skyenv/values.go +++ b/pkg/skyenv/values.go @@ -8,7 +8,6 @@ import ( "time" "github.com/bitfield/script" - "github.com/skycoin/dmsg/pkg/dmsgpty" "github.com/skycoin/skywire-utilities/pkg/buildinfo" diff --git a/scripts/mac_installer/desktop-deinstaller/deinstaller.go b/scripts/mac_installer/desktop-deinstaller/deinstaller.go index 52dc36e79e..ccce67efac 100644 --- a/scripts/mac_installer/desktop-deinstaller/deinstaller.go +++ b/scripts/mac_installer/desktop-deinstaller/deinstaller.go @@ -11,7 +11,6 @@ import ( "github.com/skycoin/skycoin/src/util/logging" - "github.com/skycoin/skywire-utilities/pkg/skyenv" "github.com/skycoin/skywire/pkg/util/osutil" ) @@ -51,7 +50,6 @@ pkgutil --forget ` + osxServiceIdentifier + ` pkgutil --forget com.skycoin.skywire.updater pkgutil --forget com.skycoin.skywire.remover -rm -rf ` + filepath.Join(skyenv.PackageSkywirePath(), "local") + ` rm -rf ` + filepath.Join(os.Getenv("HOME"), "Library", "Logs", "skywire") + ` unlink /usr/local/bin/skywire-cli rm -rf /Applications/Skywire.app diff --git a/scripts/win_installer/skywire.bat b/scripts/win_installer/skywire.bat index ddac1ea590..a557d9fb39 100644 --- a/scripts/win_installer/skywire.bat +++ b/scripts/win_installer/skywire.bat @@ -1,5 +1,5 @@ @Echo Off -%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit +%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("powershell.exe","/c %~s0 ::","","runas",1)(window.close)&&exit cd /d "%~dp0" if exist vpn-client.exe ( if not exist "apps\" ( diff --git a/vendor/github.com/getlantern/systray/CHANGELOG.md b/vendor/github.com/getlantern/systray/CHANGELOG.md index 2b07f8548d..6eaf134b69 100644 --- a/vendor/github.com/getlantern/systray/CHANGELOG.md +++ b/vendor/github.com/getlantern/systray/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## [v1.2.0](https://github.com/getlantern/systray/tree/v1.2.0) (2022-02-24) + +[Full Changelog](https://github.com/getlantern/systray/compare/v1.1.0...v1.2.0) + +** Merged pull requests:** + +- On Linux, set the title in addition to the label [\#200](https://github.com/getlantern/systray/pull/200) ([cocotyty](https://github.com/cocotyty)) +- Fix hiding/showing items with submenus on Windows [\#204](https://github.com/getlantern/systray/pull/204) ([simonlindholm](https://github.com/simonlindholm)) +- Fix delFromVisibleItems [\#205](https://github.com/getlantern/systray/pull/205) ([simonlindholm](https://github.com/simonlindholm)) +- Create menu before calling onReady on Windows [\#206](https://github.com/getlantern/systray/pull/206) ([simonlindholm](https://github.com/simonlindholm)) +- Support libayatana-appindicator on Linux [\#225](https://github.com/getlantern/systray/pull/225) ([Crosse](https://github.com/Crosse)) + +## [v1.1.0](https://github.com/getlantern/systray/tree/v1.1.0) (2020-11-18) + +[Full Changelog](https://github.com/getlantern/systray/compare/v1.0.5...v1.1.0) + +**Merged pull requests:** + +- Add submenu support for Linux [\#183](https://github.com/getlantern/systray/pull/183) ([fbrinker](https://github.com/fbrinker)) +- Add checkbox support for Linux [\#181](https://github.com/getlantern/systray/pull/181) ([fbrinker](https://github.com/fbrinker)) +- fix SetTitle documentation [\#179](https://github.com/getlantern/systray/pull/179) ([delthas](https://github.com/delthas)) + ## [v1.0.5](https://github.com/getlantern/systray/tree/v1.0.5) (2020-10-19) [Full Changelog](https://github.com/getlantern/systray/compare/v1.0.4...v1.0.5) @@ -33,19 +55,19 @@ ## [v1.0.2](https://github.com/getlantern/systray/tree/v1.0.2) (2020-05-19) -[Full Changelog](https://github.com/getlantern/systray/compare/1.0.1...v1.0.2) +[Full Changelog](https://github.com/getlantern/systray/compare/v1.0.1...v1.0.2) **Merged pull requests:** - remove unused dependencies [\#145](https://github.com/getlantern/systray/pull/145) ([joesis](https://github.com/joesis)) -## [1.0.1](https://github.com/getlantern/systray/tree/1.0.1) (2020-05-18) +## [v1.0.1](https://github.com/getlantern/systray/tree/v1.0.1) (2020-05-18) -[Full Changelog](https://github.com/getlantern/systray/compare/v1.0.1...1.0.1) +[Full Changelog](https://github.com/getlantern/systray/compare/1.0.1...v1.0.1) -## [v1.0.1](https://github.com/getlantern/systray/tree/v1.0.1) (2020-05-18) +## [1.0.1](https://github.com/getlantern/systray/tree/1.0.1) (2020-05-18) -[Full Changelog](https://github.com/getlantern/systray/compare/1.0.0...v1.0.1) +[Full Changelog](https://github.com/getlantern/systray/compare/1.0.0...1.0.1) **Merged pull requests:** @@ -61,7 +83,6 @@ **Merged pull requests:** -- Backport all features and fixes from master [\#140](https://github.com/getlantern/systray/pull/140) ([joesis](https://github.com/joesis)) - Check if the menu item is nil [\#137](https://github.com/getlantern/systray/pull/137) ([myleshorton](https://github.com/myleshorton)) ## [0.9.0](https://github.com/getlantern/systray/tree/0.9.0) (2020-03-24) @@ -74,6 +95,7 @@ **Merged pull requests:** +- Backport all features and fixes from master [\#140](https://github.com/getlantern/systray/pull/140) ([joesis](https://github.com/joesis)) - Nested menu windows [\#132](https://github.com/getlantern/systray/pull/132) ([joesis](https://github.com/joesis)) - Support for nested sub-menus on OS X [\#131](https://github.com/getlantern/systray/pull/131) ([oxtoacart](https://github.com/oxtoacart)) - Use temp directory for walk resource manager [\#129](https://github.com/getlantern/systray/pull/129) ([max-b](https://github.com/max-b)) @@ -109,9 +131,6 @@ - Fixed hide show in linux \(\#37\) [\#39](https://github.com/getlantern/systray/pull/39) ([meskio](https://github.com/meskio)) - fix: linux compilation warning [\#36](https://github.com/getlantern/systray/pull/36) ([novln](https://github.com/novln)) - Added separator functionality [\#32](https://github.com/getlantern/systray/pull/32) ([oxtoacart](https://github.com/oxtoacart)) -- Add ability to show/hide menu items [\#31](https://github.com/getlantern/systray/pull/31) ([oxtoacart](https://github.com/oxtoacart)) -- Exit handling improvements [\#29](https://github.com/getlantern/systray/pull/29) ([oxtoacart](https://github.com/oxtoacart)) -- Made onExit run reliably and process terminate on quit [\#28](https://github.com/getlantern/systray/pull/28) ([oxtoacart](https://github.com/oxtoacart)) diff --git a/vendor/github.com/getlantern/systray/README.md b/vendor/github.com/getlantern/systray/README.md index 543acfd2fd..554d03749e 100644 --- a/vendor/github.com/getlantern/systray/README.md +++ b/vendor/github.com/getlantern/systray/README.md @@ -30,6 +30,8 @@ func onExit() { See [full API](https://pkg.go.dev/github.com/getlantern/systray?tab=doc) as well as [CHANGELOG](https://github.com/getlantern/systray/tree/master/CHANGELOG.md). +Note: this package requires cgo, so make sure you set `CGO_ENABLED=1` before building. + ## Try the example app! Have go v1.12+ or higher installed? Here's an example to get started on macOS: @@ -68,13 +70,20 @@ The code under `webview_example` is to demostrate how it can co-exist with other ### Linux -* Building apps requires gcc as well as the `gtk3` and `libappindicator3` development headers to be installed. For Debian or Ubuntu, you may install these using: +* Building apps requires gcc as well as the `gtk3` and `libayatana-appindicator3` development headers to be installed. For Debian or Ubuntu, you may install these using: ```sh -sudo apt-get install gcc libgtk-3-dev libappindicator3-dev +sudo apt-get install gcc libgtk-3-dev libayatana-appindicator3-dev ``` -On Linux Mint, `libxapp-dev` is also required . +On Linux Mint, `libxapp-dev` is also required. + +If you need to support the older `libappindicator3` library instead, you can pass the build flag `legacy_appindicator` +when building. For example: + +``` +go build -tags=legacy_appindicator` +``` To build `webview_example`, you also need to install `libwebkit2gtk-4.0-dev` and remove `webview_example/rsrc.syso` which is required on Windows. diff --git a/vendor/github.com/getlantern/systray/systray_linux.c b/vendor/github.com/getlantern/systray/systray_linux.c index 8ec3e76a54..9e14ba01fb 100644 --- a/vendor/github.com/getlantern/systray/systray_linux.c +++ b/vendor/github.com/getlantern/systray/systray_linux.c @@ -2,7 +2,13 @@ #include #include #include + +#ifdef USE_LEGACY_APPINDICATOR #include +#else +#include +#endif + #include "systray.h" static AppIndicator *global_app_indicator; @@ -222,6 +228,7 @@ void setIcon(const char* iconBytes, int length, bool template) { } void setTitle(char* ctitle) { + app_indicator_set_title(global_app_indicator, ctitle); app_indicator_set_label(global_app_indicator, ctitle, ""); free(ctitle); } diff --git a/vendor/github.com/getlantern/systray/systray_linux.go b/vendor/github.com/getlantern/systray/systray_linux.go index 1f508c7b43..ec0b751f03 100644 --- a/vendor/github.com/getlantern/systray/systray_linux.go +++ b/vendor/github.com/getlantern/systray/systray_linux.go @@ -1,13 +1,5 @@ package systray -/* -#cgo darwin CFLAGS: -DDARWIN -x objective-c -fobjc-arc -#cgo darwin LDFLAGS: -framework Cocoa -framework WebKit - -#include "systray.h" -*/ -import "C" - // SetTemplateIcon sets the systray icon as a template icon (on macOS), falling back // to a regular icon on other platforms. // templateIconBytes and iconBytes should be the content of .ico for windows and diff --git a/vendor/github.com/getlantern/systray/systray_linux_appindicator.go b/vendor/github.com/getlantern/systray/systray_linux_appindicator.go new file mode 100644 index 0000000000..dde0e23d72 --- /dev/null +++ b/vendor/github.com/getlantern/systray/systray_linux_appindicator.go @@ -0,0 +1,12 @@ +// +build linux,legacy_appindicator +//go:build linux && legacy_appindicator + +package systray + +/* +#cgo linux pkg-config: appindicator3-0.1 +#cgo linux CFLAGS: -DUSE_LEGACY_APPINDICATOR + +#include "systray.h" +*/ +import "C" diff --git a/vendor/github.com/getlantern/systray/systray_linux_ayatana.go b/vendor/github.com/getlantern/systray/systray_linux_ayatana.go new file mode 100644 index 0000000000..2547f2e5fc --- /dev/null +++ b/vendor/github.com/getlantern/systray/systray_linux_ayatana.go @@ -0,0 +1,11 @@ +// +build linux,!legacy_appindicator +//go:build linux && !legacy_appindicator + +package systray + +/* +#cgo linux pkg-config: ayatana-appindicator3-0.1 + +#include "systray.h" +*/ +import "C" diff --git a/vendor/github.com/getlantern/systray/systray_nonwindows.go b/vendor/github.com/getlantern/systray/systray_nonwindows.go index 5f6b90bdd3..12eacdfa8e 100644 --- a/vendor/github.com/getlantern/systray/systray_nonwindows.go +++ b/vendor/github.com/getlantern/systray/systray_nonwindows.go @@ -1,14 +1,9 @@ // +build !windows +// go:build !windows package systray -/* -#cgo linux pkg-config: gtk+-3.0 appindicator3-0.1 -#cgo darwin CFLAGS: -DDARWIN -x objective-c -fobjc-arc -#cgo darwin LDFLAGS: -framework Cocoa - -#include "systray.h" -*/ +// #include "systray.h" import "C" import ( diff --git a/vendor/github.com/getlantern/systray/systray_windows.go b/vendor/github.com/getlantern/systray/systray_windows.go index cf9f23b09d..6bdc803dab 100644 --- a/vendor/github.com/getlantern/systray/systray_windows.go +++ b/vendor/github.com/getlantern/systray/systray_windows.go @@ -36,13 +36,12 @@ var ( pCreatePopupMenu = u32.NewProc("CreatePopupMenu") pCreateWindowEx = u32.NewProc("CreateWindowExW") pDefWindowProc = u32.NewProc("DefWindowProcW") - pDeleteMenu = u32.NewProc("DeleteMenu") + pRemoveMenu = u32.NewProc("RemoveMenu") pDestroyWindow = u32.NewProc("DestroyWindow") pDispatchMessage = u32.NewProc("DispatchMessageW") pDrawIconEx = u32.NewProc("DrawIconEx") pGetCursorPos = u32.NewProc("GetCursorPos") pGetDC = u32.NewProc("GetDC") - pGetMenuItemID = u32.NewProc("GetMenuItemID") pGetMessage = u32.NewProc("GetMessageW") pGetSystemMetrics = u32.NewProc("GetSystemMetrics") pInsertMenuItem = u32.NewProc("InsertMenuItemW") @@ -254,11 +253,8 @@ func (t *winTray) wndProc(hWnd windows.Handle, message uint32, wParam, lParam ui WM_ENDSESSION = 0x0016 WM_CLOSE = 0x0010 WM_DESTROY = 0x0002 - WM_CREATE = 0x0001 ) switch message { - case WM_CREATE: - systrayReady() case WM_COMMAND: menuItemId := int32(wParam) // https://docs.microsoft.com/en-us/windows/win32/menurc/wm-command#menus @@ -557,6 +553,14 @@ func (t *winTray) addOrUpdateMenuItem(menuItemId uint32, parentId uint32, title } if res == 0 { + // Menu item does not already exist, create it + t.muMenus.RLock() + submenu, exists := t.menus[menuItemId] + t.muMenus.RUnlock() + if exists { + mi.Mask |= MIIM_SUBMENU + mi.SubMenu = submenu + } t.addToVisibleItems(parentId, menuItemId) position := t.getVisibleItemIndex(parentId, menuItemId) res, _, err = pInsertMenuItem.Call( @@ -613,14 +617,14 @@ func (t *winTray) addSeparatorMenuItem(menuItemId, parentId uint32) error { } func (t *winTray) hideMenuItem(menuItemId, parentId uint32) error { - // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647629(v=vs.85).aspx + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-removemenu const MF_BYCOMMAND = 0x00000000 const ERROR_SUCCESS syscall.Errno = 0 t.muMenus.RLock() menu := uintptr(t.menus[parentId]) t.muMenus.RUnlock() - res, _, err := pDeleteMenu.Call( + res, _, err := pRemoveMenu.Call( menu, uintptr(menuItemId), MF_BYCOMMAND, @@ -667,7 +671,7 @@ func (t *winTray) delFromVisibleItems(parent, val uint32) { visibleItems := t.visibleItems[parent] for i, itemval := range visibleItems { if val == itemval { - visibleItems = append(visibleItems[:i], visibleItems[i+1:]...) + t.visibleItems[parent] = append(visibleItems[:i], visibleItems[i+1:]...) break } } @@ -771,6 +775,7 @@ func registerSystray() { return } + systrayReady() } func nativeLoop() { diff --git a/vendor/modules.txt b/vendor/modules.txt index fb33904026..4f5baa871a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -60,7 +60,7 @@ github.com/getlantern/hidden # github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6 ## explicit github.com/getlantern/ops -# github.com/getlantern/systray v1.1.0 +# github.com/getlantern/systray v1.2.1 ## explicit; go 1.13 github.com/getlantern/systray # github.com/go-chi/chi/v5 v5.0.8-0.20220103230436-7dbe9a0bd10f @@ -74,8 +74,6 @@ github.com/go-ole/go-ole/oleutil # github.com/go-stack/stack v1.8.0 ## explicit github.com/go-stack/stack -# github.com/google/go-cmp v0.5.7 -## explicit; go 1.11 # github.com/google/go-github v17.0.0+incompatible ## explicit github.com/google/go-github/github