http://qs321.pair.com?node_id=1229275

morgon has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am having problems scripting the window-manager i3 with perl using AnyEvent::I3 and as I could not get any help in an i3-forum, I try my luck here...

This works:

use strict; use AnyEvent; use AnyEvent::I3; my $i3 = i3(); $i3->connect->recv or die "Error connecting to i3"; $i3->command("workspace 1")->recv;
Running this changes to workspace 1.

And this also works:

use strict; use AnyEvent; use AnyEvent::I3; my $i3 = i3(); $i3->connect->recv or die "Error connecting to i3"; $i3->subscribe({ workspace => \&handle })->recv->{success} or die "Error subscribing to events" +; AE::cv->recv; sub handle { my($data)=@_; if($data->{change} eq "empty") { print "empty workspace!!\n"; } }
Running this prints "empty workspace!!" whenever a workspace become empty.

What I want now is to combine the logic, so whenever a workspace becomes empty we change to workspace 1.

Here is my attempt:

use strict; use AnyEvent; use AnyEvent::I3; my $i3 = i3(); $i3->connect->recv or die "Error connecting to i3"; $i3->subscribe({ workspace => \&handle })->recv->{success} or die "Error subscribing to events" +; AE::cv->recv; sub handle { my($data)=@_; if($data->{change} eq "empty") { print "empty workspace!!\n"; $i3->command("workspace 1")->recv; } }
However this does not work. It prints "empty workspace!!" ok, but it does not send the command, the error is:
EV: error in callback (ignoring): AnyEvent::CondVar: recursive blockin +g wait attempted
Any ideas?

Many thanks!

Replies are listed 'Best First'.
Re: scripting i3 with Perl
by Corion (Patriarch) on Feb 02, 2019 at 07:29 UTC

    The error message is pretty descriptive. You are calling ->recv from within a handler. Don't do that.

    The following should work:

    sub handle { my($data)=@_; if($data->{change} eq "empty") { print "empty workspace!!\n"; my $switched; $switched = $i3->command("workspace 1")->cb(sub { print "Switched back to workspace 1\n"; undef $switched; }); } }

    Using AnyEvent, you should basically never call ->recv and only use callbacks except in the outermost program.

      Thanks for the reply.

      Your attempt gets rid of the error message and prints "Switched back...", however the switch itself does not happen - the command does not seem to be executed...

        Maybe there is an error? The AnyEvent::i3 documentation mentions that ->command returns a result:

        use Data::Dumper; sub handle { my($data)=@_; if($data->{change} eq "empty") { print "empty workspace!!\n"; my $switched; $switched = $i3->command("workspace 1")->cb(sub { my( $reply ) = @_; print "Switched back to workspace 1\n"; undef $switched; use Data::Dumper; print Dumper $reply; }); } }