correctly sort numbered workspaces (+testcase)
Numbered workspaces (workspaces with a name containing only digits) will be inserted in the correct order now. Named workspaces are always sorted after numbered workspaces and in the order of creation.next
parent
fab8b84db7
commit
1de97a1f1f
|
@ -281,6 +281,10 @@ struct Con {
|
|||
|
||||
char *name;
|
||||
|
||||
/** the workspace number, if this Con is of type CT_WORKSPACE and the
|
||||
* workspace is not a named workspace (for named workspaces, num == -1) */
|
||||
int num;
|
||||
|
||||
/* a sticky-group is an identifier which bundles several containers to a
|
||||
* group. The contents are shared between all of them, that is they are
|
||||
* displayed on whichever of the containers is currently visible */
|
||||
|
|
34
src/con.c
34
src/con.c
|
@ -72,6 +72,35 @@ void con_attach(Con *con, Con *parent) {
|
|||
con->parent = parent;
|
||||
Con *loop;
|
||||
Con *current = NULL;
|
||||
struct nodes_head *nodes_head = &(parent->nodes_head);
|
||||
|
||||
/* Workspaces are handled differently: they need to be inserted at the
|
||||
* right position. */
|
||||
if (con->type == CT_WORKSPACE) {
|
||||
DLOG("it's a workspace. num = %d\n", con->num);
|
||||
if (con->num == -1 || TAILQ_EMPTY(nodes_head)) {
|
||||
TAILQ_INSERT_TAIL(nodes_head, con, nodes);
|
||||
} else {
|
||||
current = TAILQ_FIRST(nodes_head);
|
||||
if (con->num < current->num) {
|
||||
/* we need to insert the container at the beginning */
|
||||
TAILQ_INSERT_HEAD(nodes_head, con, nodes);
|
||||
return;
|
||||
}
|
||||
while (current->num != -1 && con->num > current->num) {
|
||||
current = TAILQ_NEXT(current, nodes);
|
||||
if (current == TAILQ_END(nodes_head)) {
|
||||
current = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* we need to insert con after current, if current is not NULL */
|
||||
if (current)
|
||||
TAILQ_INSERT_BEFORE(current, con, nodes);
|
||||
else TAILQ_INSERT_TAIL(nodes_head, con, nodes);
|
||||
}
|
||||
goto add_to_focus_head;
|
||||
}
|
||||
|
||||
/* Get the first tiling container in focus stack */
|
||||
TAILQ_FOREACH(loop, &(parent->focus_head), focused) {
|
||||
|
@ -85,9 +114,10 @@ void con_attach(Con *con, Con *parent) {
|
|||
if (current) {
|
||||
DLOG("Inserting con = %p after last focused tiling con %p\n",
|
||||
con, current);
|
||||
TAILQ_INSERT_AFTER(&(parent->nodes_head), current, con, nodes);
|
||||
} else TAILQ_INSERT_TAIL(&(parent->nodes_head), con, nodes);
|
||||
TAILQ_INSERT_AFTER(nodes_head, current, con, nodes);
|
||||
} else TAILQ_INSERT_TAIL(nodes_head, con, nodes);
|
||||
|
||||
add_to_focus_head:
|
||||
/* We insert to the TAIL because con_focus() will correct this.
|
||||
* This way, we have the option to insert Cons without having
|
||||
* to focus them. */
|
||||
|
|
|
@ -269,7 +269,9 @@ IPC_HANDLER(get_workspaces) {
|
|||
y(map_open);
|
||||
|
||||
ystr("num");
|
||||
y(integer, con_num_children(ws));
|
||||
if (ws->num == -1)
|
||||
y(null);
|
||||
else y(integer, ws->num);
|
||||
|
||||
ystr("name");
|
||||
ystr(ws->name);
|
||||
|
|
|
@ -77,10 +77,12 @@ void tree_init() {
|
|||
free(name);
|
||||
|
||||
/* add a workspace to this output */
|
||||
ws = con_new(oc);
|
||||
ws = con_new(NULL);
|
||||
ws->type = CT_WORKSPACE;
|
||||
ws->num = c;
|
||||
asprintf(&(ws->name), "%d", c);
|
||||
c++;
|
||||
con_attach(ws, oc);
|
||||
|
||||
asprintf(&name, "[i3 con] workspace %s", ws->name);
|
||||
x_set_name(ws, name);
|
||||
|
|
|
@ -38,14 +38,28 @@ Con *workspace_get(const char *num) {
|
|||
LOG("need to create this one\n");
|
||||
output = con_get_output(focused);
|
||||
LOG("got output %p\n", output);
|
||||
workspace = con_new(output);
|
||||
/* We need to attach this container after setting its type. con_attach
|
||||
* will handle CT_WORKSPACEs differently */
|
||||
workspace = con_new(NULL);
|
||||
char *name;
|
||||
asprintf(&name, "[i3 con] workspace %s", num);
|
||||
x_set_name(workspace, name);
|
||||
free(name);
|
||||
workspace->type = CT_WORKSPACE;
|
||||
workspace->name = strdup(num);
|
||||
/* We set ->num to the number if this workspace’s name consists only of
|
||||
* a positive number. Otherwise it’s a named ws and num will be -1. */
|
||||
char *end;
|
||||
long parsed_num = strtol(num, &end, 10);
|
||||
if (parsed_num == LONG_MIN ||
|
||||
parsed_num == LONG_MAX ||
|
||||
parsed_num < 0 ||
|
||||
(end && *end != '\0'))
|
||||
workspace->num = -1;
|
||||
else workspace->num = parsed_num;
|
||||
LOG("num = %d\n", workspace->num);
|
||||
workspace->orientation = HORIZ;
|
||||
con_attach(workspace, output);
|
||||
|
||||
ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"init\"}");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#!perl
|
||||
# vim:ts=4:sw=4:expandtab
|
||||
# Check if numbered workspaces and named workspaces are sorted in the right way
|
||||
# in get_workspaces IPC output (necessary for i3bar etc.).
|
||||
use i3test tests => 9;
|
||||
use X11::XCB qw(:all);
|
||||
use Time::HiRes qw(sleep);
|
||||
|
||||
BEGIN {
|
||||
use_ok('X11::XCB::Window');
|
||||
}
|
||||
|
||||
my $i3 = i3("/tmp/nestedcons");
|
||||
my $x = X11::XCB::Connection->new;
|
||||
|
||||
sub check_order {
|
||||
my ($msg) = @_;
|
||||
|
||||
my @ws = @{$i3->get_workspaces->recv};
|
||||
my @nums = map { $_->{num} } grep { defined($_->{num}) } @ws;
|
||||
my @sorted = sort @nums;
|
||||
|
||||
cmp_deeply(\@nums, \@sorted, $msg);
|
||||
}
|
||||
|
||||
check_order('workspace order alright before testing');
|
||||
|
||||
#############################################################################
|
||||
# open a window to keep this ws open
|
||||
#############################################################################
|
||||
|
||||
$i3->command("workspace 93")->recv;
|
||||
|
||||
open_standard_window($x);
|
||||
|
||||
my @ws = @{$i3->get_workspaces->recv};
|
||||
my @f = grep { defined($_->{num}) && $_->{num} == 93 } @ws;
|
||||
is(@f, 1, 'ws 93 found by num');
|
||||
check_order('workspace order alright after opening 93');
|
||||
|
||||
$i3->command("workspace 92")->recv;
|
||||
open_standard_window($x);
|
||||
check_order('workspace order alright after opening 92');
|
||||
|
||||
$i3->command("workspace 94")->recv;
|
||||
open_standard_window($x);
|
||||
check_order('workspace order alright after opening 94');
|
||||
|
||||
$i3->command("workspace 96")->recv;
|
||||
open_standard_window($x);
|
||||
check_order('workspace order alright after opening 96');
|
||||
|
||||
$i3->command("workspace foo")->recv;
|
||||
open_standard_window($x);
|
||||
check_order('workspace order alright after opening foo');
|
||||
|
||||
$i3->command("workspace 91")->recv;
|
||||
open_standard_window($x);
|
||||
check_order('workspace order alright after opening 91');
|
|
@ -10,7 +10,7 @@ use List::Util qw(first);
|
|||
use v5.10;
|
||||
|
||||
use Exporter ();
|
||||
our @EXPORT = qw(get_workspace_names get_unused_workspace get_ws_content get_ws get_focused open_empty_con);
|
||||
our @EXPORT = qw(get_workspace_names get_unused_workspace get_ws_content get_ws get_focused open_empty_con open_standard_window);
|
||||
|
||||
BEGIN {
|
||||
my $window_count = 0;
|
||||
|
|
Loading…
Reference in New Issue