i3-msg: support SUBSCRIBE message type
Patch status: rejected
Patch by Vivien Didelot
Long description:
If i3-msg is invoked with -t subscribe, it will wait for the first event
corresponding to the given payload, before exiting.
For instance, get the number of the next focused workspace with:
i3-msg -t subscribe '[ "workspace", "focus" ]' | sed 1d | jshon -e current -e num
Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
To apply this patch, use:
curl http://cr.i3wm.org/patch/640/raw.patch | git am
b/i3-msg/main.c
| 21 |
@@ -145,6 +145,8 @@ int main(int argc, char *argv[]) {
|
| 22 |
message_type = I3_IPC_MESSAGE_TYPE_COMMAND; |
| 23 |
else if (strcasecmp(optarg, "get_workspaces") == 0) |
| 24 |
message_type = I3_IPC_MESSAGE_TYPE_GET_WORKSPACES; |
| 25 |
+ else if (strcasecmp(optarg, "subscribe") == 0) |
| 26 |
+ message_type = I3_IPC_MESSAGE_TYPE_SUBSCRIBE; |
| 27 |
else if (strcasecmp(optarg, "get_outputs") == 0) |
| 28 |
message_type = I3_IPC_MESSAGE_TYPE_GET_OUTPUTS; |
| 29 |
else if (strcasecmp(optarg, "get_tree") == 0) |
| 30 |
@@ -157,7 +159,7 @@ int main(int argc, char *argv[]) {
|
| 31 |
message_type = I3_IPC_MESSAGE_TYPE_GET_VERSION; |
| 32 |
else {
|
| 33 |
printf("Unknown message type\n");
|
| 34 |
- printf("Known types: command, get_workspaces, get_outputs, get_tree, get_marks, get_bar_config, get_version\n");
|
| 35 |
+ printf("Known types: command, get_workspaces, subscribe, get_outputs, get_tree, get_marks, get_bar_config, get_version\n");
|
| 36 |
exit(EXIT_FAILURE); |
| 37 |
} |
| 38 |
} else if (o == 'q') {
|
| 39 |
@@ -219,16 +221,19 @@ int main(int argc, char *argv[]) {
|
| 40 |
uint32_t reply_type; |
| 41 |
uint8_t *reply; |
| 42 |
int ret; |
| 43 |
+recv: |
| 44 |
if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
|
| 45 |
if (ret == -1) |
| 46 |
err(EXIT_FAILURE, "IPC: read()"); |
| 47 |
exit(1); |
| 48 |
} |
| 49 |
- if (reply_type != message_type) |
| 50 |
+ |
| 51 |
+ /* For events, the highest bit of the message type is set to 1. */ |
| 52 |
+ if (reply_type != message_type && (message_type == I3_IPC_MESSAGE_TYPE_SUBSCRIBE && !(reply_type >> 31))) |
| 53 |
errx(EXIT_FAILURE, "IPC: Received reply of type %d but expected %d", reply_type, message_type); |
| 54 |
- /* For the reply of commands, have a look if that command was successful. |
| 55 |
+ /* For the reply of commands or subscribes, have a look if that command was successful. |
| 56 |
* If not, nicely format the error message. */ |
| 57 |
- if (reply_type == I3_IPC_MESSAGE_TYPE_COMMAND) {
|
| 58 |
+ if (reply_type == I3_IPC_MESSAGE_TYPE_COMMAND || reply_type == I3_IPC_MESSAGE_TYPE_SUBSCRIBE) {
|
| 59 |
yajl_handle handle; |
| 60 |
handle = yajl_alloc(&reply_callbacks, NULL, NULL); |
| 61 |
yajl_status state = yajl_parse(handle, (const unsigned char *)reply, reply_length); |
| 62 |
@@ -246,6 +251,9 @@ int main(int argc, char *argv[]) {
|
| 63 |
printf("%.*s\n", reply_length, reply);
|
| 64 |
free(reply); |
| 65 |
|
| 66 |
+ if (reply_type == I3_IPC_MESSAGE_TYPE_SUBSCRIBE) |
| 67 |
+ goto recv; |
| 68 |
+ |
| 69 |
close(sockfd); |
| 70 |
|
| 71 |
return 0; |