139 lines
2.9 KiB
Perl
139 lines
2.9 KiB
Perl
#!/usr/bin/env perl
|
|
# vim:ts=4:sw=4:expandtab:ft=perl
|
|
#
|
|
# Print i3 workspaces on every change.
|
|
#
|
|
# Format:
|
|
# For every workspace (x = workspace name)
|
|
# - "FOCx" -> Focused workspace
|
|
# - "INAx" -> Inactive workspace
|
|
# - "ACTx" -> Ative workspace
|
|
# - "URGx" -> Urgent workspace
|
|
#
|
|
# Uses AnyEvent I3 0.8 -> https://metacpan.org/module/AnyEvent::I3
|
|
# Based in i3-wsbar of Michael Stapelberg -> http://code.stapelberg.de/git/i3/tree/contrib/i3-wsbar
|
|
#
|
|
# 16 feb 2015 - Electro7
|
|
|
|
use strict;
|
|
use warnings;
|
|
use AnyEvent::I3;
|
|
use AnyEvent;
|
|
use v5.10;
|
|
|
|
my $socket_path = undef;
|
|
my ($workspaces, $outputs) = ([], {});
|
|
my $w = AnyEvent->timer(
|
|
after => 3,
|
|
cb => sub {
|
|
die "Connection to i3 timed out. Verify socket path ($socket_path)";
|
|
exit 1;
|
|
}
|
|
);
|
|
|
|
|
|
my $i3 = i3($socket_path);
|
|
|
|
# Disable buffering
|
|
$| = 1;
|
|
STDERR->autoflush;
|
|
STDOUT->autoflush;
|
|
|
|
# Wait a short amount of time and try to connect to i3 again
|
|
sub reconnect {
|
|
print "reconecting\n";
|
|
my $timer;
|
|
$i3 = i3($socket_path);
|
|
if (!defined($w)) {
|
|
$w = AnyEvent->timer(
|
|
after => 3,
|
|
cb => sub {
|
|
die "Connection to i3 timed out. Verify socket path ($socket_path)";
|
|
exit 1;
|
|
}
|
|
);
|
|
}
|
|
|
|
my $c = sub {
|
|
$timer = AnyEvent->timer(
|
|
after => 0.01,
|
|
cb => sub { $i3->connect->cb(\&connected) }
|
|
);
|
|
};
|
|
$c->();
|
|
}
|
|
|
|
# Connection attempt succeeded or failed
|
|
sub connected {
|
|
my ($cv) = @_;
|
|
|
|
if (!$cv->recv) {
|
|
reconnect();
|
|
return;
|
|
}
|
|
|
|
$w = undef;
|
|
|
|
$i3->subscribe({
|
|
workspace => \&ws_change,
|
|
output => \&output_change,
|
|
_error => sub { reconnect() }
|
|
});
|
|
ws_change();
|
|
output_change();
|
|
}
|
|
|
|
# Called when a ws changes
|
|
sub ws_change {
|
|
# Request the current workspaces and update the output afterwards
|
|
$i3->get_workspaces->cb(
|
|
sub {
|
|
my ($cv) = @_;
|
|
$workspaces = $cv->recv;
|
|
update_output();
|
|
});
|
|
}
|
|
|
|
# Called when the reply to the GET_OUTPUTS message arrives
|
|
sub got_outputs {
|
|
my $reply = shift->recv;
|
|
my %new = map { ($_->{name}, $_) } grep { $_->{active} } @{$reply};
|
|
|
|
for my $name (keys %new) {
|
|
$outputs->{$name} = $new{$name};
|
|
}
|
|
|
|
update_output();
|
|
}
|
|
|
|
sub output_change {
|
|
$i3->get_outputs->cb(\&got_outputs)
|
|
}
|
|
|
|
sub update_output {
|
|
my $out;
|
|
|
|
for my $name (keys %{$outputs}) {
|
|
$out .= "WSP";
|
|
|
|
for my $ws (@{$workspaces}) {
|
|
my $state = "INA";
|
|
$state = "ACT" if $ws->{visible};
|
|
$state = "URG" if $ws->{urgent};
|
|
$state = "FOC" if $ws->{focused};
|
|
my $name = $ws->{name};
|
|
$out .= qq|$state$name |;
|
|
}
|
|
|
|
$out .= "\n";
|
|
|
|
print $out;
|
|
}
|
|
}
|
|
|
|
$i3->connect->cb(\&connected);
|
|
|
|
# let AnyEvent do the rest ("endless loop")
|
|
AnyEvent->condvar->recv
|
|
|