# one on the first call of sync_with_i3. It will be re-used in all
# subsequent calls.
if (!defined($_sync_window)) {
- $_sync_window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => X11::XCB::Rect->new(x => -15, y => -15, width => 10, height => 10 ),
+ $_sync_window = open_window(
+ rect => [ -15, -15, 10, 10 ],
override_redirect => 1,
- background_color => '#ff0000',
- event_mask => [ 'structure_notify' ],
);
-
- $_sync_window->map;
-
- wait_for_event 2, sub { $_[0]->{response_type} == MAP_NOTIFY };
}
my $root = $x->get_root_window();
# vim:ts=4:sw=4:expandtab
use i3test;
-use X11::XCB 'WINDOW_CLASS_INPUT_OUTPUT';
my $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
-my $window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => $original_rect,
- background_color => '#C0C0C0',
-);
-
+my $window = open_window(rect => $original_rect, dont_map => 1);
isa_ok($window, 'X11::XCB::Window');
is_deeply($window->rect, $original_rect, "rect unmodified before mapping");
$window->map;
-
-sleep(0.5);
+wait_for_map $window;
my $new_rect = $window->rect;
ok(!eq_hash($new_rect, $original_rect), "Window got repositioned");
# vim:ts=4:sw=4:expandtab
use i3test;
-use X11::XCB 'WINDOW_CLASS_INPUT_OUTPUT';
my $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
-my $window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
+my $window = open_window(
rect => $original_rect,
override_redirect => 1,
- background_color => '#C0C0C0',
+ dont_map => 1,
);
isa_ok($window, 'X11::XCB::Window');
# vim:ts=4:sw=4:expandtab
use i3test;
-use X11::XCB 'WINDOW_CLASS_INPUT_OUTPUT';
# Create a floating window which is smaller than the minimum enforced size of i3
-my $window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30],
- background_color => '#C0C0C0',
- # replace the type with 'utility' as soon as the coercion works again in X11::XCB
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
- event_mask => [ 'structure_notify' ],
-);
+my $window = open_floating_window;
isa_ok($window, 'X11::XCB::Window');
-$window->map;
-
-wait_for_map $window;
-
my ($absolute, $top) = $window->rect;
ok($window->mapped, 'Window is mapped');
$window->unmap;
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 1, 1, 80, 90],
- background_color => '#C0C0C0',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
- event_mask => [ 'structure_notify' ],
-);
+$window = open_floating_window(rect => [ 1, 1, 80, 90 ]);
isa_ok($window, 'X11::XCB::Window');
-$window->map;
-
-wait_for_map $window;
-
($absolute, $top) = $window->rect;
cmp_ok($absolute->{width}, '==', 80, "i3 let the width at 80");
# at least the size of its initial geometry
#####################################################################
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 1, 1, 80, 90],
- background_color => '#C0C0C0',
- #window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
- event_mask => [ 'structure_notify' ],
-);
+$window = open_window(rect => [ 1, 1, 80, 90 ]);
isa_ok($window, 'X11::XCB::Window');
-$window->map;
-
-wait_for_map $window;
-
cmd 'floating enable';
sync_with_i3;
# vim:ts=4:sw=4:expandtab
use i3test;
-use X11::XCB 'WINDOW_CLASS_INPUT_OUTPUT';
use List::Util qw(first);
my $i3 = i3(get_socket_path());
my $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
-my $window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
+my $window = open_window(
rect => $original_rect,
- background_color => '#C0C0C0',
- event_mask => [ 'structure_notify' ],
+ dont_map => 1,
);
isa_ok($window, 'X11::XCB::Window');
cmd 'open';
$original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
+$window = open_window(
rect => $original_rect,
- background_color => 61440,
- event_mask => [ 'structure_notify' ],
+ dont_map => 1,
);
is_deeply($window->rect, $original_rect, "rect unmodified before mapping");
###############################################################################
$original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
-my $swindow = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
+my $swindow = open_window(
rect => $original_rect,
- background_color => '#C0C0C0',
- event_mask => [ 'structure_notify' ],
+ dont_map => 1,
);
$swindow->map;
# Tests all kinds of matching methods
#
use i3test;
-use X11::XCB qw(PROP_MODE_REPLACE WINDOW_CLASS_INPUT_OUTPUT);
+use X11::XCB qw(PROP_MODE_REPLACE);
my $tmp = fresh_workspace;
);
}
-my $left = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
- event_mask => [ 'structure_notify' ],
-);
-
-$left->_create;
-set_wm_class($left->id, 'special', 'special');
-$left->name('left');
-$left->map;
-ok(wait_for_map($left), 'left window mapped');
-
-my $right = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
- event_mask => [ 'structure_notify' ],
-);
-
-$right->_create;
-set_wm_class($right->id, 'special', 'special');
-$right->name('right');
-$right->map;
-ok(wait_for_map($right), 'right window mapped');
+sub open_special {
+ my %args = @_;
+ my $wm_class = delete($args{wm_class}) || 'special';
+
+ return open_window(
+ %args,
+ before_map => sub { set_wm_class($_->id, $wm_class, $wm_class) },
+ );
+}
+
+my $left = open_special(name => 'left');
+ok($left->mapped, 'left window mapped');
+
+my $right = open_special(name => 'right');
+ok($right->mapped, 'right window mapped');
# two windows should be here
$content = get_ws_content($tmp);
$tmp = fresh_workspace;
-$left = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
- event_mask => [ 'structure_notify' ],
-);
-
-$left->_create;
-set_wm_class($left->id, 'special7', 'special7');
-$left->name('left');
-$left->map;
-ok(wait_for_map($left), 'left window mapped');
+$left = open_special(name => 'left', wm_class => 'special7');
+ok($left->mapped, 'left window mapped');
# two windows should be here
$content = get_ws_content($tmp);
$tmp = fresh_workspace;
-$left = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
- event_mask => [ 'structure_notify' ],
-);
-
-$left->_create;
-set_wm_class($left->id, 'special7', 'special7');
-$left->name('ä 3');
-$left->map;
-ok(wait_for_map($left), 'left window mapped');
+$left = open_special(name => 'ä 3', wm_class => 'special7');
+ok($left->mapped, 'left window mapped');
# two windows should be here
$content = get_ws_content($tmp);
# Tests splitting
#
use i3test;
-use X11::XCB qw(:all);
my $tmp = fresh_workspace;
# found in 4be3178d4d360c2996217d811e61161c84d25898
#
use i3test;
-use X11::XCB 'WINDOW_CLASS_INPUT_OUTPUT';
my $i3 = i3(get_socket_path());
# open a dock client
-my $window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30],
- background_color => '#FF0000',
+my $window = open_window(
window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
);
-$window->map;
-
-sleep 0.25;
-
#####################################################################
# check that we can find it in the layout tree at the expected position
#####################################################################
#
#
use i3test;
-use X11::XCB qw(PROP_MODE_REPLACE WINDOW_CLASS_INPUT_OUTPUT);
+use X11::XCB qw(PROP_MODE_REPLACE);
##############################################################
# 1: test the following directive:
my $tmp = fresh_workspace;
-my $window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#00ff00',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->name('Border window');
-$window->map;
-wait_for_map $window;
+my $window = open_window(name => 'Border window');
my @content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 1, 'one node on this workspace now');
cmp_ok(@content, '==', 0, 'no more nodes');
diag('content = '. Dumper(\@content));
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#00ff00',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->_create;
# TODO: move this to X11::XCB::Window
sub set_wm_class {
);
}
-set_wm_class($window->id, 'borderless', 'borderless');
-$window->name('Borderless window');
-$window->map;
-wait_for_map $window;
+$window = open_window(
+ name => 'Borderless window',
+ before_map => sub { set_wm_class($_->id, 'borderless', 'borderless') },
+);
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 1, 'one node on this workspace now');
$tmp = fresh_workspace;
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#00ff00',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->name('special title');
-$window->map;
-wait_for_map $window;
+$window = open_window(name => 'special title');
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 1, 'one node on this workspace now');
$tmp = fresh_workspace;
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#00ff00',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->name('special mark title');
-$window->map;
-wait_for_map $window;
+$window = open_window(name => 'special mark title');
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 1, 'one node on this workspace now');
$tmp = fresh_workspace;
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#00ff00',
- event_mask => [ 'structure_notify' ],
+$window = open_window(
+ name => 'usethis',
+ before_map => sub { set_wm_class($_->id, 'borderless', 'borderless') },
);
-$window->_create;
-
-set_wm_class($window->id, 'borderless', 'borderless');
-$window->name('usethis');
-$window->map;
-wait_for_map $window;
-
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'none', 'no border');
$tmp = fresh_workspace;
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#00ff00',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->_create;
-set_wm_class($window->id, 'bar', 'foo');
-$window->name('usethis');
-$window->map;
-wait_for_map $window;
+$window = open_window(
+ name => 'usethis',
+ before_map => sub { set_wm_class($_->id, 'bar', 'foo') },
+);
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 1, 'one node on this workspace now');
$tmp = fresh_workspace;
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#00ff00',
- event_mask => [ 'structure_notify' ],
+$window = open_window(
+ name => 'usethis',
+ before_map => sub { set_wm_class($_->id, 'bar', 'foo') },
);
-$window->_create;
-
-set_wm_class($window->id, 'bar', 'foo');
-$window->name('usethis');
-$window->map;
-wait_for_map $window;
-
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'none', 'no border');
$tmp = fresh_workspace;
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#00ff00',
- event_mask => [ 'structure_notify' ],
+$window = open_window(
+ name => 'usethis',
+ before_map => sub { set_wm_class($_->id, 'bar', 'foo') },
);
-$window->_create;
-
-set_wm_class($window->id, 'bar', 'foo');
-$window->name('usethis');
-$window->map;
-wait_for_map $window;
-
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'normal', 'normal border');
$tmp = fresh_workspace;
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#00ff00',
- event_mask => [ 'structure_notify' ],
+$window = open_window(
+ name => 'usethis',
+ before_map => sub {
+ my ($window) = @_;
+ my $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
+ my $atomtype = $x->atom(name => 'STRING');
+ $x->change_property(
+ PROP_MODE_REPLACE,
+ $window->id,
+ $atomname->id,
+ $atomtype->id,
+ 8,
+ length("i3test") + 1,
+ "i3test\x00"
+ );
+ },
);
-$window->_create;
-
-my $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
-my $atomtype = $x->atom(name => 'STRING');
-$x->change_property(
- PROP_MODE_REPLACE,
- $window->id,
- $atomname->id,
- $atomtype->id,
- 8,
- length("i3test") + 1,
- "i3test\x00"
-);
-
-$window->name('usethis');
-$window->map;
-wait_for_map $window;
-
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'none', 'no border (window_role)');
$tmp = fresh_workspace;
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#00ff00',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->_create;
-
-$window->name('usethis');
-$window->map;
-wait_for_map $window;
+$window = open_window(name => 'usethis');
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'normal', 'normal border (window_role 2)');
-$atomname = $x->atom(name => 'WM_WINDOW_ROLE');
-$atomtype = $x->atom(name => 'STRING');
+my $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
+my $atomtype = $x->atom(name => 'STRING');
$x->change_property(
PROP_MODE_REPLACE,
$window->id,
# Tests if assignments work
#
use i3test;
-use X11::XCB qw(PROP_MODE_REPLACE WINDOW_CLASS_INPUT_OUTPUT);
+use X11::XCB qw(PROP_MODE_REPLACE);
# TODO: move to X11::XCB
sub set_wm_class {
);
}
+sub open_special {
+ my %args = @_;
+ my $wm_class = delete($args{wm_class}) || 'special';
+ $args{name} //= 'special window';
+
+ return open_window(
+ %args,
+ before_map => sub { set_wm_class($_->id, $wm_class, $wm_class) },
+ );
+}
#####################################################################
# start a window and see that it does not get assigned with an empty config
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
-my $window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->_create;
-set_wm_class($window->id, 'special', 'special');
-$window->name('special window');
-$window->map;
-wait_for_map $window;
+my $window = open_special;
ok(@{get_ws_content($tmp)} == 1, 'special window got managed to current (random) workspace');
my $workspaces = get_workspace_names;
ok(!("targetws" ~~ @{$workspaces}), 'targetws does not exist yet');
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->_create;
-set_wm_class($window->id, 'special', 'special');
-$window->name('special window');
-$window->map;
-wait_for_map $window;
+$window = open_special;
ok(@{get_ws_content($tmp)} == 0, 'still no containers');
ok("targetws" ~~ @{get_workspace_names()}, 'targetws exists');
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
ok("targetws" ~~ @{get_workspace_names()}, 'targetws does not exist yet');
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->_create;
-set_wm_class($window->id, 'special', 'special');
-$window->name('special window');
-$window->map;
# We use sync_with_i3 instead of wait_for_map here because i3 will not actually
# map the window -- it will be assigned to a different workspace and will only
# be mapped once you switch to that workspace
+$window = open_special(dont_map => 1);
+$window->map;
sync_with_i3;
ok(@{get_ws_content($tmp)} == 0, 'still no containers');
$workspaces = get_workspace_names;
ok(!("targetws" ~~ @{$workspaces}), 'targetws does not exist yet');
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->_create;
-set_wm_class($window->id, 'special', 'special');
-$window->name('special window');
-$window->map;
-wait_for_map $window;
+$window = open_special;
my $content = get_ws($tmp);
ok(@{$content->{nodes}} == 0, 'no tiling cons');
$workspaces = get_workspace_names;
ok(!("targetws" ~~ @{$workspaces}), 'targetws does not exist yet');
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->_create;
-set_wm_class($window->id, 'SPEcial', 'SPEcial');
-$window->name('special window');
-$window->map;
-wait_for_map $window;
+$window = open_special(wm_class => 'SPEcial');
$content = get_ws($tmp);
ok(@{$content->{nodes}} == 0, 'no tiling cons');
# syntax
is(@docked, 1, 'one dock client yet');
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
+$window = open_special(
window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
- event_mask => [ 'structure_notify' ],
);
-$window->_create;
-set_wm_class($window->id, 'special', 'special');
-$window->name('special window');
-$window->map;
-wait_for_map $window;
-
$content = get_ws($tmp);
ok(@{$content->{nodes}} == 0, 'no tiling cons');
ok(@{$content->{floating_nodes}} == 0, 'one floating con');
exit_gracefully($pid);
-sleep 0.25;
-
done_testing;
# assigned to an invisible workspace
#
use i3test;
-use X11::XCB qw(PROP_MODE_REPLACE WINDOW_CLASS_INPUT_OUTPUT);
+use X11::XCB qw(PROP_MODE_REPLACE);
# TODO: move to X11::XCB
sub set_wm_class {
);
}
+sub open_special {
+ my %args = @_;
+ my $wm_class = delete($args{wm_class}) || 'special';
+ $args{name} //= 'special window';
+
+ return open_window(
+ %args,
+ before_map => sub { set_wm_class($_->id, $wm_class, $wm_class) },
+ );
+}
#####################################################################
# start a window and see that it does not get assigned with an empty config
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
ok(get_ws($tmp)->{focused}, 'current workspace focused');
-my $window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
-);
-
-$window->_create;
-set_wm_class($window->id, 'special', 'special');
-$window->name('special window');
-$window->map;
-sleep 0.25;
-
+my $window = open_special;
ok(@{get_ws_content($tmp)} == 0, 'special window not on current workspace');
ok(@{get_ws_content('targetws')} == 1, 'special window on targetws');
# the same test, but with a floating window
#####################################################################
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#0000ff',
+$window = open_special(
window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
);
-$window->_create;
-set_wm_class($window->id, 'special', 'special');
-$window->name('special window');
-$window->map;
-sleep 0.25;
-
-
ok(@{get_ws_content($tmp)} == 0, 'special window not on current workspace');
ok(@{get_ws_content('targetws')} == 1, 'special window on targetws');
ok(get_ws($tmp)->{focused}, 'current workspace still focused');