diff options
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r-- | sway/input/seat.c | 74 |
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 | ||
978 | void 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 | |||
978 | void seat_begin_resize_floating(struct sway_seat *seat, | 988 | void 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 | ||
1028 | static 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 | |||
1035 | static 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 | |||
1018 | void seat_end_mouse_operation(struct sway_seat *seat) { | 1090 | void 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; |