10 Commits

Author SHA1 Message Date
eleksir
6047399fc7 Add examples of configs 2024-03-14 00:52:38 +03:00
eleksir
35ec64cbbc Update sample config 2024-03-14 00:52:38 +03:00
eleksir
bb797d75b4 More pulseaudio settings, fix formatting for indicator boxes
* Add setting that defines whether to exit pulseaudio daemon or not
* Fix styling of all indicators (use font settings instead of default box settings)
* Set defaults for battery, clock and volume indicators
2024-03-14 00:52:38 +03:00
eleksir
92bddadd9d Fix formatting issues for some indicator boxes, respect font setting for separators 2024-03-14 00:52:38 +03:00
eleksir
d47ce88c0d Use async handler instead of applying sound volume in stdin parser 2024-03-14 00:52:38 +03:00
eleksir
bf9893feba Print to i3bar asynchronously 2024-03-14 00:52:38 +03:00
eleksir
4919f74184 Try to gracefully quit pulseaudio daemon if it is not responding 2024-03-14 00:51:47 +03:00
eleksir
5770f9106e Explicitly set color and background attributes for all <span> tags 2024-01-16 21:59:04 +03:00
eleksir
95356ed547 Set block right separator size correctly, according config 2024-01-16 21:19:17 +03:00
eleksir
418216391b Set border width to 0 on all blocks except buttons 2024-01-16 20:51:55 +03:00
8 changed files with 1524 additions and 115 deletions

View File

