Now all indicator updates properly
This commit is contained in:
@@ -25,20 +25,25 @@ func main() {
|
|||||||
log.Panicf("Unable to read config: %s", err)
|
log.Panicf("Unable to read config: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
Conf.UpdateReady = make(chan bool)
|
Conf.Channels.UpdateReady = make(chan bool)
|
||||||
Conf.MsgChan = make(chan []lib.I3BarOutBlock, 64)
|
Conf.Channels.SVPAHandlerChan = make(chan lib.ClickEvent, 256)
|
||||||
Conf.SigChan = make(chan os.Signal, 1)
|
Conf.Channels.MsgChan = make(chan []lib.I3BarOutBlock, 64)
|
||||||
Conf.BatteryString = "<big>⚡</big> ??% •"
|
Conf.Channels.SigChan = make(chan os.Signal, 1)
|
||||||
Conf.ClockTime = "Thu, 1 Jan 1970 1:00"
|
Conf.Channels.RunChan = make(chan []string, 128)
|
||||||
Conf.IfStatus = ""
|
Conf.Values.PrintOutput = true
|
||||||
Conf.VPNStatus = ""
|
Conf.Values.BatteryString = "<big>⚡</big> ??% •"
|
||||||
Conf.Memory.Shared = 0
|
Conf.Values.ClockTime = "Thu, 1 Jan 1970 1:00"
|
||||||
Conf.Memory.Usedpct = 0
|
Conf.Values.IfStatus = ""
|
||||||
Conf.Memory.Swap = 0
|
Conf.Values.VPNStatus = ""
|
||||||
Conf.La = "-1"
|
Conf.Values.Memory.Shared = 0
|
||||||
|
Conf.Values.Memory.Usedpct = 0
|
||||||
|
Conf.Values.Memory.Swap = 0
|
||||||
|
Conf.Values.La = "-1"
|
||||||
|
// Conf.Values.PA
|
||||||
|
Conf.Values.SoundVolume = "🔊:0%"
|
||||||
|
|
||||||
// TODO: Проставить дефолтные значения для глобальных переменных модулей.
|
// TODO: Проставить дефолтные значения для глобальных переменных модулей.
|
||||||
Batt := fmt.Sprintf(
|
Conf.Values.BatteryString = fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
|
||||||
Conf.Battery.Color,
|
Conf.Battery.Color,
|
||||||
Conf.Battery.Background,
|
Conf.Battery.Background,
|
||||||
@@ -47,7 +52,7 @@ func main() {
|
|||||||
Conf.Battery.Symbol,
|
Conf.Battery.Symbol,
|
||||||
)
|
)
|
||||||
|
|
||||||
Batt += fmt.Sprintf(
|
Conf.Values.BatteryString += fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'> ??%% •</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'> ??%% •</span>",
|
||||||
Conf.Battery.Color,
|
Conf.Battery.Color,
|
||||||
Conf.Battery.Background,
|
Conf.Battery.Background,
|
||||||
@@ -55,7 +60,7 @@ func main() {
|
|||||||
Conf.Battery.FontSize,
|
Conf.Battery.FontSize,
|
||||||
)
|
)
|
||||||
|
|
||||||
SoundVolume := fmt.Sprintf(
|
Conf.Values.SoundVolume = fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>🔊</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>🔊</span>",
|
||||||
Conf.SimpleVolumePa.Color,
|
Conf.SimpleVolumePa.Color,
|
||||||
Conf.SimpleVolumePa.Background,
|
Conf.SimpleVolumePa.Background,
|
||||||
@@ -63,7 +68,7 @@ func main() {
|
|||||||
Conf.SimpleVolumePa.SymbolFontSize,
|
Conf.SimpleVolumePa.SymbolFontSize,
|
||||||
)
|
)
|
||||||
|
|
||||||
SoundVolume += fmt.Sprintf(
|
Conf.Values.SoundVolume += fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>:0%%</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>:0%%</span>",
|
||||||
Conf.SimpleVolumePa.Color,
|
Conf.SimpleVolumePa.Color,
|
||||||
Conf.SimpleVolumePa.Background,
|
Conf.SimpleVolumePa.Background,
|
||||||
@@ -71,7 +76,7 @@ func main() {
|
|||||||
Conf.SimpleVolumePa.FontSize,
|
Conf.SimpleVolumePa.FontSize,
|
||||||
)
|
)
|
||||||
|
|
||||||
Clock := fmt.Sprintf(
|
Conf.Values.ClockTime = fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>Thu, 1 Jan 1970 1:00</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>Thu, 1 Jan 1970 1:00</span>",
|
||||||
Conf.Clock.Color,
|
Conf.Clock.Color,
|
||||||
Conf.Clock.Background,
|
Conf.Clock.Background,
|
||||||
@@ -91,7 +96,7 @@ func main() {
|
|||||||
|
|
||||||
// Kick signal handler
|
// Kick signal handler
|
||||||
go Conf.SigHandler()
|
go Conf.SigHandler()
|
||||||
signal.Notify(Conf.SigChan,
|
signal.Notify(Conf.Channels.SigChan,
|
||||||
syscall.SIGUSR1,
|
syscall.SIGUSR1,
|
||||||
syscall.SIGUSR2,
|
syscall.SIGUSR2,
|
||||||
syscall.SIGQUIT,
|
syscall.SIGQUIT,
|
||||||
@@ -131,7 +136,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if Conf.Cron.Enabled {
|
if Conf.Cron.Enabled {
|
||||||
go lib.RunCron()
|
go Conf.RunCron()
|
||||||
}
|
}
|
||||||
|
|
||||||
if Conf.Vpn.Enabled {
|
if Conf.Vpn.Enabled {
|
||||||
@@ -156,7 +161,7 @@ func main() {
|
|||||||
fmt.Println("[ [],")
|
fmt.Println("[ [],")
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if <-Conf.UpdateReady {
|
if <-Conf.Channels.UpdateReady {
|
||||||
// Actually build json struct, marshal it and print result
|
// Actually build json struct, marshal it and print result
|
||||||
var j []lib.I3BarOutBlock
|
var j []lib.I3BarOutBlock
|
||||||
|
|
||||||
@@ -235,7 +240,7 @@ func main() {
|
|||||||
Conf.CPUTemp.Background,
|
Conf.CPUTemp.Background,
|
||||||
Conf.CPUTemp.Font,
|
Conf.CPUTemp.Font,
|
||||||
Conf.CPUTemp.FontSize,
|
Conf.CPUTemp.FontSize,
|
||||||
Conf.CPUTemperature,
|
Conf.Values.CPUTemperature,
|
||||||
)
|
)
|
||||||
|
|
||||||
if Conf.CPUTemp.Separator.Right.Enabled {
|
if Conf.CPUTemp.Separator.Right.Enabled {
|
||||||
@@ -279,9 +284,9 @@ func main() {
|
|||||||
Conf.Mem.Background,
|
Conf.Mem.Background,
|
||||||
Conf.Mem.Font,
|
Conf.Mem.Font,
|
||||||
Conf.Mem.FontSize,
|
Conf.Mem.FontSize,
|
||||||
Conf.Memory.Usedpct,
|
Conf.Values.Memory.Usedpct,
|
||||||
Conf.Memory.Shared,
|
Conf.Values.Memory.Shared,
|
||||||
Conf.Memory.Swap,
|
Conf.Values.Memory.Swap,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
b.FullText += fmt.Sprintf(
|
b.FullText += fmt.Sprintf(
|
||||||
@@ -290,8 +295,8 @@ func main() {
|
|||||||
Conf.Mem.Background,
|
Conf.Mem.Background,
|
||||||
Conf.Mem.Font,
|
Conf.Mem.Font,
|
||||||
Conf.Mem.FontSize,
|
Conf.Mem.FontSize,
|
||||||
Conf.Memory.Usedpct,
|
Conf.Values.Memory.Usedpct,
|
||||||
Conf.Memory.Shared,
|
Conf.Values.Memory.Shared,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +340,7 @@ func main() {
|
|||||||
Conf.LA.Background,
|
Conf.LA.Background,
|
||||||
Conf.LA.Font,
|
Conf.LA.Font,
|
||||||
Conf.LA.FontSize,
|
Conf.LA.FontSize,
|
||||||
Conf.La,
|
Conf.Values.La,
|
||||||
)
|
)
|
||||||
|
|
||||||
if Conf.LA.Separator.Right.Enabled {
|
if Conf.LA.Separator.Right.Enabled {
|
||||||
@@ -378,7 +383,7 @@ func main() {
|
|||||||
Conf.NetIf.Background,
|
Conf.NetIf.Background,
|
||||||
Conf.NetIf.Font,
|
Conf.NetIf.Font,
|
||||||
Conf.NetIf.FontSize,
|
Conf.NetIf.FontSize,
|
||||||
Conf.IfStatus,
|
Conf.Values.IfStatus,
|
||||||
)
|
)
|
||||||
|
|
||||||
if Conf.NetIf.Separator.Right.Enabled {
|
if Conf.NetIf.Separator.Right.Enabled {
|
||||||
@@ -421,7 +426,7 @@ func main() {
|
|||||||
Conf.Vpn.Background,
|
Conf.Vpn.Background,
|
||||||
Conf.Vpn.Font,
|
Conf.Vpn.Font,
|
||||||
Conf.Vpn.FontSize,
|
Conf.Vpn.FontSize,
|
||||||
Conf.VPNStatus,
|
Conf.Values.VPNStatus,
|
||||||
)
|
)
|
||||||
|
|
||||||
if Conf.Vpn.Separator.Right.Enabled {
|
if Conf.Vpn.Separator.Right.Enabled {
|
||||||
@@ -458,7 +463,7 @@ func main() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.FullText += Conf.BatteryString
|
b.FullText += Conf.Values.BatteryString
|
||||||
|
|
||||||
if Conf.Battery.Separator.Right.Enabled {
|
if Conf.Battery.Separator.Right.Enabled {
|
||||||
b.FullText += fmt.Sprintf(
|
b.FullText += fmt.Sprintf(
|
||||||
@@ -496,7 +501,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pango format is already applied in plugin src.
|
// Pango format is already applied in plugin src.
|
||||||
b.FullText += SoundVolume
|
b.FullText += Conf.Values.SoundVolume
|
||||||
|
|
||||||
if Conf.SimpleVolumePa.Separator.Right.Enabled {
|
if Conf.SimpleVolumePa.Separator.Right.Enabled {
|
||||||
b.FullText += fmt.Sprintf(
|
b.FullText += fmt.Sprintf(
|
||||||
@@ -539,7 +544,7 @@ func main() {
|
|||||||
Conf.Clock.Background,
|
Conf.Clock.Background,
|
||||||
Conf.Clock.Font,
|
Conf.Clock.Font,
|
||||||
Conf.Clock.FontSize,
|
Conf.Clock.FontSize,
|
||||||
Clock,
|
Conf.Values.ClockTime,
|
||||||
)
|
)
|
||||||
|
|
||||||
if Conf.Clock.Separator.Right.Enabled {
|
if Conf.Clock.Separator.Right.Enabled {
|
||||||
@@ -559,16 +564,16 @@ func main() {
|
|||||||
j = append(j, b)
|
j = append(j, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Conf.PrintOutput && len(j) > 0 {
|
if Conf.Values.PrintOutput && len(j) > 0 {
|
||||||
Conf.MsgChan <- j
|
Conf.Channels.MsgChan <- j
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintToI3bar prints info to stdout according to ipc docs (https://i3wm.org/docs/i3bar-protocol.html)
|
// PrintToI3bar prints info to stdout according to ipc docs (https://i3wm.org/docs/i3bar-protocol.html)
|
||||||
func PrintToI3bar(c lib.MyConfig) {
|
func PrintToI3bar(c *lib.MyConfig) {
|
||||||
for message := range c.MsgChan {
|
for message := range c.Channels.MsgChan {
|
||||||
// we do not need to html-encode output, json.Marshal does this forcefully, so invent our own Marshal
|
// we do not need to html-encode output, json.Marshal does this forcefully, so invent our own Marshal
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
encoder := json.NewEncoder(buf)
|
encoder := json.NewEncoder(buf)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// UpdateBatteryInfo updates info about battery charge.
|
// UpdateBatteryInfo updates info about battery charge.
|
||||||
func (c MyConfig) UpdateBatteryInfo() {
|
func (c *MyConfig) UpdateBatteryInfo() {
|
||||||
var (
|
var (
|
||||||
ch int
|
ch int
|
||||||
status string
|
status string
|
||||||
@@ -22,11 +22,11 @@ func (c MyConfig) UpdateBatteryInfo() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
Batts = fmt.Sprintf(
|
Batts = fmt.Sprintf(
|
||||||
"<span font='%s' size='%s'>%s</span><span font='%s' size='%s'> no batt</span>",
|
"<span font='%s' size='%s'>%s</span><span font='%s' size='%s'> no batt</span>",
|
||||||
Conf.Battery.SymbolFont,
|
c.Battery.SymbolFont,
|
||||||
Conf.Battery.SymbolFontSize,
|
c.Battery.SymbolFontSize,
|
||||||
Conf.Battery.Symbol,
|
c.Battery.Symbol,
|
||||||
Conf.Battery.Font,
|
c.Battery.Font,
|
||||||
Conf.Battery.FontSize,
|
c.Battery.FontSize,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
var (
|
var (
|
||||||
@@ -52,85 +52,85 @@ func (c MyConfig) UpdateBatteryInfo() {
|
|||||||
|
|
||||||
switch {
|
switch {
|
||||||
case ch > 85:
|
case ch > 85:
|
||||||
if Conf.Battery.ChargeColor.Full == "" {
|
if c.Battery.ChargeColor.Full == "" {
|
||||||
chStr = fmt.Sprintf(
|
chStr = fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
|
||||||
Conf.Battery.Color,
|
c.Battery.Color,
|
||||||
Conf.Battery.Background,
|
c.Battery.Background,
|
||||||
Conf.Battery.Font,
|
c.Battery.Font,
|
||||||
Conf.Battery.FontSize,
|
c.Battery.FontSize,
|
||||||
ch,
|
ch,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
chStr = fmt.Sprintf(
|
chStr = fmt.Sprintf(
|
||||||
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
|
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
|
||||||
Conf.Battery.ChargeColor.Full,
|
c.Battery.ChargeColor.Full,
|
||||||
Conf.Battery.Background,
|
c.Battery.Background,
|
||||||
Conf.Battery.Font,
|
c.Battery.Font,
|
||||||
Conf.Battery.FontSize,
|
c.Battery.FontSize,
|
||||||
ch,
|
ch,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
case ch < 85 && ch > 40:
|
case ch < 85 && ch > 40:
|
||||||
if Conf.Battery.ChargeColor.AlmostFull == "" {
|
if c.Battery.ChargeColor.AlmostFull == "" {
|
||||||
chStr = fmt.Sprintf(
|
chStr = fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
|
||||||
Conf.Battery.Color,
|
c.Battery.Color,
|
||||||
Conf.Battery.Background,
|
c.Battery.Background,
|
||||||
Conf.Battery.Font,
|
c.Battery.Font,
|
||||||
Conf.Battery.FontSize,
|
c.Battery.FontSize,
|
||||||
ch,
|
ch,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
chStr = fmt.Sprintf(
|
chStr = fmt.Sprintf(
|
||||||
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
|
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
|
||||||
Conf.Battery.ChargeColor.AlmostFull,
|
c.Battery.ChargeColor.AlmostFull,
|
||||||
Conf.Battery.Background,
|
c.Battery.Background,
|
||||||
Conf.Battery.Font,
|
c.Battery.Font,
|
||||||
Conf.Battery.FontSize,
|
c.Battery.FontSize,
|
||||||
ch,
|
ch,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
case ch <= 40 && ch >= 10:
|
case ch <= 40 && ch >= 10:
|
||||||
if Conf.Battery.ChargeColor.AlmostEmpty == "" {
|
if c.Battery.ChargeColor.AlmostEmpty == "" {
|
||||||
chStr = fmt.Sprintf(
|
chStr = fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
|
||||||
Conf.Battery.Color,
|
c.Battery.Color,
|
||||||
Conf.Battery.Background,
|
c.Battery.Background,
|
||||||
Conf.Battery.Font,
|
c.Battery.Font,
|
||||||
Conf.Battery.FontSize,
|
c.Battery.FontSize,
|
||||||
ch,
|
ch,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
chStr = fmt.Sprintf(
|
chStr = fmt.Sprintf(
|
||||||
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
|
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
|
||||||
Conf.Battery.ChargeColor.AlmostEmpty,
|
c.Battery.ChargeColor.AlmostEmpty,
|
||||||
Conf.Battery.Background,
|
c.Battery.Background,
|
||||||
Conf.Battery.Font,
|
c.Battery.Font,
|
||||||
Conf.Battery.FontSize,
|
c.Battery.FontSize,
|
||||||
ch,
|
ch,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
case ch < 10:
|
case ch < 10:
|
||||||
if Conf.Battery.ChargeColor.Empty == "" {
|
if c.Battery.ChargeColor.Empty == "" {
|
||||||
chStr = fmt.Sprintf(
|
chStr = fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
|
||||||
Conf.Battery.Color,
|
c.Battery.Color,
|
||||||
Conf.Battery.Background,
|
c.Battery.Background,
|
||||||
Conf.Battery.Font,
|
c.Battery.Font,
|
||||||
Conf.Battery.FontSize,
|
c.Battery.FontSize,
|
||||||
ch,
|
ch,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
chStr = fmt.Sprintf(
|
chStr = fmt.Sprintf(
|
||||||
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
|
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
|
||||||
Conf.Battery.ChargeColor.Empty,
|
c.Battery.ChargeColor.Empty,
|
||||||
Conf.Battery.Background,
|
c.Battery.Background,
|
||||||
Conf.Battery.Font,
|
c.Battery.Font,
|
||||||
Conf.Battery.FontSize,
|
c.Battery.FontSize,
|
||||||
ch,
|
ch,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -138,21 +138,21 @@ func (c MyConfig) UpdateBatteryInfo() {
|
|||||||
|
|
||||||
battsInfo += fmt.Sprintf(
|
battsInfo += fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>%s</span><span color='%s' background='%s' font='%s' size='%s'>B%d </span>%s<span color='%s' background='%s' font='%s' size='%s'> %s</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>%s</span><span color='%s' background='%s' font='%s' size='%s'>B%d </span>%s<span color='%s' background='%s' font='%s' size='%s'> %s</span>",
|
||||||
Conf.Battery.Color,
|
c.Battery.Color,
|
||||||
Conf.Battery.Background,
|
c.Battery.Background,
|
||||||
Conf.Battery.SymbolFont,
|
c.Battery.SymbolFont,
|
||||||
Conf.Battery.SymbolFontSize,
|
c.Battery.SymbolFontSize,
|
||||||
Conf.Battery.Symbol,
|
c.Battery.Symbol,
|
||||||
Conf.Battery.Color,
|
c.Battery.Color,
|
||||||
Conf.Battery.Background,
|
c.Battery.Background,
|
||||||
Conf.Battery.Font,
|
c.Battery.Font,
|
||||||
Conf.Battery.FontSize,
|
c.Battery.FontSize,
|
||||||
i,
|
i,
|
||||||
chStr,
|
chStr,
|
||||||
Conf.Battery.Color,
|
c.Battery.Color,
|
||||||
Conf.Battery.Background,
|
c.Battery.Background,
|
||||||
Conf.Battery.Font,
|
c.Battery.Font,
|
||||||
Conf.Battery.FontSize,
|
c.Battery.FontSize,
|
||||||
status,
|
status,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -162,9 +162,9 @@ func (c MyConfig) UpdateBatteryInfo() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.BatteryString == Batts {
|
if c.Values.BatteryString == Batts {
|
||||||
c.BatteryString = Batts
|
c.Values.BatteryString = Batts
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// UpdateClock get and updates (on i3bar) info about system clock.
|
// UpdateClock get and updates (on i3bar) info about system clock.
|
||||||
func (c MyConfig) UpdateClock() {
|
func (c *MyConfig) UpdateClock() {
|
||||||
for {
|
for {
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
hours, minutes, _ := currentTime.Clock()
|
hours, minutes, _ := currentTime.Clock()
|
||||||
@@ -17,9 +17,9 @@ func (c MyConfig) UpdateClock() {
|
|||||||
|
|
||||||
myclock := fmt.Sprintf(" %s, %d %s %d % 2d:%02d ", rdow[dow], day, rmonth[month-1], year, hours, minutes)
|
myclock := fmt.Sprintf(" %s, %d %s %d % 2d:%02d ", rdow[dow], day, rmonth[month-1], year, hours, minutes)
|
||||||
|
|
||||||
if myclock != c.ClockTime {
|
if myclock != c.Values.ClockTime {
|
||||||
c.ClockTime = myclock
|
c.Values.ClockTime = myclock
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/adrg/xdg"
|
"github.com/adrg/xdg"
|
||||||
"github.com/hjson/hjson-go"
|
"github.com/hjson/hjson-go"
|
||||||
|
p "github.com/mafik/pulseaudio"
|
||||||
)
|
)
|
||||||
|
|
||||||
// I3BarOutBlock is structure element for I3BarOut, it represents i3bar output json block format.
|
// I3BarOutBlock is structure element for I3BarOut, it represents i3bar output json block format.
|
||||||
@@ -57,17 +58,26 @@ type Separator struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MyConfig struct {
|
type MyConfig struct {
|
||||||
UpdateReady chan bool
|
Values struct {
|
||||||
PrintOutput bool
|
PrintOutput bool
|
||||||
MsgChan chan []I3BarOutBlock
|
CPUTemperature int64
|
||||||
SigChan chan os.Signal
|
BatteryString string
|
||||||
CPUTemperature int64
|
ClockTime string
|
||||||
BatteryString string
|
IfStatus string
|
||||||
ClockTime string
|
VPNStatus string
|
||||||
IfStatus string
|
Memory Mem
|
||||||
VPNStatus string
|
La string
|
||||||
Memory Mem
|
PA *p.Client
|
||||||
La string
|
SoundVolume string
|
||||||
|
}
|
||||||
|
|
||||||
|
Channels struct {
|
||||||
|
UpdateReady chan bool
|
||||||
|
MsgChan chan []I3BarOutBlock
|
||||||
|
SigChan chan os.Signal
|
||||||
|
SVPAHandlerChan chan ClickEvent
|
||||||
|
RunChan chan []string
|
||||||
|
}
|
||||||
|
|
||||||
// Default text color
|
// Default text color
|
||||||
Color string `json:"color,omitempty"`
|
Color string `json:"color,omitempty"`
|
||||||
@@ -240,15 +250,12 @@ type MyConfig struct {
|
|||||||
} `json:"apps,omitempty"`
|
} `json:"apps,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conf global variable with application config.
|
|
||||||
var Conf MyConfig
|
|
||||||
|
|
||||||
// readConf reads and validates config if config does not exist, it puts default config to the same dir where i3 config
|
// readConf reads and validates config if config does not exist, it puts default config to the same dir where i3 config
|
||||||
// is located.
|
// is located.
|
||||||
func ReadConf(DefaultConfig []byte) (MyConfig, error) {
|
func ReadConf(DefaultConfig []byte) (*MyConfig, error) {
|
||||||
var (
|
var (
|
||||||
path string
|
path string
|
||||||
config MyConfig
|
config *MyConfig
|
||||||
err error
|
err error
|
||||||
buf []byte
|
buf []byte
|
||||||
)
|
)
|
||||||
@@ -294,7 +301,7 @@ func ReadConf(DefaultConfig []byte) (MyConfig, error) {
|
|||||||
// We interested in struct as output product: so we parse config to intermediate map then marshal it to json and
|
// We interested in struct as output product: so we parse config to intermediate map then marshal it to json and
|
||||||
// then produced json unmarshal to struct. Not very effective way, but in app lifetime it happens only once.
|
// then produced json unmarshal to struct. Not very effective way, but in app lifetime it happens only once.
|
||||||
var (
|
var (
|
||||||
sampleConfig MyConfig
|
sampleConfig *MyConfig
|
||||||
tmp map[string]interface{}
|
tmp map[string]interface{}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1527,19 +1534,19 @@ func ReadConf(DefaultConfig []byte) (MyConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if app.Color == "" {
|
if app.Color == "" {
|
||||||
app.Color = Conf.Color
|
app.Color = sampleConfig.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.Background == "" {
|
if app.Background == "" {
|
||||||
app.Background = Conf.Background
|
app.Background = sampleConfig.Background
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.Border == "" {
|
if app.Border == "" {
|
||||||
app.Border = Conf.Color
|
app.Border = sampleConfig.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.BorderActive == "" {
|
if app.BorderActive == "" {
|
||||||
app.BorderActive = Conf.Color
|
app.BorderActive = sampleConfig.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.FullText == "" {
|
if app.FullText == "" {
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// UpdateCPUTemperature gets and updates average CPU cores temperature.
|
// UpdateCPUTemperature gets and updates average CPU cores temperature.
|
||||||
func (c MyConfig) UpdateCPUTemperature() {
|
func (c *MyConfig) UpdateCPUTemperature() {
|
||||||
n := len(Conf.CPUTemp.File)
|
n := len(c.CPUTemp.File)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
var (
|
var (
|
||||||
@@ -19,7 +19,7 @@ func (c MyConfig) UpdateCPUTemperature() {
|
|||||||
tAvg int64
|
tAvg int64
|
||||||
)
|
)
|
||||||
|
|
||||||
for i, filename := range Conf.CPUTemp.File {
|
for i, filename := range c.CPUTemp.File {
|
||||||
file, err := os.Open(filename)
|
file, err := os.Open(filename)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -67,9 +67,9 @@ func (c MyConfig) UpdateCPUTemperature() {
|
|||||||
tAvg = tSum / int64(len(temperature))
|
tAvg = tSum / int64(len(temperature))
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.CPUTemperature != tAvg {
|
if c.Values.CPUTemperature != tAvg {
|
||||||
c.CPUTemperature = tAvg
|
c.Values.CPUTemperature = tAvg
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(3 * time.Second)
|
time.Sleep(3 * time.Second)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
var myCron gocron.Scheduler
|
var myCron gocron.Scheduler
|
||||||
|
|
||||||
// RunCron parses config part, related to cron tasks and kicks cron to run.
|
// RunCron parses config part, related to cron tasks and kicks cron to run.
|
||||||
func RunCron() {
|
func (c MyConfig) RunCron() {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
myCron, err = gocron.NewScheduler()
|
myCron, err = gocron.NewScheduler()
|
||||||
@@ -21,14 +21,14 @@ func RunCron() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, job := range Conf.Cron.Tasks {
|
for _, job := range c.Cron.Tasks {
|
||||||
_, err := myCron.NewJob(
|
_, err := myCron.NewJob(
|
||||||
gocron.CronJob(job.Time, false),
|
gocron.CronJob(job.Time, false),
|
||||||
gocron.NewTask(
|
gocron.NewTask(
|
||||||
// Сука, просто заспавнить бинарь, ну почему это надо делать через жопу-то?
|
// Сука, просто заспавнить бинарь, ну почему это надо делать через жопу-то?
|
||||||
any(
|
any(
|
||||||
func() bool {
|
func() bool {
|
||||||
RunChan <- job.Cmd
|
c.Channels.RunChan <- job.Cmd
|
||||||
|
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ type WinList struct {
|
|||||||
var WL WinList
|
var WL WinList
|
||||||
|
|
||||||
// UpdateI3WinList subsribes to all window-related events and send them to I3EventParser() for more detailed parsing.
|
// UpdateI3WinList subsribes to all window-related events and send them to I3EventParser() for more detailed parsing.
|
||||||
func (c MyConfig) UpdateI3WinList() {
|
func (c *MyConfig) UpdateI3WinList() {
|
||||||
// TODO: Здесь получить начальный список окон, управляемых i3wm (через GetTree()) и сложить их атрибутику в переменную WL
|
// TODO: Здесь получить начальный список окон, управляемых i3wm (через GetTree()) и сложить их атрибутику в переменную WL
|
||||||
Tree, err := i3.GetTree()
|
Tree, err := i3.GetTree()
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ func (c MyConfig) UpdateI3WinList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// I3EventParser parses i3wm events and updates WL (aka Windows List).
|
// I3EventParser parses i3wm events and updates WL (aka Windows List).
|
||||||
func (c MyConfig) I3EventParser(e *i3.WindowEvent) {
|
func (c *MyConfig) I3EventParser(e *i3.WindowEvent) {
|
||||||
switch e.Change {
|
switch e.Change {
|
||||||
case "new":
|
case "new":
|
||||||
var (
|
var (
|
||||||
@@ -68,7 +68,7 @@ func (c MyConfig) I3EventParser(e *i3.WindowEvent) {
|
|||||||
count++
|
count++
|
||||||
WL.Instance.Set(e.Container.WindowProperties.Instance, count)
|
WL.Instance.Set(e.Container.WindowProperties.Instance, count)
|
||||||
|
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
|
|
||||||
case "close":
|
case "close":
|
||||||
countI, exist := WL.Class.Get(e.Container.WindowProperties.Class)
|
countI, exist := WL.Class.Get(e.Container.WindowProperties.Class)
|
||||||
@@ -99,7 +99,7 @@ func (c MyConfig) I3EventParser(e *i3.WindowEvent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ func FindWindowClass(regexpStr string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ExtractProps fills WL stricture collections with instance name and class name of given node (x11, that is).
|
// ExtractProps fills WL stricture collections with instance name and class name of given node (x11, that is).
|
||||||
func (c MyConfig) ExtractProps(n *i3.Node) {
|
func (c *MyConfig) ExtractProps(n *i3.Node) {
|
||||||
var e i3.WindowEvent
|
var e i3.WindowEvent
|
||||||
e.Change = "new"
|
e.Change = "new"
|
||||||
e.Container = *n
|
e.Container = *n
|
||||||
|
|||||||
@@ -9,15 +9,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IfStatus global var conaining cumulative status of all monitored net intefaces.
|
|
||||||
var IfStatus string
|
|
||||||
|
|
||||||
// UpdateIfStatus updates network interfaces status for i3bar.
|
// UpdateIfStatus updates network interfaces status for i3bar.
|
||||||
func (c MyConfig) UpdateIfStatus() {
|
func (c *MyConfig) UpdateIfStatus() {
|
||||||
for {
|
for {
|
||||||
var statusSum string
|
var statusSum string
|
||||||
|
|
||||||
for _, item := range Conf.NetIf.If {
|
for _, item := range c.NetIf.If {
|
||||||
var (
|
var (
|
||||||
name = item.Name
|
name = item.Name
|
||||||
)
|
)
|
||||||
@@ -35,10 +32,10 @@ func (c MyConfig) UpdateIfStatus() {
|
|||||||
} else {
|
} else {
|
||||||
switch strings.TrimSpace(string(operstate)) {
|
switch strings.TrimSpace(string(operstate)) {
|
||||||
case "up":
|
case "up":
|
||||||
StatusStr := fmt.Sprintf("<span foreground=\"%s\">⍋</span>", Conf.NetIf.UpColor)
|
StatusStr := fmt.Sprintf("<span foreground=\"%s\">⍋</span>", c.NetIf.UpColor)
|
||||||
operstate = []byte(StatusStr)
|
operstate = []byte(StatusStr)
|
||||||
case "down":
|
case "down":
|
||||||
statusStr := fmt.Sprintf("<span foreground=\"%s\">⍒</span>", Conf.NetIf.DownColor)
|
statusStr := fmt.Sprintf("<span foreground=\"%s\">⍒</span>", c.NetIf.DownColor)
|
||||||
operstate = []byte(statusStr)
|
operstate = []byte(statusStr)
|
||||||
default:
|
default:
|
||||||
operstate = []byte(`?`)
|
operstate = []byte(`?`)
|
||||||
@@ -52,9 +49,9 @@ func (c MyConfig) UpdateIfStatus() {
|
|||||||
statusSum += fmt.Sprintf("%s:%s", name, operstate)
|
statusSum += fmt.Sprintf("%s:%s", name, operstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.IfStatus != statusSum {
|
if c.Values.IfStatus != statusSum {
|
||||||
c.IfStatus = statusSum
|
c.Values.IfStatus = statusSum
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(3 * time.Second)
|
time.Sleep(3 * time.Second)
|
||||||
|
|||||||
@@ -8,15 +8,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// UpdateLaStats вытаскивает показание LA за последнюю минуту.
|
// UpdateLaStats вытаскивает показание LA за последнюю минуту.
|
||||||
func (c MyConfig) UpdateLaStats() {
|
func (c *MyConfig) UpdateLaStats() {
|
||||||
for {
|
for {
|
||||||
l, _ := load.Avg()
|
l, _ := load.Avg()
|
||||||
|
|
||||||
lav := fmt.Sprintf("%.2f", l.Load1)
|
lav := fmt.Sprintf("%.2f", l.Load1)
|
||||||
|
|
||||||
if c.La != lav {
|
if c.Values.La != lav {
|
||||||
c.La = lav
|
c.Values.La = lav
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(3 * time.Second)
|
time.Sleep(3 * time.Second)
|
||||||
|
|||||||
@@ -14,11 +14,8 @@ type Mem struct {
|
|||||||
Swap uint64
|
Swap uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory stores string with mem stats for i3bar.
|
|
||||||
var Memory Mem
|
|
||||||
|
|
||||||
// UpdateMemStats parses mem info stats.
|
// UpdateMemStats parses mem info stats.
|
||||||
func (c MyConfig) UpdateMemStats() {
|
func (c *MyConfig) UpdateMemStats() {
|
||||||
for {
|
for {
|
||||||
v, err := mem.VirtualMemory()
|
v, err := mem.VirtualMemory()
|
||||||
|
|
||||||
@@ -38,19 +35,18 @@ func (c MyConfig) UpdateMemStats() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if Conf.Mem.ShowSwap {
|
if c.Mem.ShowSwap {
|
||||||
if Memory.Usedpct != uint64(v.UsedPercent) || Memory.Shared != v.Shared/1024/1024 ||
|
if c.Values.Memory.Usedpct != uint64(v.UsedPercent) || c.Values.Memory.Shared != v.Shared/1024/1024 || c.Values.Memory.Swap != v.SwapTotal-v.SwapFree {
|
||||||
Memory.Swap != v.SwapTotal-v.SwapFree {
|
c.Values.Memory.Usedpct = uint64(v.UsedPercent)
|
||||||
Memory.Usedpct = uint64(v.UsedPercent)
|
c.Values.Memory.Shared = v.Shared / 1024 / 1024
|
||||||
Memory.Shared = v.Shared / 1024 / 1024
|
c.Values.Memory.Swap = sw.Used
|
||||||
Memory.Swap = sw.Used
|
c.Channels.UpdateReady <- true
|
||||||
c.UpdateReady <- true
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if Memory.Usedpct != uint64(v.UsedPercent) || Memory.Shared != v.Shared/1024/1024 {
|
if c.Values.Memory.Usedpct != uint64(v.UsedPercent) || c.Values.Memory.Shared != v.Shared/1024/1024 {
|
||||||
Memory.Usedpct = uint64(v.UsedPercent)
|
c.Values.Memory.Usedpct = uint64(v.UsedPercent)
|
||||||
Memory.Shared = v.Shared / 1024 / 1024
|
c.Values.Memory.Shared = v.Shared / 1024 / 1024
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,30 +10,25 @@ import (
|
|||||||
p "github.com/mafik/pulseaudio"
|
p "github.com/mafik/pulseaudio"
|
||||||
)
|
)
|
||||||
|
|
||||||
var SoundVolume = "🔊:0%"
|
|
||||||
var pa *p.Client
|
|
||||||
|
|
||||||
var SVPAHandlerChan = make(chan ClickEvent, 256)
|
|
||||||
|
|
||||||
// TODO: https://twin.sh/articles/44/add-a-timeout-to-any-function-in-go timeout pulseaudio calls
|
// TODO: https://twin.sh/articles/44/add-a-timeout-to-any-function-in-go timeout pulseaudio calls
|
||||||
|
|
||||||
// UpdateVolumeInfo updates info about current Sound Volume.
|
// UpdateVolumeInfo updates info about current Sound Volume.
|
||||||
func (c MyConfig) UpdateVolumeInfo() {
|
func (c *MyConfig) UpdateVolumeInfo() {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
pa, err = p.NewClient()
|
c.Values.PA, err = p.NewClient()
|
||||||
|
|
||||||
// It can happen if no pulseaudio server running for current user.
|
// It can happen if no pulseaudio server running for current user.
|
||||||
// If no server running we have to run one.
|
// If no server running we have to run one.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err := PaReinit(); err != nil {
|
if err := c.PaReinit(); err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vol, err := pa.Volume()
|
vol, err := c.Values.PA.Volume()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Unable get volume from pulseaudio server: %s", err)
|
log.Printf("Unable get volume from pulseaudio server: %s", err)
|
||||||
@@ -41,7 +36,7 @@ func (c MyConfig) UpdateVolumeInfo() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundVolume = fmt.Sprintf(
|
c.Values.SoundVolume = fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
|
||||||
c.SimpleVolumePa.Color,
|
c.SimpleVolumePa.Color,
|
||||||
c.SimpleVolumePa.Background,
|
c.SimpleVolumePa.Background,
|
||||||
@@ -50,7 +45,7 @@ func (c MyConfig) UpdateVolumeInfo() {
|
|||||||
c.SimpleVolumePa.Symbol,
|
c.SimpleVolumePa.Symbol,
|
||||||
)
|
)
|
||||||
|
|
||||||
SoundVolume += fmt.Sprintf(
|
c.Values.SoundVolume += fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>:%d%%</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>:%d%%</span>",
|
||||||
c.SimpleVolumePa.Color,
|
c.SimpleVolumePa.Color,
|
||||||
c.SimpleVolumePa.Background,
|
c.SimpleVolumePa.Background,
|
||||||
@@ -59,11 +54,11 @@ func (c MyConfig) UpdateVolumeInfo() {
|
|||||||
int64(vol*100),
|
int64(vol*100),
|
||||||
)
|
)
|
||||||
|
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// Subscribe to update notification channel, to get info that volume changed.
|
// Subscribe to update notification channel, to get info that volume changed.
|
||||||
pulseUpdate, err := pa.Updates()
|
pulseUpdate, err := c.Values.PA.Updates()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Unable to subscribe to pulseaudio updates: %s", err)
|
log.Printf("Unable to subscribe to pulseaudio updates: %s", err)
|
||||||
@@ -73,7 +68,7 @@ func (c MyConfig) UpdateVolumeInfo() {
|
|||||||
|
|
||||||
// Rake update events.
|
// Rake update events.
|
||||||
for range pulseUpdate {
|
for range pulseUpdate {
|
||||||
vol, err = pa.Volume()
|
vol, err = c.Values.PA.Volume()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Unable get volume from pulseaudio server: %s", err)
|
log.Printf("Unable get volume from pulseaudio server: %s", err)
|
||||||
@@ -81,7 +76,7 @@ func (c MyConfig) UpdateVolumeInfo() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundVolume = fmt.Sprintf(
|
c.Values.SoundVolume = fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
|
||||||
c.SimpleVolumePa.Color,
|
c.SimpleVolumePa.Color,
|
||||||
c.SimpleVolumePa.Background,
|
c.SimpleVolumePa.Background,
|
||||||
@@ -90,7 +85,7 @@ func (c MyConfig) UpdateVolumeInfo() {
|
|||||||
c.SimpleVolumePa.Symbol,
|
c.SimpleVolumePa.Symbol,
|
||||||
)
|
)
|
||||||
|
|
||||||
SoundVolume += fmt.Sprintf(
|
c.Values.SoundVolume += fmt.Sprintf(
|
||||||
"<span color='%s' background='%s' font='%s' size='%s'>:%d%%</span>",
|
"<span color='%s' background='%s' font='%s' size='%s'>:%d%%</span>",
|
||||||
c.SimpleVolumePa.Color,
|
c.SimpleVolumePa.Color,
|
||||||
c.SimpleVolumePa.Background,
|
c.SimpleVolumePa.Background,
|
||||||
@@ -99,10 +94,10 @@ func (c MyConfig) UpdateVolumeInfo() {
|
|||||||
int64(vol*100),
|
int64(vol*100),
|
||||||
)
|
)
|
||||||
|
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := PaReinit(); err != nil {
|
if err := c.PaReinit(); err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -110,11 +105,11 @@ func (c MyConfig) UpdateVolumeInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This code is unreachable :(
|
// This code is unreachable :(
|
||||||
pa.Close() //nolint:govet
|
c.Values.PA.Close() //nolint:govet
|
||||||
}
|
}
|
||||||
|
|
||||||
// PaReinit re-inits pulseaudio and connection to it.
|
// PaReinit re-inits pulseaudio and connection to it.
|
||||||
func PaReinit() error {
|
func (c *MyConfig) PaReinit() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// If we out of updates, seems someone killed pulseaudio server. Restart it.
|
// If we out of updates, seems someone killed pulseaudio server. Restart it.
|
||||||
@@ -157,7 +152,7 @@ func PaReinit() error {
|
|||||||
// This setting defines if pulseaudio will be run in manner that allows it to exit is other login detected (how
|
// This setting defines if pulseaudio will be run in manner that allows it to exit is other login detected (how
|
||||||
// they guess it - I do not know). In general case we do not want to allow pa to exit and leave our session without
|
// they guess it - I do not know). In general case we do not want to allow pa to exit and leave our session without
|
||||||
// audio.
|
// audio.
|
||||||
if Conf.SimpleVolumePa.DontExitOnLogin {
|
if c.SimpleVolumePa.DontExitOnLogin {
|
||||||
// Do not exit on any kind of login/logout events.
|
// Do not exit on any kind of login/logout events.
|
||||||
cmd = exec.Command("pulseaudio", "--exit-idle-time=-1", "--start")
|
cmd = exec.Command("pulseaudio", "--exit-idle-time=-1", "--start")
|
||||||
} else {
|
} else {
|
||||||
@@ -169,7 +164,7 @@ func PaReinit() error {
|
|||||||
return fmt.Errorf("unable to initialize pulseaudio server instance: %w", err)
|
return fmt.Errorf("unable to initialize pulseaudio server instance: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pa, err = p.NewClient()
|
c.Values.PA, err = p.NewClient()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to make client connection to pulseaudio: %w", err)
|
return fmt.Errorf("unable to make client connection to pulseaudio: %w", err)
|
||||||
@@ -178,21 +173,21 @@ func PaReinit() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c MyConfig) SVPAHandler() {
|
func (c *MyConfig) SVPAHandler() {
|
||||||
for e := range SVPAHandlerChan {
|
for e := range c.Channels.SVPAHandlerChan {
|
||||||
if e.Button == 3 {
|
if e.Button == 3 {
|
||||||
RunChan <- Conf.SimpleVolumePa.RightClickCmd
|
c.Channels.RunChan <- c.SimpleVolumePa.RightClickCmd
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
vol, err := pa.Volume()
|
vol, err := c.Values.PA.Volume()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err := PaReinit(); err != nil {
|
if err := c.PaReinit(); err != nil {
|
||||||
log.Printf("Unable to get pulseaudio volume: %s", err)
|
log.Printf("Unable to get pulseaudio volume: %s", err)
|
||||||
} else {
|
} else {
|
||||||
vol, err = pa.Volume()
|
vol, err = c.Values.PA.Volume()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Unable to get volume pulseaudio server behaves weirdly: %s", err)
|
log.Printf("Unable to get volume pulseaudio server behaves weirdly: %s", err)
|
||||||
@@ -201,25 +196,25 @@ func (c MyConfig) SVPAHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch e.Button {
|
switch e.Button {
|
||||||
case Conf.SimpleVolumePa.WheelUp:
|
case c.SimpleVolumePa.WheelUp:
|
||||||
vol += float32(Conf.SimpleVolumePa.Step) / 100
|
vol += float32(c.SimpleVolumePa.Step) / 100
|
||||||
|
|
||||||
if vol > (float32(Conf.SimpleVolumePa.MaxVolumeLimit) / 100) {
|
if vol > (float32(c.SimpleVolumePa.MaxVolumeLimit) / 100) {
|
||||||
vol = float32(Conf.SimpleVolumePa.MaxVolumeLimit) / 100
|
vol = float32(c.SimpleVolumePa.MaxVolumeLimit) / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := pa.SetVolume(vol); err != nil {
|
if err := c.Values.PA.SetVolume(vol); err != nil {
|
||||||
log.Printf("Unable to set pulseaudio volume: %s", err)
|
log.Printf("Unable to set pulseaudio volume: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
case Conf.SimpleVolumePa.WheelDown:
|
case c.SimpleVolumePa.WheelDown:
|
||||||
vol -= float32(Conf.SimpleVolumePa.Step) / 100
|
vol -= float32(c.SimpleVolumePa.Step) / 100
|
||||||
|
|
||||||
if vol < 0 {
|
if vol < 0 {
|
||||||
vol = 0
|
vol = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := pa.SetVolume(vol); err != nil {
|
if err := c.Values.PA.SetVolume(vol); err != nil {
|
||||||
log.Printf("Unable to set pulseaudio volume: %s", err)
|
log.Printf("Unable to set pulseaudio volume: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,20 +9,20 @@ import (
|
|||||||
var PrintOutput = true
|
var PrintOutput = true
|
||||||
|
|
||||||
// SigHandler OS signal handler.
|
// SigHandler OS signal handler.
|
||||||
func (c MyConfig) SigHandler() {
|
func (c *MyConfig) SigHandler() {
|
||||||
for s := range c.SigChan {
|
for s := range c.Channels.SigChan {
|
||||||
switch s {
|
switch s {
|
||||||
case syscall.SIGUSR1:
|
case syscall.SIGUSR1:
|
||||||
log.Print("Got SIGUSR1, stopping output")
|
log.Print("Got SIGUSR1, stopping output")
|
||||||
|
|
||||||
PrintOutput = false
|
c.Values.PrintOutput = false
|
||||||
|
|
||||||
case syscall.SIGUSR2:
|
case syscall.SIGUSR2:
|
||||||
log.Print("Got SIGUSR2, resuming output")
|
log.Print("Got SIGUSR2, resuming output")
|
||||||
|
|
||||||
PrintOutput = true
|
c.Values.PrintOutput = true
|
||||||
|
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
|
|
||||||
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
|||||||
@@ -8,12 +8,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunChan to this channel we send command and its argv to execute as separate process.
|
|
||||||
var RunChan = make(chan []string, 128)
|
|
||||||
|
|
||||||
// Spawner forks and execs given program, and also detaches form its control tty.
|
// Spawner forks and execs given program, and also detaches form its control tty.
|
||||||
func (c MyConfig) Spawner() {
|
func (c *MyConfig) Spawner() {
|
||||||
for prg := range RunChan {
|
for prg := range c.Channels.RunChan {
|
||||||
devnullR, _ := os.Open(os.DevNull)
|
devnullR, _ := os.Open(os.DevNull)
|
||||||
devnullW, _ := os.OpenFile(os.DevNull, os.O_WRONLY|os.O_APPEND, 0644)
|
devnullW, _ := os.OpenFile(os.DevNull, os.O_WRONLY|os.O_APPEND, 0644)
|
||||||
|
|
||||||
@@ -48,7 +45,7 @@ func (c MyConfig) Spawner() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CleanZombies reaps processes spawned by Spawner() and already exited.
|
// CleanZombies reaps processes spawned by Spawner() and already exited.
|
||||||
func (c MyConfig) CleanZombies() {
|
func (c *MyConfig) CleanZombies() {
|
||||||
r := syscall.Rusage{}
|
r := syscall.Rusage{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ type ClickEvent struct {
|
|||||||
|
|
||||||
// ParseStdin tries to parse text that i3bar prints to our stdin. Currently - it is mouse click events on different
|
// ParseStdin tries to parse text that i3bar prints to our stdin. Currently - it is mouse click events on different
|
||||||
// area names of i3bar.
|
// area names of i3bar.
|
||||||
func (c MyConfig) ParseStdin() {
|
func (c *MyConfig) ParseStdin() {
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
|
||||||
// De-facto it is jsonl, except first line is garbage. Also, first symbol in each strint garbage too.
|
// De-facto it is jsonl, except first line is garbage. Also, first symbol in each strint garbage too.
|
||||||
@@ -84,35 +84,35 @@ func (c MyConfig) ParseStdin() {
|
|||||||
|
|
||||||
// Clock clicks parse.
|
// Clock clicks parse.
|
||||||
if e.Name == "wallclock" {
|
if e.Name == "wallclock" {
|
||||||
if Conf.Clock.LeftClick.Enabled && e.Button == 1 {
|
if c.Clock.LeftClick.Enabled && e.Button == 1 {
|
||||||
RunChan <- Conf.Clock.LeftClick.Cmd
|
c.Channels.RunChan <- c.Clock.LeftClick.Cmd
|
||||||
} else if Conf.Clock.RightClick.Enabled && e.Button == 3 {
|
} else if c.Clock.RightClick.Enabled && e.Button == 3 {
|
||||||
RunChan <- Conf.Clock.RightClick.Cmd
|
c.Channels.RunChan <- c.Clock.RightClick.Cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Name == "simple-volume-pa" {
|
if e.Name == "simple-volume-pa" {
|
||||||
if Conf.SimpleVolumePa.Enabled {
|
if c.SimpleVolumePa.Enabled {
|
||||||
SVPAHandlerChan <- e
|
c.Channels.SVPAHandlerChan <- e
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !Conf.AppButtons.Enabled {
|
if !c.AppButtons.Enabled {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, app := range Conf.Apps {
|
for _, app := range c.Apps {
|
||||||
switch {
|
switch {
|
||||||
case app.Name != "" && app.Instance != "":
|
case app.Name != "" && app.Instance != "":
|
||||||
if app.Name == e.Name && app.Instance == e.Instance {
|
if app.Name == e.Name && app.Instance == e.Instance {
|
||||||
prg := append([]string{}, app.Cmd)
|
prg := append([]string{}, app.Cmd)
|
||||||
prg = append(prg, app.Args...)
|
prg = append(prg, app.Args...)
|
||||||
|
|
||||||
RunChan <- prg
|
c.Channels.RunChan <- prg
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -120,13 +120,13 @@ func (c MyConfig) ParseStdin() {
|
|||||||
prg := append([]string{}, app.Cmd)
|
prg := append([]string{}, app.Cmd)
|
||||||
prg = append(prg, app.Args...)
|
prg = append(prg, app.Args...)
|
||||||
|
|
||||||
RunChan <- prg
|
c.Channels.RunChan <- prg
|
||||||
|
|
||||||
case app.Instance != "" && e.Instance == app.Instance:
|
case app.Instance != "" && e.Instance == app.Instance:
|
||||||
prg := append([]string{}, app.Cmd)
|
prg := append([]string{}, app.Cmd)
|
||||||
prg = append(prg, app.Args...)
|
prg = append(prg, app.Args...)
|
||||||
|
|
||||||
RunChan <- prg
|
c.Channels.RunChan <- prg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// UpdateVPNStatus periodically update status of openvpn daemon.
|
// UpdateVPNStatus periodically update status of openvpn daemon.
|
||||||
func (c MyConfig) UpdateVPNStatus() {
|
func (c *MyConfig) UpdateVPNStatus() {
|
||||||
var (
|
var (
|
||||||
vpnCStatus string
|
vpnCStatus string
|
||||||
tcpCheck string
|
tcpCheck string
|
||||||
@@ -17,28 +17,28 @@ func (c MyConfig) UpdateVPNStatus() {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
if c.VPNFileCheck() {
|
if c.VPNFileCheck() {
|
||||||
if Conf.Vpn.UpColor == "" {
|
if c.Vpn.UpColor == "" {
|
||||||
vpnCheck = `⍋`
|
vpnCheck = `⍋`
|
||||||
} else {
|
} else {
|
||||||
vpnCheck = fmt.Sprintf(`<span foreground="%s">⍋</span>`, c.Vpn.UpColor)
|
vpnCheck = fmt.Sprintf(`<span foreground="%s">⍋</span>`, c.Vpn.UpColor)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if Conf.Vpn.DownColor == "" {
|
if c.Vpn.DownColor == "" {
|
||||||
vpnCheck = `⍒`
|
vpnCheck = `⍒`
|
||||||
} else {
|
} else {
|
||||||
vpnCheck = fmt.Sprintf(`<span foreground="%s">⍒</span>`, c.Vpn.DownColor)
|
vpnCheck = fmt.Sprintf(`<span foreground="%s">⍒</span>`, c.Vpn.DownColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if Conf.Vpn.TCPCheck.Enabled {
|
if c.Vpn.TCPCheck.Enabled {
|
||||||
if c.VPNTCPCheck() {
|
if c.VPNTCPCheck() {
|
||||||
if Conf.Vpn.UpColor == "" {
|
if c.Vpn.UpColor == "" {
|
||||||
tcpCheck = `✔`
|
tcpCheck = `✔`
|
||||||
} else {
|
} else {
|
||||||
tcpCheck = fmt.Sprintf(`<span foreground="%s">✔</span>`, c.Vpn.UpColor)
|
tcpCheck = fmt.Sprintf(`<span foreground="%s">✔</span>`, c.Vpn.UpColor)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if Conf.Vpn.DownColor == "" {
|
if c.Vpn.DownColor == "" {
|
||||||
tcpCheck = `✘`
|
tcpCheck = `✘`
|
||||||
} else {
|
} else {
|
||||||
tcpCheck = fmt.Sprintf(`<span foreground="%s">✘</span>`, c.Vpn.DownColor)
|
tcpCheck = fmt.Sprintf(`<span foreground="%s">✘</span>`, c.Vpn.DownColor)
|
||||||
@@ -50,9 +50,9 @@ func (c MyConfig) UpdateVPNStatus() {
|
|||||||
vpnCStatus = fmt.Sprintf("VPN:%s", vpnCheck)
|
vpnCStatus = fmt.Sprintf("VPN:%s", vpnCheck)
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.VPNStatus != vpnCStatus {
|
if c.Values.VPNStatus != vpnCStatus {
|
||||||
c.VPNStatus = vpnCStatus
|
c.Values.VPNStatus = vpnCStatus
|
||||||
c.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(3 * time.Second)
|
time.Sleep(3 * time.Second)
|
||||||
@@ -60,7 +60,7 @@ func (c MyConfig) UpdateVPNStatus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VPNTCPCheck intended to check arbitrary service inside vpn segment, to indicate that openvpn sevice not stoned.
|
// VPNTCPCheck intended to check arbitrary service inside vpn segment, to indicate that openvpn sevice not stoned.
|
||||||
func (c MyConfig) VPNTCPCheck() bool {
|
func (c *MyConfig) VPNTCPCheck() bool {
|
||||||
conn, err := net.DialTimeout(
|
conn, err := net.DialTimeout(
|
||||||
"tcp",
|
"tcp",
|
||||||
fmt.Sprintf("%s:%d", c.Vpn.TCPCheck.Host, c.Vpn.TCPCheck.Port),
|
fmt.Sprintf("%s:%d", c.Vpn.TCPCheck.Host, c.Vpn.TCPCheck.Port),
|
||||||
@@ -76,7 +76,7 @@ func (c MyConfig) VPNTCPCheck() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VPNFileCheck checks modification time of openvpn-status file.
|
// VPNFileCheck checks modification time of openvpn-status file.
|
||||||
func (c MyConfig) VPNFileCheck() bool {
|
func (c *MyConfig) VPNFileCheck() bool {
|
||||||
var (
|
var (
|
||||||
fi os.FileInfo
|
fi os.FileInfo
|
||||||
err error
|
err error
|
||||||
|
|||||||
Reference in New Issue
Block a user