112 lines
3.1 KiB
Go
112 lines
3.1 KiB
Go
//go:build linux
|
|
|
|
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"sync"
|
|
)
|
|
|
|
type dialogToolType int
|
|
|
|
const (
|
|
toolNone dialogToolType = iota
|
|
toolNotifySend
|
|
toolKdialogPassive
|
|
toolZenity
|
|
toolKdialogError
|
|
toolXmessage
|
|
)
|
|
|
|
var (
|
|
dialogTools map[string]bool
|
|
dialogToolOnce sync.Once
|
|
dialogToolNames = []string{"notify-send", "kdialog", "zenity", "xmessage"}
|
|
)
|
|
|
|
func init() {
|
|
dialogToolOnce.Do(func() { detectDialogTools(defaultCommandRunner{}) })
|
|
}
|
|
|
|
func platformStartupChannels(runner commandRunner) []promptChannel {
|
|
return []promptChannel{
|
|
linuxCommandChannel("notify-send", toolNotifySend, runner, linuxHasGraphicalSessionAndDBus, func(req promptRequest) []string {
|
|
return []string{"-u", "critical", "-a", appName, "-i", "nex", req.title, req.message}
|
|
}),
|
|
linuxCommandChannel("kdialog", toolKdialogPassive, runner, linuxHasGraphicalSession, func(req promptRequest) []string {
|
|
return []string{"--title", req.title, "--passivepopup", req.message, "10"}
|
|
}),
|
|
linuxCommandChannel("zenity", toolZenity, runner, linuxHasGraphicalSession, func(req promptRequest) []string {
|
|
return []string{"--error", fmt.Sprintf("--title=%s", req.title), fmt.Sprintf("--text=%s", req.message)}
|
|
}),
|
|
linuxCommandChannel("kdialog", toolKdialogError, runner, linuxHasGraphicalSession, func(req promptRequest) []string {
|
|
return []string{"--title", req.title, "--error", req.message}
|
|
}),
|
|
linuxCommandChannel("xmessage", toolXmessage, runner, linuxHasX11Display, func(req promptRequest) []string {
|
|
return []string{"-center", "-buttons", "OK:0", "-default", "OK", fmt.Sprintf("%s: %s", req.title, req.message)}
|
|
}),
|
|
}
|
|
}
|
|
|
|
func detectDialogTools(runner commandRunner) {
|
|
dialogTools = make(map[string]bool, len(dialogToolNames))
|
|
for _, name := range dialogToolNames {
|
|
_, err := runner.LookPath(name)
|
|
dialogTools[name] = err == nil
|
|
}
|
|
}
|
|
|
|
func linuxCommandChannel(name string, typ dialogToolType, runner commandRunner, environmentOK func() error, args func(promptRequest) []string) promptChannel {
|
|
return promptChannel{
|
|
name: fmt.Sprintf("linux-%s-%d", name, typ),
|
|
available: func() error {
|
|
if err := linuxCommandAvailable(runner, name); err != nil {
|
|
return err
|
|
}
|
|
return environmentOK()
|
|
},
|
|
run: func(req promptRequest) error {
|
|
return runner.Run(promptCommandTimeout, nil, name, args(req)...)
|
|
},
|
|
}
|
|
}
|
|
|
|
func linuxCommandAvailable(runner commandRunner, name string) error {
|
|
if _, ok := runner.(defaultCommandRunner); ok {
|
|
dialogToolOnce.Do(func() { detectDialogTools(runner) })
|
|
if dialogTools[name] {
|
|
return nil
|
|
}
|
|
return fmt.Errorf("%s 不可用", name)
|
|
}
|
|
|
|
_, err := runner.LookPath(name)
|
|
return err
|
|
}
|
|
|
|
func linuxHasGraphicalSession() error {
|
|
if os.Getenv("DISPLAY") == "" && os.Getenv("WAYLAND_DISPLAY") == "" {
|
|
return errors.New("缺少图形会话")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func linuxHasGraphicalSessionAndDBus() error {
|
|
if err := linuxHasGraphicalSession(); err != nil {
|
|
return err
|
|
}
|
|
if os.Getenv("DBUS_SESSION_BUS_ADDRESS") == "" {
|
|
return errors.New("缺少 DBus session bus")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func linuxHasX11Display() error {
|
|
if os.Getenv("DISPLAY") == "" {
|
|
return errors.New("缺少 X11 DISPLAY")
|
|
}
|
|
return nil
|
|
}
|