This commit is contained in:
eleksir
2026-03-31 01:32:28 +03:00
14 changed files with 1262 additions and 457 deletions

View File

@@ -1,3 +1,4 @@
// Package lib represents guts of i3status-go.
package lib
import (

View File

@@ -44,7 +44,7 @@ func (collection *Collection) Set(key any, value any) {
})
}
// Range apply function f to all keys/values in collection. Retuns immediatly on first error.
// Range apply function f to all keys/values in collection. Returns immediately on first error.
func (collection *Collection) Range(f func(key, value any) bool) {
fn := func(key, value any) bool {
it, ok := value.(item)

View File

@@ -14,264 +14,281 @@ import (
p "github.com/mafik/pulseaudio"
)
// I3BarOutBlock is structure element for I3BarOut, it represents i3bar output json block format.
type I3BarOutBlock struct {
FullText string `json:"full_text"`
// ShortText will be shown if not enough room for FullText, threshold width defined in MinWidth
ShortText string `json:"short_text,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Border string `json:"border,omitempty"`
BorderTop int `json:"border_top"`
BorderRight int `json:"border_right"`
BorderBottom int `json:"border_bottom"`
BorderLeft int `json:"border_left"`
// measured either in pixels or in characters, so either int or string, let's make it string :)
MinWidth string `json:"min_width,omitempty"`
Align string `json:"align,omitempty"`
Name string `json:"name,omitempty"`
Instance string `json:"instance,omitempty"`
Urgent bool `json:"urgent,omitempty"`
Separator bool `json:"separator"`
SeparatorBlockWidth int `json:"separator_block_width"`
Markup string `json:"markup,omitempty"`
}
type (
// I3BarOutBlock is structure element for I3BarOut, it represents i3bar output json block format.
I3BarOutBlock struct {
FullText string `json:"full_text"`
// ShortText will be shown if not enough room for FullText, threshold width defined in MinWidth.
ShortText string `json:"short_text,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Border string `json:"border,omitempty"`
BorderTop int `json:"border_top"`
BorderRight int `json:"border_right"`
BorderBottom int `json:"border_bottom"`
BorderLeft int `json:"border_left"`
// measured either in pixels or in characters, so either int or string, let's make it string :) .
MinWidth string `json:"min_width,omitempty"`
Align string `json:"align,omitempty"`
Name string `json:"name,omitempty"`
Instance string `json:"instance,omitempty"`
Urgent bool `json:"urgent,omitempty"`
Separator bool `json:"separator"`
SeparatorBlockWidth int `json:"separator_block_width"`
Markup string `json:"markup,omitempty"`
}
type Separator struct {
Left struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
// Separator usually is a bymbol that separates fields in i3 status string.
Separator struct {
Left struct {
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Symbol string `json:"symbol,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Enabled bool `json:"enabled,omitempty"`
} `json:"left"`
Right struct {
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Symbol string `json:"symbol,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Enabled bool `json:"enabled,omitempty"`
} `json:"right"`
}
// MyConfig internal represetation of running config state.
MyConfig struct {
Values struct {
PrintOutput bool
CPUTemperature int64
BatteryString string
ClockTime string
IfStatus string
VPNStatus string
Memory Mem
La string
PA *p.Client
SoundVolume string
RunCommandOutput string
}
Channels struct {
UpdateReady chan bool
MsgChan chan []I3BarOutBlock
SigChan chan os.Signal
SVPAHandlerChan chan ClickEvent
RunChan chan []string
}
// Color default text color.
Color string `json:"color,omitempty"`
// Background default background color.
Background string `json:"background,omitempty"`
Symbol string `json:"symbol,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
} `json:"left,omitempty"`
Right struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Symbol string `json:"symbol,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
} `json:"right,omitempty"`
}
// Font default text font.
Font string `json:"font,omitempty"`
type MyConfig struct {
Values struct {
PrintOutput bool
CPUTemperature int64
BatteryString string
ClockTime string
IfStatus string
VPNStatus string
Memory Mem
La string
PA *p.Client
SoundVolume string
RunCommandOutput string
// FontSize default text font size.
FontSize string `json:"font_size,omitempty"`
// Separator i3status string separator configuration.
Separator Separator `json:"separator"`
// LA Plugin.
LA struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Separator Separator `json:"separator,omitempty"`
} `json:"la"`
// Mem plugin.
Mem struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
ShowSwap bool `json:"show_swap,omitempty"`
Separator Separator `json:"separator,omitempty"`
} `json:"mem"`
// Clock plugin.
Clock struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Separator Separator `json:"separator,omitempty"`
LeftClick struct {
Enabled bool `json:"enabled,omitempty"`
Cmd []string `json:"cmd,omitempty"`
} `json:"left_click"`
RightClick struct {
Enabled bool `json:"enabled,omitempty"`
Cmd []string `json:"cmd,omitempty"`
} `json:"right_click"`
} `json:"clock"`
// Battery plugin.
Battery struct {
Enabled bool `json:"enabled,omitempty"`
UseSysfs bool `json:"use_sysfs,omitempty"`
SysfsFiles []string `json:"sysfs_files,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Symbol string `json:"symbol,omitempty"`
SymbolFont string `json:"symbol_font,omitempty"`
SymbolFontSize string `json:"symbol_font_size,omitempty"`
ChargeColor struct {
Full string `json:"full,omitempty"`
Empty string `json:"empty,omitempty"`
AlmostFull string `json:"almost_full,omitempty"`
AlmostEmpty string `json:"almost_empty,omitempty"`
} `json:"charge_color"`
Separator Separator `json:"separator,omitempty"`
} `json:"battery"`
// CPUTemp plugin.
CPUTemp struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Separator Separator `json:"separator,omitempty"`
File []string `json:"file,omitempty"`
} `json:"cpu_temp"`
// Vpn plugin.
Vpn struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
StatusFile string `json:"statusFile,omitempty"`
MtimeThreshold int `json:"mtime_threshold,omitempty"`
DownColor string `json:"down_color,omitempty"`
UpColor string `json:"up_color,omitempty"`
Separator Separator `json:"separator"`
TCPCheck struct {
Enabled bool `json:"enabled,omitempty"`
Host string `json:"host,omitempty"`
Port int `json:"port,omitempty"`
Timeout int `json:"timeout,omitempty"`
} `json:"tcp_check"`
} `json:"vpn"`
// SimpleVolumePa plugin.
SimpleVolumePa struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Symbol string `json:"symbol,omitempty"`
SymbolFont string `json:"symbol_font,omitempty"`
SymbolFontSize string `json:"symbol_font_size,omitempty"`
DontExitOnLogin bool `json:"dont_exit_on_login,omitempty"`
Separator Separator `json:"separator,omitempty"`
Step int `json:"step,omitempty"`
RightClickCmd []string `json:"right_click_cmd,omitempty"`
WheelUp int `json:"wheel_up,omitempty"`
WheelDown int `json:"wheel_down,omitempty"`
MaxVolumeLimit int `json:"max_volume_limit,omitempty"`
} `json:"simple-volume-pa"`
// NrtIf plugin.
NetIf struct {
Enabled bool `json:"enabled,omitempty"`
DownColor string `json:"down_color,omitempty"`
UpColor string `json:"up_color,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Separator Separator `json:"separator,omitempty"`
If []struct {
Name string `json:"name,omitempty"`
Dir string `json:"dir,omitempty"`
} `json:"if"`
} `json:"net-if"`
// Cron plugin.
Cron struct {
Enabled bool `json:"enabled,omitempty"`
TimeZone string `json:"timezone,omitempty"`
Tasks []struct {
Time string `json:"time,omitempty"`
Cmd []string `json:"cmd,omitempty"`
} `json:"tasks"`
} `json:"cron"`
// CmdRun plugin.
CmdRun struct {
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Cmd string `json:"cmd,omitempty"`
Args []string `json:"args,omitempty"`
Enabled bool `json:"enabled,omitempty"`
Delay int `json:"delay,omitempty"`
Separator Separator `json:"separator,omitempty"`
} `json:"cmdrun"`
// AppButtons plugin.
AppButtons struct {
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Enabled bool `json:"enabled,omitempty"`
Separator Separator `json:"separator,omitempty"`
} `json:"app_buttons"`
// Apps descriptions for AppButtons plugin.
Apps []struct {
FullText string `json:"full_text,omitempty"`
Name string `json:"name,omitempty"`
Cmd string `json:"cmd,omitempty"`
Args []string `json:"args,omitempty"`
Instance string `json:"instance,omitempty"`
Class string `json:"class,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Border string `json:"border,omitempty"`
BorderActive string `json:"border_active,omitempty"`
Separator bool `json:"separator,omitempty"`
SeparatorBlockWidth int `json:"separator_block_width,omitempty"`
} `json:"apps"`
}
)
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"`
// Default background color
Background string `json:"background,omitempty"`
// Default text font
Font string `json:"font,omitempty"`
// Default text font size
FontSize string `json:"font_size,omitempty"`
Separator Separator `json:"separator,omitempty"`
// LA Plugin
LA struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Separator Separator `json:"separator,omitempty"`
} `json:"la,omitempty"`
// Mem plugin
Mem struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
ShowSwap bool `json:"show_swap,omitempty"`
Separator Separator `json:"separator,omitempty"`
} `json:"mem,omitempty"`
Clock struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Separator Separator `json:"separator,omitempty"`
LeftClick struct {
Enabled bool `json:"enabled,omitempty"`
Cmd []string `json:"cmd,omitempty"`
} `json:"left_click,omitempty"`
RightClick struct {
Enabled bool `json:"enabled,omitempty"`
Cmd []string `json:"cmd,omitempty"`
} `json:"right_click,omitempty"`
} `json:"clock,omitempty"`
Battery struct {
Enabled bool `json:"enabled,omitempty"`
UseSysfs bool `json:"use_sysfs,omitempty"`
SysfsFiles []string `json:"sysfs_files,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Symbol string `json:"symbol,omitempty"`
SymbolFont string `json:"symbol_font,omitempty"`
SymbolFontSize string `json:"symbol_font_size,omitempty"`
ChargeColor struct {
Full string `json:"full,omitempty"`
Empty string `json:"empty,omitempty"`
AlmostFull string `json:"almost_full,omitempty"`
AlmostEmpty string `json:"almost_empty,omitempty"`
} `json:"charge_color,omitempty"`
Separator Separator `json:"separator,omitempty"`
} `json:"battery,omitempty"`
CPUTemp struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Separator Separator `json:"separator,omitempty"`
File []string `json:"file,omitempty"`
} `json:"cpu_temp,omitempty"`
Vpn struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
StatusFile string `json:"statusFile,omitempty"`
MtimeThreshold int `json:"mtime_threshold,omitempty"`
DownColor string `json:"down_color,omitempty"`
UpColor string `json:"up_color,omitempty"`
Separator Separator `json:"separator,omitempty"`
TCPCheck struct {
Enabled bool `json:"enabled,omitempty"`
Host string `json:"host,omitempty"`
Port int `json:"port,omitempty"`
Timeout int `json:"timeout,omitempty"`
} `json:"tcp_check,omitempty"`
} `json:"vpn,omitempty"`
SimpleVolumePa struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Symbol string `json:"symbol,omitempty"`
SymbolFont string `json:"symbol_font,omitempty"`
SymbolFontSize string `json:"symbol_font_size,omitempty"`
DontExitOnLogin bool `json:"dont_exit_on_login,omitempty"`
Separator Separator `json:"separator,omitempty"`
Step int `json:"step,omitempty"`
RightClickCmd []string `json:"right_click_cmd,omitempty"`
WheelUp int `json:"wheel_up,omitempty"`
WheelDown int `json:"wheel_down,omitempty"`
MaxVolumeLimit int `json:"max_volume_limit,omitempty"`
} `json:"simple-volume-pa,omitempty"`
NetIf struct {
Enabled bool `json:"enabled,omitempty"`
DownColor string `json:"down_color,omitempty"`
UpColor string `json:"up_color,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Separator Separator `json:"separator,omitempty"`
If []struct {
Name string `json:"name,omitempty"`
Dir string `json:"dir,omitempty"`
} `json:"if,omitempty"`
} `json:"net-if,omitempty"`
Cron struct {
Enabled bool `json:"enabled,omitempty"`
TimeZone string `json:"timezone,omitempty"`
Tasks []struct {
Time string `json:"time,omitempty"`
Cmd []string `json:"cmd,omitempty"`
} `json:"tasks,omitempty"`
} `json:"cron,omitempty"`
CmdRun struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Separator Separator `json:"separator,omitempty"`
Cmd string `json:"cmd,omitempty"`
Delay int `json:"delay,omitempty"`
Args []string `json:"args,omitempty"`
}
AppButtons struct {
Enabled bool `json:"enabled,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Separator Separator `json:"separator,omitempty"`
} `json:"app_buttons,omitempty"`
Apps []struct {
FullText string `json:"full_text,omitempty"`
Name string `json:"name,omitempty"`
Cmd string `json:"cmd,omitempty"`
Args []string `json:"args,omitempty"`
Instance string `json:"instance,omitempty"`
Class string `json:"class,omitempty"`
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"`
FontSize string `json:"font_size,omitempty"`
Border string `json:"border,omitempty"`
BorderActive string `json:"border_active,omitempty"`
Separator bool `json:"separator,omitempty"`
SeparatorBlockWidth int `json:"separator_block_width,omitempty"`
} `json:"apps,omitempty"`
}
// 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.
func ReadConf(defaultConfig []byte) (*MyConfig, error) {
var (
@@ -842,20 +859,20 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
}
}
// sampleConfig.Clock.LeftClick.Enabled will be false if not set in config
// sampleConfig.Clock.LeftClick.Enabled will be false if not set in config.
if len(sampleConfig.Clock.LeftClick.Cmd) == 0 {
sampleConfig.Clock.LeftClick.Cmd = append(sampleConfig.Clock.LeftClick.Cmd, "true")
}
// sampleConfig.Clock.RightClick.Enabled will be false if not set in config
// sampleConfig.Clock.RightClick.Enabled will be false if not set in config.
if len(sampleConfig.Clock.RightClick.Cmd) == 0 {
sampleConfig.Clock.RightClick.Cmd = append(sampleConfig.Clock.RightClick.Cmd, "true")
}
// sampleConfig.Battery.Enabled will be false if not set in config
// sampleConfig.Battery.UseSysfs will be false if not set in config
// sampleConfig.Battery.Enabled will be false if not set in config.
// sampleConfig.Battery.UseSysfs will be false if not set in config.
if len(sampleConfig.Battery.SysfsFiles) == 0 {
sampleConfig.Battery.SysfsFiles = append(
@@ -940,10 +957,10 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
}
}
// sampleConfig.Battery.ChargeColor.Full will be empty string if not set
// sampleConfig.Battery.ChargeColor.Empty will be empty string if not set
// sampleConfig.Battery.ChargeColor.AlmostFull will be empty string if not set
// sampleConfig.Battery.ChargeColor.AlmostEmpty will be empty string if not set
// sampleConfig.Battery.ChargeColor.Full will be empty string if not set.
// sampleConfig.Battery.ChargeColor.Empty will be empty string if not set.
// sampleConfig.Battery.ChargeColor.AlmostFull will be empty string if not set.
// sampleConfig.Battery.ChargeColor.AlmostEmpty will be empty string if not set.
if sampleConfig.Battery.Separator.Left.Color == "" {
sampleConfig.Battery.Separator.Left.Color = sampleConfig.Separator.Left.Color
}
@@ -1032,9 +1049,9 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
}
}
// sampleConfig.CpuTemp.Enabled will be false if not set in config
// sampleConfig.CpuTemp.Enabled will be false if not set in config.
// No files configured - disable plugin
// No files configured - disable plugin.
if len(sampleConfig.CPUTemp.File) == 0 {
sampleConfig.CPUTemp.Enabled = false
}
@@ -1167,9 +1184,9 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
}
}
// sampleConfig.Vpn.Enabled will false if not set in config
// sampleConfig.Vpn.Enabled will false if not set in config.
// No status file - disable plugin
// No status file - disable plugin.
if sampleConfig.Vpn.StatusFile == "" {
sampleConfig.Vpn.Enabled = false
}
@@ -1214,16 +1231,16 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
}
}
// Check status file at least once per 3 seconds
// Check status file at least once per 3 seconds.
if sampleConfig.Vpn.MtimeThreshold < 3 {
log.Printf("vpn.mtime_threshold not set, using 3")
sampleConfig.Vpn.MtimeThreshold = 3
}
// sampleConfig.Vpn.DownColor will be empty string if no value set in config
// sampleConfig.Vpn.UpColor will be empty string if no value set in config
// sampleConfig.Vpn.TcpCheck.Enabled will false if not set in config
// sampleConfig.Vpn.DownColor will be empty string if no value set in config.
// sampleConfig.Vpn.UpColor will be empty string if no value set in config.
// sampleConfig.Vpn.TcpCheck.Enabled will false if not set in config.
if sampleConfig.Vpn.Separator.Left.Enabled {
if sampleConfig.Vpn.Separator.Left.Color == "" {
@@ -1315,7 +1332,7 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
}
}
// Disable plugin if value inadequate
// Disable plugin if value inadequate.
if sampleConfig.Vpn.TCPCheck.Port > 65535 {
if sampleConfig.Vpn.TCPCheck.Enabled {
log.Printf("vpn.tcp_check.port > 65535, disabling vpn.tcp_check.enabled")
@@ -1324,7 +1341,7 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
sampleConfig.Vpn.TCPCheck.Enabled = false
}
// Disable plugin if value indaquate
// Disable plugin if value indaquate.
if sampleConfig.Vpn.TCPCheck.Host == "" {
if sampleConfig.Vpn.TCPCheck.Enabled {
log.Printf("vpn.tcp_check.host not set, disabling vpn.tcp_check.enabled")
@@ -1341,7 +1358,7 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
sampleConfig.Vpn.TCPCheck.Timeout = 3
}
// sampleConfig.SimpleVolumePa.Enabled will false if not set in config
// sampleConfig.SimpleVolumePa.Enabled will false if not set in config.
if sampleConfig.SimpleVolumePa.Color == "" {
sampleConfig.SimpleVolumePa.Color = sampleConfig.Color
}
@@ -1538,7 +1555,7 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
}
}
// sampleConfig.Cron.Enabled will false if not set in config
// sampleConfig.Cron.Enabled will false if not set in config.
if len(sampleConfig.Cron.Tasks) == 0 {
sampleConfig.Cron.Enabled = false
@@ -1548,7 +1565,7 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
sampleConfig.Cron.TimeZone = "GMT+0"
}
// sampleConfig.NetIf.Enabled will false if not set in config
// sampleConfig.NetIf.Enabled will false if not set in config.
if len(sampleConfig.NetIf.If) == 0 {
sampleConfig.NetIf.Enabled = false
@@ -1688,7 +1705,7 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
}
}
// sampleConfig.CmdRun.Enabled will false if not set in config
// sampleConfig.CmdRun.Enabled will false if not set in config.
if sampleConfig.CmdRun.Cmd == "" && sampleConfig.CmdRun.Enabled {
sampleConfig.CmdRun.Enabled = false
@@ -1698,7 +1715,7 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
)
}
// sampleConfig.CmdRun.Args can be empty
// sampleConfig.CmdRun.Args can be empty.
if sampleConfig.CmdRun.Color == "" {
sampleConfig.CmdRun.Color = sampleConfig.Color
@@ -1828,7 +1845,7 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
}
}
// sampleConfig.AppButtons.Enabled will false if not set in config
// sampleConfig.AppButtons.Enabled will false if not set in config.
if sampleConfig.AppButtons.Color == "" {
sampleConfig.AppButtons.Color = sampleConfig.Color
}
@@ -1963,29 +1980,29 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
// app.Instance can be missing.
// app.Class can be missing.
if app.Name == "" {
app.Name = fmt.Sprintf("app%d", num)
sampleConfig.Apps[num].Name = fmt.Sprintf("app%d", num)
}
// app.Args can be empty slice. In that case command will be run without aruments.
if app.Cmd == "" {
// If command omitted it will be just /usr/bin/true.
app.Cmd = "true"
sampleConfig.Apps[num].Cmd = "true"
}
if app.Color == "" {
app.Color = sampleConfig.AppButtons.Color
sampleConfig.Apps[num].Color = sampleConfig.AppButtons.Color
}
if app.Background == "" {
app.Background = sampleConfig.AppButtons.Background
sampleConfig.Apps[num].Background = sampleConfig.AppButtons.Background
}
if app.Font == "" {
app.Font = sampleConfig.AppButtons.Font
sampleConfig.Apps[num].Font = sampleConfig.AppButtons.Font
}
if app.FontSize == "" {
app.FontSize = sampleConfig.AppButtons.FontSize
sampleConfig.Apps[num].FontSize = sampleConfig.AppButtons.FontSize
} else {
matched, err := regexp.MatchString(
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
@@ -2000,7 +2017,7 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
sampleConfig.AppButtons.FontSize,
)
app.FontSize = sampleConfig.AppButtons.FontSize
sampleConfig.Apps[num].FontSize = sampleConfig.AppButtons.FontSize
}
if !matched {
@@ -2009,22 +2026,22 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
sampleConfig.AppButtons.FontSize,
)
app.FontSize = sampleConfig.AppButtons.FontSize
sampleConfig.Apps[num].FontSize = sampleConfig.AppButtons.FontSize
}
}
if app.Border == "" {
app.Border = sampleConfig.AppButtons.Color
sampleConfig.Apps[num].Border = sampleConfig.AppButtons.Color
}
if app.BorderActive == "" {
app.BorderActive = sampleConfig.AppButtons.Color
sampleConfig.Apps[num].BorderActive = sampleConfig.AppButtons.Color
}
// app.Separator can be omitted, in that case it is false
// app.SeparatorBlockWidth can be missing
// app.Separator can be omitted, in that case it is false.
// app.SeparatorBlockWidth can be missing.
if app.FullText == "" {
app.FullText = fmt.Sprintf(" %d ", num)
sampleConfig.Apps[num].FullText = fmt.Sprintf(" %d ", num)
}
}
}

