diff options
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r-- | sway/input/seat.c | 236 |
1 files changed, 42 insertions, 194 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c index a8df5b99..7bd889d7 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -308,7 +308,7 @@ static void handle_new_drag_icon(struct wl_listener *listener, void *data) { | |||
308 | wl_list_insert(&root->drag_icons, &icon->link); | 308 | wl_list_insert(&root->drag_icons, &icon->link); |
309 | 309 | ||
310 | drag_icon_update_position(icon); | 310 | drag_icon_update_position(icon); |
311 | seat_end_mouse_operation(seat); | 311 | seatop_abort(seat); |
312 | } | 312 | } |
313 | 313 | ||
314 | static void collect_focus_iter(struct sway_node *node, void *data) { | 314 | static void collect_focus_iter(struct sway_node *node, void *data) { |
@@ -625,18 +625,6 @@ static int handle_urgent_timeout(void *data) { | |||
625 | return 0; | 625 | return 0; |
626 | } | 626 | } |
627 | 627 | ||
628 | static void container_raise_floating(struct sway_container *con) { | ||
629 | // Bring container to front by putting it at the end of the floating list. | ||
630 | struct sway_container *floater = con; | ||
631 | while (floater->parent) { | ||
632 | floater = floater->parent; | ||
633 | } | ||
634 | if (container_is_floating(floater)) { | ||
635 | list_move_to_end(floater->workspace->floating, floater); | ||
636 | node_set_dirty(&floater->workspace->node); | ||
637 | } | ||
638 | } | ||
639 | |||
640 | static void set_workspace(struct sway_seat *seat, | 628 | static void set_workspace(struct sway_seat *seat, |
641 | struct sway_workspace *new_ws) { | 629 | struct sway_workspace *new_ws) { |
642 | if (seat->workspace == new_ws) { | 630 | if (seat->workspace == new_ws) { |
@@ -1025,187 +1013,6 @@ struct seat_config *seat_get_config_by_name(const char *name) { | |||
1025 | return NULL; | 1013 | return NULL; |
1026 | } | 1014 | } |
1027 | 1015 | ||
1028 | void seat_begin_down(struct sway_seat *seat, struct sway_container *con, | ||
1029 | uint32_t button, double sx, double sy) { | ||
1030 | seat->operation = OP_DOWN; | ||
1031 | seat->op_container = con; | ||
1032 | seat->op_button = button; | ||
1033 | seat->op_ref_lx = seat->cursor->cursor->x; | ||
1034 | seat->op_ref_ly = seat->cursor->cursor->y; | ||
1035 | seat->op_ref_con_lx = sx; | ||
1036 | seat->op_ref_con_ly = sy; | ||
1037 | seat->op_moved = false; | ||
1038 | |||
1039 | container_raise_floating(con); | ||
1040 | } | ||
1041 | |||
1042 | void seat_begin_move_floating(struct sway_seat *seat, | ||
1043 | struct sway_container *con, uint32_t button) { | ||
1044 | if (!seat->cursor) { | ||
1045 | wlr_log(WLR_DEBUG, "Ignoring move request due to no cursor device"); | ||
1046 | return; | ||
1047 | } | ||
1048 | seat->operation = OP_MOVE_FLOATING; | ||
1049 | seat->op_container = con; | ||
1050 | seat->op_button = button; | ||
1051 | |||
1052 | container_raise_floating(con); | ||
1053 | |||
1054 | cursor_set_image(seat->cursor, "grab", NULL); | ||
1055 | } | ||
1056 | |||
1057 | void seat_begin_move_tiling_threshold(struct sway_seat *seat, | ||
1058 | struct sway_container *con, uint32_t button) { | ||
1059 | seat->operation = OP_MOVE_TILING_THRESHOLD; | ||
1060 | seat->op_container = con; | ||
1061 | seat->op_button = button; | ||
1062 | seat->op_target_node = NULL; | ||
1063 | seat->op_target_edge = 0; | ||
1064 | seat->op_ref_lx = seat->cursor->cursor->x; | ||
1065 | seat->op_ref_ly = seat->cursor->cursor->y; | ||
1066 | } | ||
1067 | |||
1068 | void seat_begin_move_tiling(struct sway_seat *seat, | ||
1069 | struct sway_container *con, uint32_t button) { | ||
1070 | seat->operation = OP_MOVE_TILING; | ||
1071 | seat->op_container = con; | ||
1072 | seat->op_button = button; | ||
1073 | seat->op_target_node = NULL; | ||
1074 | seat->op_target_edge = 0; | ||
1075 | cursor_set_image(seat->cursor, "grab", NULL); | ||
1076 | } | ||
1077 | |||
1078 | void seat_begin_resize_floating(struct sway_seat *seat, | ||
1079 | struct sway_container *con, uint32_t button, enum wlr_edges edge) { | ||
1080 | if (!seat->cursor) { | ||
1081 | wlr_log(WLR_DEBUG, "Ignoring resize request due to no cursor device"); | ||
1082 | return; | ||
1083 | } | ||
1084 | struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); | ||
1085 | seat->operation = OP_RESIZE_FLOATING; | ||
1086 | seat->op_container = con; | ||
1087 | seat->op_resize_preserve_ratio = keyboard && | ||
1088 | (wlr_keyboard_get_modifiers(keyboard) & WLR_MODIFIER_SHIFT); | ||
1089 | seat->op_resize_edge = edge == WLR_EDGE_NONE ? | ||
1090 | WLR_EDGE_BOTTOM | WLR_EDGE_RIGHT : edge; | ||
1091 | seat->op_button = button; | ||
1092 | seat->op_ref_lx = seat->cursor->cursor->x; | ||
1093 | seat->op_ref_ly = seat->cursor->cursor->y; | ||
1094 | seat->op_ref_con_lx = con->x; | ||
1095 | seat->op_ref_con_ly = con->y; | ||
1096 | seat->op_ref_width = con->width; | ||
1097 | seat->op_ref_height = con->height; | ||
1098 | |||
1099 | container_raise_floating(con); | ||
1100 | |||
1101 | const char *image = edge == WLR_EDGE_NONE ? | ||
1102 | "se-resize" : wlr_xcursor_get_resize_name(edge); | ||
1103 | cursor_set_image(seat->cursor, image, NULL); | ||
1104 | } | ||
1105 | |||
1106 | void seat_begin_resize_tiling(struct sway_seat *seat, | ||
1107 | struct sway_container *con, uint32_t button, enum wlr_edges edge) { | ||
1108 | seat->operation = OP_RESIZE_TILING; | ||
1109 | seat->op_container = con; | ||
1110 | seat->op_resize_edge = edge; | ||
1111 | seat->op_button = button; | ||
1112 | seat->op_ref_lx = seat->cursor->cursor->x; | ||
1113 | seat->op_ref_ly = seat->cursor->cursor->y; | ||
1114 | seat->op_ref_con_lx = con->x; | ||
1115 | seat->op_ref_con_ly = con->y; | ||
1116 | seat->op_ref_width = con->width; | ||
1117 | seat->op_ref_height = con->height; | ||
1118 | } | ||
1119 | |||
1120 | static bool is_parallel(enum sway_container_layout layout, | ||
1121 | enum wlr_edges edge) { | ||
1122 | bool layout_is_horiz = layout == L_HORIZ || layout == L_TABBED; | ||
1123 | bool edge_is_horiz = edge == WLR_EDGE_LEFT || edge == WLR_EDGE_RIGHT; | ||
1124 | return layout_is_horiz == edge_is_horiz; | ||
1125 | } | ||
1126 | |||
1127 | static void seat_end_move_tiling(struct sway_seat *seat) { | ||
1128 | struct sway_container *con = seat->op_container; | ||
1129 | struct sway_container *old_parent = con->parent; | ||
1130 | struct sway_workspace *old_ws = con->workspace; | ||
1131 | struct sway_node *target_node = seat->op_target_node; | ||
1132 | struct sway_workspace *new_ws = target_node->type == N_WORKSPACE ? | ||
1133 | target_node->sway_workspace : target_node->sway_container->workspace; | ||
1134 | enum wlr_edges edge = seat->op_target_edge; | ||
1135 | int after = edge != WLR_EDGE_TOP && edge != WLR_EDGE_LEFT; | ||
1136 | |||
1137 | container_detach(con); | ||
1138 | |||
1139 | // Moving container into empty workspace | ||
1140 | if (target_node->type == N_WORKSPACE && edge == WLR_EDGE_NONE) { | ||
1141 | workspace_add_tiling(new_ws, con); | ||
1142 | } else if (target_node->type == N_CONTAINER) { | ||
1143 | // Moving container before/after another | ||
1144 | struct sway_container *target = target_node->sway_container; | ||
1145 | enum sway_container_layout layout = container_parent_layout(target); | ||
1146 | if (edge && !is_parallel(layout, edge)) { | ||
1147 | enum sway_container_layout new_layout = edge == WLR_EDGE_TOP || | ||
1148 | edge == WLR_EDGE_BOTTOM ? L_VERT : L_HORIZ; | ||
1149 | container_split(target, new_layout); | ||
1150 | } | ||
1151 | container_add_sibling(target, con, after); | ||
1152 | } else { | ||
1153 | // Target is a workspace which requires splitting | ||
1154 | enum sway_container_layout new_layout = edge == WLR_EDGE_TOP || | ||
1155 | edge == WLR_EDGE_BOTTOM ? L_VERT : L_HORIZ; | ||
1156 | workspace_split(new_ws, new_layout); | ||
1157 | workspace_insert_tiling(new_ws, con, after); | ||
1158 | } | ||
1159 | |||
1160 | if (old_parent) { | ||
1161 | container_reap_empty(old_parent); | ||
1162 | } | ||
1163 | |||
1164 | // This is a bit dirty, but we'll set the dimensions to that of a sibling. | ||
1165 | // I don't think there's any other way to make it consistent without | ||
1166 | // changing how we auto-size containers. | ||
1167 | list_t *siblings = container_get_siblings(con); | ||
1168 | if (siblings->length > 1) { | ||
1169 | int index = list_find(siblings, con); | ||
1170 | struct sway_container *sibling = index == 0 ? | ||
1171 | siblings->items[1] : siblings->items[index - 1]; | ||
1172 | con->width = sibling->width; | ||
1173 | con->height = sibling->height; | ||
1174 | } | ||
1175 | |||
1176 | arrange_workspace(old_ws); | ||
1177 | if (new_ws != old_ws) { | ||
1178 | arrange_workspace(new_ws); | ||
1179 | } | ||
1180 | } | ||
1181 | |||
1182 | void seat_end_mouse_operation(struct sway_seat *seat) { | ||
1183 | enum sway_seat_operation operation = seat->operation; | ||
1184 | if (seat->operation == OP_MOVE_FLOATING) { | ||
1185 | // We "move" the container to its own location so it discovers its | ||
1186 | // output again. | ||
1187 | struct sway_container *con = seat->op_container; | ||
1188 | container_floating_move_to(con, con->x, con->y); | ||
1189 | } else if (seat->operation == OP_MOVE_TILING && seat->op_target_node) { | ||
1190 | seat_end_move_tiling(seat); | ||
1191 | } | ||
1192 | seat->operation = OP_NONE; | ||
1193 | seat->op_container = NULL; | ||
1194 | if (operation == OP_DOWN) { | ||
1195 | // Set the cursor's previous coords to the x/y at the start of the | ||
1196 | // operation, so the container change will be detected if using | ||
1197 | // focus_follows_mouse and the cursor moved off the original container | ||
1198 | // during the operation. | ||
1199 | seat->cursor->previous.x = seat->op_ref_lx; | ||
1200 | seat->cursor->previous.y = seat->op_ref_ly; | ||
1201 | if (seat->op_moved) { | ||
1202 | cursor_send_pointer_motion(seat->cursor, 0); | ||
1203 | } | ||
1204 | } else { | ||
1205 | cursor_set_image(seat->cursor, "left_ptr", NULL); | ||
1206 | } | ||
1207 | } | ||
1208 | |||
1209 | void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, | 1016 | void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, |
1210 | uint32_t button, enum wlr_button_state state) { | 1017 | uint32_t button, enum wlr_button_state state) { |
1211 | seat->last_button = button; | 1018 | seat->last_button = button; |
@@ -1238,3 +1045,44 @@ void seat_consider_warp_to_focus(struct sway_seat *seat) { | |||
1238 | wl_event_source_timer_update(seat->cursor->hide_source, cursor_get_timeout(seat->cursor)); | 1045 | wl_event_source_timer_update(seat->cursor->hide_source, cursor_get_timeout(seat->cursor)); |
1239 | } | 1046 | } |
1240 | } | 1047 | } |
1048 | |||
1049 | bool seat_doing_seatop(struct sway_seat *seat) { | ||
1050 | return seat->seatop_impl != NULL; | ||
1051 | } | ||
1052 | |||
1053 | void seatop_unref(struct sway_seat *seat, struct sway_container *con) { | ||
1054 | if (seat->seatop_impl && seat->seatop_impl->unref) { | ||
1055 | seat->seatop_impl->unref(seat, con); | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | void seatop_motion(struct sway_seat *seat, uint32_t time_msec) { | ||
1060 | if (seat->seatop_impl && seat->seatop_impl->motion) { | ||
1061 | seat->seatop_impl->motion(seat, time_msec); | ||
1062 | } | ||
1063 | } | ||
1064 | |||
1065 | void seatop_finish(struct sway_seat *seat) { | ||
1066 | if (seat->seatop_impl && seat->seatop_impl->finish) { | ||
1067 | seat->seatop_impl->finish(seat); | ||
1068 | } | ||
1069 | free(seat->seatop_data); | ||
1070 | seat->seatop_data = NULL; | ||
1071 | seat->seatop_impl = NULL; | ||
1072 | } | ||
1073 | |||
1074 | void seatop_abort(struct sway_seat *seat) { | ||
1075 | if (seat->seatop_impl && seat->seatop_impl->abort) { | ||
1076 | seat->seatop_impl->abort(seat); | ||
1077 | } | ||
1078 | free(seat->seatop_data); | ||
1079 | seat->seatop_data = NULL; | ||
1080 | seat->seatop_impl = NULL; | ||
1081 | } | ||
1082 | |||
1083 | void seatop_render(struct sway_seat *seat, struct sway_output *output, | ||
1084 | pixman_region32_t *damage) { | ||
1085 | if (seat->seatop_impl && seat->seatop_impl->render) { | ||
1086 | seat->seatop_impl->render(seat, output, damage); | ||
1087 | } | ||
1088 | } | ||