Skip to content

Commit

Permalink
tests: implement xtest_sync_with_i3
Browse files Browse the repository at this point in the history
The regular sync_with_i3 is not sufficient because i3test::XTEST uses a separate
X11 connection.
  • Loading branch information
stapelberg committed Sep 30, 2017
1 parent c08ef36 commit 14c8cf8
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 4 deletions.
92 changes: 91 additions & 1 deletion testcases/lib/i3test/XTEST.pm
Expand Up @@ -14,6 +14,7 @@ use ExtUtils::PkgConfig;
use Exporter ();
our @EXPORT = qw(
inlinec_connect
xtest_sync_with_i3
set_xkb_group
xtest_key_press
xtest_key_release
Expand All @@ -38,7 +39,7 @@ i3test::XTEST - Inline::C wrappers for xcb-xtest and xcb-xkb
# ineffective.
my %sn_config;
BEGIN {
%sn_config = ExtUtils::PkgConfig->find('xcb-xkb xcb-xtest');
%sn_config = ExtUtils::PkgConfig->find('xcb-xkb xcb-xtest xcb-util');
}

use Inline C => Config => LIBS => $sn_config{libs}, CCFLAGS => $sn_config{cflags};
Expand All @@ -53,8 +54,12 @@ use Inline C => <<'END_OF_C_CODE';
#include <xcb/xcb.h>
#include <xcb/xkb.h>
#include <xcb/xtest.h>
#include <xcb/xcb_aux.h>
static xcb_connection_t *conn = NULL;
static xcb_window_t sync_window;
static xcb_window_t root_window;
static xcb_atom_t i3_sync_atom;
bool inlinec_connect() {
int screen;
Expand Down Expand Up @@ -89,9 +94,90 @@ bool inlinec_connect() {
}
free(usereply);
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, xcb_intern_atom(conn, 0, strlen("I3_SYNC"), "I3_SYNC"), NULL);
i3_sync_atom = reply->atom;
free(reply);
xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screen);
root_window = root_screen->root;
sync_window = xcb_generate_id(conn);
xcb_create_window(conn,
XCB_COPY_FROM_PARENT, // depth
sync_window, // window
root_window, // parent
-15, // x
-15, // y
1, // width
1, // height
0, // border_width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // class
XCB_COPY_FROM_PARENT, // visual
XCB_CW_OVERRIDE_REDIRECT, // value_mask
(uint32_t[]){
1, // override_redirect
}); // value_list
return true;
}
void xtest_sync_with_i3() {
xcb_client_message_event_t ev;
memset(&ev, '\0', sizeof(xcb_client_message_event_t));
const int nonce = rand() % 255;
ev.response_type = XCB_CLIENT_MESSAGE;
ev.window = sync_window;
ev.type = i3_sync_atom;
ev.format = 32;
ev.data.data32[0] = sync_window;
ev.data.data32[1] = nonce;
xcb_send_event(conn, false, root_window, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char *)&ev);
xcb_flush(conn);
xcb_generic_event_t *event = NULL;
while (1) {
free(event);
if ((event = xcb_wait_for_event(conn)) == NULL) {
break;
}
if (event->response_type == 0) {
fprintf(stderr, "X11 Error received! sequence %x\n", event->sequence);
continue;
}
/* Strip off the highest bit (set if the event is generated) */
const int type = (event->response_type & 0x7F);
switch (type) {
case XCB_CLIENT_MESSAGE: {
xcb_client_message_event_t *ev = (xcb_client_message_event_t *)event;
{
const uint32_t got = ev->data.data32[0];
const uint32_t want = sync_window;
if (got != want) {
fprintf(stderr, "Ignoring ClientMessage: unknown window: got %d, want %d\n", got, want);
continue;
}
}
{
const uint32_t got = ev->data.data32[1];
const uint32_t want = nonce;
if (got != want) {
fprintf(stderr, "Ignoring ClientMessage: unknown nonce: got %d, want %d\n", got, want);
continue;
}
}
return;
}
default:
fprintf(stderr, "Unexpected X11 event of type %d received (XCB_CLIENT_MESSAGE = %d)\n", type, XCB_CLIENT_MESSAGE);
break;
}
}
free(event);
}
// NOTE: while |group| should be a uint8_t, Inline::C will not define the
// function unless we use an int.
bool set_xkb_group(int group) {
Expand Down Expand Up @@ -283,6 +369,10 @@ Sends a ButtonRelease event via XTEST, with the specified C<$button>.
Returns false when there was an X11 error, true otherwise.
=head2 xtest_sync_with_i3()
Ensures i3 has processed all X11 events which were triggered by this module.
=head1 AUTHOR
Michael Stapelberg <michael@i3wm.org>
Expand Down
4 changes: 4 additions & 0 deletions testcases/t/257-keypress-group1-fallback.t
Expand Up @@ -44,6 +44,7 @@ is(listen_for_binding(
sub {
xtest_key_press(107);
xtest_key_release(107);
xtest_sync_with_i3;
},
),
'Print',
Expand All @@ -55,6 +56,7 @@ is(listen_for_binding(
xtest_key_press(36); # Return
xtest_key_release(36); # Return
xtest_key_release(133); # Super_L
xtest_sync_with_i3;
},
),
'Mod4+Return',
Expand All @@ -67,6 +69,7 @@ is(listen_for_binding(
sub {
xtest_key_press(107);
xtest_key_release(107);
xtest_sync_with_i3;
},
),
'Print',
Expand All @@ -78,6 +81,7 @@ is(listen_for_binding(
xtest_key_press(36); # Return
xtest_key_release(36); # Return
xtest_key_release(133); # Super_L
xtest_sync_with_i3;
},
),
'Mod4+Return',
Expand Down
4 changes: 4 additions & 0 deletions testcases/t/258-keypress-release.t
Expand Up @@ -43,6 +43,7 @@ is(listen_for_binding(
sub {
xtest_key_press(107); # Print
xtest_key_release(107); # Print
xtest_sync_with_i3;
},
),
'Print',
Expand All @@ -54,6 +55,7 @@ is(listen_for_binding(
xtest_key_press(107); # Print
xtest_key_release(107); # Print
xtest_key_release(37); # Control_L
xtest_sync_with_i3;
},
),
'Control+Print',
Expand All @@ -65,6 +67,7 @@ is(listen_for_binding(
xtest_key_press(56); # b
xtest_key_release(56); # b
xtest_key_release(64); # Alt_L
xtest_sync_with_i3;
},
),
'Mod1+b',
Expand All @@ -78,6 +81,7 @@ is(listen_for_binding(
xtest_key_release(56); # b
xtest_key_release(50); # Shift_L
xtest_key_release(64); # Alt_L
xtest_sync_with_i3;
},
),
'Mod1+Shift+b release',
Expand Down
2 changes: 1 addition & 1 deletion testcases/t/286-root-window-mouse-binding.t
Expand Up @@ -30,7 +30,7 @@ fresh_workspace;

xtest_button_press(4, 50, 50);
xtest_button_release(4, 50, 50);
sync_with_i3;
xtest_sync_with_i3;

is(focused_ws(), 'special', 'the binding was triggered');

Expand Down
26 changes: 24 additions & 2 deletions testcases/t/290-keypress-numlock.t
Expand Up @@ -57,6 +57,7 @@ is(listen_for_binding(
sub {
xtest_key_press(87); # KP_End
xtest_key_release(87); # KP_End
xtest_sync_with_i3;
},
),
'KP_End',
Expand All @@ -70,6 +71,7 @@ is(listen_for_binding(
xtest_key_release(87); # KP_1
xtest_key_press(77); # disable Num_Lock
xtest_key_release(77); # disable Num_Lock
xtest_sync_with_i3;
},
),
'KP_1',
Expand All @@ -81,6 +83,7 @@ is(listen_for_binding(
xtest_key_press(38); # a
xtest_key_release(38); # a
xtest_key_release(133); # Super_L
xtest_sync_with_i3;
},
),
'a',
Expand All @@ -96,6 +99,7 @@ is(listen_for_binding(
xtest_key_release(133); # Super_L
xtest_key_press(77); # disable Num_Lock
xtest_key_release(77); # disable Num_Lock
xtest_sync_with_i3;
},
),
'a',
Expand All @@ -105,6 +109,7 @@ is(listen_for_binding(
sub {
xtest_key_press(9); # Escape
xtest_key_release(9); # Escape
xtest_sync_with_i3;
},
),
'Escape',
Expand All @@ -118,6 +123,7 @@ is(listen_for_binding(
xtest_key_release(9); # Escape
xtest_key_press(77); # disable Num_Lock
xtest_key_release(77); # disable Num_Lock
xtest_sync_with_i3;
},
),
'Escape',
Expand All @@ -129,6 +135,7 @@ is(listen_for_binding(
xtest_key_press(9); # Escape
xtest_key_release(9); # Escape
xtest_key_release(50); # Shift_L
xtest_sync_with_i3;
},
),
'Shift+Escape',
Expand All @@ -144,6 +151,7 @@ is(listen_for_binding(
xtest_key_release(50); # Shift_L
xtest_key_press(77); # disable Num_Lock
xtest_key_release(77); # disable Num_Lock
xtest_sync_with_i3;
},
),
'Shift+Escape',
Expand All @@ -157,6 +165,7 @@ is(listen_for_binding(
xtest_key_release(24); # q
xtest_key_release(64); # Alt_L
xtest_key_release(50); # Shift_L
xtest_sync_with_i3;
},
),
'Mod1+Shift+q',
Expand All @@ -174,6 +183,7 @@ is(listen_for_binding(
xtest_key_release(50); # Shift_L
xtest_key_press(77); # disable Num_Lock
xtest_key_release(77); # disable Num_Lock
xtest_sync_with_i3;
},
),
'Mod1+Shift+q',
Expand All @@ -183,6 +193,7 @@ is(listen_for_binding(
sub {
xtest_key_press(39); # s
xtest_key_release(39); # s
xtest_sync_with_i3;
},
),
's',
Expand All @@ -196,6 +207,7 @@ is(listen_for_binding(
xtest_key_release(39); # s
xtest_key_press(77); # disable Num_Lock
xtest_key_release(77); # disable Num_Lock
xtest_sync_with_i3;
},
),
's',
Expand Down Expand Up @@ -228,6 +240,7 @@ is(listen_for_binding(
sub {
xtest_key_press(133); # Super_L
xtest_key_release(133); # Super_L
xtest_sync_with_i3;
},
),
'Super_L',
Expand All @@ -241,6 +254,7 @@ is(listen_for_binding(
xtest_key_release(133); # Super_L
xtest_key_press(77); # disable Num_Lock
xtest_key_release(77); # disable Num_Lock
xtest_sync_with_i3;
},
),
'Super_L',
Expand All @@ -252,6 +266,7 @@ is(listen_for_binding(
xtest_key_press(36); # Return
xtest_key_release(36); # Return
xtest_key_release(133); # Super_L
xtest_sync_with_i3;
},
),
'Return',
Expand All @@ -267,6 +282,7 @@ is(listen_for_binding(
xtest_key_release(133); # Super_L
xtest_key_press(77); # disable Num_Lock
xtest_key_release(77); # disable Num_Lock
xtest_sync_with_i3;
},
),
'Return',
Expand Down Expand Up @@ -297,6 +313,7 @@ is(listen_for_binding(
sub {
xtest_key_press(87); # KP_End
xtest_key_release(87); # KP_End
xtest_sync_with_i3;
},
),
'KP_End',
Expand All @@ -306,6 +323,7 @@ is(listen_for_binding(
sub {
xtest_key_press(88); # KP_Down
xtest_key_release(88); # KP_Down
xtest_sync_with_i3;
},
),
'KP_Down',
Expand All @@ -319,6 +337,7 @@ is(listen_for_binding(
xtest_key_release(87); # KP_1
xtest_key_press(77); # disable Num_Lock
xtest_key_release(77); # disable Num_Lock
xtest_sync_with_i3;
},
),
'timeout',
Expand All @@ -332,6 +351,7 @@ is(listen_for_binding(
xtest_key_release(88); # KP_2
xtest_key_press(77); # disable Num_Lock
xtest_key_release(77); # disable Num_Lock
xtest_sync_with_i3;
},
),
'timeout',
Expand Down Expand Up @@ -369,15 +389,17 @@ is(listen_for_binding(
xtest_button_release(4, 50, 50);
xtest_key_press(77); # disable Num_Lock
xtest_key_release(77); # disable Num_Lock
xtest_sync_with_i3;
},
),
'button4',
'triggered the button4 keybinding with NumLock');

is(listen_for_binding(
sub {
xtest_button_press(4, 50, 50);
xtest_button_release(4, 50, 50);
xtest_button_press(4, 50, 50);
xtest_button_release(4, 50, 50);
xtest_sync_with_i3;
},
),
'button4',
Expand Down

0 comments on commit 14c8cf8

Please sign in to comment.