View File

@@ -7,7 +7,9 @@ import (
)
// myCron contains cron handler.
var myCron gocron.Scheduler
var (
myCron gocron.Scheduler
)
// RunCron parses config part, related to cron tasks and kicks cron to run.
func (c MyConfig) RunCron() {

View File

@@ -108,7 +108,7 @@ func (c *MyConfig) I3EventParser(e *i3.WindowEvent) {
// interfaceToUint превращает данный интерфейс в Uint64.
// Если может, конечно :) .
func interfaceToUint64(iface interface{}) uint64 {
func interfaceToUint64(iface any) uint64 {
if iface == nil {
return 0
}

View File

@@ -113,12 +113,12 @@ func (c *MyConfig) PaReinit() error {
var err error
// If we out of updates, seems someone killed pulseaudio server. Restart it.
cmd := exec.Command("pulseaudio", "--check")
cmd := exec.Command("pulseaudio", "--check") //nolint: noctx
if err := cmd.Run(); err == nil {
log.Printf("pulseaudio already running, but seems not responding, try gracefully kill it")
cmd = exec.Command("pulseaudio", "--kill")
cmd = exec.Command("pulseaudio", "--kill") //nolint: noctx
if err := cmd.Run(); err != nil {
return fmt.Errorf("unable to kill pulseaudio: %w", err)
@@ -127,7 +127,7 @@ func (c *MyConfig) PaReinit() error {
cnt := 0
for {
cmd := exec.Command("pulseaudio", "--check")
cmd := exec.Command("pulseaudio", "--check") //nolint: noctx
// PA not running. Breakout of loop.
if err := cmd.Run(); err != nil {
@@ -154,10 +154,10 @@ func (c *MyConfig) PaReinit() error {
// audio.
if c.SimpleVolumePa.DontExitOnLogin {
// 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") //nolint: noctx
} else {
// Exit immediately on logout(?).
cmd = exec.Command("pulseaudio", "--exit-idle-time=0", "--start")
cmd = exec.Command("pulseaudio", "--exit-idle-time=0", "--start") //nolint: noctx
}
if err := cmd.Run(); err != nil {
@@ -173,6 +173,8 @@ func (c *MyConfig) PaReinit() error {
return err
}
// SVPAHandler simple volume pulse audio handler works with events sent to SVPAHandlerChan cahnnel. Left/right clicks,
// wheel turning events etc.
func (c *MyConfig) SVPAHandler() {
for e := range c.Channels.SVPAHandlerChan {
if e.Button == 3 {

View File

@@ -5,7 +5,7 @@ import (
"time"
)
// RunCommands gets list of commands runs them sequentally and conacatenates their output.
// RunCommand gets list of commands runs them sequentally and conacatenates their output.
func (c *MyConfig) RunCommand() {
var (
InitialDelay = 100 * time.Millisecond

View File

@@ -71,7 +71,7 @@ func (c *MyConfig) CleanZombies() {
}
}
// RunProcess runs given command and returns contens of command stdout. On error prints error on stderr and returns
// RunProcess runs given command and returns contents of command stdout. On error prints error on stderr and returns
// empty syting.
func RunProcess(command []string) string {
var (

View File

@@ -110,6 +110,7 @@ func (c *MyConfig) ParseStdin() {
break
}
case app.Name != "" && e.Name == app.Name:
prg := append([]string{}, app.Cmd)
prg = append(prg, app.Args...)

View File

@@ -4,6 +4,7 @@ import (
"fmt"
"net"
"os"
"strings"
"time"
)
@@ -11,8 +12,8 @@ import (
func (c *MyConfig) UpdateVPNStatus() {
var (
vpnCStatus string
tcpCheck string
vpnCheck string
b strings.Builder
InitialDelay = 100 * time.Millisecond
LoopIterationDelay = 3 * time.Second
Delay = InitialDelay
@@ -27,36 +28,47 @@ func (c *MyConfig) UpdateVPNStatus() {
if c.VPNFileCheck() {
if c.Vpn.UpColor == "" {
vpnCheck = `⍋`
b.WriteRune('⍋')
} else {
vpnCheck = fmt.Sprintf(`<span foreground="%s">⍋</span>`, c.Vpn.UpColor)
b.WriteString("<span foreground=\"")
b.WriteString(c.Vpn.UpColor)
b.WriteString("\">⍋</span>")
}
} else {
if c.Vpn.DownColor == "" {
vpnCheck = `⍒`
b.WriteRune('⍒')
} else {
vpnCheck = fmt.Sprintf(`<span foreground="%s">⍒</span>`, c.Vpn.DownColor)
b.WriteString("<span foreground=\"")
b.WriteString(c.Vpn.DownColor)
b.WriteString("\">⍒</span>")
}
}
vpnCheck = b.String()
b.Reset()
if c.Vpn.TCPCheck.Enabled {
if c.VPNTCPCheck() {
if c.Vpn.UpColor == "" {
tcpCheck = `✔`
b.WriteRune('✔')
} else {
tcpCheck = fmt.Sprintf(`<span foreground="%s">✔</span>`, c.Vpn.UpColor)
b.WriteString("<span foreground=\"")
b.WriteString(c.Vpn.UpColor)
b.WriteString("\">✔</span>")
}
} else {
if c.Vpn.DownColor == "" {
tcpCheck = `✘`
b.WriteRune('✘')
} else {
tcpCheck = fmt.Sprintf(`<span foreground="%s">✘</span>`, c.Vpn.DownColor)
b.WriteString("<span foreground=\"")
b.WriteString(c.Vpn.DownColor)
b.WriteString("\">✘</span>")
}
}
vpnCStatus = fmt.Sprintf("VPN:%s:%s", vpnCheck, tcpCheck)
vpnCStatus = "VPN:" + vpnCheck + ":" + b.String()
} else {
vpnCStatus = fmt.Sprintf("VPN:%s", vpnCheck)
vpnCStatus = "VPN:" + vpnCheck
}
if c.Values.VPNStatus != vpnCStatus {
@@ -66,9 +78,9 @@ 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 service not stoned.
func (c *MyConfig) VPNTCPCheck() bool {
conn, err := net.DialTimeout(
conn, err := net.DialTimeout( //nolint: noctx
"tcp",
fmt.Sprintf("%s:%d", c.Vpn.TCPCheck.Host, c.Vpn.TCPCheck.Port), //nolint: hostport
time.Second*time.Duration(c.Vpn.TCPCheck.Timeout),