Created
October 7, 2014 04:17
-
-
Save vivien/343cb3de3f0706a15257 to your computer and use it in GitHub Desktop.
i3-msg hack to implement the "SUBSCRIBE" message type
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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