ATOM_DO(_NET_SYSTEM_TRAY_COLORS)
ATOM_DO(_XEMBED_INFO)
ATOM_DO(_XEMBED)
+ATOM_DO(I3_SYNC)
#undef ATOM_DO
*
*/
static void handle_client_message(xcb_client_message_event_t *event) {
- if (event->type == atoms[_NET_SYSTEM_TRAY_OPCODE] &&
- event->format == 32) {
+ if (event->type == atoms[I3_SYNC]) {
+ xcb_window_t window = event->data.data32[0];
+ uint32_t rnd = event->data.data32[1];
+ DLOG("[i3 sync protocol] Forwarding random value %d, X11 window 0x%08x to i3\n", rnd, window);
+
+ void *reply = scalloc(32, 1);
+ xcb_client_message_event_t *ev = reply;
+
+ ev->response_type = XCB_CLIENT_MESSAGE;
+ ev->window = window;
+ ev->type = atoms[I3_SYNC];
+ ev->format = 32;
+ ev->data.data32[0] = window;
+ ev->data.data32[1] = rnd;
+
+ xcb_send_event(conn, false, xcb_root, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char *)ev);
+ xcb_flush(conn);
+ free(reply);
+ } else if (event->type == atoms[_NET_SYSTEM_TRAY_OPCODE] &&
+ event->format == 32) {
DLOG("_NET_SYSTEM_TRAY_OPCODE received\n");
/* event->data.data32[0] is the timestamp */
uint32_t op = event->data.data32[1];
use Exporter ();
our @EXPORT = qw(
inlinec_connect
+ xtest_sync_with
xtest_sync_with_i3
set_xkb_group
xtest_key_press
return true;
}
-void xtest_sync_with_i3() {
+void xtest_sync_with(int window) {
xcb_client_message_event_t ev;
memset(&ev, '\0', sizeof(xcb_client_message_event_t));
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_send_event(conn, false, (xcb_window_t)window, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char *)&ev);
xcb_flush(conn);
xcb_generic_event_t *event = NULL;
free(event);
}
+void xtest_sync_with_i3() {
+ xtest_sync_with((int)root_window);
+}
+
// 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) {
Returns false when there was an X11 error, true otherwise.
+=head2 xtest_sync_with($window)
+
+Ensures the specified window has processed all X11 events which were triggered
+by this module, provided the window response to the i3 sync protocol.
+
=head2 xtest_sync_with_i3()
Ensures i3 has processed all X11 events which were triggered by this module.
for my $node (@{$nodes}) {
my $props = $node->{window_properties};
if (defined($props) && $props->{class} eq 'i3bar') {
- return 1;
+ return $node->{window};
}
}
return i3bar_present(\@children);
}
-if (i3bar_present($i3->get_tree->recv->{nodes})) {
+my $i3bar_window = i3bar_present($i3->get_tree->recv->{nodes});
+if ($i3bar_window) {
ok(1, 'i3bar present');
} else {
my $con = $cv->recv;
ok($con, 'i3bar appeared');
+ $i3bar_window = $con->{window};
}
+diag('i3bar window = ' . $i3bar_window);
+
my $left = open_window;
my $right = open_window;
sync_with_i3;
sub {
xtest_button_press(1, 3, 3);
xtest_button_release(1, 3, 3);
- xtest_sync_with_i3;
+ xtest_sync_with($i3bar_window);
},
[ $left->{id} ],
'button 1 moves focus left';
sub {
xtest_button_press(2, 3, 3);
xtest_button_release(2, 3, 3);
- xtest_sync_with_i3;
+ xtest_sync_with($i3bar_window);
},
[ $right->{id} ],
'button 2 moves focus right';
sub {
xtest_button_press(3, 3, 3);
xtest_button_release(3, 3, 3);
- xtest_sync_with_i3;
+ xtest_sync_with($i3bar_window);
},
[ $left->{id} ],
'button 3 moves focus left';
sub {
xtest_button_press(4, 3, 3);
xtest_button_release(4, 3, 3);
- xtest_sync_with_i3;
+ xtest_sync_with($i3bar_window);
},
[ $right->{id} ],
'button 4 moves focus right';
sub {
xtest_button_press(5, 3, 3);
xtest_button_release(5, 3, 3);
- xtest_sync_with_i3;
+ xtest_sync_with($i3bar_window);
},
[ $left->{id} ],
'button 5 moves focus left';