@@ -57,17 +57,20 @@ func UpdateBatteryInfo() {
case ch > 85:
if Conf.Battery.ChargeColor.Full == "" {
chStr = fmt.Sprintf(
"<span font='%s' size='%s'>% 3d%%</span>",
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
Conf.Battery.Color,
Conf.Battery.Background,
Conf.Battery.Font,
Conf.Battery.FontSize,
Conf.Battery.ChargeColor.Full,
ch,
)
} else {
chStr = fmt.Sprintf(
`<span font='%s' size='%s' foreground='%s'>% 3d%%</span>`,
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
Conf.Battery.ChargeColor.Full,
Conf.Battery.Background,
Conf.Battery.Font,
Conf.Battery.FontSize,
Conf.Battery.ChargeColor.Full,
ch,
)
}
@@ -75,17 +78,20 @@ func UpdateBatteryInfo() {
case ch < 85 && ch > 40:
if Conf.Battery.ChargeColor.AlmostFull == "" {
chStr = fmt.Sprintf(
"<span font='%s' size='%s'>% 3d%%</span>",
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
Conf.Battery.Color,
Conf.Battery.Background,
Conf.Battery.Font,
Conf.Battery.FontSize,
Conf.Battery.ChargeColor.Full,
ch,
)
} else {
chStr = fmt.Sprintf(
`<span font='%s' size='%s' foreground='%s'>% 3d%%</span>`,
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
Conf.Battery.ChargeColor.AlmostFull,
Conf.Battery.Background,
Conf.Battery.Font,
Conf.Battery.FontSize,
Conf.Battery.ChargeColor.AlmostFull,
ch,
)
}
@@ -93,17 +99,20 @@ func UpdateBatteryInfo() {
case ch <= 40 && ch >= 10:
if Conf.Battery.ChargeColor.AlmostEmpty == "" {
chStr = fmt.Sprintf(
"<span font='%s' size='%s'>% 3d%%</span>",
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
Conf.Battery.Color,
Conf.Battery.Background,
Conf.Battery.Font,
Conf.Battery.FontSize,
Conf.Battery.ChargeColor.Full,
ch,
)
} else {
chStr = fmt.Sprintf(
`<span font='%s' size='%s' foreground='%s'>% 3d%%</span>`,
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
Conf.Battery.ChargeColor.AlmostEmpty,
Conf.Battery.Background,
Conf.Battery.Font,
Conf.Battery.FontSize,
Conf.Battery.ChargeColor.AlmostEmpty,
ch,
)
}
@@ -111,31 +120,40 @@ func UpdateBatteryInfo() {
case ch < 10:
if Conf.Battery.ChargeColor.Empty == "" {
chStr = fmt.Sprintf(
"<span font='%s' size='%s'>% 3d%%</span>",
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
Conf.Battery.Color,
Conf.Battery.Background,
Conf.Battery.Font,
Conf.Battery.FontSize,
Conf.Battery.ChargeColor.Full,
ch,
)
} else {
chStr = fmt.Sprintf(
`<span font='%s' size='%s' foreground='%s'>% 3d%%</span>`,
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
Conf.Battery.ChargeColor.Empty,
Conf.Battery.Background,
Conf.Battery.Font,
Conf.Battery.FontSize,
Conf.Battery.ChargeColor.Empty,
ch,
)
}
}
battsInfo += fmt.Sprintf(
"<span font='%s' size='%s'>%s</span><span font='%s' size='%s'>B%d </span>%s<span 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,
Conf.Battery.Background,
Conf.Battery.SymbolFont,
Conf.Battery.SymbolFontSize,
Conf.Battery.Symbol,
Conf.Battery.Color,
Conf.Battery.Background,
Conf.Battery.Font,
Conf.Battery.FontSize,
i,
chStr,
Conf.Battery.Color,
Conf.Battery.Background,
Conf.Battery.Font,
Conf.Battery.FontSize,
status,

View File

@@ -248,14 +248,15 @@ type MyConfig struct {
} `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"`
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 struct {
Left struct {
@@ -743,14 +744,14 @@ func readConf() (MyConfig, error) {
} else {
matched, err := regexp.MatchString(
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
sampleConfig.Clock.Separator.Right.FontSize,
sampleConfig.Mem.Separator.Right.FontSize,
)
if err != nil {
log.Printf(
"Unable to set sampleConfig.Mem.Separator.Right.FontSize: %s, fallback to %s",
err,
sampleConfig.Clock.Separator.Right.FontSize,
sampleConfig.Mem.Separator.Right.FontSize,
)
sampleConfig.Mem.Separator.Right.FontSize = sampleConfig.Separator.Right.FontSize

View File

@@ -0,0 +1,793 @@
{
// Memory stats
"mem" : {
"enabled": true,
// If omitted set to default color defined up here.
"color": "#ffffff",
// If omitted set to default background color defined up here.
"background": "#008099",
// If omitted set to default font defined up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined up here.
"font_size": "large",
// Do we show used swap megs?
"show_swap": false,
// Re-define separator parameters for net-if block here.
"separator" : {
"left": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#000000",
// If omitted set to default background color defined for separator up here.
"background": "#008099",
// If omitted set to default symbol defined for separator up here.
"symbol": " ",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "large"
},
"right": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#008099",
// If omitted set to default background color defined for separator up here.
"background": "#fae864",
// If omitted set to default symbol defined for separator up here.
"symbol": " ",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "large"
}
}
},
// Load Average
"la" : {
"enabled": true,
// If omitted set to default color defined up here.
"color": "#3e78fd",
// If omitted set to default background color defined up here.
"background": "#fae864",
// If omitted set to default font defined up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined up here.
"font_size": "x-large",
// Re-define separator parameters for net-if block here.
"separator" : {
"left": {
// Set to false if omitted.
"enabled": false,
// If omitted set to default color defined for separator up here.
"color": "#e00000",
// If omitted set to default background color defined for separator up here.
"background": "#e00000",
// If omitted set to default symbol defined for separator up here.
"symbol": "",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "large"
},
"right": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#fae864",
// If omitted set to default background color defined for separator up here.
"background": "#5bde52",
// If omitted set to default symbol defined for separator up here.
"symbol": " ",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "large"
}
}
},
"net-if" : {
"enabled" : false,
// If omitted set to default color defined up here.
"color": "#3e78fd",
// If omitted set to default background color defined up here.
"background": "#000000",
// If omitted set to default font defined up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined up here.
"font_size": "medium",
// Net interface down symbol color, in html notation.
"down_color" : "red",
// Net interface up symbol color, in html notation.
"up_color" : "green",
// Re-define separator parameters for net-if block here.
"separator": {
"left": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
},
"right": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "◀",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
}
},
"if" : [
{
// Name as it displayed on i3bar
"name" : "eth0",
// Directory containing net if status files
"dir" : "/sys/class/net/eth0"
}
]
},
// OpenVPN status. Note that directive status in openvpn.conf should point to state file and *update* its timestamp at
// least as frequent as mtime_threshold in seconds.
"vpn": {
"enabled": false,
// If omitted set to default color defined up here.
"color": "#3e78fd",
// If omitted set to default background color defined up here.
"background": "#000000",
// If omitted set to default font defined up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined up here.
"font_size": "medium",
// Status file location. Plugin will be disabled if this value omitted.
"statusfile" : "/tmp/openvpn-status.stat",
// mtime check period.
"mtime_threshold": 10,
// Vpn down symbol color, in html notation.
"down_color" : "red",
// Vpn up symbol color, in html notation.
"up_color" : "green",
// Re-define separator parameters for net-if block here.
"separator": {
"left": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "▶",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
},
"right": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "◀",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
}
},
// Also we can tcp-ping some service inside vpn network to ensure that connection is not stoned.
"tcp_check" : {
"enabled": false,
"host": "somehost.tld",
"port": 443,
"timeout" : 3
}
},
// Simple sound volume indicator
"simple-volume-pa": {
"enabled": false,
// If omitted set to default color defined up here.
"color": "#3e78fd",
// If omitted set to default background color defined up here.
"background": "#666666",
// If omitted set to default font defined up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined up here.
"font_size": "large",
"symbol": "🔊",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of the relative sizes
// ‘smaller’ or ‘larger’. If omitted set to value of simple-volume-pa.font_size by default.
"symbol_font_size": "large",
// If not defined - will be "true"
"right_click_cmd": ["pavucontrol"],
// Change volume step in %, if not configured it is 5
"step": 3,
// We'll change volume level with mouse wheel. Under X11 it is mapped to some buttons, typically 4 and 5 (z-axis).
// If omited, default value is 4
"wheel_up": 4,
// If omited, default value is 5
"wheel_down": 5,
// Maximum sound volume, can be over 100%, but sould not be :) Default value 100 if not set.
"max_volume_limit": 120,
// Re-define separator parameters for net-if block here.
"separator": {
"left": {
// Set to false if omitted.
"enabled": false,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "▶",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
},
"right": {
// Set to false if omitted.
"enabled": false,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "◀",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
}
}
},
// Just clock
"clock": {
"enabled" : true,
// If omitted set to default color defined up here.
"color": "#000000",
// If omitted set to default background color defined up here.
"background": "#5bde52",
// If omitted set to default font defined up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined up here.
"font_size": "large",
// Re-define separator parameters for net-if block here.
"separator": {
"left": {
// Set to false if omitted.
"enabled": false,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "▶",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
},
"right": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#5bde52",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": " ",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "large"
}
},
"left_click" : {
"enabled" : false,
// cmd is array of command itself and its arguments
"cmd" : [ "orage" ]
},
"right_click" : {
"enabled" : false,
"cmd" : [ "true" ]
}
},
// Battery, useful for laptops
"battery": {
"enabled": false,
// If omitted set to default color defined up here.
"color": "#3e78fd",
// If omitted set to default background color defined up here.
"background": "#000000",
// If omitted set to default font defined up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined up here.
"font_size": "medium",
// If omitted "⚡" (no quotes) is used.
"symbol": "⚡",
// If omitted battery.font is used.
"symbol_font" : "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of the relative sizes
// ‘smaller’ or ‘larger’. If omitted set to value of simple-volume-pa.font_size by default.
"symbol_font_size": "large",
"charge_color": {
// colors in html notation
"full": "green",
"empty": "red",
"almost_full": "yellow",
"almost_empty": "orange"
},
// Re-define separator parameters for net-if block here.
"separator": {
"left": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "▶",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
},
"right": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "◀",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
}
}
},
// CPU Temperature monitor, shows average value among given sources
"cpu_temp": {
"enabled": false,
// If omitted set to default color defined up here.
"color": "#3e78fd",
// If omitted set to default background color defined up here.
"background": "#000000",
// If omitted set to default font defined up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined up here.
"font_size": "medium",
// Re-define separator parameters for net-if block here.
"separator": {
"left": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "▶",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
},
"right": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "◀",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
}
},
// Files in sysfs that contains cpu temperatures
"file": [
"/sys/class/hwmon/hwmon4/temp2_input",
"/sys/class/hwmon/hwmon4/temp3_input",
"/sys/class/hwmon/hwmon4/temp4_input",
"/sys/class/hwmon/hwmon4/temp5_input",
"/sys/class/hwmon/hwmon4/temp6_input",
"/sys/class/hwmon/hwmon4/temp7_input"
]
},
// Intended mainly for use with desktop notifications
// Because it inherits all env vars from i3, it can intercat with dbus and other
// such user session services.
"cron" : {
"enabled" : false,
"tasks" : [
{
// Time in crontab notation
"time" : "55 23 * * *",
"cmd" : [
"notify-send", "Sleeping Time!", "Take a nap."
]
},
{
// time in crontab format
"time" : "55 12 * * 2,4",
// commands as it should be invoked in bash script
"cmd" : [
"notify-send", "Pizza time!", "M-m-m, tasty!"
]
}
]
},
// Whether to display Application Buttons.
"app_buttons": {
"enabled": true,
// Re-define separator parameters for net-if block here.
"separator": {
"left": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "-",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
},
"right": {
// Set to false if omitted.
"enabled": true,
// If omitted set to default color defined for separator up here.
"color": "#3e78fd",
// If omitted set to default background color defined for separator up here.
"background": "#000000",
// If omitted set to default symbol defined for separator up here.
"symbol": "◀",
// If omitted set to default font defined for separator up here.
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
"font_size": "medium"
}
},
},
// Buttons - application launch "buttons"
"apps": [
{
// Text dispalyed on button
"full_text" : "📂",
// Internal name, can be any string, but unique for each app button
"name" : "thunar",
// Command itself
"cmd" : "thunar",
// Array of command args, optional
"args": [ "." ],
// Regexp that match with Instance component of WM_CLASS(STRING) of xprop output
"instance": "^thunar$",
// Regexp that match with Class component of WM_CLASS(STRING) of xprop output
"class": "^Thunar$",
// text color in html notation
"color": "#ffa500",
// background color in html notation
"background" : "#000000",
// border color in html notation
"border": "#666666",
// border color if there is at least one window with given Instance and/or Class exist
"border_active": "#3e78fd",
// Vertical line between objects on bar - if omitted true value is assumed by i3bar, but we set it to false
// in that case. It is limitation of golang json parser.
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " ♬ ",
"name" : "deadbeef",
"cmd" : "deadbeef",
"instance" : "^deadbeef$",
"class" : "^Deadbeef$",
"color" : "#00aa33",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " Term ",
"name" : "xterm",
"cmd" : "xterm",
"instance" : "^xterm$",
"class" : "^XTerm$",
"color" : "#666666",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " Ff ",
"name" : "firefox",
"cmd" : "firefox",
"instance" : "^Navigator$",
"class" : "^Firefox$",
"color" : "#ffa500",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " C ",
"name" : "chrome",
"cmd" : "chrome",
"instance" : "^google-chrome$",
"class" : "^Google-chrome$",
"color" : "#ffa500",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " @ ",
"name" : "thunderbird",
"cmd" : "thunderbird",
"instance" : "^Mail$",
"class" : "^Thunderbird$",
"color" : "#006994",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " Tg ",
"name" : "telegram",
"cmd" : "Telegram",
"instance" : "^Telegram$",
"class" : "^TelegramDesktop$",
"color" : "#5a8850",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " T ",
"name" : "mousepad",
"cmd" : "mousepad",
"instance" : "^mousepad$",
"class" : "^Mousepad$",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
}
]
}

