diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2018-11-28 11:19:18 -0500 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2018-11-28 11:19:18 -0500 |
commit | bf9a52bab0f8ae9b4ace43c7d9c75ece0c76b562 (patch) | |
tree | 812af4f8fee1f289bc244136ac21acca44de15b0 /swaymsg/main.c | |
parent | Merge pull request #3211 from emersion/child-view-unmapped-segfault (diff) | |
download | sway-bf9a52bab0f8ae9b4ace43c7d9c75ece0c76b562.tar.gz sway-bf9a52bab0f8ae9b4ace43c7d9c75ece0c76b562.tar.zst sway-bf9a52bab0f8ae9b4ace43c7d9c75ece0c76b562.zip |
Implement support for swaymsg -t SUBSCRIBE [-m]
In `i3 4.16`, `i3-msg` can be used with the message type `subscribe`
and has the ability to monitor for responses until killed. This adds
support for both to swaymsg.
If the JSON array of event types is malformed or contains an invalid
event, sway will send a response with `success` set to `false`. If
swaymsg sees this, it will not display the failure and exit.
If the `subscribe` event is successful, swaymsg will wait for the first
response and display that instead of the success message. If
`-m/--monitor` is given, swaymsg will continue monitor for responses
until killed or a malformed response is received.
For the `subscribe` event, the responses will always be printed as JSON.
If `-r/--raw` is given, the JSON will not be pretty printed, which may
be preferred when monitoring due to there being multiple responses.
Example: `swaymsg -t SUBSCRIBE -m "['window']"`
Diffstat (limited to 'swaymsg/main.c')
-rw-r--r-- | swaymsg/main.c | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/swaymsg/main.c b/swaymsg/main.c index e640cadf..3e61b94a 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c | |||
@@ -305,8 +305,9 @@ static void pretty_print(int type, json_object *resp) { | |||
305 | } | 305 | } |
306 | 306 | ||
307 | int main(int argc, char **argv) { | 307 | int main(int argc, char **argv) { |
308 | static int quiet = 0; | 308 | static bool quiet = false; |
309 | static int raw = 0; | 309 | static bool raw = false; |
310 | static bool monitor = false; | ||
310 | char *socket_path = NULL; | 311 | char *socket_path = NULL; |
311 | char *cmdtype = NULL; | 312 | char *cmdtype = NULL; |
312 | 313 | ||
@@ -314,6 +315,7 @@ int main(int argc, char **argv) { | |||
314 | 315 | ||
315 | static struct option long_options[] = { | 316 | static struct option long_options[] = { |
316 | {"help", no_argument, NULL, 'h'}, | 317 | {"help", no_argument, NULL, 'h'}, |
318 | {"monitor", no_argument, NULL, 'm'}, | ||
317 | {"quiet", no_argument, NULL, 'q'}, | 319 | {"quiet", no_argument, NULL, 'q'}, |
318 | {"raw", no_argument, NULL, 'r'}, | 320 | {"raw", no_argument, NULL, 'r'}, |
319 | {"socket", required_argument, NULL, 's'}, | 321 | {"socket", required_argument, NULL, 's'}, |
@@ -326,6 +328,7 @@ int main(int argc, char **argv) { | |||
326 | "Usage: swaymsg [options] [message]\n" | 328 | "Usage: swaymsg [options] [message]\n" |
327 | "\n" | 329 | "\n" |
328 | " -h, --help Show help message and quit.\n" | 330 | " -h, --help Show help message and quit.\n" |
331 | " -m, --monitor Monitor until killed (-t SUBSCRIBE only)\n" | ||
329 | " -q, --quiet Be quiet.\n" | 332 | " -q, --quiet Be quiet.\n" |
330 | " -r, --raw Use raw output even if using a tty\n" | 333 | " -r, --raw Use raw output even if using a tty\n" |
331 | " -s, --socket <socket> Use the specified socket.\n" | 334 | " -s, --socket <socket> Use the specified socket.\n" |
@@ -337,16 +340,19 @@ int main(int argc, char **argv) { | |||
337 | int c; | 340 | int c; |
338 | while (1) { | 341 | while (1) { |
339 | int option_index = 0; | 342 | int option_index = 0; |
340 | c = getopt_long(argc, argv, "hqrs:t:v", long_options, &option_index); | 343 | c = getopt_long(argc, argv, "hmqrs:t:v", long_options, &option_index); |
341 | if (c == -1) { | 344 | if (c == -1) { |
342 | break; | 345 | break; |
343 | } | 346 | } |
344 | switch (c) { | 347 | switch (c) { |
348 | case 'm': // Monitor | ||
349 | monitor = true; | ||
350 | break; | ||
345 | case 'q': // Quiet | 351 | case 'q': // Quiet |
346 | quiet = 1; | 352 | quiet = true; |
347 | break; | 353 | break; |
348 | case 'r': // Raw | 354 | case 'r': // Raw |
349 | raw = 1; | 355 | raw = true; |
350 | break; | 356 | break; |
351 | case 's': // Socket | 357 | case 's': // Socket |
352 | socket_path = strdup(optarg); | 358 | socket_path = strdup(optarg); |
@@ -400,12 +406,20 @@ int main(int argc, char **argv) { | |||
400 | type = IPC_GET_CONFIG; | 406 | type = IPC_GET_CONFIG; |
401 | } else if (strcasecmp(cmdtype, "send_tick") == 0) { | 407 | } else if (strcasecmp(cmdtype, "send_tick") == 0) { |
402 | type = IPC_SEND_TICK; | 408 | type = IPC_SEND_TICK; |
409 | } else if (strcasecmp(cmdtype, "subscribe") == 0) { | ||
410 | type = IPC_SUBSCRIBE; | ||
403 | } else { | 411 | } else { |
404 | sway_abort("Unknown message type %s", cmdtype); | 412 | sway_abort("Unknown message type %s", cmdtype); |
405 | } | 413 | } |
406 | 414 | ||
407 | free(cmdtype); | 415 | free(cmdtype); |
408 | 416 | ||
417 | if (monitor && type != IPC_SUBSCRIBE) { | ||
418 | wlr_log(WLR_ERROR, "Monitor can only be used with -t SUBSCRIBE"); | ||
419 | free(socket_path); | ||
420 | return 1; | ||
421 | } | ||
422 | |||
409 | char *command = NULL; | 423 | char *command = NULL; |
410 | if (optind < argc) { | 424 | if (optind < argc) { |
411 | command = join_args(argv + optind, argc - optind); | 425 | command = join_args(argv + optind, argc - optind); |
@@ -422,26 +436,56 @@ int main(int argc, char **argv) { | |||
422 | json_object *obj = json_tokener_parse(resp); | 436 | json_object *obj = json_tokener_parse(resp); |
423 | 437 | ||
424 | if (obj == NULL) { | 438 | if (obj == NULL) { |
425 | fprintf(stderr, "ERROR: Could not parse json response from ipc. This is a bug in sway."); | 439 | fprintf(stderr, "ERROR: Could not parse json response from ipc. " |
440 | "This is a bug in sway."); | ||
426 | printf("%s\n", resp); | 441 | printf("%s\n", resp); |
427 | ret = 1; | 442 | ret = 1; |
428 | } else { | 443 | } else { |
429 | if (!success(obj, true)) { | 444 | if (!success(obj, true)) { |
430 | ret = 1; | 445 | ret = 1; |
431 | } | 446 | } |
432 | if (raw) { | 447 | if (type != IPC_SUBSCRIBE || ret != 0) { |
433 | printf("%s\n", json_object_to_json_string_ext(obj, | 448 | if (raw) { |
434 | JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); | 449 | printf("%s\n", json_object_to_json_string_ext(obj, |
435 | } else { | 450 | JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); |
436 | pretty_print(type, obj); | 451 | } else { |
452 | pretty_print(type, obj); | ||
453 | } | ||
437 | } | 454 | } |
438 | json_object_put(obj); | 455 | json_object_put(obj); |
439 | } | 456 | } |
440 | } | 457 | } |
441 | close(socketfd); | ||
442 | |||
443 | free(command); | 458 | free(command); |
444 | free(resp); | 459 | free(resp); |
460 | |||
461 | if (type == IPC_SUBSCRIBE && ret == 0) { | ||
462 | do { | ||
463 | struct ipc_response *reply = ipc_recv_response(socketfd); | ||
464 | if (!reply) { | ||
465 | break; | ||
466 | } | ||
467 | |||
468 | json_object *obj = json_tokener_parse(reply->payload); | ||
469 | if (obj == NULL) { | ||
470 | fprintf(stderr, "ERROR: Could not parse json response from ipc" | ||
471 | ". This is a bug in sway."); | ||
472 | ret = 1; | ||
473 | break; | ||
474 | } else { | ||
475 | if (raw) { | ||
476 | printf("%s\n", json_object_to_json_string(obj)); | ||
477 | } else { | ||
478 | printf("%s\n", json_object_to_json_string_ext(obj, | ||
479 | JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); | ||
480 | } | ||
481 | json_object_put(obj); | ||
482 | } | ||
483 | |||
484 | free_ipc_response(reply); | ||
485 | } while (monitor); | ||
486 | } | ||
487 | |||
488 | close(socketfd); | ||
445 | free(socket_path); | 489 | free(socket_path); |
446 | return ret; | 490 | return ret; |
447 | } | 491 | } |