Better comments, prevent duplicate waybars

Generate a single config file. Multiple processes seems to have run into
a bug where waybar will restore killed bars.
This commit is contained in:
John Mertz 2020-11-15 23:47:18 -05:00
parent 7f41003cdc
commit dd6a04088f
1 changed files with 83 additions and 48 deletions

View File

@ -1,5 +1,16 @@
#!/usr/bin/perl #!/usr/bin/perl
########################################################################
# Usage
########################################################################
#
# $ displays.pl [layout] [-w]
#
# layout Name of desired layout, as configured starting at line 100
# If missing, last known layout is used (logged to file $last)
# -w (Re)load waybar only. Skip display configuration. Only kill
# existing waybars and start new ones for desired layout
######################################################################## ########################################################################
# Dependencies # Dependencies
######################################################################## ########################################################################
@ -17,11 +28,14 @@
# "output": __OUTPUT__ # "output": __OUTPUT__
# "position": __POSITION__ # "position": __POSITION__
# "width": __WIDTH__ (optional) # "width": __WIDTH__ (optional)
my $waybar_template = '/home/jpm/.config/waybar/config.template'; my $waybar_template = "$ENV{'HOME'}/.config/waybar/config.template";
# Temporary directory to save generated waybar config(s) # Temporary directory to save generated waybar config(s)
my $waybar_temporary = '/tmp'; my $waybar_temporary = '/tmp';
# File to log and recover last used layout name
my $last = "$ENV{'HOME'}/.config/last_display";
######################################################################## ########################################################################
# Display Serials and Names # Display Serials and Names
######################################################################## ########################################################################
@ -138,8 +152,6 @@ my %configs = (
use strict; use strict;
use warnings; use warnings;
# Bail if zero or >1 args
my $last = "/home/jpm/.config/last_display";
my $waybar_only = 0; my $waybar_only = 0;
my $config; my $config;
@ -157,12 +169,12 @@ if (scalar(@ARGV)) {
} }
} }
# Get previous config if one is not provided
unless (defined $config) { unless (defined $config) {
open(my $fh, '<', $last); open(my $fh, '<', $last) || die "Config name not provided and failed to open $last\n";
$config = <$fh>; $config = <$fh>;
close($fh); close($fh);
chomp $config; chomp $config;
print "$config\n";
} }
# Bail if requested config doesn't exist # Bail if requested config doesn't exist
@ -170,11 +182,14 @@ unless (defined $configs{$config}) {
die "$config is not a defined configuration: " . join(', ', keys %configs) . "\n"; die "$config is not a defined configuration: " . join(', ', keys %configs) . "\n";
} }
# Import and setup JSON object # Write config that is to be used so that it can be recovered as default
use JSON::XS; open(my $fh, '>', $last) || print STDERR "Config name cannot be written to $last\n";
my $json = JSON::XS->new(); print $fh $config;
close($fh);
# Fetch connected displays # Fetch connected displays
use JSON::XS;
my $json = JSON::XS->new();
my $displays_raw = `swaymsg -t get_outputs --raw`; my $displays_raw = `swaymsg -t get_outputs --raw`;
my $displays = $json->decode($displays_raw); my $displays = $json->decode($displays_raw);
@ -182,7 +197,6 @@ my $displays = $json->decode($displays_raw);
# displays and a list of displays to disable # displays and a list of displays to disable
my $on; my $on;
my @off; my @off;
for (my $i = 0; $i < scalar(@$displays); $i++) { for (my $i = 0; $i < scalar(@$displays); $i++) {
# If a display is found without any settings, print error and turn it off # If a display is found without any settings, print error and turn it off
@ -203,8 +217,9 @@ for (my $i = 0; $i < scalar(@$displays); $i++) {
} }
# Skip enabling/disabling displays if only running waybar (re)start
unless ($waybar_only) { unless ($waybar_only) {
# Number of simultaneous outputs is limited by possible, so disabled displays first # Number of simultaneous outputs is limited by gpu, so disabled displays first
foreach (@off) { foreach (@off) {
# Sway returns status as JSON # Sway returns status as JSON
@ -226,14 +241,35 @@ foreach my $p ( @{ $t->table } ) {
my $cmndline = $p->{'cmndline'}; my $cmndline = $p->{'cmndline'};
$cmndline =~ s/\s*$//g; $cmndline =~ s/\s*$//g;
if ($cmndline =~ /^waybar.*/) { if ($cmndline =~ /^waybar.*/) {
# Never kill this process
if ($p->{'pid'} == $$) { if ($p->{'pid'} == $$) {
next; next;
# SIGKILL match
# TODO BUG: when multiple processes are running, some respawn with new PIDs. IDK why?
} else { } else {
$p->kill(9); $p->kill(9);
} }
} }
} }
# Load in config template
my $template;
if (open (my $fh, '<', $waybar_template)) {
while (<$fh>) {
$template .= $_;
}
close $fh;
chomp $template;
} else {
print STDERR "Failed to load template $waybar_template\n";
}
# If template is already set up as an array, remove the square brackets so that we can concatenate multiple displays
$template =~ s/^[^\[\{]*\[(.*)\]$/$1/s;
# Setup waybar config file
my $waybar = '';
# Configure each enabled display # Configure each enabled display
foreach my $out (keys %$on) { foreach my $out (keys %$on) {
@ -262,46 +298,45 @@ foreach my $out (keys %$on) {
} }
} }
# If waybar position is set, fork, generate config and execute it # Skip waybar setup if template failed to be loaded
if (defined $on->{$out}->{waybar}) { if ( (defined $template) && (defined $on->{$out}->{waybar}) && ($on->{$out}->{waybar} =~ m/(top|bottom|left|right)/) ) {
my $pid = fork;
unless ($pid) {
open STDIN, '/dev/null';
open STDOUT, '>>/dev/null';
open STDERR, '>>/dev/null';
# Load in config template # If there's already a display set up, add a comma
my $waybar; unless ($waybar eq '') {
open (my $fh, '<', $waybar_template); $waybar .= ',';
while (<$fh>) {
$waybar .= $_;
}
close $fh;
chomp $waybar;
# Replace basic preferences
$waybar =~ s/__OUTPUT__/"$on->{$out}->{output}"/;
$waybar =~ s/__POSITION__/"$on->{$out}->{waybar}"/;
if (defined $on->{$out}->{width}) {
$waybar =~ s/__WIDTH__/$on->{$out}->{width}/;
# If width is not set, comment that line out to use default
} else {
$waybar =~ s/([^\s]*\s*)__WIDTH__/\/\/ $1__WIDTH__/gg;
}
# Write config to a temporary file
my $tmp = $waybar_temporary . "/" . $on->{$out}->{output} . ".tmp";
open ($fh, '>', $tmp);
print $fh $waybar;
close $fh;
`nohup waybar --config=$tmp`;
# Remove config
unlink $tmp;
} }
$waybar .= $template;
# Replace basic preferences
$waybar =~ s/__OUTPUT__/"$on->{$out}->{output}"/;
$waybar =~ s/__POSITION__/"$on->{$out}->{waybar}"/;
if (defined $on->{$out}->{width}) {
$waybar =~ s/__WIDTH__/$on->{$out}->{width}/;
# If width is not set, comment that line out to use default
} else {
$waybar =~ s/([^\s]*\s*)__WIDTH__/\/\/ $1__WIDTH__/gg;
}
} }
} }
open(my $fh, '>', $last); # Restore array formatting
print $fh $config; $waybar = '[' . $waybar . ']';
close($fh);
# Start Waybar as fork
my $pid = fork;
unless ($pid) {
open STDIN, '/dev/null';
open STDOUT, '>>/dev/null';
open STDERR, '>>/dev/null';
# Write config to a temporary file
my $tmp = $waybar_temporary . "/waybar-" . time() .".config";
open ($fh, '>', $tmp);
print $fh $waybar;
close $fh;
`nohup waybar --config=$tmp`;
# Remove config
unlink $tmp;
}