Skip to content

Instantly share code, notes, and snippets.

@vivien
Created October 7, 2014 04:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vivien/343cb3de3f0706a15257 to your computer and use it in GitHub Desktop.
Save vivien/343cb3de3f0706a15257 to your computer and use it in GitHub Desktop.
i3-msg hack to implement the "SUBSCRIBE" message type
diff --git a/i3-msg/main.c b/i3-msg/main.c
index 354e8af..a1af25c 100644
--- a/i3-msg/main.c
+++ b/i3-msg/main.c
@@ -124,16 +124,18 @@ int main(int argc, char *argv[]) {
uint32_t message_type = I3_IPC_MESSAGE_TYPE_COMMAND;
char *payload = NULL;
bool quiet = false;
+ bool monitor = false;
static struct option long_options[] = {
{"socket", required_argument, 0, 's'},
{"type", required_argument, 0, 't'},
{"version", no_argument, 0, 'v'},
{"quiet", no_argument, 0, 'q'},
+ {"monitor", no_argument, 0, 'm'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}};
- char *options_string = "s:t:vhq";
+ char *options_string = "s:t:vhqm";
while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
if (o == 's') {
@@ -145,6 +147,8 @@ int main(int argc, char *argv[]) {
message_type = I3_IPC_MESSAGE_TYPE_COMMAND;
else if (strcasecmp(optarg, "get_workspaces") == 0)
message_type = I3_IPC_MESSAGE_TYPE_GET_WORKSPACES;
+ else if (strcasecmp(optarg, "subscribe") == 0)
+ message_type = I3_IPC_MESSAGE_TYPE_SUBSCRIBE;
else if (strcasecmp(optarg, "get_outputs") == 0)
message_type = I3_IPC_MESSAGE_TYPE_GET_OUTPUTS;
else if (strcasecmp(optarg, "get_tree") == 0)
@@ -157,17 +161,19 @@ int main(int argc, char *argv[]) {
message_type = I3_IPC_MESSAGE_TYPE_GET_VERSION;
else {
printf("Unknown message type\n");
- printf("Known types: command, get_workspaces, get_outputs, get_tree, get_marks, get_bar_config, get_version\n");
+ printf("Known types: command, get_workspaces, subscribe, get_outputs, get_tree, get_marks, get_bar_config, get_version\n");
exit(EXIT_FAILURE);
}
} else if (o == 'q') {
quiet = true;
+ } else if (o == 'm') {
+ monitor = true;
} else if (o == 'v') {
printf("i3-msg " I3_VERSION "\n");
return 0;
} else if (o == 'h') {
printf("i3-msg " I3_VERSION "\n");
- printf("i3-msg [-s <socket>] [-t <type>] <message>\n");
+ printf("i3-msg [-s <socket>] [-t <type>] [-m] <message>\n");
return 0;
}
}
@@ -219,16 +225,19 @@ int main(int argc, char *argv[]) {
uint32_t reply_type;
uint8_t *reply;
int ret;
+recv:
if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
if (ret == -1)
err(EXIT_FAILURE, "IPC: read()");
exit(1);
}
- if (reply_type != message_type)
+
+ /* For events, the highest bit of the message type is set to 1. */
+ if (reply_type != message_type && (message_type == I3_IPC_MESSAGE_TYPE_SUBSCRIBE && !(reply_type >> 31)))
errx(EXIT_FAILURE, "IPC: Received reply of type %d but expected %d", reply_type, message_type);
- /* For the reply of commands, have a look if that command was successful.
+ /* For the reply of commands or subscribes, have a look if that command was successful.
* If not, nicely format the error message. */
- if (reply_type == I3_IPC_MESSAGE_TYPE_COMMAND) {
+ if (reply_type == I3_IPC_MESSAGE_TYPE_COMMAND || reply_type == I3_IPC_MESSAGE_TYPE_SUBSCRIBE) {
yajl_handle handle;
handle = yajl_alloc(&reply_callbacks, NULL, NULL);
yajl_status state = yajl_parse(handle, (const unsigned char *)reply, reply_length);
@@ -246,6 +255,9 @@ int main(int argc, char *argv[]) {
printf("%.*s\n", reply_length, reply);
free(reply);
+ if (reply_type == I3_IPC_MESSAGE_TYPE_SUBSCRIBE || monitor)
+ goto recv;
+
close(sockfd);
return 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment