|  |  |  | @ -2,7 +2,6 @@ | 
			
		
	
		
			
				
					|  |  |  |  | #include <limits.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <wlr/types/wlr_cursor.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <wlr/util/edges.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/desktop.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/desktop/transaction.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/input/cursor.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/input/seat.h" | 
			
		
	
	
		
			
				
					|  |  |  | @ -24,28 +23,17 @@ struct seatop_move_tiling_event { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_container *con; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_node *target_node; | 
			
		
	
		
			
				
					|  |  |  |  | 	enum wlr_edges target_edge; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_box drop_box; | 
			
		
	
		
			
				
					|  |  |  |  | 	double ref_lx, ref_ly; // cursor's x/y at start of op
 | 
			
		
	
		
			
				
					|  |  |  |  | 	bool threshold_reached; | 
			
		
	
		
			
				
					|  |  |  |  | 	bool split_target; | 
			
		
	
		
			
				
					|  |  |  |  | 	bool insert_after_target; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_scene_rect *indicator_rect; | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void handle_render(struct sway_seat *seat, struct render_context *ctx) { | 
			
		
	
		
			
				
					|  |  |  |  | static void handle_end(struct sway_seat *seat) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct seatop_move_tiling_event *e = seat->seatop_data; | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!e->threshold_reached) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	if (e->target_node && node_get_output(e->target_node) == ctx->output) { | 
			
		
	
		
			
				
					|  |  |  |  | 		float color[4]; | 
			
		
	
		
			
				
					|  |  |  |  | 		memcpy(&color, config->border_colors.focused.indicator, | 
			
		
	
		
			
				
					|  |  |  |  | 				sizeof(float) * 4); | 
			
		
	
		
			
				
					|  |  |  |  | 		premultiply_alpha(color, 0.5); | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_box box; | 
			
		
	
		
			
				
					|  |  |  |  | 		memcpy(&box, &e->drop_box, sizeof(struct wlr_box)); | 
			
		
	
		
			
				
					|  |  |  |  | 		scale_box(&box, ctx->output->wlr_output->scale); | 
			
		
	
		
			
				
					|  |  |  |  | 		render_rect(ctx, &box, color); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_scene_node_destroy(&e->indicator_rect->node); | 
			
		
	
		
			
				
					|  |  |  |  | 	e->indicator_rect = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void handle_motion_prethreshold(struct sway_seat *seat) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -66,6 +54,7 @@ static void handle_motion_prethreshold(struct sway_seat *seat) { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// If the threshold has been exceeded, start the actual drag
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if ((cx - sx) * (cx - sx) + (cy - sy) * (cy - sy) > threshold) { | 
			
		
	
		
			
				
					|  |  |  |  | 		wlr_scene_node_set_enabled(&e->indicator_rect->node, true); | 
			
		
	
		
			
				
					|  |  |  |  | 		e->threshold_reached = true; | 
			
		
	
		
			
				
					|  |  |  |  | 		cursor_set_image(seat->cursor, "grab", NULL); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
	
		
			
				
					|  |  |  | @ -164,6 +153,11 @@ static bool split_titlebar(struct sway_node *node, struct sway_container *avoid, | 
			
		
	
		
			
				
					|  |  |  |  | 	return false; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void update_indicator(struct seatop_move_tiling_event *e, struct wlr_box *box) { | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_scene_node_set_position(&e->indicator_rect->node, box->x, box->y); | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_scene_rect_set_size(e->indicator_rect, box->width, box->height); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void handle_motion_postthreshold(struct sway_seat *seat) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct seatop_move_tiling_event *e = seat->seatop_data; | 
			
		
	
		
			
				
					|  |  |  |  | 	e->split_target = false; | 
			
		
	
	
		
			
				
					|  |  |  | @ -172,8 +166,6 @@ static void handle_motion_postthreshold(struct sway_seat *seat) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_cursor *cursor = seat->cursor; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct sway_node *node = node_at_coords(seat, | 
			
		
	
		
			
				
					|  |  |  |  | 			cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy); | 
			
		
	
		
			
				
					|  |  |  |  | 	// Damage the old location
 | 
			
		
	
		
			
				
					|  |  |  |  | 	desktop_damage_box(&e->drop_box); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!node) { | 
			
		
	
		
			
				
					|  |  |  |  | 		// Eg. hovered over a layer surface such as swaybar
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -186,8 +178,10 @@ static void handle_motion_postthreshold(struct sway_seat *seat) { | 
			
		
	
		
			
				
					|  |  |  |  | 		// Empty workspace
 | 
			
		
	
		
			
				
					|  |  |  |  | 		e->target_node = node; | 
			
		
	
		
			
				
					|  |  |  |  | 		e->target_edge = WLR_EDGE_NONE; | 
			
		
	
		
			
				
					|  |  |  |  | 		workspace_get_box(node->sway_workspace, &e->drop_box); | 
			
		
	
		
			
				
					|  |  |  |  | 		desktop_damage_box(&e->drop_box); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		struct wlr_box drop_box; | 
			
		
	
		
			
				
					|  |  |  |  | 		workspace_get_box(node->sway_workspace, &drop_box); | 
			
		
	
		
			
				
					|  |  |  |  | 		update_indicator(e, &drop_box); | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -200,11 +194,18 @@ static void handle_motion_postthreshold(struct sway_seat *seat) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wlr_box drop_box = { | 
			
		
	
		
			
				
					|  |  |  |  | 		.x = con->pending.content_x, | 
			
		
	
		
			
				
					|  |  |  |  | 		.y = con->pending.content_y, | 
			
		
	
		
			
				
					|  |  |  |  | 		.width = con->pending.content_width, | 
			
		
	
		
			
				
					|  |  |  |  | 		.height = con->pending.content_height, | 
			
		
	
		
			
				
					|  |  |  |  | 	}; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// Check if the cursor is over a tilebar only if the destination
 | 
			
		
	
		
			
				
					|  |  |  |  | 	// container is not a descendant of the source container.
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!surface && !container_has_ancestor(con, e->con) && | 
			
		
	
		
			
				
					|  |  |  |  | 			split_titlebar(node, e->con, cursor->cursor, | 
			
		
	
		
			
				
					|  |  |  |  | 				&e->drop_box, &e->insert_after_target)) { | 
			
		
	
		
			
				
					|  |  |  |  | 				&drop_box, &e->insert_after_target)) { | 
			
		
	
		
			
				
					|  |  |  |  | 		// Don't allow dropping over the source container's titlebar
 | 
			
		
	
		
			
				
					|  |  |  |  | 		// to give users a chance to cancel a drag operation.
 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (con == e->con) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -214,6 +215,7 @@ static void handle_motion_postthreshold(struct sway_seat *seat) { | 
			
		
	
		
			
				
					|  |  |  |  | 			e->split_target = true; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		e->target_edge = WLR_EDGE_NONE; | 
			
		
	
		
			
				
					|  |  |  |  | 		update_indicator(e, &drop_box); | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -255,8 +257,7 @@ static void handle_motion_postthreshold(struct sway_seat *seat) { | 
			
		
	
		
			
				
					|  |  |  |  | 				e->target_node = node_get_parent(e->target_node); | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 			e->target_edge = edge; | 
			
		
	
		
			
				
					|  |  |  |  | 			e->drop_box = box; | 
			
		
	
		
			
				
					|  |  |  |  | 			desktop_damage_box(&e->drop_box); | 
			
		
	
		
			
				
					|  |  |  |  | 			update_indicator(e, &box); | 
			
		
	
		
			
				
					|  |  |  |  | 			return; | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		con = con->pending.parent; | 
			
		
	
	
		
			
				
					|  |  |  | @ -298,12 +299,8 @@ static void handle_motion_postthreshold(struct sway_seat *seat) { | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	e->target_node = node; | 
			
		
	
		
			
				
					|  |  |  |  | 	e->drop_box.x = con->pending.content_x; | 
			
		
	
		
			
				
					|  |  |  |  | 	e->drop_box.y = con->pending.content_y; | 
			
		
	
		
			
				
					|  |  |  |  | 	e->drop_box.width = con->pending.content_width; | 
			
		
	
		
			
				
					|  |  |  |  | 	e->drop_box.height = con->pending.content_height; | 
			
		
	
		
			
				
					|  |  |  |  | 	resize_box(&e->drop_box, e->target_edge, thickness); | 
			
		
	
		
			
				
					|  |  |  |  | 	desktop_damage_box(&e->drop_box); | 
			
		
	
		
			
				
					|  |  |  |  | 	resize_box(&drop_box, e->target_edge, thickness); | 
			
		
	
		
			
				
					|  |  |  |  | 	update_indicator(e, &drop_box); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void handle_pointer_motion(struct sway_seat *seat, uint32_t time_msec) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -438,7 +435,7 @@ static const struct sway_seatop_impl seatop_impl = { | 
			
		
	
		
			
				
					|  |  |  |  | 	.pointer_motion = handle_pointer_motion, | 
			
		
	
		
			
				
					|  |  |  |  | 	.tablet_tool_tip = handle_tablet_tool_tip, | 
			
		
	
		
			
				
					|  |  |  |  | 	.unref = handle_unref, | 
			
		
	
		
			
				
					|  |  |  |  | 	.render = handle_render, | 
			
		
	
		
			
				
					|  |  |  |  | 	.end = handle_end, | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void seatop_begin_move_tiling_threshold(struct sway_seat *seat, | 
			
		
	
	
		
			
				
					|  |  |  | @ -450,6 +447,20 @@ void seatop_begin_move_tiling_threshold(struct sway_seat *seat, | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!e) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	const float *indicator = config->border_colors.focused.indicator; | 
			
		
	
		
			
				
					|  |  |  |  | 	float color[4] = { | 
			
		
	
		
			
				
					|  |  |  |  | 		indicator[0] * .5, | 
			
		
	
		
			
				
					|  |  |  |  | 		indicator[1] * .5, | 
			
		
	
		
			
				
					|  |  |  |  | 		indicator[2] * .5, | 
			
		
	
		
			
				
					|  |  |  |  | 		indicator[3] * .5, | 
			
		
	
		
			
				
					|  |  |  |  | 	}; | 
			
		
	
		
			
				
					|  |  |  |  | 	e->indicator_rect = wlr_scene_rect_create(seat->scene_tree, 0, 0, color); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!e->indicator_rect) { | 
			
		
	
		
			
				
					|  |  |  |  | 		free(e); | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	e->con = con; | 
			
		
	
		
			
				
					|  |  |  |  | 	e->ref_lx = seat->cursor->cursor->x; | 
			
		
	
		
			
				
					|  |  |  |  | 	e->ref_ly = seat->cursor->cursor->y; | 
			
		
	
	
		
			
				
					|  |  |  | 
 |