diff --git a/cmd/i3status-go/main.go b/cmd/i3status-go/main.go
index 22c8fc7..17e7a2a 100644
--- a/cmd/i3status-go/main.go
+++ b/cmd/i3status-go/main.go
@@ -25,20 +25,25 @@ func main() {
log.Panicf("Unable to read config: %s", err)
}
- Conf.UpdateReady = make(chan bool)
- Conf.MsgChan = make(chan []lib.I3BarOutBlock, 64)
- Conf.SigChan = make(chan os.Signal, 1)
- Conf.BatteryString = "⚡ ??% •"
- Conf.ClockTime = "Thu, 1 Jan 1970 1:00"
- Conf.IfStatus = ""
- Conf.VPNStatus = ""
- Conf.Memory.Shared = 0
- Conf.Memory.Usedpct = 0
- Conf.Memory.Swap = 0
- Conf.La = "-1"
+ Conf.Channels.UpdateReady = make(chan bool)
+ Conf.Channels.SVPAHandlerChan = make(chan lib.ClickEvent, 256)
+ Conf.Channels.MsgChan = make(chan []lib.I3BarOutBlock, 64)
+ Conf.Channels.SigChan = make(chan os.Signal, 1)
+ Conf.Channels.RunChan = make(chan []string, 128)
+ Conf.Values.PrintOutput = true
+ Conf.Values.BatteryString = "⚡ ??% •"
+ Conf.Values.ClockTime = "Thu, 1 Jan 1970 1:00"
+ Conf.Values.IfStatus = ""
+ Conf.Values.VPNStatus = ""
+ 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: Проставить дефолтные значения для глобальных переменных модулей.
- Batt := fmt.Sprintf(
+ Conf.Values.BatteryString = fmt.Sprintf(
"%s",
Conf.Battery.Color,
Conf.Battery.Background,
@@ -47,7 +52,7 @@ func main() {
Conf.Battery.Symbol,
)
- Batt += fmt.Sprintf(
+ Conf.Values.BatteryString += fmt.Sprintf(
" ??%% •",
Conf.Battery.Color,
Conf.Battery.Background,
@@ -55,7 +60,7 @@ func main() {
Conf.Battery.FontSize,
)
- SoundVolume := fmt.Sprintf(
+ Conf.Values.SoundVolume = fmt.Sprintf(
"🔊",
Conf.SimpleVolumePa.Color,
Conf.SimpleVolumePa.Background,
@@ -63,7 +68,7 @@ func main() {
Conf.SimpleVolumePa.SymbolFontSize,
)
- SoundVolume += fmt.Sprintf(
+ Conf.Values.SoundVolume += fmt.Sprintf(
":0%%",
Conf.SimpleVolumePa.Color,
Conf.SimpleVolumePa.Background,
@@ -71,7 +76,7 @@ func main() {
Conf.SimpleVolumePa.FontSize,
)
- Clock := fmt.Sprintf(
+ Conf.Values.ClockTime = fmt.Sprintf(
"Thu, 1 Jan 1970 1:00",
Conf.Clock.Color,
Conf.Clock.Background,
@@ -91,7 +96,7 @@ func main() {
// Kick signal handler
go Conf.SigHandler()
- signal.Notify(Conf.SigChan,
+ signal.Notify(Conf.Channels.SigChan,
syscall.SIGUSR1,
syscall.SIGUSR2,
syscall.SIGQUIT,
@@ -131,7 +136,7 @@ func main() {
}
if Conf.Cron.Enabled {
- go lib.RunCron()
+ go Conf.RunCron()
}
if Conf.Vpn.Enabled {
@@ -156,7 +161,7 @@ func main() {
fmt.Println("[ [],")
for {
- if <-Conf.UpdateReady {
+ if <-Conf.Channels.UpdateReady {
// Actually build json struct, marshal it and print result
var j []lib.I3BarOutBlock
@@ -235,7 +240,7 @@ func main() {
Conf.CPUTemp.Background,
Conf.CPUTemp.Font,
Conf.CPUTemp.FontSize,
- Conf.CPUTemperature,
+ Conf.Values.CPUTemperature,
)
if Conf.CPUTemp.Separator.Right.Enabled {
@@ -279,9 +284,9 @@ func main() {
Conf.Mem.Background,
Conf.Mem.Font,
Conf.Mem.FontSize,
- Conf.Memory.Usedpct,
- Conf.Memory.Shared,
- Conf.Memory.Swap,
+ Conf.Values.Memory.Usedpct,
+ Conf.Values.Memory.Shared,
+ Conf.Values.Memory.Swap,
)
} else {
b.FullText += fmt.Sprintf(
@@ -290,8 +295,8 @@ func main() {
Conf.Mem.Background,
Conf.Mem.Font,
Conf.Mem.FontSize,
- Conf.Memory.Usedpct,
- Conf.Memory.Shared,
+ Conf.Values.Memory.Usedpct,
+ Conf.Values.Memory.Shared,
)
}
@@ -335,7 +340,7 @@ func main() {
Conf.LA.Background,
Conf.LA.Font,
Conf.LA.FontSize,
- Conf.La,
+ Conf.Values.La,
)
if Conf.LA.Separator.Right.Enabled {
@@ -378,7 +383,7 @@ func main() {
Conf.NetIf.Background,
Conf.NetIf.Font,
Conf.NetIf.FontSize,
- Conf.IfStatus,
+ Conf.Values.IfStatus,
)
if Conf.NetIf.Separator.Right.Enabled {
@@ -421,7 +426,7 @@ func main() {
Conf.Vpn.Background,
Conf.Vpn.Font,
Conf.Vpn.FontSize,
- Conf.VPNStatus,
+ Conf.Values.VPNStatus,
)
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 {
b.FullText += fmt.Sprintf(
@@ -496,7 +501,7 @@ func main() {
}
// Pango format is already applied in plugin src.
- b.FullText += SoundVolume
+ b.FullText += Conf.Values.SoundVolume
if Conf.SimpleVolumePa.Separator.Right.Enabled {
b.FullText += fmt.Sprintf(
@@ -539,7 +544,7 @@ func main() {
Conf.Clock.Background,
Conf.Clock.Font,
Conf.Clock.FontSize,
- Clock,
+ Conf.Values.ClockTime,
)
if Conf.Clock.Separator.Right.Enabled {
@@ -559,16 +564,16 @@ func main() {
j = append(j, b)
}
- if Conf.PrintOutput && len(j) > 0 {
- Conf.MsgChan <- j
+ if Conf.Values.PrintOutput && len(j) > 0 {
+ Conf.Channels.MsgChan <- j
}
}
}
}
// PrintToI3bar prints info to stdout according to ipc docs (https://i3wm.org/docs/i3bar-protocol.html)
-func PrintToI3bar(c lib.MyConfig) {
- for message := range c.MsgChan {
+func PrintToI3bar(c *lib.MyConfig) {
+ for message := range c.Channels.MsgChan {
// we do not need to html-encode output, json.Marshal does this forcefully, so invent our own Marshal
buf := new(bytes.Buffer)
encoder := json.NewEncoder(buf)
diff --git a/internal/lib/batteries.go b/internal/lib/batteries.go
index 42e3d17..f4f6a31 100644
--- a/internal/lib/batteries.go
+++ b/internal/lib/batteries.go
@@ -9,7 +9,7 @@ import (
)
// UpdateBatteryInfo updates info about battery charge.
-func (c MyConfig) UpdateBatteryInfo() {
+func (c *MyConfig) UpdateBatteryInfo() {
var (
ch int
status string
@@ -22,11 +22,11 @@ func (c MyConfig) UpdateBatteryInfo() {
if err != nil {
Batts = fmt.Sprintf(
"%s no batt",
- Conf.Battery.SymbolFont,
- Conf.Battery.SymbolFontSize,
- Conf.Battery.Symbol,
- Conf.Battery.Font,
- Conf.Battery.FontSize,
+ c.Battery.SymbolFont,
+ c.Battery.SymbolFontSize,
+ c.Battery.Symbol,
+ c.Battery.Font,
+ c.Battery.FontSize,
)
} else {
var (
@@ -52,85 +52,85 @@ func (c MyConfig) UpdateBatteryInfo() {
switch {
case ch > 85:
- if Conf.Battery.ChargeColor.Full == "" {
+ if c.Battery.ChargeColor.Full == "" {
chStr = fmt.Sprintf(
"% 3d%%",
- Conf.Battery.Color,
- Conf.Battery.Background,
- Conf.Battery.Font,
- Conf.Battery.FontSize,
+ c.Battery.Color,
+ c.Battery.Background,
+ c.Battery.Font,
+ c.Battery.FontSize,
ch,
)
} else {
chStr = fmt.Sprintf(
`% 3d%%`,
- Conf.Battery.ChargeColor.Full,
- Conf.Battery.Background,
- Conf.Battery.Font,
- Conf.Battery.FontSize,
+ c.Battery.ChargeColor.Full,
+ c.Battery.Background,
+ c.Battery.Font,
+ c.Battery.FontSize,
ch,
)
}
case ch < 85 && ch > 40:
- if Conf.Battery.ChargeColor.AlmostFull == "" {
+ if c.Battery.ChargeColor.AlmostFull == "" {
chStr = fmt.Sprintf(
"% 3d%%",
- Conf.Battery.Color,
- Conf.Battery.Background,
- Conf.Battery.Font,
- Conf.Battery.FontSize,
+ c.Battery.Color,
+ c.Battery.Background,
+ c.Battery.Font,
+ c.Battery.FontSize,
ch,
)
} else {
chStr = fmt.Sprintf(
`% 3d%%`,
- Conf.Battery.ChargeColor.AlmostFull,
- Conf.Battery.Background,
- Conf.Battery.Font,
- Conf.Battery.FontSize,
+ c.Battery.ChargeColor.AlmostFull,
+ c.Battery.Background,
+ c.Battery.Font,
+ c.Battery.FontSize,
ch,
)
}
case ch <= 40 && ch >= 10:
- if Conf.Battery.ChargeColor.AlmostEmpty == "" {
+ if c.Battery.ChargeColor.AlmostEmpty == "" {
chStr = fmt.Sprintf(
"% 3d%%",
- Conf.Battery.Color,
- Conf.Battery.Background,
- Conf.Battery.Font,
- Conf.Battery.FontSize,
+ c.Battery.Color,
+ c.Battery.Background,
+ c.Battery.Font,
+ c.Battery.FontSize,
ch,
)
} else {
chStr = fmt.Sprintf(
`% 3d%%`,
- Conf.Battery.ChargeColor.AlmostEmpty,
- Conf.Battery.Background,
- Conf.Battery.Font,
- Conf.Battery.FontSize,
+ c.Battery.ChargeColor.AlmostEmpty,
+ c.Battery.Background,
+ c.Battery.Font,
+ c.Battery.FontSize,
ch,
)
}
case ch < 10:
- if Conf.Battery.ChargeColor.Empty == "" {
+ if c.Battery.ChargeColor.Empty == "" {
chStr = fmt.Sprintf(
"% 3d%%",
- Conf.Battery.Color,
- Conf.Battery.Background,
- Conf.Battery.Font,
- Conf.Battery.FontSize,
+ c.Battery.Color,
+ c.Battery.Background,
+ c.Battery.Font,
+ c.Battery.FontSize,
ch,
)
} else {
chStr = fmt.Sprintf(
`% 3d%%`,
- Conf.Battery.ChargeColor.Empty,
- Conf.Battery.Background,
- Conf.Battery.Font,
- Conf.Battery.FontSize,
+ c.Battery.ChargeColor.Empty,
+ c.Battery.Background,
+ c.Battery.Font,
+ c.Battery.FontSize,
ch,
)
}
@@ -138,21 +138,21 @@ func (c MyConfig) UpdateBatteryInfo() {
battsInfo += fmt.Sprintf(
"%sB%d %s %s",
- Conf.Battery.Color,
- Conf.Battery.Background,
- Conf.Battery.SymbolFont,
- Conf.Battery.SymbolFontSize,
- Conf.Battery.Symbol,
- Conf.Battery.Color,
- Conf.Battery.Background,
- Conf.Battery.Font,
- Conf.Battery.FontSize,
+ c.Battery.Color,
+ c.Battery.Background,
+ c.Battery.SymbolFont,
+ c.Battery.SymbolFontSize,
+ c.Battery.Symbol,
+ c.Battery.Color,
+ c.Battery.Background,
+ c.Battery.Font,
+ c.Battery.FontSize,
i,
chStr,
- Conf.Battery.Color,
- Conf.Battery.Background,
- Conf.Battery.Font,
- Conf.Battery.FontSize,
+ c.Battery.Color,
+ c.Battery.Background,
+ c.Battery.Font,
+ c.Battery.FontSize,
status,
)
}
@@ -162,9 +162,9 @@ func (c MyConfig) UpdateBatteryInfo() {
}
}
- if c.BatteryString == Batts {
- c.BatteryString = Batts
- c.UpdateReady <- true
+ if c.Values.BatteryString == Batts {
+ c.Values.BatteryString = Batts
+ c.Channels.UpdateReady <- true
}
time.Sleep(5 * time.Second)
diff --git a/internal/lib/clock.go b/internal/lib/clock.go
index 4f9b986..97042fc 100644
--- a/internal/lib/clock.go
+++ b/internal/lib/clock.go
@@ -6,7 +6,7 @@ import (
)
// UpdateClock get and updates (on i3bar) info about system clock.
-func (c MyConfig) UpdateClock() {
+func (c *MyConfig) UpdateClock() {
for {
currentTime := time.Now()
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)
- if myclock != c.ClockTime {
- c.ClockTime = myclock
- c.UpdateReady <- true
+ if myclock != c.Values.ClockTime {
+ c.Values.ClockTime = myclock
+ c.Channels.UpdateReady <- true
}
time.Sleep(1 * time.Second)
diff --git a/internal/lib/config.go b/internal/lib/config.go
index 32979b0..87ff9bd 100644
--- a/internal/lib/config.go
+++ b/internal/lib/config.go
@@ -11,6 +11,7 @@ import (
"github.com/adrg/xdg"
"github.com/hjson/hjson-go"
+ p "github.com/mafik/pulseaudio"
)
// I3BarOutBlock is structure element for I3BarOut, it represents i3bar output json block format.
@@ -57,17 +58,26 @@ type Separator struct {
}
type MyConfig struct {
- UpdateReady chan bool
- PrintOutput bool
- MsgChan chan []I3BarOutBlock
- SigChan chan os.Signal
- CPUTemperature int64
- BatteryString string
- ClockTime string
- IfStatus string
- VPNStatus string
- Memory Mem
- La string
+ Values struct {
+ PrintOutput bool
+ CPUTemperature int64
+ BatteryString string
+ ClockTime string
+ IfStatus string
+ VPNStatus string
+ Memory Mem
+ La string
+ PA *p.Client
+ SoundVolume string
+ }
+
+ Channels struct {
+ UpdateReady chan bool
+ MsgChan chan []I3BarOutBlock
+ SigChan chan os.Signal
+ SVPAHandlerChan chan ClickEvent
+ RunChan chan []string
+ }
// Default text color
Color string `json:"color,omitempty"`
@@ -240,15 +250,12 @@ type MyConfig struct {
} `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
// is located.
-func ReadConf(DefaultConfig []byte) (MyConfig, error) {
+func ReadConf(DefaultConfig []byte) (*MyConfig, error) {
var (
path string
- config MyConfig
+ config *MyConfig
err error
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
// then produced json unmarshal to struct. Not very effective way, but in app lifetime it happens only once.
var (
- sampleConfig MyConfig
+ sampleConfig *MyConfig
tmp map[string]interface{}
)
@@ -1527,19 +1534,19 @@ func ReadConf(DefaultConfig []byte) (MyConfig, error) {
}
if app.Color == "" {
- app.Color = Conf.Color
+ app.Color = sampleConfig.Color
}
if app.Background == "" {
- app.Background = Conf.Background
+ app.Background = sampleConfig.Background
}
if app.Border == "" {
- app.Border = Conf.Color
+ app.Border = sampleConfig.Color
}
if app.BorderActive == "" {
- app.BorderActive = Conf.Color
+ app.BorderActive = sampleConfig.Color
}
if app.FullText == "" {
diff --git a/internal/lib/cputemp.go b/internal/lib/cputemp.go
index 306939e..e4290c0 100644
--- a/internal/lib/cputemp.go
+++ b/internal/lib/cputemp.go
@@ -9,8 +9,8 @@ import (
)
// UpdateCPUTemperature gets and updates average CPU cores temperature.
-func (c MyConfig) UpdateCPUTemperature() {
- n := len(Conf.CPUTemp.File)
+func (c *MyConfig) UpdateCPUTemperature() {
+ n := len(c.CPUTemp.File)
for {
var (
@@ -19,7 +19,7 @@ func (c MyConfig) UpdateCPUTemperature() {
tAvg int64
)
- for i, filename := range Conf.CPUTemp.File {
+ for i, filename := range c.CPUTemp.File {
file, err := os.Open(filename)
if err != nil {
@@ -67,9 +67,9 @@ func (c MyConfig) UpdateCPUTemperature() {
tAvg = tSum / int64(len(temperature))
}
- if c.CPUTemperature != tAvg {
- c.CPUTemperature = tAvg
- c.UpdateReady <- true
+ if c.Values.CPUTemperature != tAvg {
+ c.Values.CPUTemperature = tAvg
+ c.Channels.UpdateReady <- true
}
time.Sleep(3 * time.Second)
diff --git a/internal/lib/cron.go b/internal/lib/cron.go
index 2cbce41..0943814 100644
--- a/internal/lib/cron.go
+++ b/internal/lib/cron.go
@@ -10,7 +10,7 @@ import (
var myCron gocron.Scheduler
// RunCron parses config part, related to cron tasks and kicks cron to run.
-func RunCron() {
+func (c MyConfig) RunCron() {
var err error
myCron, err = gocron.NewScheduler()
@@ -21,14 +21,14 @@ func RunCron() {
return
}
- for _, job := range Conf.Cron.Tasks {
+ for _, job := range c.Cron.Tasks {
_, err := myCron.NewJob(
gocron.CronJob(job.Time, false),
gocron.NewTask(
// Сука, просто заспавнить бинарь, ну почему это надо делать через жопу-то?
any(
func() bool {
- RunChan <- job.Cmd
+ c.Channels.RunChan <- job.Cmd
return true
},
diff --git a/internal/lib/i3.go b/internal/lib/i3.go
index 83d50aa..a6c0a18 100644
--- a/internal/lib/i3.go
+++ b/internal/lib/i3.go
@@ -18,7 +18,7 @@ type WinList struct {
var WL WinList
// 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
Tree, err := i3.GetTree()
@@ -39,7 +39,7 @@ func (c MyConfig) UpdateI3WinList() {
}
// 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 {
case "new":
var (
@@ -68,7 +68,7 @@ func (c MyConfig) I3EventParser(e *i3.WindowEvent) {
count++
WL.Instance.Set(e.Container.WindowProperties.Instance, count)
- c.UpdateReady <- true
+ c.Channels.UpdateReady <- true
case "close":
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).
-func (c MyConfig) ExtractProps(n *i3.Node) {
+func (c *MyConfig) ExtractProps(n *i3.Node) {
var e i3.WindowEvent
e.Change = "new"
e.Container = *n
diff --git a/internal/lib/ifmon.go b/internal/lib/ifmon.go
index a1434d3..d975d38 100644
--- a/internal/lib/ifmon.go
+++ b/internal/lib/ifmon.go
@@ -9,15 +9,12 @@ import (
"time"
)
-// IfStatus global var conaining cumulative status of all monitored net intefaces.
-var IfStatus string
-
// UpdateIfStatus updates network interfaces status for i3bar.
-func (c MyConfig) UpdateIfStatus() {
+func (c *MyConfig) UpdateIfStatus() {
for {
var statusSum string
- for _, item := range Conf.NetIf.If {
+ for _, item := range c.NetIf.If {
var (
name = item.Name
)
@@ -35,10 +32,10 @@ func (c MyConfig) UpdateIfStatus() {
} else {
switch strings.TrimSpace(string(operstate)) {
case "up":
- StatusStr := fmt.Sprintf("⍋", Conf.NetIf.UpColor)
+ StatusStr := fmt.Sprintf("⍋", c.NetIf.UpColor)
operstate = []byte(StatusStr)
case "down":
- statusStr := fmt.Sprintf("⍒", Conf.NetIf.DownColor)
+ statusStr := fmt.Sprintf("⍒", c.NetIf.DownColor)
operstate = []byte(statusStr)
default:
operstate = []byte(`?`)
@@ -52,9 +49,9 @@ func (c MyConfig) UpdateIfStatus() {
statusSum += fmt.Sprintf("%s:%s", name, operstate)
}
- if c.IfStatus != statusSum {
- c.IfStatus = statusSum
- c.UpdateReady <- true
+ if c.Values.IfStatus != statusSum {
+ c.Values.IfStatus = statusSum
+ c.Channels.UpdateReady <- true
}
time.Sleep(3 * time.Second)
diff --git a/internal/lib/la.go b/internal/lib/la.go
index 6d8308e..88c7456 100644
--- a/internal/lib/la.go
+++ b/internal/lib/la.go
@@ -8,15 +8,15 @@ import (
)
// UpdateLaStats вытаскивает показание LA за последнюю минуту.
-func (c MyConfig) UpdateLaStats() {
+func (c *MyConfig) UpdateLaStats() {
for {
l, _ := load.Avg()
lav := fmt.Sprintf("%.2f", l.Load1)
- if c.La != lav {
- c.La = lav
- c.UpdateReady <- true
+ if c.Values.La != lav {
+ c.Values.La = lav
+ c.Channels.UpdateReady <- true
}
time.Sleep(3 * time.Second)
diff --git a/internal/lib/memory.go b/internal/lib/memory.go
index 2abe03e..148cc7b 100644
--- a/internal/lib/memory.go
+++ b/internal/lib/memory.go
@@ -14,11 +14,8 @@ type Mem struct {
Swap uint64
}
-// Memory stores string with mem stats for i3bar.
-var Memory Mem
-
// UpdateMemStats parses mem info stats.
-func (c MyConfig) UpdateMemStats() {
+func (c *MyConfig) UpdateMemStats() {
for {
v, err := mem.VirtualMemory()
@@ -38,19 +35,18 @@ func (c MyConfig) UpdateMemStats() {
continue
}
- if Conf.Mem.ShowSwap {
- if Memory.Usedpct != uint64(v.UsedPercent) || Memory.Shared != v.Shared/1024/1024 ||
- Memory.Swap != v.SwapTotal-v.SwapFree {
- Memory.Usedpct = uint64(v.UsedPercent)
- Memory.Shared = v.Shared / 1024 / 1024
- Memory.Swap = sw.Used
- c.UpdateReady <- true
+ if c.Mem.ShowSwap {
+ if c.Values.Memory.Usedpct != uint64(v.UsedPercent) || c.Values.Memory.Shared != v.Shared/1024/1024 || c.Values.Memory.Swap != v.SwapTotal-v.SwapFree {
+ c.Values.Memory.Usedpct = uint64(v.UsedPercent)
+ c.Values.Memory.Shared = v.Shared / 1024 / 1024
+ c.Values.Memory.Swap = sw.Used
+ c.Channels.UpdateReady <- true
}
} else {
- if Memory.Usedpct != uint64(v.UsedPercent) || Memory.Shared != v.Shared/1024/1024 {
- Memory.Usedpct = uint64(v.UsedPercent)
- Memory.Shared = v.Shared / 1024 / 1024
- c.UpdateReady <- true
+ if c.Values.Memory.Usedpct != uint64(v.UsedPercent) || c.Values.Memory.Shared != v.Shared/1024/1024 {
+ c.Values.Memory.Usedpct = uint64(v.UsedPercent)
+ c.Values.Memory.Shared = v.Shared / 1024 / 1024
+ c.Channels.UpdateReady <- true
}
}
diff --git a/internal/lib/pulseaudio.go b/internal/lib/pulseaudio.go
index 0f45be1..b289740 100644
--- a/internal/lib/pulseaudio.go
+++ b/internal/lib/pulseaudio.go
@@ -10,30 +10,25 @@ import (
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
// UpdateVolumeInfo updates info about current Sound Volume.
-func (c MyConfig) UpdateVolumeInfo() {
+func (c *MyConfig) UpdateVolumeInfo() {
var err error
- pa, err = p.NewClient()
+ c.Values.PA, err = p.NewClient()
// It can happen if no pulseaudio server running for current user.
// If no server running we have to run one.
if err != nil {
- if err := PaReinit(); err != nil {
+ if err := c.PaReinit(); err != nil {
log.Print(err)
return
}
}
- vol, err := pa.Volume()
+ vol, err := c.Values.PA.Volume()
if err != nil {
log.Printf("Unable get volume from pulseaudio server: %s", err)
@@ -41,7 +36,7 @@ func (c MyConfig) UpdateVolumeInfo() {
return
}
- SoundVolume = fmt.Sprintf(
+ c.Values.SoundVolume = fmt.Sprintf(
"%s",
c.SimpleVolumePa.Color,
c.SimpleVolumePa.Background,
@@ -50,7 +45,7 @@ func (c MyConfig) UpdateVolumeInfo() {
c.SimpleVolumePa.Symbol,
)
- SoundVolume += fmt.Sprintf(
+ c.Values.SoundVolume += fmt.Sprintf(
":%d%%",
c.SimpleVolumePa.Color,
c.SimpleVolumePa.Background,
@@ -59,11 +54,11 @@ func (c MyConfig) UpdateVolumeInfo() {
int64(vol*100),
)
- c.UpdateReady <- true
+ c.Channels.UpdateReady <- true
for {
// Subscribe to update notification channel, to get info that volume changed.
- pulseUpdate, err := pa.Updates()
+ pulseUpdate, err := c.Values.PA.Updates()
if err != nil {
log.Printf("Unable to subscribe to pulseaudio updates: %s", err)
@@ -73,7 +68,7 @@ func (c MyConfig) UpdateVolumeInfo() {
// Rake update events.
for range pulseUpdate {
- vol, err = pa.Volume()
+ vol, err = c.Values.PA.Volume()
if err != nil {
log.Printf("Unable get volume from pulseaudio server: %s", err)
@@ -81,7 +76,7 @@ func (c MyConfig) UpdateVolumeInfo() {
return
}
- SoundVolume = fmt.Sprintf(
+ c.Values.SoundVolume = fmt.Sprintf(
"%s",
c.SimpleVolumePa.Color,
c.SimpleVolumePa.Background,
@@ -90,7 +85,7 @@ func (c MyConfig) UpdateVolumeInfo() {
c.SimpleVolumePa.Symbol,
)
- SoundVolume += fmt.Sprintf(
+ c.Values.SoundVolume += fmt.Sprintf(
":%d%%",
c.SimpleVolumePa.Color,
c.SimpleVolumePa.Background,
@@ -99,10 +94,10 @@ func (c MyConfig) UpdateVolumeInfo() {
int64(vol*100),
)
- c.UpdateReady <- true
+ c.Channels.UpdateReady <- true
}
- if err := PaReinit(); err != nil {
+ if err := c.PaReinit(); err != nil {
log.Print(err)
return
@@ -110,11 +105,11 @@ func (c MyConfig) UpdateVolumeInfo() {
}
// This code is unreachable :(
- pa.Close() //nolint:govet
+ c.Values.PA.Close() //nolint:govet
}
// PaReinit re-inits pulseaudio and connection to it.
-func PaReinit() error {
+func (c *MyConfig) PaReinit() error {
var err error
// 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
// 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.
- if Conf.SimpleVolumePa.DontExitOnLogin {
+ if c.SimpleVolumePa.DontExitOnLogin {
// Do not exit on any kind of login/logout events.
cmd = exec.Command("pulseaudio", "--exit-idle-time=-1", "--start")
} else {
@@ -169,7 +164,7 @@ func PaReinit() error {
return fmt.Errorf("unable to initialize pulseaudio server instance: %w", err)
}
- pa, err = p.NewClient()
+ c.Values.PA, err = p.NewClient()
if err != nil {
return fmt.Errorf("unable to make client connection to pulseaudio: %w", err)
@@ -178,21 +173,21 @@ func PaReinit() error {
return err
}
-func (c MyConfig) SVPAHandler() {
- for e := range SVPAHandlerChan {
+func (c *MyConfig) SVPAHandler() {
+ for e := range c.Channels.SVPAHandlerChan {
if e.Button == 3 {
- RunChan <- Conf.SimpleVolumePa.RightClickCmd
+ c.Channels.RunChan <- c.SimpleVolumePa.RightClickCmd
continue
}
- vol, err := pa.Volume()
+ vol, err := c.Values.PA.Volume()
if err != nil {
- if err := PaReinit(); err != nil {
+ if err := c.PaReinit(); err != nil {
log.Printf("Unable to get pulseaudio volume: %s", err)
} else {
- vol, err = pa.Volume()
+ vol, err = c.Values.PA.Volume()
if err != nil {
log.Printf("Unable to get volume pulseaudio server behaves weirdly: %s", err)
@@ -201,25 +196,25 @@ func (c MyConfig) SVPAHandler() {
}
switch e.Button {
- case Conf.SimpleVolumePa.WheelUp:
- vol += float32(Conf.SimpleVolumePa.Step) / 100
+ case c.SimpleVolumePa.WheelUp:
+ vol += float32(c.SimpleVolumePa.Step) / 100
- if vol > (float32(Conf.SimpleVolumePa.MaxVolumeLimit) / 100) {
- vol = float32(Conf.SimpleVolumePa.MaxVolumeLimit) / 100
+ if vol > (float32(c.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)
}
- case Conf.SimpleVolumePa.WheelDown:
- vol -= float32(Conf.SimpleVolumePa.Step) / 100
+ case c.SimpleVolumePa.WheelDown:
+ vol -= float32(c.SimpleVolumePa.Step) / 100
if 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)
}
}
diff --git a/internal/lib/signal.go b/internal/lib/signal.go
index 857c890..0d787c1 100644
--- a/internal/lib/signal.go
+++ b/internal/lib/signal.go
@@ -9,20 +9,20 @@ import (
var PrintOutput = true
// SigHandler OS signal handler.
-func (c MyConfig) SigHandler() {
- for s := range c.SigChan {
+func (c *MyConfig) SigHandler() {
+ for s := range c.Channels.SigChan {
switch s {
case syscall.SIGUSR1:
log.Print("Got SIGUSR1, stopping output")
- PrintOutput = false
+ c.Values.PrintOutput = false
case syscall.SIGUSR2:
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:
os.Exit(0)
diff --git a/internal/lib/spawn.go b/internal/lib/spawn.go
index 0a9a136..89f5555 100644
--- a/internal/lib/spawn.go
+++ b/internal/lib/spawn.go
@@ -8,12 +8,9 @@ import (
"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.
-func (c MyConfig) Spawner() {
- for prg := range RunChan {
+func (c *MyConfig) Spawner() {
+ for prg := range c.Channels.RunChan {
devnullR, _ := os.Open(os.DevNull)
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.
-func (c MyConfig) CleanZombies() {
+func (c *MyConfig) CleanZombies() {
r := syscall.Rusage{}
for {
diff --git a/internal/lib/stdin.go b/internal/lib/stdin.go
index 401bf10..f6b69ec 100644
--- a/internal/lib/stdin.go
+++ b/internal/lib/stdin.go
@@ -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
// area names of i3bar.
-func (c MyConfig) ParseStdin() {
+func (c *MyConfig) ParseStdin() {
reader := bufio.NewReader(os.Stdin)
// 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.
if e.Name == "wallclock" {
- if Conf.Clock.LeftClick.Enabled && e.Button == 1 {
- RunChan <- Conf.Clock.LeftClick.Cmd
- } else if Conf.Clock.RightClick.Enabled && e.Button == 3 {
- RunChan <- Conf.Clock.RightClick.Cmd
+ if c.Clock.LeftClick.Enabled && e.Button == 1 {
+ c.Channels.RunChan <- c.Clock.LeftClick.Cmd
+ } else if c.Clock.RightClick.Enabled && e.Button == 3 {
+ c.Channels.RunChan <- c.Clock.RightClick.Cmd
}
continue
}
if e.Name == "simple-volume-pa" {
- if Conf.SimpleVolumePa.Enabled {
- SVPAHandlerChan <- e
+ if c.SimpleVolumePa.Enabled {
+ c.Channels.SVPAHandlerChan <- e
}
continue
}
- if !Conf.AppButtons.Enabled {
+ if !c.AppButtons.Enabled {
continue
}
- for _, app := range Conf.Apps {
+ for _, app := range c.Apps {
switch {
case app.Name != "" && app.Instance != "":
if app.Name == e.Name && app.Instance == e.Instance {
prg := append([]string{}, app.Cmd)
prg = append(prg, app.Args...)
- RunChan <- prg
+ c.Channels.RunChan <- prg
break
}
@@ -120,13 +120,13 @@ func (c MyConfig) ParseStdin() {
prg := append([]string{}, app.Cmd)
prg = append(prg, app.Args...)
- RunChan <- prg
+ c.Channels.RunChan <- prg
case app.Instance != "" && e.Instance == app.Instance:
prg := append([]string{}, app.Cmd)
prg = append(prg, app.Args...)
- RunChan <- prg
+ c.Channels.RunChan <- prg
}
}
}
diff --git a/internal/lib/vpn.go b/internal/lib/vpn.go
index fb55f3c..9e8add9 100644
--- a/internal/lib/vpn.go
+++ b/internal/lib/vpn.go
@@ -8,7 +8,7 @@ import (
)
// UpdateVPNStatus periodically update status of openvpn daemon.
-func (c MyConfig) UpdateVPNStatus() {
+func (c *MyConfig) UpdateVPNStatus() {
var (
vpnCStatus string
tcpCheck string
@@ -17,28 +17,28 @@ func (c MyConfig) UpdateVPNStatus() {
for {
if c.VPNFileCheck() {
- if Conf.Vpn.UpColor == "" {
+ if c.Vpn.UpColor == "" {
vpnCheck = `⍋`
} else {
vpnCheck = fmt.Sprintf(`⍋`, c.Vpn.UpColor)
}
} else {
- if Conf.Vpn.DownColor == "" {
+ if c.Vpn.DownColor == "" {
vpnCheck = `⍒`
} else {
vpnCheck = fmt.Sprintf(`⍒`, c.Vpn.DownColor)
}
}
- if Conf.Vpn.TCPCheck.Enabled {
+ if c.Vpn.TCPCheck.Enabled {
if c.VPNTCPCheck() {
- if Conf.Vpn.UpColor == "" {
+ if c.Vpn.UpColor == "" {
tcpCheck = `✔`
} else {
tcpCheck = fmt.Sprintf(`✔`, c.Vpn.UpColor)
}
} else {
- if Conf.Vpn.DownColor == "" {
+ if c.Vpn.DownColor == "" {
tcpCheck = `✘`
} else {
tcpCheck = fmt.Sprintf(`✘`, c.Vpn.DownColor)
@@ -50,9 +50,9 @@ func (c MyConfig) UpdateVPNStatus() {
vpnCStatus = fmt.Sprintf("VPN:%s", vpnCheck)
}
- if c.VPNStatus != vpnCStatus {
- c.VPNStatus = vpnCStatus
- c.UpdateReady <- true
+ if c.Values.VPNStatus != vpnCStatus {
+ c.Values.VPNStatus = vpnCStatus
+ c.Channels.UpdateReady <- true
}
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.
-func (c MyConfig) VPNTCPCheck() bool {
+func (c *MyConfig) VPNTCPCheck() bool {
conn, err := net.DialTimeout(
"tcp",
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.
-func (c MyConfig) VPNFileCheck() bool {
+func (c *MyConfig) VPNFileCheck() bool {
var (
fi os.FileInfo
err error