View File

@@ -0,0 +1,438 @@
{
// Default text and *block* border colors. If not set #3e78fd is used.
"color" : "#3e78fd",
// Default backbround color. If not set value of #edeceb is used.
"background" : "#000000",
"separator": {
"left": {
"enabled": false,
"color": "#3e78fd",
"background": "#000000",
"symbol": "|",
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’
"font_size": "medium"
},
"right": {
// False if value omitted
"enabled": false,
// Used #edeceb as default if value omitted
"color": "#3e78fd",
// If not set #3e78fd is used.
"background": "#000000",
// If omitted, used "|" (no quotes) as default
"symbol": "|",
"font": "Noto Sans",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
// ‘smaller’ or ‘larger’
"font_size": "medium"
}
},
// Memory stats
"mem" : {
"enabled": true,
"show_swap": false,
"separator" : {
"left": {
"enabled": true,
"symbol": " |"
}
"right": {
"enabled": true
}
}
},
// Load Average
"la" : {
"enabled": true,
"separator" : {
"right": {
"enabled": true,
}
}
},
"net-if" : {
"enabled" : false,
// In html notation
"down_color" : "red",
"up_color" : "green",
"separator" : {
"right": {
"enabled": true,
}
},
"if" : [
{
// Name as it displayed on i3bar
"name" : "eth0",
// Directory containing net if status files
"dir" : "/sys/class/net/eth0"
}
]
},
// OpenVPN status. Note that directive status in openvpn.conf should point to
// state file and *update* its timestamp at least as frequent as mtime_threshold in seconds
"vpn": {
"enabled": false,
"statusfile" : "/tmp/openvpn-status.stat",
"mtime_threshold": 10,
// Color in html notation
"down_color" : "red",
"up_color" : "green",
"separator" : {
"right": {
"enabled": true,
}
},
// Also we can tcp-ping some service inside vpn network to ensure that connection is not stoned
"tcp_check" : {
"enabled": false,
"host": "somehost.tld",
"port": 443,
"timeout" : 3
}
},
// Simple sound volume indicator
"simple-volume-pa": {
"enabled": true,
"symbol": "VOL",
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of the relative sizes
// ‘smaller’ or ‘larger’. If omitted set to medium by default.
"font_size": "medium",
// If not defined - will be "true"
"right_click_cmd": ["pavucontrol"],
// Change volume step in %, if not configured it is 5
"step": 3,
// We'll change volume level with mouse wheel. Under X11 it is mapped to some buttons, typically 4 and 5 (z-axis).
// If omited, default value is 4
"wheel_up": 4,
// If omited, default value is 5
"wheel_down": 5,
// Maximum sound volume, can be over 100%, but sould not be :) Default value 100 if not set.
"max_volume_limit": 120,
"separator" : {
"right": {
"enabled": true,
}
}
},
// Just clock
"clock": {
"enabled" : true,
// Text color in html (actually, pango) notation
"color" : "#666666",
"font_size": "large",
"separator" : {
"right": {
"enabled": false,
}
},
"left_click" : {
"enabled" : false,
// cmd is array of command itself and its arguments
"cmd" : [ "orage" ]
},
"right_click" : {
"enabled" : false,
"cmd" : [ "true" ]
}
},
// Battery, useful for laptops
"battery": {
"enabled": false,
"charge_color": {
// colors in html notation
"full": "green",
"empty": "red",
"almost_full": "yellow",
"almost_empty": "orange"
},
"separator" : {
"right": {
"enabled": true,
}
}
},
// CPU Temperature monitor, shows average value among given sources
"cpu_temp": {
"enabled": false,
"separator" : {
"right": {
"enabled": true,
}
},
// Files in sysfs that contains cpu temperatures
"file": [
"/sys/class/hwmon/hwmon4/temp2_input",
"/sys/class/hwmon/hwmon4/temp3_input",
"/sys/class/hwmon/hwmon4/temp4_input",
"/sys/class/hwmon/hwmon4/temp5_input",
"/sys/class/hwmon/hwmon4/temp6_input",
"/sys/class/hwmon/hwmon4/temp7_input"
]
},
// Intended mainly for use with desktop notifications
// Because it inherits all env vars from i3, it can intercat with dbus and other
// such user session services.
"cron" : {
"enabled" : false,
"tasks" : [
{
// Time in crontab notation
"time" : "55 23 * * *",
"cmd" : [
"notify-send", "Sleeping Time!", "Take a nap."
]
},
{
// time in crontab format
"time" : "55 12 * * 2,4",
// commands as it should be invoked in bash script
"cmd" : [
"notify-send", "Pizza time!", "M-m-m, tasty!"
]
}
]
},
// Weather to display Application Buttons
"app_buttons": {
"enabled": true,
},
// Buttons - application launch "buttons"
"apps": [
{
"full_text" : "📂",
"name" : "thunar",
"cmd" : "thunar",
"instance": "thunar",
"class": "Thunar",
"color": "#ffa500",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 9
},
{
"full_text" : " ♬ ",
"name" : "deadbeef",
"cmd" : "deadbeef",
"instance" : "deadbeef",
"class" : "Deadbeef",
"color" : "#00aa33",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " Term ",
"name" : "alacritty",
"cmd" : "alacritty",
"instance" : "Alacritty",
"class" : "Alacritty",
"color" : "#666666",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 9
},
{
"full_text" : " E ",
"name" : "edge",
"cmd" : "edge",
"instance" : "microsoft-edge",
"class" : "Microsoft-edge",
"color" : "#ffa500",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " Ff ",
"name" : "firefox",
"cmd" : "firefox",
"instance" : "Navigator",
"class" : "Firefox",
"color" : "#ff5f1f",
"border": "#666666",
"border_active": "#3e78fd",
"separator_block_width": 2
},
{
"full_text" : " V ",
"name" : "vivaldi",
"cmd" : "Vivaldi",
"instance" : "vivaldi-stable",
"class" : "Vivaldi-stable",
"color" : "#ffa500",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " C ",
"name" : "chrome",
"cmd" : "chrome",
"instance" : "google-chrome",
"class" : "Google-chrome",
"color" : "#ffa500",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 9
},
{
"full_text" : " @ ",
"name" : "thunderbird",
"cmd" : "thunderbird",
"instance" : "Mail",
"class" : "Thunderbird",
"color" : "#006994",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " Tg ",
"name" : "telegram",
"cmd" : "Telegram",
"instance" : "Telegram",
"class" : "TelegramDesktop",
"color" : "#5a8850",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " D ",
"name" : "discord",
"cmd" : "Discord",
"instance" : "discord",
"class" : "discord",
"color" : "#5a8850",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " H ",
"name" : "hexchat",
"cmd" : "hexchat",
"instance" : "hexchat",
"class" : "Hexchat",
"color" : "#5a8850",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : "Psi",
"name" : "psi-plus",
"cmd" : "psi-plus",
"instance" : "psi-plus",
"class" : "Psi-plus",
"color" : "#5a8850",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 9
},
{
"full_text" : " T ",
"name" : "mousepad",
"cmd" : "mousepad",
"instance" : "mousepad",
"class" : "Mousepad",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " VSC ",
"name" : "code",
"cmd" : "code",
"instance" : "code",
"class" : "Code",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " G ",
"name" : "goland",
"cmd" : "goland",
"instance" : "goland",
"class" : "Goland",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 2
},
{
"full_text" : " ▢ ",
"name" : "ToolBox",
"cmd" : "/home/eleksir/.local/share/JetBrains/Toolbox/bin/jetbrains-toolbox",
"instance" : "JetBrains Toolbox",
"class" : "jetbrains-toolbox",
"border": "#666666",
"border_active": "#3e78fd",
"separator": false,
"separator_block_width": 9
},
{
"full_text" : " 🔑 ",
"name" : "keepassxc",
"cmd" : "kee",
"instance" : "keepassxc",
"class" : "KeePassXC",
"color" : "#7ec850",
"border" : "#666666",
"border_active" : "#3e78fd"
}
]
}

