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; |