Merge branch 'get-marks' into next
This commit is contained in:
commit
eb0a56fad1
16
docs/ipc
16
docs/ipc
|
@ -59,6 +59,10 @@ GET_TREE (4)::
|
||||||
Gets the layout tree. i3 uses a tree as data structure which includes
|
Gets the layout tree. i3 uses a tree as data structure which includes
|
||||||
every container. The reply will be the JSON-encoded tree (see the reply
|
every container. The reply will be the JSON-encoded tree (see the reply
|
||||||
section).
|
section).
|
||||||
|
GET_MARKS (5)::
|
||||||
|
Gets a list of marks (identifiers for containers to easily jump to them
|
||||||
|
later). The reply will be a JSON-encoded list of window marks (see
|
||||||
|
reply section).
|
||||||
|
|
||||||
So, a typical message could look like this:
|
So, a typical message could look like this:
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
@ -110,6 +114,8 @@ GET_OUTPUTS (3)::
|
||||||
Reply to the GET_OUTPUTS message.
|
Reply to the GET_OUTPUTS message.
|
||||||
GET_TREE (4)::
|
GET_TREE (4)::
|
||||||
Reply to the GET_TREE message.
|
Reply to the GET_TREE message.
|
||||||
|
GET_MARKS (5)::
|
||||||
|
Reply to the GET_MARKS message.
|
||||||
|
|
||||||
=== COMMAND reply
|
=== COMMAND reply
|
||||||
|
|
||||||
|
@ -416,6 +422,16 @@ JSON dump:
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
=== GET_MARKS reply
|
||||||
|
|
||||||
|
The reply consists of a single array of strings for each container that has a
|
||||||
|
mark. The order of that array is undefined. If more than one container has the
|
||||||
|
same mark, it will be represented multiple times in the reply (the array
|
||||||
|
contents are not unique).
|
||||||
|
|
||||||
|
If no window has a mark the response will be the empty array [].
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -180,9 +180,11 @@ int main(int argc, char *argv[]) {
|
||||||
message_type = I3_IPC_MESSAGE_TYPE_GET_OUTPUTS;
|
message_type = I3_IPC_MESSAGE_TYPE_GET_OUTPUTS;
|
||||||
else if (strcasecmp(optarg, "get_tree") == 0)
|
else if (strcasecmp(optarg, "get_tree") == 0)
|
||||||
message_type = I3_IPC_MESSAGE_TYPE_GET_TREE;
|
message_type = I3_IPC_MESSAGE_TYPE_GET_TREE;
|
||||||
|
else if (strcasecmp(optarg, "get_marks") == 0)
|
||||||
|
message_type = I3_IPC_MESSAGE_TYPE_GET_MARKS;
|
||||||
else {
|
else {
|
||||||
printf("Unknown message type\n");
|
printf("Unknown message type\n");
|
||||||
printf("Known types: command, get_workspaces, get_outputs, get_tree\n");
|
printf("Known types: command, get_workspaces, get_outputs, get_tree, get_marks\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
} else if (o == 'q') {
|
} else if (o == 'q') {
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
/** Requests the tree layout from i3 */
|
/** Requests the tree layout from i3 */
|
||||||
#define I3_IPC_MESSAGE_TYPE_GET_TREE 4
|
#define I3_IPC_MESSAGE_TYPE_GET_TREE 4
|
||||||
|
|
||||||
|
/** Request the current defined marks from i3 */
|
||||||
|
#define I3_IPC_MESSAGE_TYPE_GET_MARKS 5
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Messages from i3 to clients
|
* Messages from i3 to clients
|
||||||
|
@ -59,6 +61,8 @@
|
||||||
/** Tree reply type */
|
/** Tree reply type */
|
||||||
#define I3_IPC_REPLY_TYPE_TREE 4
|
#define I3_IPC_REPLY_TYPE_TREE 4
|
||||||
|
|
||||||
|
/** Marks reply type*/
|
||||||
|
#define I3_IPC_REPLY_TYPE_MARKS 5
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Events from i3 to clients. Events have the first bit set high.
|
* Events from i3 to clients. Events have the first bit set high.
|
||||||
|
|
39
src/ipc.c
39
src/ipc.c
|
@ -203,6 +203,11 @@ void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) {
|
||||||
ystr("urgent");
|
ystr("urgent");
|
||||||
y(bool, con->urgent);
|
y(bool, con->urgent);
|
||||||
|
|
||||||
|
if (con->mark != NULL) {
|
||||||
|
ystr("mark");
|
||||||
|
ystr(con->mark);
|
||||||
|
}
|
||||||
|
|
||||||
ystr("focused");
|
ystr("focused");
|
||||||
y(bool, (con == focused));
|
y(bool, (con == focused));
|
||||||
|
|
||||||
|
@ -333,6 +338,7 @@ IPC_HANDLER(tree) {
|
||||||
y(free);
|
y(free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Formats the reply message for a GET_WORKSPACES request and sends it to the
|
* Formats the reply message for a GET_WORKSPACES request and sends it to the
|
||||||
* client
|
* client
|
||||||
|
@ -463,6 +469,34 @@ IPC_HANDLER(get_outputs) {
|
||||||
y(free);
|
y(free);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Formats the reply message for a GET_MARKS request and sends it to the
|
||||||
|
* client
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IPC_HANDLER(get_marks) {
|
||||||
|
#if YAJL_MAJOR >= 2
|
||||||
|
yajl_gen gen = yajl_gen_alloc(NULL);
|
||||||
|
#else
|
||||||
|
yajl_gen gen = yajl_gen_alloc(NULL, NULL);
|
||||||
|
#endif
|
||||||
|
y(array_open);
|
||||||
|
|
||||||
|
Con *con;
|
||||||
|
TAILQ_FOREACH(con, &all_cons, all_cons)
|
||||||
|
if (con->mark != NULL)
|
||||||
|
ystr(con->mark);
|
||||||
|
|
||||||
|
y(array_close);
|
||||||
|
|
||||||
|
const unsigned char *payload;
|
||||||
|
unsigned int length;
|
||||||
|
y(get_buf, &payload, &length);
|
||||||
|
|
||||||
|
ipc_send_message(fd, payload, I3_IPC_REPLY_TYPE_MARKS, length);
|
||||||
|
y(free);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback for the YAJL parser (will be called when a string is parsed).
|
* Callback for the YAJL parser (will be called when a string is parsed).
|
||||||
*
|
*
|
||||||
|
@ -550,12 +584,13 @@ IPC_HANDLER(subscribe) {
|
||||||
|
|
||||||
/* The index of each callback function corresponds to the numeric
|
/* The index of each callback function corresponds to the numeric
|
||||||
* value of the message type (see include/i3/ipc.h) */
|
* value of the message type (see include/i3/ipc.h) */
|
||||||
handler_t handlers[5] = {
|
handler_t handlers[6] = {
|
||||||
handle_command,
|
handle_command,
|
||||||
handle_get_workspaces,
|
handle_get_workspaces,
|
||||||
handle_subscribe,
|
handle_subscribe,
|
||||||
handle_get_outputs,
|
handle_get_outputs,
|
||||||
handle_tree
|
handle_tree,
|
||||||
|
handle_get_marks
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -146,6 +146,10 @@ static int json_string(void *ctx, const unsigned char *val, unsigned int len) {
|
||||||
json_node->layout = L_OUTPUT;
|
json_node->layout = L_OUTPUT;
|
||||||
else LOG("Unhandled \"layout\": %s\n", buf);
|
else LOG("Unhandled \"layout\": %s\n", buf);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
} else if (strcasecmp(last_key, "mark") == 0) {
|
||||||
|
char *buf = NULL;
|
||||||
|
asprintf(&buf, "%.*s", (int)len, val);
|
||||||
|
json_node->mark = buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
#!perl
|
||||||
|
# vim:ts=4:sw=4:expandtab
|
||||||
|
#
|
||||||
|
# checks if the IPC message type get_marks works correctly
|
||||||
|
#
|
||||||
|
use i3test;
|
||||||
|
|
||||||
|
# TODO: this will be available in AnyEvent::I3 soon
|
||||||
|
sub get_marks {
|
||||||
|
my $i3 = i3(get_socket_path());
|
||||||
|
$i3->connect->recv;
|
||||||
|
my $cv = AnyEvent->condvar;
|
||||||
|
my $msg = $i3->message(5);
|
||||||
|
my $t;
|
||||||
|
$msg->cb(sub {
|
||||||
|
my ($_cv) = @_;
|
||||||
|
$cv->send($_cv->recv);
|
||||||
|
});
|
||||||
|
$t = AnyEvent->timer(after => 2, cb => sub {
|
||||||
|
$cv->croak('timeout while waiting for the marks');
|
||||||
|
});
|
||||||
|
return $cv->recv;
|
||||||
|
}
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# 1: check that get_marks returns no marks yet
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
my $tmp = fresh_workspace;
|
||||||
|
|
||||||
|
my $marks = get_marks();
|
||||||
|
cmp_deeply($marks, [], 'no marks set so far');
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# 2: check that setting a mark is reflected in the get_marks reply
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
cmd 'open';
|
||||||
|
cmd 'mark foo';
|
||||||
|
|
||||||
|
cmp_deeply(get_marks(), [ 'foo' ], 'mark foo set');
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# 3: check that the mark is gone after killing the container
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
cmd 'kill';
|
||||||
|
|
||||||
|
cmp_deeply(get_marks(), [ ], 'mark gone');
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# 4: check that duplicate marks are included twice in the get_marks reply
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
cmd 'open';
|
||||||
|
cmd 'mark bar';
|
||||||
|
|
||||||
|
cmd 'open';
|
||||||
|
cmd 'mark bar';
|
||||||
|
|
||||||
|
cmp_deeply(get_marks(), [ 'bar', 'bar' ], 'duplicate mark found twice');
|
||||||
|
|
||||||
|
done_testing;
|
Loading…
Reference in New Issue