#####################################################################
# Create a window so we can get a focus different from NULL
-my $window = open_standard_window($x);
-sync_with_i3($x);
+my $window = open_window($x);
my $focus = $x->input_focus;
# vim:ts=4:sw=4:expandtab
use i3test;
-use X11::XCB qw(:all);
-
-BEGIN {
- use_ok('X11::XCB::Connection') or BAIL_OUT('Cannot load X11::XCB::Connection');
-}
my $x = X11::XCB::Connection->new;
-my $i3 = i3(get_socket_path());
my $tmp = fresh_workspace;
#####################################################################
cmd 'layout default';
cmd 'split v';
-my $top = open_standard_window($x);
-my $mid = open_standard_window($x);
-my $bottom = open_standard_window($x);
-##sleep 0.25;
-
-diag("top id = " . $top->id);
-diag("mid id = " . $mid->id);
-diag("bottom id = " . $bottom->id);
+my $top = open_window($x);
+my $mid = open_window($x);
+my $bottom = open_window($x);
#
# Returns the input focus after sending the given command to i3 via IPC
sub focus_after {
my $msg = shift;
- $i3->command($msg)->recv;
+ cmd $msg;
+ sync_with_i3 $x;
return $x->input_focus;
}
my $x = X11::XCB::Connection->new;
-my $i3 = i3(get_socket_path());
fresh_workspace;
cmd 'split h';
-my $tiled_left = open_standard_window($x);
-my $tiled_right = open_standard_window($x);
-
-sync_with_i3($x);
+my $tiled_left = open_window($x);
+my $tiled_right = open_window($x);
# Get input focus before creating the floating window
my $focus = $x->input_focus;
# Create a floating window which is smaller than the minimum enforced size of i3
-my $window = open_standard_window($x, undef, 1);
-sync_with_i3($x);
+my $window = open_floating_window($x);
is($x->input_focus, $window->id, 'floating window focused');
$window->unmap;
-# TODO: wait for unmap
-sync_with_i3($x);
+wait_for_unmap($x);
is($x->input_focus, $focus, 'Focus correctly restored');
my $primary = first { $_->primary } @{$screens};
# TODO: focus the primary screen before
-
-my $window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30],
- background_color => '#FF0000',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
- event_mask => [ 'structure_notify' ],
-);
-
-$window->map;
-
-wait_for_map $x;
+my $window = open_window($x, {
+ window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
+ });
my $rect = $window->rect;
is($rect->width, $primary->rect->width, 'dock client is as wide as the screen');
# check if it gets placed on bottom (by coordinates)
#####################################################################
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 1000, 30, 30],
- background_color => '#FF0000',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
- event_mask => [ 'structure_notify' ],
-);
-
-$window->map;
-
-wait_for_map $x;
+$window = open_window($x, {
+ rect => [ 0, 1000, 30, 30 ],
+ background_color => '#FF0000',
+ window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
+ });
my $rect = $window->rect;
is($rect->width, $primary->rect->width, 'dock client is as wide as the screen');
# check if it gets placed on bottom (by hint)
#####################################################################
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 1000, 30, 30],
- background_color => '#FF0000',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
- event_mask => [ 'structure_notify' ],
-);
+$window = open_window($x, {
+ dont_map => 1,
+ rect => [ 0, 1000, 30, 30 ],
+ background_color => '#FF0000',
+ window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
+ });
$window->_create();
@docked = get_dock_clients();
is(@docked, 0, 'no more dock clients');
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 1000, 30, 30],
- background_color => '#FF0000',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
- event_mask => [ 'structure_notify' ],
-);
+$window = open_window($x, {
+ dont_map => 1,
+ rect => [ 0, 1000, 30, 30 ],
+ background_color => '#FF0000',
+ window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
+ });
$window->_create();
# regression test: transient dock client
#####################################################################
-my $fwindow = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30],
- background_color => '#FF0000',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
- event_mask => [ 'structure_notify' ],
-);
+$fwindow = open_window($x, {
+ dont_map => 1,
+ background_color => '#FF0000',
+ window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
+ });
$fwindow->transient_for($window);
$fwindow->map;
my $x = X11::XCB::Connection->new;
-my $i3 = i3(get_socket_path());
my $tmp = fresh_workspace;
cmd 'split h';
# Create two windows and make sure focus switching works
#####################################################################
-my $top = open_standard_window($x);
-my $mid = open_standard_window($x);
-my $bottom = open_standard_window($x);
-
-diag("top id = " . $top->id);
-diag("mid id = " . $mid->id);
-diag("bottom id = " . $bottom->id);
+my $top = open_window($x);
+my $mid = open_window($x);
+my $bottom = open_window($x);
#
# Returns the input focus after sending the given command to i3 via IPC
$focus = focus_after(qq|[con_mark="$random_mark"] focus|);
is($focus, $mid->id, "focus unchanged");
-$i3->command("mark $random_mark")->recv;
+cmd "mark $random_mark";
$focus = focus_after('focus left');
is($focus, $top->id, "Top window focused");
# Create a floating window and see if resizing works
#####################################################################
-# Create a floating window
-my $window = open_standard_window($x, undef, 1);
+my $window = open_floating_window($x);
# See if configurerequests cause window movements (they should not)
my ($a, $t) = $window->rect;
cmd 'split v';
-my $top = open_standard_window($x);
-my $bottom = open_standard_window($x);
+my $top = open_window($x);
+my $bottom = open_window($x);
my @urgent = grep { $_->{urgent} } @{get_ws_content($tmp)};
is(@urgent, 0, 'no window got the urgent flag');
# one of both (depending on your screen resolution) will be positioned wrong.
####################################################################################
-my $left = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [0, 0, 30, 30],
- background_color => '#FF0000',
- event_mask => [ 'structure_notify' ],
-);
-
-$left->name('Left');
-$left->map;
-
-my $right = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [0, 0, 30, 30],
- background_color => '#FF0000',
- event_mask => [ 'structure_notify' ],
-);
-
-$right->name('Right');
-$right->map;
-
-ok(wait_for_map($x), 'left window mapped');
-ok(wait_for_map($x), 'right window mapped');
+my $left = open_window($x, { name => 'Left' });
+my $right = open_window($x, { name => 'Right' });
my ($abs, $rgeom) = $right->rect;
-my $child = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#C0C0C0',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
- event_mask => [ 'structure_notify' ],
-);
-
-$child->name('Child window');
+my $child = open_floating_window($x, {
+ dont_map => 1,
+ name => 'Child window',
+ });
$child->client_leader($right);
$child->map;
($abs, $cgeom) = $child->rect;
cmp_ok($cgeom->x, '>=', $rgeom->x, 'Child X >= right container X');
-my $child2 = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#C0C0C0',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
- event_mask => [ 'structure_notify' ],
-);
-
-$child2->name('Child window 2');
+my $child2 = open_floating_window($x, {
+ dont_map => 1,
+ name => 'Child window 2',
+ });
$child2->client_leader($left);
$child2->map;
cmp_ok(($cgeom->x + $cgeom->width), '<', $rgeom->x, 'child above left window');
# check wm_transient_for
-
-
-my $fwindow = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30],
- background_color => '#FF0000',
- event_mask => [ 'structure_notify' ],
-);
-
+my $fwindow = open_window($x, { dont_map => 1 });
$fwindow->transient_for($right);
$fwindow->map;
# Create a parent window
#####################################################################
-my $window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#C0C0C0',
- event_mask => [ 'structure_notify' ],
-);
-
-$window->name('Parent window');
+my $window = open_window($x, { dont_map => 1, name => 'Parent window' });
$window->map;
ok(wait_for_map($x), 'parent window mapped');
#########################################################################
fresh_workspace;
-my $child = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30 ],
- background_color => '#C0C0C0',
- event_mask => [ 'structure_notify' ],
-);
-
-$child->name('Child window');
+my $child = open_window($x, { dont_map => 1, name => 'Child window' });
$child->client_leader($window);
$child->map;
# Open a new window
my $x = X11::XCB::Connection->new;
-my $window = open_standard_window($x);
+my $window = open_window($x);
my $content = get_ws_content($tmp);
ok(@{$content} == 1, 'window mapped');
my $win = $content->[0];
$middle = open_empty_con($i3);
# XXX: the $right empty con will be filled with the x11 window we are creating afterwards
$right = open_empty_con($i3);
-my $win = open_standard_window($x, '#00ff00');
+my $win = open_window($x, { background_color => '#00ff00' });
cmd qq|[con_id="$middle"] focus|;
$win->destroy;
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
-my $win = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30),
- background_color => '#C0C0C0',
- event_mask => [ 'structure_notify' ],
-);
-
+my $win = open_window($x, { dont_map => 1 });
# XXX: we should check screen size. in screens with an AR of 2.0,
# this is not a good idea.
my $aspect = X11::XCB::Sizehints::Aspect->new;
# 1: see if focus stays the same when toggling tiling/floating mode
#############################################################################
-my $first = open_standard_window($x);
-my $second = open_standard_window($x);
-
-sync_with_i3($x);
+my $first = open_window($x);
+my $second = open_window($x);
is($x->input_focus, $second->id, 'second window focused');
$tmp = fresh_workspace;
-$first = open_standard_window($x); # window 2
-$second = open_standard_window($x); # window 3
-my $third = open_standard_window($x); # window 4
-
-sync_with_i3($x);
+$first = open_window($x); # window 2
+$second = open_window($x); # window 3
+my $third = open_window($x); # window 4
is($x->input_focus, $third->id, 'last container focused');
$tmp = fresh_workspace;
-$first = open_standard_window($x, '#ff0000'); # window 5
-$second = open_standard_window($x, '#00ff00'); # window 6
-my $third = open_standard_window($x, '#0000ff'); # window 7
-
-sync_with_i3($x);
+$first = open_window($x, '#ff0000'); # window 5
+$second = open_window($x, '#00ff00'); # window 6
+my $third = open_window($x, '#0000ff'); # window 7
is($x->input_focus, $third->id, 'last container focused');
$tmp = fresh_workspace;
-$first = open_standard_window($x, '#ff0000'); # window 5
+$first = open_window($x, { background_color => '#ff0000' }); # window 5
cmd 'split v';
cmd 'layout stacked';
-$second = open_standard_window($x, '#00ff00'); # window 6
-$third = open_standard_window($x, '#0000ff'); # window 7
-
-sync_with_i3($x);
+$second = open_window($x, { background_color => '#00ff00' }); # window 6
+$third = open_window($x, { background_color => '#0000ff' }); # window 7
is($x->input_focus, $third->id, 'last container focused');
$tmp = fresh_workspace;
-$first = open_standard_window($x, '#ff0000'); # window 8
-$second = open_standard_window($x, '#00ff00'); # window 9
+$first = open_window($x, { background_color => '#ff0000' }); # window 8
+$second = open_window($x, { background_color => '#00ff00' }); # window 9
sync_with_i3($x);
$tmp = fresh_workspace;
-$first = open_standard_window($x, '#ff0000', 1); # window 10
-$second = open_standard_window($x, '#00ff00', 1); # window 11
-$third = open_standard_window($x, '#0000ff', 1); # window 12
+$first = open_floating_window($x, { background_color => '#ff0000' });# window 10
+$second = open_floating_window($x, { background_color => '#00ff00' }); # window 11
+$third = open_floating_window($x, { background_color => '#0000ff' }); # window 12
sync_with_i3($x);
my $x = X11::XCB::Connection->new;
# Create a floating window which is smaller than the minimum enforced size of i3
-my $window = open_standard_window($x, undef, 1);
+my $window = open_floating_window($x);
ok($window->mapped, 'Window is mapped');
# switch to a different workspace, see if the window is still mapped?
my $x = X11::XCB::Connection->new;
# Create a floating window which is smaller than the minimum enforced size of i3
-my $window = open_standard_window($x, undef, 1);
+my $window = open_floating_window($x);
ok($window->mapped, 'Window is mapped');
# switch to a different workspace, see if the window is still mapped?
my $x = X11::XCB::Connection->new;
# Create a floating window
-my $window = open_standard_window($x, undef, 1);
+my $window = open_floating_window($x);
ok($window->mapped, 'Window is mapped');
my $ws = get_ws($tmp);
is(@{$nodes}, 0, 'no tiling nodes');
# Create a tiling window
-my $twindow = open_standard_window($x);
+my $twindow = open_window($x);
($nodes, $focus) = get_ws_content($tmp);
$tmp = fresh_workspace;
-my $first = open_standard_window($x);
-my $second = open_standard_window($x);
+my $first = open_window($x);
+my $second = open_window($x);
cmd 'layout stacked';
is(@{$ws->{nodes}}, 1, 'one tiling node (stacked con)');
# Create a floating window
-my $window = open_standard_window($x, undef, 1);
+my $window = open_floating_window($x);
ok($window->mapped, 'Window is mapped');
$ws = get_ws($tmp);
is(@{$ws->{floating_nodes}}, 1, 'one floating nodes');
is(@{$ws->{nodes}}, 1, 'one tiling node (stacked con)');
-my $third = open_standard_window($x);
+my $third = open_window($x);
$ws = get_ws($tmp);
cmd "workspace 93";
-open_standard_window($x);
+open_window($x);
my @ws = @{$i3->get_workspaces->recv};
my @f = grep { defined($_->{num}) && $_->{num} == 93 } @ws;
check_order('workspace order alright after opening 93');
cmd "workspace 92";
-open_standard_window($x);
+open_window($x);
check_order('workspace order alright after opening 92');
cmd "workspace 94";
-open_standard_window($x);
+open_window($x);
check_order('workspace order alright after opening 94');
cmd "workspace 96";
-open_standard_window($x);
+open_window($x);
check_order('workspace order alright after opening 96');
cmd "workspace foo";
-open_standard_window($x);
+open_window($x);
check_order('workspace order alright after opening foo');
cmd "workspace 91";
-open_standard_window($x);
+open_window($x);
check_order('workspace order alright after opening 91');
done_testing;
my $tmp = fresh_workspace;
-my $left = open_standard_window($x);
-my $mid = open_standard_window($x);
-my $right = open_standard_window($x);
+my $left = open_window($x);
+my $mid = open_window($x);
+my $right = open_window($x);
sync_with_i3($x);
cmd 'split v';
-my $top = open_standard_window($x);
-my $bottom = open_standard_window($x);
+my $top = open_window($x);
+my $bottom = open_window($x);
sync_with_i3($x);
cmd 'split v';
-$top = open_standard_window($x);
-$bottom = open_standard_window($x);
+$top = open_window($x);
+$bottom = open_window($x);
cmd 'split h';
cmd 'layout stacked';
$tmp = fresh_workspace;
-$top = open_standard_window($x);
+$top = open_window($x);
cmd 'floating enable';
my $tmp = fresh_workspace;
-my $left = open_standard_window($x);
-my $mid = open_standard_window($x);
-my $right = open_standard_window($x);
+my $left = open_window($x);
+my $mid = open_window($x);
+my $right = open_window($x);
cmd 'move before v';
cmd 'move after h';
my $tmp = fresh_workspace;
-my $left = open_standard_window($x);
-my $mid = open_standard_window($x);
+my $left = open_window($x);
+my $mid = open_window($x);
cmd 'split v';
-my $bottom = open_standard_window($x);
+my $bottom = open_window($x);
my ($nodes, $focus) = get_ws_content($tmp);
# 1: open a floating window, get it mapped
#############################################################################
-my $x = X11::XCB::Connection->new;
-
# Create a floating window
-my $window = open_standard_window($x, undef, 1);
+my $window = open_floating_window($x);
ok($window->mapped, 'Window is mapped');
($nodes, $focus) = get_ws_content($tmp);
my $tmp = fresh_workspace;
-my $left = open_standard_window($x);
-my $mid = open_standard_window($x);
-my $right = open_standard_window($x);
+my $left = open_window($x);
+my $mid = open_window($x);
+my $right = open_window($x);
# go to workspace level
cmd 'level up';
my $tmp = fresh_workspace;
# open a tiling window on the first workspace
-open_standard_window($x);
+open_window($x);
#sleep 0.25;
my $first = get_focused($tmp);
# on a different ws, open a floating window
my $otmp = fresh_workspace;
-open_standard_window($x);
+open_window($x);
#sleep 0.25;
my $float = get_focused($otmp);
cmd 'mode toggle';
}
my $x = X11::XCB::Connection->new;
-my $i3 = i3(get_socket_path());
my $tmp = fresh_workspace;
# open a dock client
-my $window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30],
- background_color => '#FF0000',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
- event_mask => [ 'structure_notify' ],
-);
-
-$window->map;
-
-wait_for_map $x;
+my $window = open_window($x, {
+ background_color => '#FF0000',
+ window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
+ });
#####################################################################
# check that we can find it in the layout tree at the expected position
# create a dock client with a 1px border
#####################################################################
-$window = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- border => 1,
- rect => [ 0, 0, 30, 20],
- background_color => '#00FF00',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
- event_mask => [ 'structure_notify' ],
-);
-
-$window->map;
-
-wait_for_map $x;
+$window = open_window($x, {
+ border => 1,
+ rect => [ 0, 0, 30, 20 ],
+ background_color => '#00FF00',
+ window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
+ });
@docked = get_dock_clients;
is(@docked, 1, 'one dock client found');
my $x = X11::XCB::Connection->new;
# 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, 400, 150],
- background_color => '#C0C0C0',
- event_mask => [ 'structure_notify' ],
-);
-
-isa_ok($window, 'X11::XCB::Window');
-
-$window->map;
-
-wait_for_map $x;
+my $window = open_window($x, { rect => [ 0, 0, 400, 150 ] });
my ($absolute, $top) = $window->rect;
# open a dock client
#####################################################################
-my $first = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30],
- background_color => '#FF0000',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
- event_mask => [ 'structure_notify' ],
-);
-
-$first->map;
-
-wait_for_map $x;
+my $first = open_window($x, {
+ background_color => '#FF0000',
+ window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
+ });
#####################################################################
# Open a second dock client
#####################################################################
-my $second = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 30, 30],
- background_color => '#FF0000',
- window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
- event_mask => [ 'structure_notify' ],
-);
-
-$second->map;
-
-wait_for_map $x;
+my $second = open_window($x, {
+ background_color => '#FF0000',
+ window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
+ });
#####################################################################
# Kill the second dock client
# open a window with 200x80
#####################################################################
-my $first = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 200, 80],
- background_color => '#FF0000',
- event_mask => [ 'structure_notify' ],
-);
-
-$first->map;
-
-wait_for_map $x;
+my $first = open_window($x, {
+ rect => [ 0, 0, 200, 80],
+ background_color => '#FF0000',
+ });
#####################################################################
# Open a second window with 300x90
#####################################################################
-my $second = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => [ 0, 0, 300, 90],
- background_color => '#00FF00',
- event_mask => [ 'structure_notify' ],
-);
-
-$second->map;
-
-wait_for_map $x;
+my $second = open_window($x, {
+ rect => [ 0, 0, 300, 90],
+ background_color => '#00FF00',
+ });
#####################################################################
# Set the parent to floating
# open the left window
#####################################################################
-my $left = open_standard_window($x, '#ff0000');
+my $left = open_window($x, { background_color => '#ff0000' });
is($x->input_focus, $left->id, 'left window focused');
# Open the right window
#####################################################################
-my $right = open_standard_window($x, '#00ff00');
+my $right = open_window($x, { background_color => '#00ff00' });
diag("right = " . $right->id);
# Open a third window
#####################################################################
-#my $third = open_standard_window($x, '#0000ff');
+my $third = open_window($x, {
+ background_color => '#0000ff',
+ name => 'Third window',
+ dont_map => 1,
+ });
-my $third = $x->root->create_child(
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30 ),
- background_color => '#0000ff',
- event_mask => [ 'structure_notify' ],
-);
-
-$third->name('Third window');
$third->map;
sync_with_i3 $x;
}
my $x = X11::XCB::Connection->new;
-my $i3 = i3(get_socket_path());
my $tmp = fresh_workspace;
# open a window, verify it’s not in fullscreen mode
#####################################################################
-my $win = open_standard_window($x);
+my $win = open_window($x);
my $nodes = get_ws_content $tmp;
is(@$nodes, 1, 'exactly one client');
}
my $x = X11::XCB::Connection->new;
-my $i3 = i3(get_socket_path());
subtest 'Window without WM_TAKE_FOCUS', sub {
my $x = X11::XCB::Connection->new;
my $i3 = i3(get_socket_path());
my $tmp = fresh_workspace;
-my $window = open_standard_window($x);
+my $window = open_window($x);
sub get_border_style {
my @content = @{get_ws_content($tmp)};
use X11::XCB qw(:all);
use i3test;
-BEGIN {
- use_ok('X11::XCB::Window');
- use_ok('X11::XCB::Event::Generic');
- use_ok('X11::XCB::Event::MapNotify');
- use_ok('X11::XCB::Event::ClientMessage');
-}
-
my $x = X11::XCB::Connection->new;
-my $window = open_standard_window($x);
+my $window = open_window($x);
sync_with_i3($x);
-diag('window mapped');
-
is($window->state, ICCCM_WM_STATE_NORMAL, 'WM_STATE normal');
$window->unmap;
-# TODO: wait for unmapnotify
-sync_with_i3($x);
+wait_for_unmap $x;
is($window->state, ICCCM_WM_STATE_WITHDRAWN, 'WM_STATE withdrawn');
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
- my $first = open_standard_window($x);
- my $second = open_standard_window($x);
+ my $first = open_window($x);
+ my $second = open_window($x);
sync_with_i3 $x;
cmp_ok(@content, '==', 1, 'one node on this workspace now');
is($content[0]->{border}, 'none', 'no border');
-my $other = open_standard_window($x);
+my $other = open_window($x);
@content = @{get_ws_content($tmp)};
cmp_ok(@content, '==', 2, 'two nodes');
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
-my $first = open_standard_window($x);
-my $second = open_standard_window($x);
+my $first = open_window($x);
+my $second = open_window($x);
sync_with_i3($x);
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
-$first = open_standard_window($x);
-$second = open_standard_window($x);
+$first = open_window($x);
+$second = open_window($x);
sync_with_i3($x);
#####################################################################
cmd 'focus parent';
-my $right_top = open_standard_window($x);
-my $right_bot = open_standard_window($x);
+my $right_top = open_window($x);
+my $right_bot = open_window($x);
@content = @{get_ws_content($tmp)};
is(@content, 2, 'two cons at workspace level after focus parent');
fresh_workspace;
-open_standard_window($x);
-open_standard_window($x);
+open_window($x);
+open_window($x);
cmd 'layout stacking';
sleep 1;
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
-my $first = open_standard_window($x);
-my $second = open_standard_window($x);
+my $first = open_window($x);
+my $second = open_window($x);
cmd 'layout tabbed';
cmd 'focus parent';
-my $third = open_standard_window($x);
+my $third = open_window($x);
is($x->input_focus, $third->id, 'third window focused');
cmd 'focus left';
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
-$first = open_standard_window($x);
-$second = open_standard_window($x);
+$first = open_window($x);
+$second = open_window($x);
cmd 'layout tabbed';
cmd 'focus parent';
-$third = open_standard_window($x);
+$third = open_window($x);
sync_with_i3($x);
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
-my $first = open_standard_window($x);
+my $first = open_window($x);
my @content = @{get_ws_content($tmp)};
ok(@content == 1, 'one container opened');
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
-$first = open_standard_window($x);
+$first = open_window($x);
@content = @{get_ws_content($tmp)};
ok(@content == 1, 'one container opened');
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
-# Create a floating window which is smaller than the minimum enforced size of i3
-$first = $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' ],
-);
-
-$first->map;
-
-wait_for_map $x;
+$first = open_floating_window($x);
my $wscontent = get_ws($tmp);
my @floating = @{$wscontent->{floating_nodes}};
ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
-# Create a floating window which is smaller than the minimum enforced size of i3
-$first = $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' ],
-);
-
-$first->map;
-
-wait_for_map $x;
+$first = open_floating_window($x);
$wscontent = get_ws($tmp);
@floating = @{$wscontent->{floating_nodes}};
get_ws
get_focused
open_empty_con
- open_standard_window
+ open_window
+ open_floating_window
get_dock_clients
cmd
sync_with_i3
sync_with_i3($x);
}
-sub open_standard_window {
- my ($x, $color, $floating) = @_;
+#
+# Opens a new window (see X11::XCB::Window), maps it, waits until it got mapped
+# and synchronizes with i3.
+#
+# set dont_map to a true value to avoid mapping
+#
+# default values:
+# class => WINDOW_CLASS_INPUT_OUTPUT
+# rect => [ 0, 0, 30, 30 ]
+# background_color => '#c0c0c0'
+# event_mask => [ 'structure_notify' ]
+# name => 'Window <n>'
+#
+sub open_window {
+ my ($x, $args) = @_;
+ my %args = ($args ? %$args : ());
- $color ||= '#c0c0c0';
+ my $dont_map = delete $args{dont_map};
- # We cannot use a hashref here because create_child expands the arguments into an array
- my @args = (
- class => WINDOW_CLASS_INPUT_OUTPUT,
- rect => X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30 ),
- background_color => $color,
- event_mask => [ 'structure_notify' ],
- );
+ $args{class} = WINDOW_CLASS_INPUT_OUTPUT unless exists $args{class};
+ $args{rect} = [ 0, 0, 30, 30 ] unless exists $args{rect};
+ $args{background_color} = '#c0c0c0' unless exists $args{background_color};
+ $args{event_mask} = [ 'structure_notify' ] unless exists $args{event_mask};
+ $args{name} = 'Window ' . counter_window() unless exists $args{name};
- if (defined($floating) && $floating) {
- @args = (@args, window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'));
- }
+ my $window = $x->root->create_child(%args);
- my $window = $x->root->create_child(@args);
+ return $window if $dont_map;
- $window->name('Window ' . counter_window());
$window->map;
+ wait_for_map($x);
+ # We sync with i3 here to make sure $x->input_focus is updated.
+ sync_with_i3($x);
+ return $window;
+}
- wait_for_event $x, 0.5, sub { $_[0]->{response_type} == MAP_NOTIFY };
+# Thin wrapper around open_window which sets window_type to
+# _NET_WM_WINDOW_TYPE_UTILITY to make the window floating.
+sub open_floating_window {
+ my ($x, $args) = @_;
+ my %args = ($args ? %$args : ());
- return $window;
+ $args{window_type} = $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY');
+
+ return open_window($x, \%args);
}
sub open_empty_con {