diff --git a/testcases/lib/i3test/XTEST.pm b/testcases/lib/i3test/XTEST.pm index 065c8a35..9ec083b1 100644 --- a/testcases/lib/i3test/XTEST.pm +++ b/testcases/lib/i3test/XTEST.pm @@ -15,6 +15,8 @@ our @EXPORT = qw( set_xkb_group xtest_key_press xtest_key_release + xtest_button_press + xtest_button_release listen_for_binding start_binding_capture binding_events @@ -107,7 +109,7 @@ bool set_xkb_group(int group) { return true; } -bool xtest_key(int type, int detail) { +bool xtest_input(int type, int detail, int x, int y) { xcb_generic_error_t *err; xcb_void_cookie_t cookie; @@ -117,8 +119,8 @@ bool xtest_key(int type, int detail) { detail, /* detail */ XCB_CURRENT_TIME, /* time */ XCB_NONE, /* root */ - 0, /* rootX */ - 0, /* rootY */ + x, /* rootX */ + y, /* rootY */ XCB_NONE); /* deviceid */ if ((err = xcb_request_check(conn, cookie)) != NULL) { fprintf(stderr, "X error code %d\n", err->error_code); @@ -128,6 +130,10 @@ bool xtest_key(int type, int detail) { return true; } +bool xtest_key(int type, int detail) { + return xtest_input(type, detail, 0, 0); +} + bool xtest_key_press(int detail) { return xtest_key(XCB_KEY_PRESS, detail); } @@ -136,6 +142,14 @@ bool xtest_key_release(int detail) { return xtest_key(XCB_KEY_RELEASE, detail); } +bool xtest_button_press(int button, int x, int y) { + return xtest_input(XCB_BUTTON_PRESS, button, x, y); +} + +bool xtest_button_release(int button, int x, int y) { + return xtest_input(XCB_BUTTON_RELEASE, button, x, y); +} + END_OF_C_CODE sub import { @@ -240,14 +254,26 @@ Returns false when there was an X11 error changing the group, true otherwise. Sends a KeyPress event via XTEST, with the specified C<$detail>, i.e. key code. Use C to find key codes. -Returns false when there was an X11 error changing the group, true otherwise. +Returns false when there was an X11 error, true otherwise. =head2 xtest_key_release($detail) Sends a KeyRelease event via XTEST, with the specified C<$detail>, i.e. key code. Use C to find key codes. -Returns false when there was an X11 error changing the group, true otherwise. +Returns false when there was an X11 error, true otherwise. + +=head2 xtest_button_press($button, $x, $y) + +Sends a ButtonPress event via XTEST, with the specified C<$button>. + +Returns false when there was an X11 error, true otherwise. + +=head2 xtest_button_release($button, $x, $y) + +Sends a ButtonRelease event via XTEST, with the specified C<$button>. + +Returns false when there was an X11 error, true otherwise. =head1 AUTHOR diff --git a/testcases/t/262-root-window-mouse-binding.t b/testcases/t/262-root-window-mouse-binding.t new file mode 100644 index 00000000..c8fd89ef --- /dev/null +++ b/testcases/t/262-root-window-mouse-binding.t @@ -0,0 +1,42 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Verifies that mouse bindings work on the root window if +# --whole-window is set. +# Ticket: #2115 +use i3test i3_autostart => 0; +use i3test::XTEST; + +my $config = < 0; +use i3test::XTEST; my ($cv, $timer); sub reset_test { @@ -41,17 +42,13 @@ bar { } EOT -SKIP: { - qx(command -v xdotool 2> /dev/null); - skip 'xdotool is required for this test', 1 if $?; +my $pid = launch_with_config($config); +my $i3 = i3(get_socket_path()); +$i3->connect()->recv; +my $ws = fresh_workspace; - my $pid = launch_with_config($config); - my $i3 = i3(get_socket_path()); - $i3->connect()->recv; - my $ws = fresh_workspace; - - reset_test; - $i3->subscribe({ +reset_test; +$i3->subscribe({ window => sub { my ($event) = @_; if ($event->{change} eq 'focus') { @@ -60,45 +57,48 @@ SKIP: { }, })->recv; - my $left = open_window; - my $right = open_window; - sync_with_i3; - my $con = $cv->recv; - is($con->{window}, $right->{id}, 'focus is initially on the right container'); - reset_test; +my $left = open_window; +my $right = open_window; +sync_with_i3; +my $con = $cv->recv; +is($con->{window}, $right->{id}, 'focus is initially on the right container'); +reset_test; - qx(xdotool mousemove 3 3 click 1); - sync_with_i3; - $con = $cv->recv; - is($con->{window}, $left->{id}, 'button 1 moves focus left'); - reset_test; +xtest_button_press(1, 3, 3); +xtest_button_release(1, 3, 3); +sync_with_i3; +$con = $cv->recv; +is($con->{window}, $left->{id}, 'button 1 moves focus left'); +reset_test; - qx(xdotool mousemove 3 3 click 2); - sync_with_i3; - $con = $cv->recv; - is($con->{window}, $right->{id}, 'button 2 moves focus right'); - reset_test; +xtest_button_press(2, 3, 3); +xtest_button_release(2, 3, 3); +sync_with_i3; +$con = $cv->recv; +is($con->{window}, $right->{id}, 'button 2 moves focus right'); +reset_test; - qx(xdotool mousemove 3 3 click 3); - sync_with_i3; - $con = $cv->recv; - is($con->{window}, $left->{id}, 'button 3 moves focus left'); - reset_test; +xtest_button_press(3, 3, 3); +xtest_button_release(3, 3, 3); +sync_with_i3; +$con = $cv->recv; +is($con->{window}, $left->{id}, 'button 3 moves focus left'); +reset_test; - qx(xdotool mousemove 3 3 click 4); - sync_with_i3; - $con = $cv->recv; - is($con->{window}, $right->{id}, 'button 4 moves focus right'); - reset_test; +xtest_button_press(4, 3, 3); +xtest_button_release(4, 3, 3); +sync_with_i3; +$con = $cv->recv; +is($con->{window}, $right->{id}, 'button 4 moves focus right'); +reset_test; - qx(xdotool mousemove 3 3 click 5); - sync_with_i3; - $con = $cv->recv; - is($con->{window}, $left->{id}, 'button 5 moves focus left'); - reset_test; +xtest_button_press(5, 3, 3); +xtest_button_release(5, 3, 3); +sync_with_i3; +$con = $cv->recv; +is($con->{window}, $left->{id}, 'button 5 moves focus left'); +reset_test; - exit_gracefully($pid); - -} +exit_gracefully($pid); done_testing;