aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/move.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands/move.c')
-rw-r--r--sway/commands/move.c91
1 files changed, 43 insertions, 48 deletions
diff --git a/sway/commands/move.c b/sway/commands/move.c
index 72e177e8..d4fe2f01 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -21,7 +21,7 @@
21#include "log.h" 21#include "log.h"
22#include "util.h" 22#include "util.h"
23 23
24static const char *expected_syntax = 24static const char expected_syntax[] =
25 "Expected 'move <left|right|up|down> <[px] px>' or " 25 "Expected 'move <left|right|up|down> <[px] px>' or "
26 "'move [--no-auto-back-and-forth] <container|window> [to] workspace <name>' or " 26 "'move [--no-auto-back-and-forth] <container|window> [to] workspace <name>' or "
27 "'move <container|window|workspace> [to] output <name|direction>' or " 27 "'move <container|window|workspace> [to] output <name|direction>' or "
@@ -378,7 +378,7 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
378 struct sway_container *container = config->handler_context.container; 378 struct sway_container *container = config->handler_context.container;
379 if (node->type == N_WORKSPACE) { 379 if (node->type == N_WORKSPACE) {
380 if (workspace->tiling->length == 0) { 380 if (workspace->tiling->length == 0) {
381 return cmd_results_new(CMD_FAILURE, "move", 381 return cmd_results_new(CMD_FAILURE,
382 "Can't move an empty workspace"); 382 "Can't move an empty workspace");
383 } 383 }
384 container = workspace_wrap_children(workspace); 384 container = workspace_wrap_children(workspace);
@@ -388,21 +388,21 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
388 while (strcasecmp(argv[0], "--no-auto-back-and-forth") == 0) { 388 while (strcasecmp(argv[0], "--no-auto-back-and-forth") == 0) {
389 no_auto_back_and_forth = true; 389 no_auto_back_and_forth = true;
390 if (--argc < 3) { 390 if (--argc < 3) {
391 return cmd_results_new(CMD_INVALID, "move", expected_syntax); 391 return cmd_results_new(CMD_INVALID, expected_syntax);
392 } 392 }
393 ++argv; 393 ++argv;
394 } 394 }
395 while (strcasecmp(argv[1], "--no-auto-back-and-forth") == 0) { 395 while (strcasecmp(argv[1], "--no-auto-back-and-forth") == 0) {
396 no_auto_back_and_forth = true; 396 no_auto_back_and_forth = true;
397 if (--argc < 3) { 397 if (--argc < 3) {
398 return cmd_results_new(CMD_INVALID, "move", expected_syntax); 398 return cmd_results_new(CMD_INVALID, expected_syntax);
399 } 399 }
400 argv++; 400 argv++;
401 } 401 }
402 402
403 while (strcasecmp(argv[1], "to") == 0) { 403 while (strcasecmp(argv[1], "to") == 0) {
404 if (--argc < 3) { 404 if (--argc < 3) {
405 return cmd_results_new(CMD_INVALID, "move", expected_syntax); 405 return cmd_results_new(CMD_INVALID, expected_syntax);
406 } 406 }
407 argv++; 407 argv++;
408 } 408 }
@@ -429,7 +429,7 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
429 if (seat->prev_workspace_name) { 429 if (seat->prev_workspace_name) {
430 ws_name = strdup(seat->prev_workspace_name); 430 ws_name = strdup(seat->prev_workspace_name);
431 } else { 431 } else {
432 return cmd_results_new(CMD_FAILURE, "move", 432 return cmd_results_new(CMD_FAILURE,
433 "No workspace was previously active."); 433 "No workspace was previously active.");
434 } 434 }
435 } 435 }
@@ -437,11 +437,10 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
437 if (strcasecmp(argv[2], "number") == 0) { 437 if (strcasecmp(argv[2], "number") == 0) {
438 // move "container to workspace number x" 438 // move "container to workspace number x"
439 if (argc < 4) { 439 if (argc < 4) {
440 return cmd_results_new(CMD_INVALID, "move", 440 return cmd_results_new(CMD_INVALID, expected_syntax);
441 expected_syntax);
442 } 441 }
443 if (!isdigit(argv[3][0])) { 442 if (!isdigit(argv[3][0])) {
444 return cmd_results_new(CMD_INVALID, "move", 443 return cmd_results_new(CMD_INVALID,
445 "Invalid workspace number '%s'", argv[3]); 444 "Invalid workspace number '%s'", argv[3]);
446 } 445 }
447 ws_name = join_args(argv + 3, argc - 3); 446 ws_name = join_args(argv + 3, argc - 3);
@@ -472,7 +471,7 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
472 workspace_get_initial_output(ws_name); 471 workspace_get_initial_output(ws_name);
473 if (old_output == new_output) { 472 if (old_output == new_output) {
474 free(ws_name); 473 free(ws_name);
475 return cmd_results_new(CMD_FAILURE, "move", 474 return cmd_results_new(CMD_FAILURE,
476 "Can't move sticky container to another workspace " 475 "Can't move sticky container to another workspace "
477 "on the same output"); 476 "on the same output");
478 } 477 }
@@ -486,24 +485,24 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
486 struct sway_output *new_output = output_in_direction(argv[2], 485 struct sway_output *new_output = output_in_direction(argv[2],
487 old_output, container->x, container->y); 486 old_output, container->x, container->y);
488 if (!new_output) { 487 if (!new_output) {
489 return cmd_results_new(CMD_FAILURE, "move workspace", 488 return cmd_results_new(CMD_FAILURE,
490 "Can't find output with name/direction '%s'", argv[2]); 489 "Can't find output with name/direction '%s'", argv[2]);
491 } 490 }
492 destination = seat_get_focus_inactive(seat, &new_output->node); 491 destination = seat_get_focus_inactive(seat, &new_output->node);
493 } else if (strcasecmp(argv[1], "mark") == 0) { 492 } else if (strcasecmp(argv[1], "mark") == 0) {
494 struct sway_container *dest_con = container_find_mark(argv[2]); 493 struct sway_container *dest_con = container_find_mark(argv[2]);
495 if (dest_con == NULL) { 494 if (dest_con == NULL) {
496 return cmd_results_new(CMD_FAILURE, "move", 495 return cmd_results_new(CMD_FAILURE,
497 "Mark '%s' not found", argv[2]); 496 "Mark '%s' not found", argv[2]);
498 } 497 }
499 destination = &dest_con->node; 498 destination = &dest_con->node;
500 } else { 499 } else {
501 return cmd_results_new(CMD_INVALID, "move", expected_syntax); 500 return cmd_results_new(CMD_INVALID, expected_syntax);
502 } 501 }
503 502
504 if (container->is_sticky && old_output && 503 if (container->is_sticky && old_output &&
505 node_has_ancestor(destination, &old_output->node)) { 504 node_has_ancestor(destination, &old_output->node)) {
506 return cmd_results_new(CMD_FAILURE, "move", "Can't move sticky " 505 return cmd_results_new(CMD_FAILURE, "Can't move sticky "
507 "container to another workspace on the same output"); 506 "container to another workspace on the same output");
508 } 507 }
509 508
@@ -569,7 +568,7 @@ static struct cmd_results *cmd_move_container(int argc, char **argv) {
569 } 568 }
570 arrange_node(node_get_parent(destination)); 569 arrange_node(node_get_parent(destination));
571 570
572 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 571 return cmd_results_new(CMD_SUCCESS, NULL);
573} 572}
574 573
575static void workspace_move_to_output(struct sway_workspace *workspace, 574static void workspace_move_to_output(struct sway_workspace *workspace,
@@ -611,13 +610,13 @@ static struct cmd_results *cmd_move_workspace(int argc, char **argv) {
611 610
612 while (strcasecmp(argv[1], "to") == 0) { 611 while (strcasecmp(argv[1], "to") == 0) {
613 if (--argc < 3) { 612 if (--argc < 3) {
614 return cmd_results_new(CMD_INVALID, "move", expected_syntax); 613 return cmd_results_new(CMD_INVALID, expected_syntax);
615 } 614 }
616 ++argv; 615 ++argv;
617 } 616 }
618 617
619 if (strcasecmp(argv[1], "output") != 0) { 618 if (strcasecmp(argv[1], "output") != 0) {
620 return cmd_results_new(CMD_INVALID, "move", expected_syntax); 619 return cmd_results_new(CMD_INVALID, expected_syntax);
621 } 620 }
622 621
623 struct sway_workspace *workspace = config->handler_context.workspace; 622 struct sway_workspace *workspace = config->handler_context.workspace;
@@ -627,7 +626,7 @@ static struct cmd_results *cmd_move_workspace(int argc, char **argv) {
627 struct sway_output *new_output = output_in_direction(argv[2], 626 struct sway_output *new_output = output_in_direction(argv[2],
628 old_output, center_x, center_y); 627 old_output, center_x, center_y);
629 if (!new_output) { 628 if (!new_output) {
630 return cmd_results_new(CMD_FAILURE, "move workspace", 629 return cmd_results_new(CMD_FAILURE,
631 "Can't find output with name/direction '%s'", argv[2]); 630 "Can't find output with name/direction '%s'", argv[2]);
632 } 631 }
633 workspace_move_to_output(workspace, new_output); 632 workspace_move_to_output(workspace, new_output);
@@ -635,7 +634,7 @@ static struct cmd_results *cmd_move_workspace(int argc, char **argv) {
635 arrange_output(old_output); 634 arrange_output(old_output);
636 arrange_output(new_output); 635 arrange_output(new_output);
637 636
638 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 637 return cmd_results_new(CMD_SUCCESS, NULL);
639} 638}
640 639
641static struct cmd_results *cmd_move_in_direction( 640static struct cmd_results *cmd_move_in_direction(
@@ -645,19 +644,18 @@ static struct cmd_results *cmd_move_in_direction(
645 char *inv; 644 char *inv;
646 move_amt = (int)strtol(argv[1], &inv, 10); 645 move_amt = (int)strtol(argv[1], &inv, 10);
647 if (*inv != '\0' && strcasecmp(inv, "px") != 0) { 646 if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
648 return cmd_results_new(CMD_FAILURE, "move", 647 return cmd_results_new(CMD_FAILURE, "Invalid distance specified");
649 "Invalid distance specified");
650 } 648 }
651 } 649 }
652 650
653 struct sway_container *container = config->handler_context.container; 651 struct sway_container *container = config->handler_context.container;
654 if (!container) { 652 if (!container) {
655 return cmd_results_new(CMD_FAILURE, "move", 653 return cmd_results_new(CMD_FAILURE,
656 "Cannot move workspaces in a direction"); 654 "Cannot move workspaces in a direction");
657 } 655 }
658 if (container_is_floating(container)) { 656 if (container_is_floating(container)) {
659 if (container->is_fullscreen) { 657 if (container->is_fullscreen) {
660 return cmd_results_new(CMD_FAILURE, "move", 658 return cmd_results_new(CMD_FAILURE,
661 "Cannot move fullscreen floating container"); 659 "Cannot move fullscreen floating container");
662 } 660 }
663 double lx = container->x; 661 double lx = container->x;
@@ -677,13 +675,13 @@ static struct cmd_results *cmd_move_in_direction(
677 break; 675 break;
678 } 676 }
679 container_floating_move_to(container, lx, ly); 677 container_floating_move_to(container, lx, ly);
680 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 678 return cmd_results_new(CMD_SUCCESS, NULL);
681 } 679 }
682 struct sway_workspace *old_ws = container->workspace; 680 struct sway_workspace *old_ws = container->workspace;
683 681
684 if (!container_move_in_direction(container, direction)) { 682 if (!container_move_in_direction(container, direction)) {
685 // Container didn't move 683 // Container didn't move
686 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 684 return cmd_results_new(CMD_SUCCESS, NULL);
687 } 685 }
688 686
689 struct sway_workspace *new_ws = container->workspace; 687 struct sway_workspace *new_ws = container->workspace;
@@ -708,10 +706,10 @@ static struct cmd_results *cmd_move_in_direction(
708 } 706 }
709 container_end_mouse_operation(container); 707 container_end_mouse_operation(container);
710 708
711 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 709 return cmd_results_new(CMD_SUCCESS, NULL);
712} 710}
713 711
714static const char *expected_position_syntax = 712static const char expected_position_syntax[] =
715 "Expected 'move [absolute] position <x> [px] <y> [px]' or " 713 "Expected 'move [absolute] position <x> [px] <y> [px]' or "
716 "'move [absolute] position center' or " 714 "'move [absolute] position center' or "
717 "'move position cursor|mouse|pointer'"; 715 "'move position cursor|mouse|pointer'";
@@ -719,12 +717,11 @@ static const char *expected_position_syntax =
719static struct cmd_results *cmd_move_to_position(int argc, char **argv) { 717static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
720 struct sway_container *container = config->handler_context.container; 718 struct sway_container *container = config->handler_context.container;
721 if (!container || !container_is_floating(container)) { 719 if (!container || !container_is_floating(container)) {
722 return cmd_results_new(CMD_FAILURE, "move", 720 return cmd_results_new(CMD_FAILURE, "Only floating containers "
723 "Only floating containers "
724 "can be moved to an absolute position"); 721 "can be moved to an absolute position");
725 } 722 }
726 if (!argc) { 723 if (!argc) {
727 return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); 724 return cmd_results_new(CMD_FAILURE, expected_position_syntax);
728 } 725 }
729 726
730 bool absolute = false; 727 bool absolute = false;
@@ -734,25 +731,25 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
734 ++argv; 731 ++argv;
735 } 732 }
736 if (!argc) { 733 if (!argc) {
737 return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); 734 return cmd_results_new(CMD_FAILURE, expected_position_syntax);
738 } 735 }
739 if (strcmp(argv[0], "position") == 0) { 736 if (strcmp(argv[0], "position") == 0) {
740 --argc; 737 --argc;
741 ++argv; 738 ++argv;
742 } 739 }
743 if (!argc) { 740 if (!argc) {
744 return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); 741 return cmd_results_new(CMD_FAILURE, expected_position_syntax);
745 } 742 }
746 if (strcmp(argv[0], "cursor") == 0 || strcmp(argv[0], "mouse") == 0 || 743 if (strcmp(argv[0], "cursor") == 0 || strcmp(argv[0], "mouse") == 0 ||
747 strcmp(argv[0], "pointer") == 0) { 744 strcmp(argv[0], "pointer") == 0) {
748 struct sway_seat *seat = config->handler_context.seat; 745 struct sway_seat *seat = config->handler_context.seat;
749 if (!seat->cursor) { 746 if (!seat->cursor) {
750 return cmd_results_new(CMD_FAILURE, "move", "No cursor device"); 747 return cmd_results_new(CMD_FAILURE, "No cursor device");
751 } 748 }
752 double lx = seat->cursor->cursor->x - container->width / 2; 749 double lx = seat->cursor->cursor->x - container->width / 2;
753 double ly = seat->cursor->cursor->y - container->height / 2; 750 double ly = seat->cursor->cursor->y - container->height / 2;
754 container_floating_move_to(container, lx, ly); 751 container_floating_move_to(container, lx, ly);
755 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 752 return cmd_results_new(CMD_SUCCESS, NULL);
756 } else if (strcmp(argv[0], "center") == 0) { 753 } else if (strcmp(argv[0], "center") == 0) {
757 double lx, ly; 754 double lx, ly;
758 if (absolute) { 755 if (absolute) {
@@ -764,19 +761,18 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
764 ly = ws->y + (ws->height - container->height) / 2; 761 ly = ws->y + (ws->height - container->height) / 2;
765 } 762 }
766 container_floating_move_to(container, lx, ly); 763 container_floating_move_to(container, lx, ly);
767 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 764 return cmd_results_new(CMD_SUCCESS, NULL);
768 } 765 }
769 766
770 if (argc < 2) { 767 if (argc < 2) {
771 return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); 768 return cmd_results_new(CMD_FAILURE, expected_position_syntax);
772 } 769 }
773 770
774 double lx, ly; 771 double lx, ly;
775 char *inv; 772 char *inv;
776 lx = (double)strtol(argv[0], &inv, 10); 773 lx = (double)strtol(argv[0], &inv, 10);
777 if (*inv != '\0' && strcasecmp(inv, "px") != 0) { 774 if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
778 return cmd_results_new(CMD_FAILURE, "move", 775 return cmd_results_new(CMD_FAILURE, "Invalid position specified");
779 "Invalid position specified");
780 } 776 }
781 if (strcmp(argv[1], "px") == 0) { 777 if (strcmp(argv[1], "px") == 0) {
782 --argc; 778 --argc;
@@ -784,14 +780,13 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
784 } 780 }
785 781
786 if (argc > 3) { 782 if (argc > 3) {
787 return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); 783 return cmd_results_new(CMD_FAILURE, expected_position_syntax);
788 } 784 }
789 785
790 ly = (double)strtol(argv[1], &inv, 10); 786 ly = (double)strtol(argv[1], &inv, 10);
791 if ((*inv != '\0' && strcasecmp(inv, "px") != 0) || 787 if ((*inv != '\0' && strcasecmp(inv, "px") != 0) ||
792 (argc == 3 && strcmp(argv[2], "px") != 0)) { 788 (argc == 3 && strcmp(argv[2], "px") != 0)) {
793 return cmd_results_new(CMD_FAILURE, "move", 789 return cmd_results_new(CMD_FAILURE, "Invalid position specified");
794 "Invalid position specified");
795 } 790 }
796 791
797 if (!absolute) { 792 if (!absolute) {
@@ -799,7 +794,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
799 ly += container->workspace->y; 794 ly += container->workspace->y;
800 } 795 }
801 container_floating_move_to(container, lx, ly); 796 container_floating_move_to(container, lx, ly);
802 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 797 return cmd_results_new(CMD_SUCCESS, NULL);
803} 798}
804 799
805static struct cmd_results *cmd_move_to_scratchpad(void) { 800static struct cmd_results *cmd_move_to_scratchpad(void) {
@@ -807,7 +802,7 @@ static struct cmd_results *cmd_move_to_scratchpad(void) {
807 struct sway_container *con = config->handler_context.container; 802 struct sway_container *con = config->handler_context.container;
808 struct sway_workspace *ws = config->handler_context.workspace; 803 struct sway_workspace *ws = config->handler_context.workspace;
809 if (node->type == N_WORKSPACE && ws->tiling->length == 0) { 804 if (node->type == N_WORKSPACE && ws->tiling->length == 0) {
810 return cmd_results_new(CMD_INVALID, "move", 805 return cmd_results_new(CMD_INVALID,
811 "Can't move an empty workspace to the scratchpad"); 806 "Can't move an empty workspace to the scratchpad");
812 } 807 }
813 if (node->type == N_WORKSPACE) { 808 if (node->type == N_WORKSPACE) {
@@ -825,11 +820,11 @@ static struct cmd_results *cmd_move_to_scratchpad(void) {
825 } 820 }
826 821
827 if (con->scratchpad) { 822 if (con->scratchpad) {
828 return cmd_results_new(CMD_INVALID, "move", 823 return cmd_results_new(CMD_INVALID,
829 "Container is already in the scratchpad"); 824 "Container is already in the scratchpad");
830 } 825 }
831 root_scratchpad_add_container(con); 826 root_scratchpad_add_container(con);
832 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 827 return cmd_results_new(CMD_SUCCESS, NULL);
833} 828}
834 829
835struct cmd_results *cmd_move(int argc, char **argv) { 830struct cmd_results *cmd_move(int argc, char **argv) {
@@ -838,7 +833,7 @@ struct cmd_results *cmd_move(int argc, char **argv) {
838 return error; 833 return error;
839 } 834 }
840 if (!root->outputs->length) { 835 if (!root->outputs->length) {
841 return cmd_results_new(CMD_INVALID, "move", 836 return cmd_results_new(CMD_INVALID,
842 "Can't run this command while there's no outputs connected."); 837 "Can't run this command while there's no outputs connected.");
843 } 838 }
844 839
@@ -867,7 +862,7 @@ struct cmd_results *cmd_move(int argc, char **argv) {
867 } else if (strcasecmp(argv[0], "absolute") == 0) { 862 } else if (strcasecmp(argv[0], "absolute") == 0) {
868 return cmd_move_to_position(argc, argv); 863 return cmd_move_to_position(argc, argv);
869 } else { 864 } else {
870 return cmd_results_new(CMD_INVALID, "move", expected_syntax); 865 return cmd_results_new(CMD_INVALID, expected_syntax);
871 } 866 }
872 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 867 return cmd_results_new(CMD_SUCCESS, NULL);
873} 868}