tests: implement xtest_sync_with_i3
The regular sync_with_i3 is not sufficient because i3test::XTEST uses a separate X11 connection.
This commit is contained in:
parent
c08ef36199
commit
14c8cf8622
|
@ -14,6 +14,7 @@ use ExtUtils::PkgConfig;
|
||||||
use Exporter ();
|
use Exporter ();
|
||||||
our @EXPORT = qw(
|
our @EXPORT = qw(
|
||||||
inlinec_connect
|
inlinec_connect
|
||||||
|
xtest_sync_with_i3
|
||||||
set_xkb_group
|
set_xkb_group
|
||||||
xtest_key_press
|
xtest_key_press
|
||||||
xtest_key_release
|
xtest_key_release
|
||||||
|
@ -38,7 +39,7 @@ i3test::XTEST - Inline::C wrappers for xcb-xtest and xcb-xkb
|
||||||
# ineffective.
|
# ineffective.
|
||||||
my %sn_config;
|
my %sn_config;
|
||||||
BEGIN {
|
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};
|
use Inline C => Config => LIBS => $sn_config{libs}, CCFLAGS => $sn_config{cflags};
|
||||||
|
@ -53,8 +54,12 @@ use Inline C => <<'END_OF_C_CODE';
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xkb.h>
|
#include <xcb/xkb.h>
|
||||||
#include <xcb/xtest.h>
|
#include <xcb/xtest.h>
|
||||||
|
#include <xcb/xcb_aux.h>
|
||||||
|
|
||||||
static xcb_connection_t *conn = NULL;
|
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() {
|
bool inlinec_connect() {
|
||||||
int screen;
|
int screen;
|
||||||
|
@ -89,9 +94,90 @@ bool inlinec_connect() {
|
||||||
}
|
}
|
||||||
free(usereply);
|
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;
|
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
|
// NOTE: while |group| should be a uint8_t, Inline::C will not define the
|
||||||
// function unless we use an int.
|
// function unless we use an int.
|
||||||
bool set_xkb_group(int group) {
|
bool set_xkb_group(int group) {
|
||||||
|
@ -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.
|
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
|
=head1 AUTHOR
|
||||||
|
|
||||||
Michael Stapelberg <michael@i3wm.org>
|
Michael Stapelberg <michael@i3wm.org>
|
||||||
|
|
|
@ -44,6 +44,7 @@ is(listen_for_binding(
|
||||||
sub {
|
sub {
|
||||||
xtest_key_press(107);
|
xtest_key_press(107);
|
||||||
xtest_key_release(107);
|
xtest_key_release(107);
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Print',
|
'Print',
|
||||||
|
@ -55,6 +56,7 @@ is(listen_for_binding(
|
||||||
xtest_key_press(36); # Return
|
xtest_key_press(36); # Return
|
||||||
xtest_key_release(36); # Return
|
xtest_key_release(36); # Return
|
||||||
xtest_key_release(133); # Super_L
|
xtest_key_release(133); # Super_L
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Mod4+Return',
|
'Mod4+Return',
|
||||||
|
@ -67,6 +69,7 @@ is(listen_for_binding(
|
||||||
sub {
|
sub {
|
||||||
xtest_key_press(107);
|
xtest_key_press(107);
|
||||||
xtest_key_release(107);
|
xtest_key_release(107);
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Print',
|
'Print',
|
||||||
|
@ -78,6 +81,7 @@ is(listen_for_binding(
|
||||||
xtest_key_press(36); # Return
|
xtest_key_press(36); # Return
|
||||||
xtest_key_release(36); # Return
|
xtest_key_release(36); # Return
|
||||||
xtest_key_release(133); # Super_L
|
xtest_key_release(133); # Super_L
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Mod4+Return',
|
'Mod4+Return',
|
||||||
|
|
|
@ -43,6 +43,7 @@ is(listen_for_binding(
|
||||||
sub {
|
sub {
|
||||||
xtest_key_press(107); # Print
|
xtest_key_press(107); # Print
|
||||||
xtest_key_release(107); # Print
|
xtest_key_release(107); # Print
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Print',
|
'Print',
|
||||||
|
@ -54,6 +55,7 @@ is(listen_for_binding(
|
||||||
xtest_key_press(107); # Print
|
xtest_key_press(107); # Print
|
||||||
xtest_key_release(107); # Print
|
xtest_key_release(107); # Print
|
||||||
xtest_key_release(37); # Control_L
|
xtest_key_release(37); # Control_L
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Control+Print',
|
'Control+Print',
|
||||||
|
@ -65,6 +67,7 @@ is(listen_for_binding(
|
||||||
xtest_key_press(56); # b
|
xtest_key_press(56); # b
|
||||||
xtest_key_release(56); # b
|
xtest_key_release(56); # b
|
||||||
xtest_key_release(64); # Alt_L
|
xtest_key_release(64); # Alt_L
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Mod1+b',
|
'Mod1+b',
|
||||||
|
@ -78,6 +81,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(56); # b
|
xtest_key_release(56); # b
|
||||||
xtest_key_release(50); # Shift_L
|
xtest_key_release(50); # Shift_L
|
||||||
xtest_key_release(64); # Alt_L
|
xtest_key_release(64); # Alt_L
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Mod1+Shift+b release',
|
'Mod1+Shift+b release',
|
||||||
|
|
|
@ -30,7 +30,7 @@ fresh_workspace;
|
||||||
|
|
||||||
xtest_button_press(4, 50, 50);
|
xtest_button_press(4, 50, 50);
|
||||||
xtest_button_release(4, 50, 50);
|
xtest_button_release(4, 50, 50);
|
||||||
sync_with_i3;
|
xtest_sync_with_i3;
|
||||||
|
|
||||||
is(focused_ws(), 'special', 'the binding was triggered');
|
is(focused_ws(), 'special', 'the binding was triggered');
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ is(listen_for_binding(
|
||||||
sub {
|
sub {
|
||||||
xtest_key_press(87); # KP_End
|
xtest_key_press(87); # KP_End
|
||||||
xtest_key_release(87); # KP_End
|
xtest_key_release(87); # KP_End
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'KP_End',
|
'KP_End',
|
||||||
|
@ -70,6 +71,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(87); # KP_1
|
xtest_key_release(87); # KP_1
|
||||||
xtest_key_press(77); # disable Num_Lock
|
xtest_key_press(77); # disable Num_Lock
|
||||||
xtest_key_release(77); # disable Num_Lock
|
xtest_key_release(77); # disable Num_Lock
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'KP_1',
|
'KP_1',
|
||||||
|
@ -81,6 +83,7 @@ is(listen_for_binding(
|
||||||
xtest_key_press(38); # a
|
xtest_key_press(38); # a
|
||||||
xtest_key_release(38); # a
|
xtest_key_release(38); # a
|
||||||
xtest_key_release(133); # Super_L
|
xtest_key_release(133); # Super_L
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'a',
|
'a',
|
||||||
|
@ -96,6 +99,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(133); # Super_L
|
xtest_key_release(133); # Super_L
|
||||||
xtest_key_press(77); # disable Num_Lock
|
xtest_key_press(77); # disable Num_Lock
|
||||||
xtest_key_release(77); # disable Num_Lock
|
xtest_key_release(77); # disable Num_Lock
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'a',
|
'a',
|
||||||
|
@ -105,6 +109,7 @@ is(listen_for_binding(
|
||||||
sub {
|
sub {
|
||||||
xtest_key_press(9); # Escape
|
xtest_key_press(9); # Escape
|
||||||
xtest_key_release(9); # Escape
|
xtest_key_release(9); # Escape
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Escape',
|
'Escape',
|
||||||
|
@ -118,6 +123,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(9); # Escape
|
xtest_key_release(9); # Escape
|
||||||
xtest_key_press(77); # disable Num_Lock
|
xtest_key_press(77); # disable Num_Lock
|
||||||
xtest_key_release(77); # disable Num_Lock
|
xtest_key_release(77); # disable Num_Lock
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Escape',
|
'Escape',
|
||||||
|
@ -129,6 +135,7 @@ is(listen_for_binding(
|
||||||
xtest_key_press(9); # Escape
|
xtest_key_press(9); # Escape
|
||||||
xtest_key_release(9); # Escape
|
xtest_key_release(9); # Escape
|
||||||
xtest_key_release(50); # Shift_L
|
xtest_key_release(50); # Shift_L
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Shift+Escape',
|
'Shift+Escape',
|
||||||
|
@ -144,6 +151,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(50); # Shift_L
|
xtest_key_release(50); # Shift_L
|
||||||
xtest_key_press(77); # disable Num_Lock
|
xtest_key_press(77); # disable Num_Lock
|
||||||
xtest_key_release(77); # disable Num_Lock
|
xtest_key_release(77); # disable Num_Lock
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Shift+Escape',
|
'Shift+Escape',
|
||||||
|
@ -157,6 +165,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(24); # q
|
xtest_key_release(24); # q
|
||||||
xtest_key_release(64); # Alt_L
|
xtest_key_release(64); # Alt_L
|
||||||
xtest_key_release(50); # Shift_L
|
xtest_key_release(50); # Shift_L
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Mod1+Shift+q',
|
'Mod1+Shift+q',
|
||||||
|
@ -174,6 +183,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(50); # Shift_L
|
xtest_key_release(50); # Shift_L
|
||||||
xtest_key_press(77); # disable Num_Lock
|
xtest_key_press(77); # disable Num_Lock
|
||||||
xtest_key_release(77); # disable Num_Lock
|
xtest_key_release(77); # disable Num_Lock
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Mod1+Shift+q',
|
'Mod1+Shift+q',
|
||||||
|
@ -183,6 +193,7 @@ is(listen_for_binding(
|
||||||
sub {
|
sub {
|
||||||
xtest_key_press(39); # s
|
xtest_key_press(39); # s
|
||||||
xtest_key_release(39); # s
|
xtest_key_release(39); # s
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
's',
|
's',
|
||||||
|
@ -196,6 +207,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(39); # s
|
xtest_key_release(39); # s
|
||||||
xtest_key_press(77); # disable Num_Lock
|
xtest_key_press(77); # disable Num_Lock
|
||||||
xtest_key_release(77); # disable Num_Lock
|
xtest_key_release(77); # disable Num_Lock
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
's',
|
's',
|
||||||
|
@ -228,6 +240,7 @@ is(listen_for_binding(
|
||||||
sub {
|
sub {
|
||||||
xtest_key_press(133); # Super_L
|
xtest_key_press(133); # Super_L
|
||||||
xtest_key_release(133); # Super_L
|
xtest_key_release(133); # Super_L
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Super_L',
|
'Super_L',
|
||||||
|
@ -241,6 +254,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(133); # Super_L
|
xtest_key_release(133); # Super_L
|
||||||
xtest_key_press(77); # disable Num_Lock
|
xtest_key_press(77); # disable Num_Lock
|
||||||
xtest_key_release(77); # disable Num_Lock
|
xtest_key_release(77); # disable Num_Lock
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Super_L',
|
'Super_L',
|
||||||
|
@ -252,6 +266,7 @@ is(listen_for_binding(
|
||||||
xtest_key_press(36); # Return
|
xtest_key_press(36); # Return
|
||||||
xtest_key_release(36); # Return
|
xtest_key_release(36); # Return
|
||||||
xtest_key_release(133); # Super_L
|
xtest_key_release(133); # Super_L
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Return',
|
'Return',
|
||||||
|
@ -267,6 +282,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(133); # Super_L
|
xtest_key_release(133); # Super_L
|
||||||
xtest_key_press(77); # disable Num_Lock
|
xtest_key_press(77); # disable Num_Lock
|
||||||
xtest_key_release(77); # disable Num_Lock
|
xtest_key_release(77); # disable Num_Lock
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'Return',
|
'Return',
|
||||||
|
@ -297,6 +313,7 @@ is(listen_for_binding(
|
||||||
sub {
|
sub {
|
||||||
xtest_key_press(87); # KP_End
|
xtest_key_press(87); # KP_End
|
||||||
xtest_key_release(87); # KP_End
|
xtest_key_release(87); # KP_End
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'KP_End',
|
'KP_End',
|
||||||
|
@ -306,6 +323,7 @@ is(listen_for_binding(
|
||||||
sub {
|
sub {
|
||||||
xtest_key_press(88); # KP_Down
|
xtest_key_press(88); # KP_Down
|
||||||
xtest_key_release(88); # KP_Down
|
xtest_key_release(88); # KP_Down
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'KP_Down',
|
'KP_Down',
|
||||||
|
@ -319,6 +337,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(87); # KP_1
|
xtest_key_release(87); # KP_1
|
||||||
xtest_key_press(77); # disable Num_Lock
|
xtest_key_press(77); # disable Num_Lock
|
||||||
xtest_key_release(77); # disable Num_Lock
|
xtest_key_release(77); # disable Num_Lock
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'timeout',
|
'timeout',
|
||||||
|
@ -332,6 +351,7 @@ is(listen_for_binding(
|
||||||
xtest_key_release(88); # KP_2
|
xtest_key_release(88); # KP_2
|
||||||
xtest_key_press(77); # disable Num_Lock
|
xtest_key_press(77); # disable Num_Lock
|
||||||
xtest_key_release(77); # disable Num_Lock
|
xtest_key_release(77); # disable Num_Lock
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'timeout',
|
'timeout',
|
||||||
|
@ -369,6 +389,7 @@ is(listen_for_binding(
|
||||||
xtest_button_release(4, 50, 50);
|
xtest_button_release(4, 50, 50);
|
||||||
xtest_key_press(77); # disable Num_Lock
|
xtest_key_press(77); # disable Num_Lock
|
||||||
xtest_key_release(77); # disable Num_Lock
|
xtest_key_release(77); # disable Num_Lock
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'button4',
|
'button4',
|
||||||
|
@ -378,6 +399,7 @@ is(listen_for_binding(
|
||||||
sub {
|
sub {
|
||||||
xtest_button_press(4, 50, 50);
|
xtest_button_press(4, 50, 50);
|
||||||
xtest_button_release(4, 50, 50);
|
xtest_button_release(4, 50, 50);
|
||||||
|
xtest_sync_with_i3;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
'button4',
|
'button4',
|
||||||
|
|
Loading…
Reference in New Issue