]> git.sur5r.net Git - i3/i3/blobdiff - testcases/lib/i3test.pm.in
Implement the tick event
[i3/i3] / testcases / lib / i3test.pm.in
index a484c91a441fe318cbecfe5f3286e2c9e094ba76..5b24ab39144a28c8422201092eda9ca95c074a2a 100644 (file)
@@ -47,6 +47,8 @@ our @EXPORT = qw(
     wait_for_unmap
     $x
     kill_all_windows
+    events_for
+    listen_for_binding
 );
 
 =head1 NAME
@@ -900,6 +902,86 @@ sub kill_all_windows {
     cmd '[title=".*"] kill';
 }
 
+=head2 events_for($subscribecb, [ $rettype ], [ $eventcbs ])
+
+Helper function which returns an array containing all events of type $rettype
+which were generated by i3 while $subscribecb was running.
+
+Set $eventcbs to subscribe to multiple event types and/or perform your own event
+aggregation.
+
+=cut
+sub events_for {
+    my ($subscribecb, $rettype, $eventcbs) = @_;
+
+    my @events;
+    $eventcbs //= {};
+    if (defined($rettype)) {
+       $eventcbs->{$rettype} = sub { push @events, shift };
+    }
+    my $subscribed = AnyEvent->condvar;
+    my $flushed = AnyEvent->condvar;
+    $eventcbs->{tick} = sub {
+       my ($event) = @_;
+       if ($event->{first}) {
+           $subscribed->send($event);
+       } else {
+           $flushed->send($event);
+       }
+    };
+    my $i3 = i3(get_socket_path(0));
+    $i3->connect->recv;
+    $i3->subscribe($eventcbs)->recv;
+    $subscribed->recv;
+    # Subscription established, run the callback.
+    $subscribecb->();
+    # Now generate a tick event, which we know we’ll receive (and at which point
+    # all other events have been received).
+    my $nonce = int(rand(255)) + 1;
+    $i3->send_tick($nonce);
+
+    my $tick = $flushed->recv;
+    $tester->is_eq($tick->{payload}, $nonce, 'tick nonce received');
+    return @events;
+}
+
+=head2 listen_for_binding($cb)
+
+Helper function to evaluate whether sending KeyPress/KeyRelease events via XTEST
+triggers an i3 key binding or not. Expects key bindings to be configured in the
+form “bindsym <binding> nop <binding>”, e.g.  “bindsym Mod4+Return nop
+Mod4+Return”.
+
+  is(listen_for_binding(
+      sub {
+          xtest_key_press(133); # Super_L
+          xtest_key_press(36); # Return
+          xtest_key_release(36); # Return
+          xtest_key_release(133); # Super_L
+          xtest_sync_with_i3;
+      },
+      ),
+     'Mod4+Return',
+     'triggered the "Mod4+Return" keybinding');
+
+=cut
+
+sub listen_for_binding {
+    my ($cb) = @_;
+    my $triggered = AnyEvent->condvar;
+    my @events = events_for(
+       $cb,
+       'binding');
+
+    $tester->is_eq(scalar @events, 1, 'Received precisely one event');
+    $tester->is_eq($events[0]->{change}, 'run', 'change is "run"');
+    # We look at the command (which is “nop <binding>”) because that is easier
+    # than re-assembling the string representation of $event->{binding}.
+    my $command = $events[0]->{binding}->{command};
+    $command =~ s/^nop //g;
+    return $command;
+}
+
 =head1 AUTHOR
 
 Michael Stapelberg <michael@i3wm.org>