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
|
||||
every container. The reply will be the JSON-encoded tree (see the reply
|
||||
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:
|
||||
--------------------------------------------------
|
||||
|
@ -110,6 +114,8 @@ GET_OUTPUTS (3)::
|
|||
Reply to the GET_OUTPUTS message.
|
||||
GET_TREE (4)::
|
||||
Reply to the GET_TREE message.
|
||||
GET_MARKS (5)::
|
||||
Reply to the GET_MARKS message.
|
||||
|
||||
=== 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;
|
||||
else if (strcasecmp(optarg, "get_tree") == 0)
|
||||
message_type = I3_IPC_MESSAGE_TYPE_GET_TREE;
|
||||
else if (strcasecmp(optarg, "get_marks") == 0)
|
||||
message_type = I3_IPC_MESSAGE_TYPE_GET_MARKS;
|
||||
else {
|
||||
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);
|
||||
}
|
||||
} else if (o == 'q') {
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
/** Requests the tree layout from i3 */
|
||||
#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
|
||||
|
@ -59,6 +61,8 @@
|
|||
/** Tree reply type */
|
||||
#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.
|
||||
|
|
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");
|
||||
y(bool, con->urgent);
|
||||
|
||||
if (con->mark != NULL) {
|
||||
ystr("mark");
|
||||
ystr(con->mark);
|
||||
}
|
||||
|
||||
ystr("focused");
|
||||
y(bool, (con == focused));
|
||||
|
||||
|
@ -333,6 +338,7 @@ IPC_HANDLER(tree) {
|
|||
y(free);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Formats the reply message for a GET_WORKSPACES request and sends it to the
|
||||
* client
|
||||
|
@ -463,6 +469,34 @@ IPC_HANDLER(get_outputs) {
|
|||
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).
|
||||
*
|
||||
|
@ -550,12 +584,13 @@ IPC_HANDLER(subscribe) {
|
|||
|
||||
/* The index of each callback function corresponds to the numeric
|
||||
* value of the message type (see include/i3/ipc.h) */
|
||||
handler_t handlers[5] = {
|
||||
handler_t handlers[6] = {
|
||||
handle_command,
|
||||
handle_get_workspaces,
|
||||
handle_subscribe,
|
||||
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;
|
||||
else LOG("Unhandled \"layout\": %s\n", 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;
|
||||
|
|
|
@ -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