aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/seat.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r--sway/input/seat.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c
index a908560a..86e5f809 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -975,6 +975,16 @@ void seat_begin_move_floating(struct sway_seat *seat,
975 cursor_set_image(seat->cursor, "grab", NULL); 975 cursor_set_image(seat->cursor, "grab", NULL);
976} 976}
977 977
978void seat_begin_move_tiling(struct sway_seat *seat,
979 struct sway_container *con, uint32_t button) {
980 seat->operation = OP_MOVE_TILING;
981 seat->op_container = con;
982 seat->op_button = button;
983 seat->op_target_node = NULL;
984 seat->op_target_edge = 0;
985 cursor_set_image(seat->cursor, "grab", NULL);
986}
987
978void seat_begin_resize_floating(struct sway_seat *seat, 988void seat_begin_resize_floating(struct sway_seat *seat,
979 struct sway_container *con, uint32_t button, enum wlr_edges edge) { 989 struct sway_container *con, uint32_t button, enum wlr_edges edge) {
980 if (!seat->cursor) { 990 if (!seat->cursor) {
@@ -1015,6 +1025,68 @@ void seat_begin_resize_tiling(struct sway_seat *seat,
1015 seat->op_ref_height = con->height; 1025 seat->op_ref_height = con->height;
1016} 1026}
1017 1027
1028static bool is_parallel(enum sway_container_layout layout,
1029 enum wlr_edges edge) {
1030 bool layout_is_horiz = layout == L_HORIZ || layout == L_TABBED;
1031 bool edge_is_horiz = edge == WLR_EDGE_LEFT || edge == WLR_EDGE_RIGHT;
1032 return layout_is_horiz == edge_is_horiz;
1033}
1034
1035static void seat_end_move_tiling(struct sway_seat *seat) {
1036 struct sway_container *con = seat->op_container;
1037 struct sway_container *old_parent = con->parent;
1038 struct sway_workspace *old_ws = con->workspace;
1039 struct sway_node *target_node = seat->op_target_node;
1040 struct sway_workspace *new_ws = target_node->type == N_WORKSPACE ?
1041 target_node->sway_workspace : target_node->sway_container->workspace;
1042 enum wlr_edges edge = seat->op_target_edge;
1043 int after = edge != WLR_EDGE_TOP && edge != WLR_EDGE_LEFT;
1044
1045 container_detach(con);
1046 if (old_parent) {
1047 container_reap_empty(old_parent);
1048 }
1049
1050 // Moving container into empty workspace
1051 if (target_node->type == N_WORKSPACE && edge == WLR_EDGE_NONE) {
1052 workspace_add_tiling(new_ws, con);
1053
1054 // Moving container before/after another
1055 } else if (target_node->type == N_CONTAINER) {
1056 struct sway_container *target = target_node->sway_container;
1057 enum sway_container_layout layout = container_parent_layout(target);
1058 if (edge && !is_parallel(layout, edge)) {
1059 enum sway_container_layout new_layout = edge == WLR_EDGE_TOP ||
1060 edge == WLR_EDGE_BOTTOM ? L_VERT : L_HORIZ;
1061 container_split(target, new_layout);
1062 }
1063 container_add_sibling(target, con, after);
1064
1065 // Target is a workspace which requires splitting
1066 } else {
1067 enum sway_container_layout new_layout = edge == WLR_EDGE_TOP ||
1068 edge == WLR_EDGE_BOTTOM ? L_VERT : L_HORIZ;
1069 workspace_split(new_ws, new_layout);
1070 workspace_insert_tiling(new_ws, con, after);
1071 }
1072
1073 // This is a bit dirty, but we'll set the dimensions to that of a sibling.
1074 // I don't think there's any other way to make it consistent without
1075 // changing how we auto-size containers.
1076 list_t *siblings = container_get_siblings(con);
1077 if (siblings->length > 1) {
1078 int index = list_find(siblings, con);
1079 struct sway_container *sibling = index == 0 ? siblings->items[1] : siblings->items[index - 1];
1080 con->width = sibling->width;
1081 con->height = sibling->height;
1082 }
1083
1084 arrange_workspace(old_ws);
1085 if (new_ws != old_ws) {
1086 arrange_workspace(new_ws);
1087 }
1088}
1089
1018void seat_end_mouse_operation(struct sway_seat *seat) { 1090void seat_end_mouse_operation(struct sway_seat *seat) {
1019 enum sway_seat_operation operation = seat->operation; 1091 enum sway_seat_operation operation = seat->operation;
1020 if (seat->operation == OP_MOVE_FLOATING) { 1092 if (seat->operation == OP_MOVE_FLOATING) {
@@ -1022,6 +1094,8 @@ void seat_end_mouse_operation(struct sway_seat *seat) {
1022 // output again. 1094 // output again.
1023 struct sway_container *con = seat->op_container; 1095 struct sway_container *con = seat->op_container;
1024 container_floating_move_to(con, con->x, con->y); 1096 container_floating_move_to(con, con->x, con->y);
1097 } else if (seat->operation == OP_MOVE_TILING && seat->op_target_node) {
1098 seat_end_move_tiling(seat);
1025 } 1099 }
1026 seat->operation = OP_NONE; 1100 seat->operation = OP_NONE;
1027 seat->op_container = NULL; 1101 seat->op_container = NULL;