aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/seat.c
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2019-01-13 20:38:34 -0500
committerLibravatar GitHub <noreply@github.com>2019-01-13 20:38:34 -0500
commit23ab56bbf746e7aa4a940caa343d447a969fa37e (patch)
tree087201fd4d39c3a551c925c4f5479311e10e6623 /sway/input/seat.c
parentMerge pull request #3388 from RedSoxFan/reset-inputs-on-reload (diff)
parentRefactor seat operations to use an interface (diff)
downloadsway-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.c236
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
314static void collect_focus_iter(struct sway_node *node, void *data) { 314static 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
665static 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
677static void set_workspace(struct sway_seat *seat, 665static 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
1065void 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
1079void 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
1094void 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
1105void 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
1115void 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
1143void 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
1157static 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
1164static 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
1219void 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
1246void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, 1053void 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
1086bool seat_doing_seatop(struct sway_seat *seat) {
1087 return seat->seatop_impl != NULL;
1088}
1089
1090void 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
1096void 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
1102void 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
1111void 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
1120void 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}