AnyEvent-I3
view release on metacpan or search on metacpan
lib/AnyEvent/I3.pm view on Meta::CPAN
return unless defined($self->{callbacks}->{$type});
my $cb = $self->{callbacks}->{$type};
$cb->(decode_json $payload);
return if ($type & $event_mask) == $event_mask;
# If this was a one-time callback, we delete it
# (when connection is lost, all one-time callbacks get triggered)
delete $self->{callbacks}->{$type};
}
=head2 $i3->subscribe(\%callbacks)
Subscribes to the given event types. This function awaits a hashref with the
key being the name of the event and the value being a callback.
my %callbacks = (
workspace => sub { say "Workspaces changed" }
);
if ($i3->subscribe(\%callbacks)->recv->{success}) {
say "Successfully subscribed";
}
The special callback with name C<_error> is called when the connection to i3
is killed (because of a crash, exit or restart of i3 most likely). You can
use it to print an appropriate message and exit cleanly or to try to reconnect.
my %callbacks = (
_error => sub {
my ($msg) = @_;
say "I am sorry. I am so sorry: $msg";
exit 1;
}
);
$i3->subscribe(\%callbacks)->recv;
=cut
sub subscribe {
my ($self, $callbacks) = @_;
# Register callbacks for each message type
for my $key (keys %{$callbacks}) {
if (!exists $events{$key}) {
warn "Could not subscribe to event type '$key'." .
" Supported events are " . join(" ", sort keys %events), $/;
next;
}
my $type = $events{$key};
$self->{callbacks}->{$type} = $callbacks->{$key};
}
$self->message(TYPE_SUBSCRIBE, [ keys %{$callbacks} ])
}
=head2 $i3->message($type, $content)
Sends a message of the specified C<type> to i3, possibly containing the data
structure C<content> (or C<content>, encoded as utf8, if C<content> is a
scalar), if specified.
my $reply = $i3->message(TYPE_RUN_COMMAND, "reload")->recv;
if ($reply->{success}) {
say "Configuration successfully reloaded";
}
=cut
sub message {
my ($self, $type, $content) = @_;
confess "No message type specified" unless defined($type);
confess "No connection to i3" unless defined($self->{ipchdl});
my $payload = "";
if ($content) {
if (not ref($content)) {
# Convert from Perlâs internal encoding to UTF8 octets
$payload = encode_utf8($content);
} else {
$payload = encode_json $content;
}
}
my $message = $magic . pack("LL", length($payload), $type) . $payload;
$self->{ipchdl}->push_write($message);
my $cv = AnyEvent->condvar;
# We donât preserve the old callback as it makes no sense to
# have a callback on message reply types (only on events)
$self->{callbacks}->{$type} =
sub {
my ($reply) = @_;
$cv->send($reply);
undef $self->{callbacks}->{$type};
};
$cv
}
=head1 SUGAR METHODS
These methods intend to make your scripts as beautiful as possible. All of
them automatically establish a connection to i3 blockingly (if it does not
already exist).
=cut
sub _ensure_connection {
my ($self) = @_;
return if defined($self->{ipchdl});
$self->connect->recv or confess "Unable to connect to i3 (socket path " . $self->{path} . ")";
}
=head2 get_workspaces
Gets the current workspaces from i3.
my $ws = i3->get_workspaces->recv;
say Dumper($ws);
=cut
sub get_workspaces {
my ($self) = @_;
$self->_ensure_connection;
$self->message(TYPE_GET_WORKSPACES)
}
=head2 get_outputs
Gets the current outputs from i3.
my $outs = i3->get_outputs->recv;
say Dumper($outs);
( run in 0.860 second using v1.01-cache-2.11-cpan-5837b0d9d2c )