diff options
author | Drew DeVault <sir@cmpwn.com> | 2019-01-13 20:38:34 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-13 20:38:34 -0500 |
commit | 23ab56bbf746e7aa4a940caa343d447a969fa37e (patch) | |
tree | 087201fd4d39c3a551c925c4f5479311e10e6623 /sway/input/seat.c | |
parent | Merge pull request #3388 from RedSoxFan/reset-inputs-on-reload (diff) | |
parent | Refactor seat operations to use an interface (diff) | |
download | sway-23ab56bbf746e7aa4a940caa343d447a969fa37e.tar.gz sway-23ab56bbf746e7aa4a940caa343d447a969fa37e.tar.zst sway-23ab56bbf746e7aa4a940caa343d447a969fa37e.zip |
Merge pull request #3402 from RyanDwyer/refactor-seatops
Refactor seat operations to use an interface
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 09acab0d..a63999b6 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) { |
@@ -662,18 +662,6 @@ static int handle_urgent_timeout(void *data) { | |||
662 | return 0; | 662 | return 0; |
663 | } | 663 | } |
664 | 664 | ||
665 | static void container_raise_floating(struct sway_container *con) { | ||
666 | // Bring container to front by putting it at the end of the floating list. | ||
667 | struct sway_container *floater = con; | ||
668 | while (floater->parent) { | ||
669 | floater = floater->parent; | ||
670 | } | ||
671 | if (container_is_floating(floater)) { | ||
672 | list_move_to_end(floater->workspace->floating, floater); | ||
673 | node_set_dirty(&floater->workspace->node); | ||
674 | } | ||
675 | } | ||
676 | |||
677 | static void set_workspace(struct sway_seat *seat, | 665 | static void set_workspace(struct sway_seat *seat, |
678 | struct sway_workspace *new_ws) { | 666 | struct sway_workspace *new_ws) { |
679 | if (seat->workspace == new_ws) { | 667 | if (seat->workspace == new_ws) { |
@@ -1062,187 +1050,6 @@ struct seat_config *seat_get_config_by_name(const char *name) { | |||
1062 | return NULL; | 1050 | return NULL; |
1063 | } | 1051 | } |
1064 | 1052 | ||
1065 | void seat_begin_down(struct sway_seat *seat, struct sway_container *con, | ||
1066 | uint32_t button, double sx, double sy) { | ||
1067 | seat->operation = OP_DOWN; | ||
1068 | seat->op_container = con; | ||
1069 | seat->op_button = button; | ||
1070 | seat->op_ref_lx = seat->cursor->cursor->x; | ||
1071 | seat->op_ref_ly = seat->cursor->cursor->y; | ||
1072 | seat->op_ref_con_lx = sx; | ||
1073 | seat->op_ref_con_ly = sy; | ||
1074 | seat->op_moved = false; | ||
1075 | |||
1076 | container_raise_floating(con); | ||
1077 | } | ||
1078 | |||
1079 | void seat_begin_move_floating(struct sway_seat *seat, | ||
1080 | struct sway_container *con, uint32_t button) { | ||
1081 | if (!seat->cursor) { | ||
1082 | wlr_log(WLR_DEBUG, "Ignoring move request due to no cursor device"); | ||
1083 | return; | ||
1084 | } | ||
1085 | seat->operation = OP_MOVE_FLOATING; | ||
1086 | seat->op_container = con; | ||
1087 | seat->op_button = button; | ||
1088 | |||
1089 | container_raise_floating(con); | ||
1090 | |||
1091 | cursor_set_image(seat->cursor, "grab", NULL); | ||
1092 | } | ||
1093 | |||
1094 | void seat_begin_move_tiling_threshold(struct sway_seat *seat, | ||
1095 | struct sway_container *con, uint32_t button) { | ||
1096 | seat->operation = OP_MOVE_TILING_THRESHOLD; | ||
1097 | seat->op_container = con; | ||
1098 | seat->op_button = button; | ||
1099 | seat->op_target_node = NULL; | ||
1100 | seat->op_target_edge = 0; | ||
1101 | seat->op_ref_lx = seat->cursor->cursor->x; | ||
1102 | seat->op_ref_ly = seat->cursor->cursor->y; | ||
1103 | } | ||
1104 | |||
1105 | void seat_begin_move_tiling(struct sway_seat *seat, | ||
1106 | struct sway_container *con, uint32_t button) { | ||
1107 | seat->operation = OP_MOVE_TILING; | ||
1108 | seat->op_container = con; | ||
1109 | seat->op_button = button; | ||
1110 | seat->op_target_node = NULL; | ||
1111 | seat->op_target_edge = 0; | ||
1112 | cursor_set_image(seat->cursor, "grab", NULL); | ||
1113 | } | ||
1114 | |||
1115 | void seat_begin_resize_floating(struct sway_seat *seat, | ||
1116 | struct sway_container *con, uint32_t button, enum wlr_edges edge) { | ||
1117 | if (!seat->cursor) { | ||
1118 | wlr_log(WLR_DEBUG, "Ignoring resize request due to no cursor device"); | ||
1119 | return; | ||
1120 | } | ||
1121 | struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); | ||
1122 | seat->operation = OP_RESIZE_FLOATING; | ||
1123 | seat->op_container = con; | ||
1124 | seat->op_resize_preserve_ratio = keyboard && | ||
1125 | (wlr_keyboard_get_modifiers(keyboard) & WLR_MODIFIER_SHIFT); | ||
1126 | seat->op_resize_edge = edge == WLR_EDGE_NONE ? | ||
1127 | WLR_EDGE_BOTTOM | WLR_EDGE_RIGHT : edge; | ||
1128 | seat->op_button = button; | ||
1129 | seat->op_ref_lx = seat->cursor->cursor->x; | ||
1130 | seat->op_ref_ly = seat->cursor->cursor->y; | ||
1131 | seat->op_ref_con_lx = con->x; | ||
1132 | seat->op_ref_con_ly = con->y; | ||
1133 | seat->op_ref_width = con->width; | ||
1134 | seat->op_ref_height = con->height; | ||
1135 | |||
1136 | container_raise_floating(con); | ||
1137 | |||
1138 | const char *image = edge == WLR_EDGE_NONE ? | ||
1139 | "se-resize" : wlr_xcursor_get_resize_name(edge); | ||
1140 | cursor_set_image(seat->cursor, image, NULL); | ||
1141 | } | ||
1142 | |||
1143 | void seat_begin_resize_tiling(struct sway_seat *seat, | ||
1144 | struct sway_container *con, uint32_t button, enum wlr_edges edge) { | ||
1145 | seat->operation = OP_RESIZE_TILING; | ||
1146 | seat->op_container = con; | ||
1147 | seat->op_resize_edge = edge; | ||
1148 | seat->op_button = button; | ||
1149 | seat->op_ref_lx = seat->cursor->cursor->x; | ||
1150 | seat->op_ref_ly = seat->cursor->cursor->y; | ||
1151 | seat->op_ref_con_lx = con->x; | ||
1152 | seat->op_ref_con_ly = con->y; | ||
1153 | seat->op_ref_width = con->width; | ||
1154 | seat->op_ref_height = con->height; | ||
1155 | } | ||
1156 | |||
1157 | static bool is_parallel(enum sway_container_layout layout, | ||
1158 | enum wlr_edges edge) { | ||
1159 | bool layout_is_horiz = layout == L_HORIZ || layout == L_TABBED; | ||
1160 | bool edge_is_horiz = edge == WLR_EDGE_LEFT || edge == WLR_EDGE_RIGHT; | ||
1161 | return layout_is_horiz == edge_is_horiz; | ||
1162 | } | ||
1163 | |||
1164 | static void seat_end_move_tiling(struct sway_seat *seat) { | ||
1165 | struct sway_container *con = seat->op_container; | ||
1166 | struct sway_container *old_parent = con->parent; | ||
1167 | struct sway_workspace *old_ws = con->workspace; | ||
1168 | struct sway_node *target_node = seat->op_target_node; | ||
1169 | struct sway_workspace *new_ws = target_node->type == N_WORKSPACE ? | ||
1170 | target_node->sway_workspace : target_node->sway_container->workspace; | ||
1171 | enum wlr_edges edge = seat->op_target_edge; | ||
1172 | int after = edge != WLR_EDGE_TOP && edge != WLR_EDGE_LEFT; | ||
1173 | |||
1174 | container_detach(con); | ||
1175 | |||
1176 | // Moving container into empty workspace | ||
1177 | if (target_node->type == N_WORKSPACE && edge == WLR_EDGE_NONE) { | ||
1178 | workspace_add_tiling(new_ws, con); | ||
1179 | } else if (target_node->type == N_CONTAINER) { | ||
1180 | // Moving container before/after another | ||
1181 | struct sway_container *target = target_node->sway_container; | ||
1182 | enum sway_container_layout layout = container_parent_layout(target); | ||
1183 | if (edge && !is_parallel(layout, edge)) { | ||
1184 | enum sway_container_layout new_layout = edge == WLR_EDGE_TOP || | ||
1185 | edge == WLR_EDGE_BOTTOM ? L_VERT : L_HORIZ; | ||
1186 | container_split(target, new_layout); | ||
1187 | } | ||
1188 | container_add_sibling(target, con, after); | ||
1189 | } else { | ||
1190 | // Target is a workspace which requires splitting | ||
1191 | enum sway_container_layout new_layout = edge == WLR_EDGE_TOP || | ||
1192 | edge == WLR_EDGE_BOTTOM ? L_VERT : L_HORIZ; | ||
1193 | workspace_split(new_ws, new_layout); | ||
1194 | workspace_insert_tiling(new_ws, con, after); | ||
1195 | } | ||
1196 | |||
1197 | if (old_parent) { | ||
1198 | container_reap_empty(old_parent); | ||
1199 | } | ||
1200 | |||
1201 | // This is a bit dirty, but we'll set the dimensions to that of a sibling. | ||
1202 | // I don't think there's any other way to make it consistent without | ||
1203 | // changing how we auto-size containers. | ||
1204 | list_t *siblings = container_get_siblings(con); | ||
1205 | if (siblings->length > 1) { | ||
1206 | int index = list_find(siblings, con); | ||
1207 | struct sway_container *sibling = index == 0 ? | ||
1208 | siblings->items[1] : siblings->items[index - 1]; | ||
1209 | con->width = sibling->width; | ||
1210 | con->height = sibling->height; | ||
1211 | } | ||
1212 | |||
1213 | arrange_workspace(old_ws); | ||
1214 | if (new_ws != old_ws) { | ||
1215 | arrange_workspace(new_ws); | ||
1216 | } | ||
1217 | } | ||
1218 | |||
1219 | void seat_end_mouse_operation(struct sway_seat *seat) { | ||
1220 | enum sway_seat_operation operation = seat->operation; | ||
1221 | if (seat->operation == OP_MOVE_FLOATING) { | ||
1222 | // We "move" the container to its own location so it discovers its | ||
1223 | // output again. | ||
1224 | struct sway_container *con = seat->op_container; | ||
1225 | container_floating_move_to(con, con->x, con->y); | ||
1226 | } else if (seat->operation == OP_MOVE_TILING && seat->op_target_node) { | ||
1227 | seat_end_move_tiling(seat); | ||
1228 | } | ||
1229 | seat->operation = OP_NONE; | ||
1230 | seat->op_container = NULL; | ||
1231 | if (operation == OP_DOWN) { | ||
1232 | // Set the cursor's previous coords to the x/y at the start of the | ||
1233 | // operation, so the container change will be detected if using | ||
1234 | // focus_follows_mouse and the cursor moved off the original container | ||
1235 | // during the operation. | ||
1236 | seat->cursor->previous.x = seat->op_ref_lx; | ||
1237 | seat->cursor->previous.y = seat->op_ref_ly; | ||
1238 | if (seat->op_moved) { | ||
1239 | cursor_send_pointer_motion(seat->cursor, 0); | ||
1240 | } | ||
1241 | } else { | ||
1242 | cursor_set_image(seat->cursor, "left_ptr", NULL); | ||
1243 | } | ||
1244 | } | ||
1245 | |||
1246 | void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, | 1053 | void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, |
1247 | uint32_t button, enum wlr_button_state state) { | 1054 | uint32_t button, enum wlr_button_state state) { |
1248 | seat->last_button = button; | 1055 | seat->last_button = button; |
@@ -1275,3 +1082,44 @@ void seat_consider_warp_to_focus(struct sway_seat *seat) { | |||
1275 | wl_event_source_timer_update(seat->cursor->hide_source, cursor_get_timeout(seat->cursor)); | 1082 | wl_event_source_timer_update(seat->cursor->hide_source, cursor_get_timeout(seat->cursor)); |
1276 | } | 1083 | } |
1277 | } | 1084 | } |
1085 | |||
1086 | bool seat_doing_seatop(struct sway_seat *seat) { | ||
1087 | return seat->seatop_impl != NULL; | ||
1088 | } | ||
1089 | |||
1090 | void seatop_unref(struct sway_seat *seat, struct sway_container *con) { | ||
1091 | if (seat->seatop_impl && seat->seatop_impl->unref) { | ||
1092 | seat->seatop_impl->unref(seat, con); | ||
1093 | } | ||
1094 | } | ||
1095 | |||
1096 | void seatop_motion(struct sway_seat *seat, uint32_t time_msec) { | ||
1097 | if (seat->seatop_impl && seat->seatop_impl->motion) { | ||
1098 | seat->seatop_impl->motion(seat, time_msec); | ||
1099 | } | ||
1100 | } | ||
1101 | |||
1102 | void seatop_finish(struct sway_seat *seat) { | ||
1103 | if (seat->seatop_impl && seat->seatop_impl->finish) { | ||
1104 | seat->seatop_impl->finish(seat); | ||
1105 | } | ||
1106 | free(seat->seatop_data); | ||
1107 | seat->seatop_data = NULL; | ||
1108 | seat->seatop_impl = NULL; | ||
1109 | } | ||
1110 | |||
1111 | void seatop_abort(struct sway_seat *seat) { | ||
1112 | if (seat->seatop_impl && seat->seatop_impl->abort) { | ||
1113 | seat->seatop_impl->abort(seat); | ||
1114 | } | ||
1115 | free(seat->seatop_data); | ||
1116 | seat->seatop_data = NULL; | ||
1117 | seat->seatop_impl = NULL; | ||
1118 | } | ||
1119 | |||
1120 | void seatop_render(struct sway_seat *seat, struct sway_output *output, | ||
1121 | pixman_region32_t *damage) { | ||
1122 | if (seat->seatop_impl && seat->seatop_impl->render) { | ||
1123 | seat->seatop_impl->render(seat, output, damage); | ||
1124 | } | ||
1125 | } | ||