aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go67
1 files changed, 40 insertions, 27 deletions
diff --git a/main.go b/main.go
index 7597155..10be005 100644
--- a/main.go
+++ b/main.go
@@ -24,7 +24,7 @@ const (
LOGFILE = "/tmp/waybar-mpris.log"
OUTFILE = "/tmp/waybar-mpris.out" // Used for sharing waybar output when args are the same.
DATAFILE = "/tmp/waybar-mpris.data.out" // Used for sharing "\n"-separated player data between instances when args are different.
- POLL = 1
+ POLL = 900
)
// Mostly default values for flag options.
@@ -36,12 +36,11 @@ var (
autofocus = false
// Available commands that can be sent to running instances.
commands = []string{"player-next", "player-prev", "next", "prev", "toggle", "list"}
- showPos = false
interpolate = false
replace = false
isSharing = false
isDataSharing = false
- maxTitleLen = 70
+ maxTitleLen = 50
writer io.Writer = os.Stdout
shareWriter, dataWriter io.Writer
)
@@ -55,7 +54,6 @@ const (
tokPosition = 'p'
tokLength = 'd'
tokPlayer = 'P'
- tokPercent = '%'
)
const (
@@ -169,7 +167,9 @@ func secondsToString(seconds int) string {
return fmt.Sprintf("%02d:%02d", minutes, seconds)
}
-func formatOutput(p *player, icon string, fstr string) string {
+// Function to format the output as requested by the user preferences of icon,
+// format specifier string and maximum title length
+func formatOutput(p *player, icon string, fstr string, maxTitleLen int) string {
var buf []byte
for i := 0; i < len(fstr); i++ {
if fstr[i] == '%' {
@@ -181,17 +181,31 @@ func formatOutput(p *player, icon string, fstr string) string {
case tokIcon:
buf = append(buf, []byte(icon)...)
case tokArtist:
- buf = append(buf, []byte(p.Artist)...)
+ artist := strings.ReplaceAll(p.Artist, "&", "&amp;")
+ buf = append(buf, []byte(artist)...)
case tokAlbum:
- buf = append(buf, []byte(p.Album)...)
+ album := strings.ReplaceAll(p.Album, "&", "&amp;")
+ buf = append(buf, []byte(album)...)
case tokTitle:
title := p.Title
- if maxTitleLen > 0 && len(title) > maxTitleLen {
- title = title[:maxTitleLen-3] + "..."
+ if maxTitleLen > 0 && len([]rune(title)) > maxTitleLen {
+ // Probably not the most effective thing to do, but this way
+ // we don't slice the string in the middle of a UTF-8
+ // character it happens to be more than 1 byte, and the
+ // maximum length actually correlates to the displayed
+ // charaacters instead of the bytes.
+ title = string([]rune(title)[:maxTitleLen-3]) + "..."
}
+ title = strings.ReplaceAll(title, "&", "&amp;")
buf = append(buf, []byte(title)...)
case tokPosition:
- position := secondsToString(int(p.Position / 1000000))
+ var position string
+ if p.Length > 0 {
+ p.GetPosition()
+ position = secondsToString(int(p.Position / 1000000))
+ } else {
+ position = secondsToString(0)
+ }
buf = append(buf, []byte(position)...)
case tokLength:
length := secondsToString(p.Length)
@@ -206,10 +220,7 @@ func formatOutput(p *player, icon string, fstr string) string {
}
}
- out := strings.ReplaceAll(string(buf), `"`, `\"`)
- out = strings.ReplaceAll(out, "&", "&amp;")
-
- return out
+ return string(buf)
}
// Returns JSON for waybar to consume.
@@ -224,8 +235,10 @@ func playerJSON(p *player) string {
data.Class = "paused"
}
- data.Text = formatOutput(p, icon, textFormat)
- data.Tooltip = formatOutput(p, icon, tooltipFormat)
+ data.Text = formatOutput(p, icon, textFormat, maxTitleLen)
+ // There's no point in limiting the length of the output/title in the
+ // tooltip, so we set it to 0
+ data.Tooltip = formatOutput(p, icon, tooltipFormat, 0)
out, err := json.Marshal(data)
if err != nil {
@@ -277,7 +290,7 @@ func execCommand(cmd string) {
func duplicateOutput() error {
// Print to stderr to avoid errors from waybar
- os.Stderr.WriteString("waybar-mpris is already running. This instance will clone its output.")
+ os.Stderr.WriteString("waybar-mpris is already running. This instance will clone its output.\n")
conn, err := net.Dial("unix", SOCK)
if err != nil {
@@ -613,6 +626,8 @@ func main() {
os.Remove(SOCK)
os.Remove(OUTFILE)
}
+ } else {
+ fmt.Fprintf(os.Stderr, "error: %v\n", err)
}
conn, err := dbus.SessionBus()
if err != nil {
@@ -626,18 +641,16 @@ func main() {
lastLine := ""
go listenForCommands(players)
go players.mpris2.Listen()
- if showPos {
- go func() {
- for {
- time.Sleep(POLL * time.Second)
- if len(players.mpris2.List) != 0 {
- if players.mpris2.List[players.mpris2.Current].Playing {
- go fmt.Fprintln(writer, players.JSON())
- }
+ go func() {
+ for {
+ time.Sleep(POLL * time.Millisecond)
+ if len(players.mpris2.List) != 0 {
+ if players.mpris2.List[players.mpris2.Current].Playing {
+ go fmt.Fprintln(writer, players.JSON())
}
}
- }()
- }
+ }
+ }()
fmt.Fprintln(writer, players.JSON())
for v := range players.mpris2.Messages {
if v.Name == "refresh" {