Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dexc in system tray #1828

Merged
merged 6 commits into from
Sep 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion client/cmd/dexc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (
var (
defaultApplicationDirectory = dcrutil.AppDataDir("dexc", false)
defaultConfigPath = filepath.Join(defaultApplicationDirectory, configFilename)
cfgPath string // used config file path
logFilename, netDirectory string
logDirectory string
cfg *Config
Expand Down Expand Up @@ -151,7 +152,7 @@ func configure() (*Config, error) {
}
}

cfgPath := dex.CleanAndExpandPath(preCfg.Config)
cfgPath = dex.CleanAndExpandPath(preCfg.Config)

// Load additional config from file.
parser := flags.NewParser(&iniCfg, flags.Default)
Expand Down
15 changes: 15 additions & 0 deletions client/cmd/dexc/fileurl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//go:build systray && !darwin && !windows

package main

import (
"path/filepath"
)

func filePathToURL(name string) (string, error) {
path, err := filepath.Abs(name)
if err != nil { // can't pwd if name was relative, probably impossible
return "", err
}
return "file://" + path, nil
}
24 changes: 24 additions & 0 deletions client/cmd/dexc/fileurl_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//go:build systray && darwin

package main

import (
"net/url"
"path/filepath"
)

// Darwin appears to need paths pre-escaped.

func filePathToURL(name string) (string, error) {
path, err := filepath.Abs(name)
if err != nil { // can't pwd if name was relative, probably impossible
return "", err
}
fileURL, err := url.Parse("file://" + path)
if err != nil {
return "", err
}
// url.Parse can be touchy, so consider replacing only spaces, manually:
// path = strings.ReplaceAll(path, " ", "%20")
return fileURL.String(), nil
}
20 changes: 20 additions & 0 deletions client/cmd/dexc/fileurl_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//go:build systray && windows

package main

import (
"path/filepath"
)

// Windows requires a leading "/" before the "C:" of an absolute path, and
// slashes converted to forward slashes.
// https://en.wikipedia.org/wiki/File_URI_scheme#Windows

func filePathToURL(name string) (string, error) {
path, err := filepath.Abs(name)
if err != nil { // can't pwd if name was relative, probably impossible
return "", err
}
path = filepath.ToSlash(path)
return "file:///" + path, nil
}
11 changes: 11 additions & 0 deletions client/cmd/dexc/gen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// This code is available on the terms of the project LICENSE.md file,
// also available online at https://blueoakcouncil.org/license/1.0.0.

//go:generate go run github.com/tc-hib/[email protected] make --in winres.json --arch "386,amd64"

package main

// After generating the rsrc_windows_amd64.syso file, it will be included in the
// binary when making an amd64 build for windows:
//
// GOOS=windows GOARCH=amd64 go build -v
14 changes: 14 additions & 0 deletions client/cmd/dexc/icons.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// This code is available on the terms of the project LICENSE.md file,
// also available online at https://blueoakcouncil.org/license/1.0.0.

//go:build systray && !windows

package main

import _ "embed"

//go:embed icons/logo_icon_v1.png
var FavIcon []byte

//go:embed icons/symbol-bw-round.png
var SymbolBWIcon []byte
Binary file added client/cmd/dexc/icons/logo_icon_v1.ico
Binary file not shown.
Binary file added client/cmd/dexc/icons/logo_icon_v1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/cmd/dexc/icons/symbol-bw-round.ico
Binary file not shown.
Binary file added client/cmd/dexc/icons/symbol-bw-round.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/cmd/dexc/icons/symbol-bw.ico
Binary file not shown.
Binary file added client/cmd/dexc/icons/symbol-bw.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/cmd/dexc/icons/symbol-gradient-round.ico
Binary file not shown.
Binary file added client/cmd/dexc/icons/symbol-gradient-round.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/cmd/dexc/icons/symbol-gradient.ico
Binary file not shown.
Binary file added client/cmd/dexc/icons/symbol-gradient.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/cmd/dexc/icons/symbol-negative-bw-256.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions client/cmd/dexc/icons_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// This code is available on the terms of the project LICENSE.md file,
// also available online at https://blueoakcouncil.org/license/1.0.0.

//go:build systray && windows

package main

import _ "embed"

//go:embed icons/logo_icon_v1.ico
var FavIcon []byte

//go:embed icons/symbol-bw.ico
var SymbolBWIcon []byte
23 changes: 10 additions & 13 deletions client/cmd/dexc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,18 @@ import (
"decred.org/dcrdex/dex/version"
)

func main() {
// Wrap the actual main so defers run in it.
err := mainCore()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
os.Exit(0)
}
var (
appCtx, cancel = context.WithCancel(context.Background())
webserverReady = make(chan string, 1)
)

func mainCore() error {
appCtx, cancel := context.WithCancel(context.Background())
defer cancel() // don't leak on the earliest returns
func runCore() error {
defer cancel() // for the earliest returns

// Parse configuration.
cfg, err := configure()
if err != nil {
return fmt.Errorf("configration error: %w", err)
return fmt.Errorf("configuration error: %w", err)
}

asset.SetNetwork(cfg.Net)
Expand Down Expand Up @@ -217,8 +211,11 @@ func mainCore() error {
cancel()
return
}
webserverReady <- webSrv.Addr()
cm.Wait()
}()
} else {
close(webserverReady)
}

// Wait for everything to stop.
Expand Down
21 changes: 21 additions & 0 deletions client/cmd/dexc/main_notray.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// This code is available on the terms of the project LICENSE.md file,
// also available online at https://blueoakcouncil.org/license/1.0.0.

//go:build !systray

package main

import (
"fmt"
"os"
)

func main() {
// Wrap the actual main so defers run in it.
err := runCore()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
os.Exit(0)
}
128 changes: 128 additions & 0 deletions client/cmd/dexc/main_tray.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// This code is available on the terms of the project LICENSE.md file,
// also available online at https://blueoakcouncil.org/license/1.0.0.

//go:build systray

package main

import (
"fmt"
"os"

"fyne.io/systray"
"github.com/pkg/browser"
)

var mainDone = make(chan struct{})

func onReady() {
go func() {
defer close(mainDone)
if err := runCore(); err != nil {
fmt.Fprintln(os.Stderr, err)
}
}()

go func() {
<-appCtx.Done()
systray.SetTooltip("Shutting down. Please wait...")
<-mainDone
systray.Quit()
}()

systray.SetIcon(FavIcon)
systray.SetTitle("DCRDEX")
systray.SetTooltip("The Decred DEX")

mStarting := systray.AddMenuItem("Starting...", "Starting up. Please wait...")
var addr string
var ok bool
select {
case addr, ok = <-webserverReady:
if !ok { // no webserver started
fmt.Fprintln(os.Stderr, "Web server required!")
cancel()
return
}
case <-mainDone:
return
}

mStarting.Hide()

mOpen := systray.AddMenuItem("Launch browser", "Open the interface in a browser window.")
mOpen.SetIcon(SymbolBWIcon)
go func() {
for range mOpen.ClickedCh {
err := browser.OpenURL("http://" + addr)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
}()

systray.AddSeparator()

if logDirURL, err := filePathToURL(logDirectory); err != nil {
fmt.Fprintln(os.Stderr, err)
} else {
mLogs := systray.AddMenuItem("Open logs folder", "Open the folder with your DEX logs.")
go func() {
for range mLogs.ClickedCh {
err := browser.OpenURL(logDirURL)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
}()
}

if cfgPathURL, err := filePathToURL(cfgPath); err != nil {
fmt.Fprintln(os.Stderr, err)
} else {
mConfigFile := systray.AddMenuItem("Edit config file", "Open the config file in a text editor.")
go func() {
for range mConfigFile.ClickedCh {
if _, err := os.Stat(cfgPath); err != nil {
if os.IsNotExist(err) {
fid, err := os.Create(cfgPath)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to create new config file: %v", err)
continue
}
fid.Close()
}
}
err := browser.OpenURL(cfgPathURL)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}
}()
}

systray.AddSeparator()

mQuit := systray.AddMenuItem("Quit", "Quit the DEX.")
go func() {
<-mQuit.ClickedCh
mOpen.Disable()
mQuit.Disable()
cancel()
}()

err := browser.OpenURL("http://" + addr)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}

func onExit() {
// In case we got here before shutting down, do it now.
cancel()
<-mainDone
}

func main() {
systray.Run(onReady, onExit)
}
Binary file added client/cmd/dexc/rsrc_windows_386.syso
Binary file not shown.
Binary file added client/cmd/dexc/rsrc_windows_amd64.syso
Binary file not shown.
39 changes: 39 additions & 0 deletions client/cmd/dexc/winres.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"RT_GROUP_ICON": {
"#1": {
"0000": "./icons/symbol-positive-gradient-256.png"
},
"#2": {
"0000": "./icons/symbol-negative-solid-256.png"
},
"#3": {
"0000": "./icons/symbol-negative-bw-256.png"
}
},
"RT_VERSION": {
"#1": {
"0000": {
"fixed": {
"file_version": "0.6.0.0",
"product_version": "0.6.0.0"
},
"info": {
"0409": {
"Comments": "",
"CompanyName": "Decred",
"FileDescription": "The Decred DEX Client Application",
"FileVersion": "0.6.0",
"InternalName": "dexc",
"LegalCopyright": "© The Decred Developers. Blue Oak Model License 1.0.0",
"LegalTrademarks": "",
"OriginalFilename": "dexc.exe",
"PrivateBuild": "",
"ProductName": "The Decred DEX",
"ProductVersion": "0.6.0",
"SpecialBuild": ""
}
}
}
}
}
}
6 changes: 6 additions & 0 deletions client/webserver/webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,12 @@ func (s *WebServer) buildTemplates(lang, siteDir string) error {
return s.html.buildErr()
}

// Addr gives the address on which WebServer is listening. Use only after
// Connect.
func (s *WebServer) Addr() string {
return s.addr
}

// Connect starts the web server. Satisfies the dex.Connector interface.
func (s *WebServer) Connect(ctx context.Context) (*sync.WaitGroup, error) {
// Start serving.
Expand Down
Loading