View File

@@ -386,6 +386,14 @@
// Maximum sound volume, can be over 100%, but sould not be :) Default value 100 if not set.
"max_volume_limit": 120,
// PA has annoying feature - socket activation. Sound system must persist and be available to all users regardless
// of init or other things. They just fail to understand that. Or they fucked up pulseaudio just because they scary
// of security something of resposibility. Anyway this is grand disign flaw, but we still have to bear with it.
// This setting defines if pulseaudion 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 allow pa to exit and leave our session without
// audio.
"dont_exit_on_login": true,
// Re-define separator parameters for net-if block here.
"separator": {
"left": {

164
main.go
View File

@@ -19,10 +19,10 @@ type I3BarOutBlock struct {
Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"`
Border string `json:"border,omitempty"`
BorderTop int `json:"border_top,omitempty"`
BorderRight int `json:"border_right,omitempty"`
BorderBottom int `json:"border_bottom,omitempty"`
BorderLeft int `json:"border_left,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"`
@@ -36,6 +36,7 @@ type I3BarOutBlock struct {
// UpdateReady channel that "refreshes" i3bar (generates stdout json line).
var UpdateReady = make(chan bool)
var MsgChan = make(chan []I3BarOutBlock, 64)
//go:embed i3status-go-example.json
var EmbeddedDefaultConfig embed.FS
@@ -51,6 +52,48 @@ func main() {
Conf, err = readConf()
// TODO: Проставить дефолтные значения для глобальных переменных модулей.
Batt = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Battery.Color,
Conf.Battery.Background,
Conf.Battery.SymbolFont,
Conf.Battery.SymbolFontSize,
Conf.Battery.Symbol,
)
Batt += fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'> ??%% •</span>",
Conf.Battery.Color,
Conf.Battery.Background,
Conf.Battery.Font,
Conf.Battery.FontSize,
)
SoundVolume = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>🔊</span>",
Conf.SimpleVolumePa.Color,
Conf.SimpleVolumePa.Background,
Conf.SimpleVolumePa.SymbolFont,
Conf.SimpleVolumePa.SymbolFontSize,
)
SoundVolume += fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>:0%%</span>",
Conf.SimpleVolumePa.Color,
Conf.SimpleVolumePa.Background,
Conf.SimpleVolumePa.Font,
Conf.SimpleVolumePa.FontSize,
)
Clock = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>Thu, 1 Jan 1970 1:00</span>",
Conf.Clock.Color,
Conf.Clock.Background,
Conf.Clock.Font,
Conf.Clock.FontSize,
)
if err != nil {
log.Panicln(err)
}
@@ -58,6 +101,8 @@ func main() {
go Spawner()
go ParseStdin()
go CleanZombies()
go SVPAHandler()
go PrintToI3bar()
if Conf.AppButtons.Enabled {
go UpdateI3WinList()
@@ -138,9 +183,10 @@ func main() {
if num == 0 {
b.FullText = fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.AppButtons.Separator.Left.Color,
Conf.AppButtons.Separator.Left.Background,
Conf.AppButtons.Separator.Left.Font,
Conf.AppButtons.Separator.Left.FontSize,
Conf.AppButtons.Separator.Left.Symbol,
)
@@ -150,9 +196,10 @@ func main() {
if num == len(Conf.Apps) {
b.FullText = fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.AppButtons.Separator.Right.Color,
Conf.AppButtons.Separator.Right.Background,
Conf.AppButtons.Separator.Right.Font,
Conf.AppButtons.Separator.Right.FontSize,
Conf.AppButtons.Separator.Right.Symbol,
)
@@ -172,6 +219,11 @@ func main() {
b.Border = app.Border
}
b.BorderTop = 1
b.BorderRight = 1
b.BorderBottom = 1
b.BorderLeft = 1
j = append(j, b)
}
}
@@ -184,16 +236,19 @@ func main() {
if Conf.CPUTemp.Separator.Left.Enabled {
b.FullText = fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.CPUTemp.Separator.Left.Color,
Conf.CPUTemp.Separator.Left.Background,
Conf.CPUTemp.Separator.Left.Font,
Conf.CPUTemp.Separator.Left.FontSize,
Conf.CPUTemp.Separator.Left.Symbol,
)
}
b.FullText += fmt.Sprintf(
"<span font='%s' size='%s'>CPU: %d°</span>",
"<span color='%s' background='%s' font='%s' size='%s'>CPU: %d°</span>",
Conf.CPUTemp.Color,
Conf.CPUTemp.Background,
Conf.CPUTemp.Font,
Conf.CPUTemp.FontSize,
CPUTemperature,
@@ -201,9 +256,10 @@ func main() {
if Conf.CPUTemp.Separator.Right.Enabled {
b.FullText += fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.CPUTemp.Separator.Right.Color,
Conf.CPUTemp.Separator.Right.Background,
Conf.CPUTemp.Separator.Right.Font,
Conf.CPUTemp.Separator.Right.FontSize,
Conf.CPUTemp.Separator.Right.Symbol,
)
@@ -223,9 +279,10 @@ func main() {
if Conf.Mem.Separator.Left.Enabled {
b.FullText = fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Mem.Separator.Left.Color,
Conf.Mem.Separator.Left.Background,
Conf.Mem.Separator.Left.Font,
Conf.Mem.Separator.Left.FontSize,
Conf.Mem.Separator.Left.Symbol,
)
@@ -233,7 +290,9 @@ func main() {
if Conf.Mem.ShowSwap {
b.FullText += fmt.Sprintf(
"<span font='%s' size='%s'>M:%d%% SHM:%dM SW:%dM</span>",
"<span color='%s' background='%s' font='%s' size='%s'>M:%d%% SHM:%dM SW:%dM</span>",
Conf.Mem.Color,
Conf.Mem.Background,
Conf.Mem.Font,
Conf.Mem.FontSize,
Memory.Usedpct,
@@ -242,7 +301,9 @@ func main() {
)
} else {
b.FullText += fmt.Sprintf(
"<span font='%s' size='%s'>M:%d%% SHM:%dM</span>",
"<span color='%s' background='%s' font='%s' size='%s'>M:%d%% SHM:%dM</span>",
Conf.Mem.Color,
Conf.Mem.Background,
Conf.Mem.Font,
Conf.Mem.FontSize,
Memory.Usedpct,
@@ -252,9 +313,10 @@ func main() {
if Conf.Mem.Separator.Right.Enabled {
b.FullText += fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Mem.Separator.Right.Color,
Conf.Mem.Separator.Right.Background,
Conf.Mem.Separator.Right.Font,
Conf.Mem.Separator.Right.FontSize,
Conf.Mem.Separator.Right.Symbol,
)
@@ -274,16 +336,19 @@ func main() {
if Conf.LA.Separator.Left.Enabled {
b.FullText = fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.LA.Separator.Left.Color,
Conf.LA.Separator.Left.Background,
Conf.LA.Separator.Left.Font,
Conf.LA.Separator.Left.FontSize,
Conf.LA.Separator.Left.Symbol,
)
}
b.FullText += fmt.Sprintf(
"<span font='%s' size='%s'>LA:%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>LA:%s</span>",
Conf.LA.Color,
Conf.LA.Background,
Conf.LA.Font,
Conf.LA.FontSize,
La,
@@ -291,9 +356,10 @@ func main() {
if Conf.LA.Separator.Right.Enabled {
b.FullText += fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.LA.Separator.Right.Color,
Conf.LA.Separator.Right.Background,
Conf.LA.Separator.Right.Font,
Conf.LA.Separator.Right.FontSize,
Conf.LA.Separator.Right.Symbol,
)
@@ -313,16 +379,19 @@ func main() {
if Conf.NetIf.Separator.Left.Enabled {
b.FullText = fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.NetIf.Separator.Left.Color,
Conf.NetIf.Separator.Left.Background,
Conf.NetIf.Separator.Left.Font,
Conf.NetIf.Separator.Left.FontSize,
Conf.NetIf.Separator.Left.Symbol,
)
}
b.FullText += fmt.Sprintf(
"<span font='%s' size= '%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size= '%s'>%s</span>",
Conf.NetIf.Color,
Conf.NetIf.Background,
Conf.NetIf.Font,
Conf.NetIf.FontSize,
IfStatus,
@@ -330,9 +399,10 @@ func main() {
if Conf.NetIf.Separator.Right.Enabled {
b.FullText += fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.NetIf.Separator.Right.Color,
Conf.NetIf.Separator.Right.Background,
Conf.NetIf.Separator.Right.Font,
Conf.NetIf.Separator.Right.FontSize,
Conf.NetIf.Separator.Right.Symbol,
)
@@ -352,16 +422,19 @@ func main() {
if Conf.Vpn.Separator.Left.Enabled {
b.FullText = fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Vpn.Separator.Left.Color,
Conf.Vpn.Separator.Left.Background,
Conf.Vpn.Separator.Left.Font,
Conf.Vpn.Separator.Left.FontSize,
Conf.Vpn.Separator.Left.Symbol,
)
}
b.FullText += fmt.Sprintf(
"<span font='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Vpn.Color,
Conf.Vpn.Background,
Conf.Vpn.Font,
Conf.Vpn.FontSize,
VPNStatus,
@@ -369,9 +442,10 @@ func main() {
if Conf.Vpn.Separator.Right.Enabled {
b.FullText += fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Vpn.Separator.Right.Color,
Conf.Vpn.Separator.Right.Background,
Conf.Vpn.Separator.Right.Font,
Conf.Vpn.Separator.Right.FontSize,
Conf.Vpn.Separator.Right.Symbol,
)
@@ -391,9 +465,10 @@ func main() {
if Conf.Battery.Separator.Left.Enabled {
b.FullText = fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Battery.Separator.Left.Color,
Conf.Battery.Separator.Left.Background,
Conf.Battery.Separator.Left.Font,
Conf.Battery.Separator.Left.FontSize,
Conf.Battery.Separator.Left.Symbol,
)
@@ -403,9 +478,10 @@ func main() {
if Conf.Battery.Separator.Right.Enabled {
b.FullText += fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Battery.Separator.Right.Color,
Conf.Battery.Separator.Right.Background,
Conf.Battery.Separator.Right.Font,
Conf.Battery.Separator.Right.FontSize,
Conf.Battery.Separator.Right.Symbol,
)
@@ -426,9 +502,10 @@ func main() {
if Conf.SimpleVolumePa.Separator.Left.Enabled {
b.FullText = fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.SimpleVolumePa.Separator.Left.Color,
Conf.SimpleVolumePa.Separator.Left.Background,
Conf.SimpleVolumePa.Separator.Left.Font,
Conf.SimpleVolumePa.Separator.Left.FontSize,
Conf.SimpleVolumePa.Separator.Left.Symbol,
)
@@ -439,9 +516,10 @@ func main() {
if Conf.SimpleVolumePa.Separator.Right.Enabled {
b.FullText += fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.SimpleVolumePa.Separator.Right.Color,
Conf.SimpleVolumePa.Separator.Right.Background,
Conf.SimpleVolumePa.Separator.Right.Font,
Conf.SimpleVolumePa.Separator.Right.FontSize,
Conf.SimpleVolumePa.Separator.Right.Symbol,
)
@@ -462,16 +540,19 @@ func main() {
if Conf.Clock.Separator.Left.Enabled {
b.FullText = fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Clock.Separator.Left.Color,
Conf.Clock.Separator.Left.Background,
Conf.Clock.Separator.Left.Font,
Conf.Clock.Separator.Left.FontSize,
Conf.Clock.Separator.Left.Symbol,
)
}
b.FullText += fmt.Sprintf(
"<span font='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Clock.Color,
Conf.Clock.Background,
Conf.Clock.Font,
Conf.Clock.FontSize,
Clock,
@@ -479,9 +560,10 @@ func main() {
if Conf.Clock.Separator.Right.Enabled {
b.FullText += fmt.Sprintf(
"<span color='%s' background='%s' size='%s'>%s</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Clock.Separator.Right.Color,
Conf.Clock.Separator.Right.Background,
Conf.Clock.Separator.Right.Font,
Conf.Clock.Separator.Right.FontSize,
Conf.Clock.Separator.Right.Symbol,
)
@@ -494,23 +576,25 @@ func main() {
}
if PrintOutput && len(j) > 0 {
PrintToI3bar(j)
MsgChan <- j
}
}
}
}
// PrintToI3bar prints info to stdout according to ipc docs (https://i3wm.org/docs/i3bar-protocol.html)
func PrintToI3bar(message []I3BarOutBlock) {
// 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)
encoder.SetEscapeHTML(false)
err := encoder.Encode(message)
func PrintToI3bar() {
for message := range 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)
encoder.SetEscapeHTML(false)
err := encoder.Encode(message)
if err != nil {
log.Printf("Unable to json-encode message, %s\n", err)
if err != nil {
log.Printf("Unable to json-encode message, %s\n", err)
}
fmt.Println(strings.TrimSuffix(buf.String(), "\n") + ",")
}
fmt.Println(strings.TrimSuffix(buf.String(), "\n") + ",")
}

View File

@@ -1,9 +1,11 @@
package main
import (
"errors"
"fmt"
"log"
"os/exec"
"time"
p "github.com/mafik/pulseaudio"
)
@@ -11,6 +13,10 @@ import (
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 UpdateVolumeInfo() {
var err error
@@ -36,10 +42,18 @@ func UpdateVolumeInfo() {
}
SoundVolume = fmt.Sprintf(
"<span font='%s' size='%s'>%s</span><span font='%s' size='%s'>:%d%%</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.SimpleVolumePa.Color,
Conf.SimpleVolumePa.Background,
Conf.SimpleVolumePa.SymbolFont,
Conf.SimpleVolumePa.SymbolFontSize,
Conf.SimpleVolumePa.Symbol,
)
SoundVolume += fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>:%d%%</span>",
Conf.SimpleVolumePa.Color,
Conf.SimpleVolumePa.Background,
Conf.SimpleVolumePa.Font,
Conf.SimpleVolumePa.FontSize,
int64(vol*100),
@@ -57,7 +71,7 @@ func UpdateVolumeInfo() {
return
}
// Rake update events
// Rake update events.
for range pulseUpdate {
vol, err = pa.Volume()
@@ -68,10 +82,18 @@ func UpdateVolumeInfo() {
}
SoundVolume = fmt.Sprintf(
"<span font='%s' size='%s'>%s</span><span font='%s' size='%s'>:%d%%</span>",
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.SimpleVolumePa.Color,
Conf.SimpleVolumePa.Background,
Conf.SimpleVolumePa.SymbolFont,
Conf.SimpleVolumePa.SymbolFontSize,
Conf.SimpleVolumePa.Symbol,
)
SoundVolume += fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>:%d%%</span>",
Conf.SimpleVolumePa.Color,
Conf.SimpleVolumePa.Background,
Conf.SimpleVolumePa.Font,
Conf.SimpleVolumePa.FontSize,
int64(vol*100),
@@ -99,10 +121,49 @@ func PaReinit() error {
cmd := exec.Command("pulseaudio", "--check")
if err := cmd.Run(); err == nil {
return fmt.Errorf("pulseaudio is already running, but we have troubles contacting it: %w", err)
log.Printf("pulseaudio already running, but seems not responding, try gracefully kill it")
cmd = exec.Command("pulseaudio", "--kill")
if err := cmd.Run(); err != nil {
return fmt.Errorf("unable to kill pulseaudio: %w", err)
}
cnt := 0
for {
cmd := exec.Command("pulseaudio", "--check")
// PA not running. Breakout of loop.
if err := cmd.Run(); err != nil {
break
}
if cnt >= 5 {
return errors.New("timeout waiting pulseaudio to exit") //nolint: goerr113
}
log.Print("Waiting for pulseaudio to exit")
cnt++
time.Sleep(300 * time.Millisecond)
}
}
cmd = exec.Command("pulseaudio", "--start")
// PA has annoying feature: socket activation. Sound system must be persistent and available to all users regardless
// of init or other things. They just fail to understand that. Or they fucked up pulseaudio just because they scary
// of security something responsibility. Anyway this is grand design flaw, but we still have to bear with it.
// 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 {
// Do not exit on any kind of login/logout events.
cmd = exec.Command("pulseaudio", "--exit-idle-time=-1", "--start")
} else {
// Exit immediately on logout(?).
cmd = exec.Command("pulseaudio", "--exit-idle-time=0", "--start")
}
if err := cmd.Run(); err != nil {
return fmt.Errorf("unable to initialize pulseaudio server instance: %w", err)
@@ -116,3 +177,51 @@ func PaReinit() error {
return err
}
func SVPAHandler() {
for e := range SVPAHandlerChan {
if e.Button == 3 {
RunChan <- Conf.SimpleVolumePa.RightClickCmd
continue
}
vol, err := pa.Volume()
if err != nil {
if err := PaReinit(); err != nil {
log.Printf("Unable to get pulseaudio volume: %s", err)
} else {
vol, err = pa.Volume()
if err != nil {
log.Printf("Unable to get volume pulseaudio server behaves weirdly: %s", err)
}
}
}
switch e.Button {
case Conf.SimpleVolumePa.WheelUp:
vol += float32(Conf.SimpleVolumePa.Step) / 100
if vol > (float32(Conf.SimpleVolumePa.MaxVolumeLimit) / 100) {
vol = float32(Conf.SimpleVolumePa.MaxVolumeLimit) / 100
}
if err := pa.SetVolume(vol); err != nil {
log.Printf("Unable to set pulseaudio volume: %s", err)
}
case Conf.SimpleVolumePa.WheelDown:
vol -= float32(Conf.SimpleVolumePa.Step) / 100
if vol < 0 {
vol = 0
}
if err := pa.SetVolume(vol); err != nil {
log.Printf("Unable to set pulseaudio volume: %s", err)
}
}
}
}

View File

@@ -95,49 +95,7 @@ func ParseStdin() {
if e.Name == "simple-volume-pa" {
if Conf.SimpleVolumePa.Enabled {
if e.Button == 3 {
RunChan <- Conf.SimpleVolumePa.RightClickCmd
continue
}
vol, err := pa.Volume()
if err != nil {
if err := PaReinit(); err != nil {
log.Printf("Unable to get pulseaudio volume: %s", err)
} else {
vol, err = pa.Volume()
if err != nil {
log.Printf("Unable to get volume pulseaudio server behaves weirdly: %s", err)
}
}
}
switch e.Button {
case Conf.SimpleVolumePa.WheelUp:
vol += float32(Conf.SimpleVolumePa.Step) / 100
if vol > (float32(Conf.SimpleVolumePa.MaxVolumeLimit) / 100) {
vol = float32(Conf.SimpleVolumePa.MaxVolumeLimit) / 100
}
if err := pa.SetVolume(vol); err != nil {
log.Printf("Unable to set pulseaudio volume: %s", err)
}
case Conf.SimpleVolumePa.WheelDown:
vol -= float32(Conf.SimpleVolumePa.Step) / 100
if vol < 0 {
vol = 0
}
if err := pa.SetVolume(vol); err != nil {
log.Printf("Unable to set pulseaudio volume: %s", err)
}
}
SVPAHandlerChan <- e
}
continue