mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	output-layout: make wlr_output_layout_get_box() take a box as parameter
Closes https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/812
This commit is contained in:
		
							parent
							
								
									2c59435e82
								
							
						
					
					
						commit
						498f30aad1
					
				
					 3 changed files with 92 additions and 85 deletions
				
			
		| 
						 | 
				
			
			@ -107,10 +107,10 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout,
 | 
			
		|||
/**
 | 
			
		||||
 * Get the box of the layout for the given reference output in layout
 | 
			
		||||
 * coordinates. If `reference` is NULL, the box will be for the extents of the
 | 
			
		||||
 * entire layout.
 | 
			
		||||
 * entire layout. If the output isn't in the layout, the box will be empty.
 | 
			
		||||
 */
 | 
			
		||||
struct wlr_box *wlr_output_layout_get_box(
 | 
			
		||||
		struct wlr_output_layout *layout, struct wlr_output *reference);
 | 
			
		||||
void wlr_output_layout_get_box(struct wlr_output_layout *layout,
 | 
			
		||||
		struct wlr_output *reference, struct wlr_box *dest_box);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* Add an auto configured output to the layout. This will place the output in a
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -237,33 +237,32 @@ static void cursor_warp_unchecked(struct wlr_cursor *cur,
 | 
			
		|||
 * Absolute movement for touch and pen devices will be relative to this box and
 | 
			
		||||
 * pointer movement will be constrained to this box.
 | 
			
		||||
 *
 | 
			
		||||
 * If none of these are set, returns NULL and absolute movement should be
 | 
			
		||||
 * If none of these are set, empties the box and absolute movement should be
 | 
			
		||||
 * relative to the extents of the layout.
 | 
			
		||||
 */
 | 
			
		||||
static struct wlr_box *get_mapping(struct wlr_cursor *cur,
 | 
			
		||||
		struct wlr_input_device *dev) {
 | 
			
		||||
static void get_mapping(struct wlr_cursor *cur,
 | 
			
		||||
		struct wlr_input_device *dev, struct wlr_box *box) {
 | 
			
		||||
	assert(cur->state->layout);
 | 
			
		||||
	struct wlr_cursor_device *c_device = get_cursor_device(cur, dev);
 | 
			
		||||
 | 
			
		||||
	if (c_device) {
 | 
			
		||||
		if (c_device->mapped_box) {
 | 
			
		||||
			return c_device->mapped_box;
 | 
			
		||||
		}
 | 
			
		||||
		if (c_device->mapped_output) {
 | 
			
		||||
			return wlr_output_layout_get_box(cur->state->layout,
 | 
			
		||||
				c_device->mapped_output);
 | 
			
		||||
			*box = *c_device->mapped_box;
 | 
			
		||||
		} else if (c_device->mapped_output) {
 | 
			
		||||
			wlr_output_layout_get_box(cur->state->layout,
 | 
			
		||||
				c_device->mapped_output, box);
 | 
			
		||||
		}
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cur->state->mapped_box) {
 | 
			
		||||
		return cur->state->mapped_box;
 | 
			
		||||
		*box = *cur->state->mapped_box;
 | 
			
		||||
	} else if (cur->state->mapped_output) {
 | 
			
		||||
		wlr_output_layout_get_box(cur->state->layout,
 | 
			
		||||
			cur->state->mapped_output, box);
 | 
			
		||||
	} else {
 | 
			
		||||
		box->width = box->height = 0;
 | 
			
		||||
	}
 | 
			
		||||
	if (cur->state->mapped_output) {
 | 
			
		||||
		return wlr_output_layout_get_box(cur->state->layout,
 | 
			
		||||
			cur->state->mapped_output);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
 | 
			
		||||
| 
						 | 
				
			
			@ -271,9 +270,10 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
 | 
			
		|||
	assert(cur->state->layout);
 | 
			
		||||
 | 
			
		||||
	bool result = false;
 | 
			
		||||
	struct wlr_box *mapping = get_mapping(cur, dev);
 | 
			
		||||
	if (mapping) {
 | 
			
		||||
		result = wlr_box_contains_point(mapping, lx, ly);
 | 
			
		||||
	struct wlr_box mapping;
 | 
			
		||||
	get_mapping(cur, dev, &mapping);
 | 
			
		||||
	if (!wlr_box_empty(&mapping)) {
 | 
			
		||||
		result = wlr_box_contains_point(&mapping, lx, ly);
 | 
			
		||||
	} else {
 | 
			
		||||
		result = wlr_output_layout_contains_point(cur->state->layout, NULL,
 | 
			
		||||
			lx, ly);
 | 
			
		||||
| 
						 | 
				
			
			@ -288,9 +288,10 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
 | 
			
		|||
 | 
			
		||||
void wlr_cursor_warp_closest(struct wlr_cursor *cur,
 | 
			
		||||
		struct wlr_input_device *dev, double lx, double ly) {
 | 
			
		||||
	struct wlr_box *mapping = get_mapping(cur, dev);
 | 
			
		||||
	if (mapping) {
 | 
			
		||||
		wlr_box_closest_point(mapping, lx, ly, &lx, &ly);
 | 
			
		||||
	struct wlr_box mapping;
 | 
			
		||||
	get_mapping(cur, dev, &mapping);
 | 
			
		||||
	if (!wlr_box_empty(&mapping)) {
 | 
			
		||||
		wlr_box_closest_point(&mapping, lx, ly, &lx, &ly);
 | 
			
		||||
		if (isnan(lx) || isnan(ly)) {
 | 
			
		||||
			lx = 0;
 | 
			
		||||
			ly = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -308,13 +309,14 @@ void wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur,
 | 
			
		|||
		double *lx, double *ly) {
 | 
			
		||||
	assert(cur->state->layout);
 | 
			
		||||
 | 
			
		||||
	struct wlr_box *mapping = get_mapping(cur, dev);
 | 
			
		||||
	if (!mapping) {
 | 
			
		||||
		mapping = wlr_output_layout_get_box(cur->state->layout, NULL);
 | 
			
		||||
	struct wlr_box mapping;
 | 
			
		||||
	get_mapping(cur, dev, &mapping);
 | 
			
		||||
	if (wlr_box_empty(&mapping)) {
 | 
			
		||||
		wlr_output_layout_get_box(cur->state->layout, NULL, &mapping);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*lx = !isnan(x) ? mapping->width * x + mapping->x : cur->x;
 | 
			
		||||
	*ly = !isnan(y) ? mapping->height * y + mapping->y : cur->y;
 | 
			
		||||
	*lx = !isnan(x) ? mapping.width * x + mapping.x : cur->x;
 | 
			
		||||
	*ly = !isnan(y) ? mapping.height * y + mapping.y : cur->y;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void wlr_cursor_warp_absolute(struct wlr_cursor *cur,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,15 +73,13 @@ void wlr_output_layout_destroy(struct wlr_output_layout *layout) {
 | 
			
		|||
	free(layout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct wlr_box *output_layout_output_get_box(
 | 
			
		||||
		struct wlr_output_layout_output *l_output) {
 | 
			
		||||
	l_output->state->_box.x = l_output->x;
 | 
			
		||||
	l_output->state->_box.y = l_output->y;
 | 
			
		||||
	int width, height;
 | 
			
		||||
	wlr_output_effective_resolution(l_output->output, &width, &height);
 | 
			
		||||
	l_output->state->_box.width = width;
 | 
			
		||||
	l_output->state->_box.height = height;
 | 
			
		||||
	return &l_output->state->_box;
 | 
			
		||||
static void output_layout_output_get_box(
 | 
			
		||||
		struct wlr_output_layout_output *l_output,
 | 
			
		||||
		struct wlr_box *box) {
 | 
			
		||||
	box->x = l_output->x;
 | 
			
		||||
	box->y = l_output->y;
 | 
			
		||||
	wlr_output_effective_resolution(l_output->output,
 | 
			
		||||
		&box->width, &box->height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -98,15 +96,17 @@ static void output_layout_reconfigure(struct wlr_output_layout *layout) {
 | 
			
		|||
	// find the rightmost x coordinate occupied by a manually configured output
 | 
			
		||||
	// in the layout
 | 
			
		||||
	struct wlr_output_layout_output *l_output;
 | 
			
		||||
	struct wlr_box output_box;
 | 
			
		||||
 | 
			
		||||
	wl_list_for_each(l_output, &layout->outputs, link) {
 | 
			
		||||
		if (l_output->state->auto_configured) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		struct wlr_box *box = output_layout_output_get_box(l_output);
 | 
			
		||||
		if (box->x + box->width > max_x) {
 | 
			
		||||
			max_x = box->x + box->width;
 | 
			
		||||
			max_x_y = box->y;
 | 
			
		||||
		output_layout_output_get_box(l_output, &output_box);
 | 
			
		||||
		if (output_box.x + output_box.width > max_x) {
 | 
			
		||||
			max_x = output_box.x + output_box.width;
 | 
			
		||||
			max_x_y = output_box.y;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -120,10 +120,10 @@ static void output_layout_reconfigure(struct wlr_output_layout *layout) {
 | 
			
		|||
		if (!l_output->state->auto_configured) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		struct wlr_box *box = output_layout_output_get_box(l_output);
 | 
			
		||||
		output_layout_output_get_box(l_output, &output_box);
 | 
			
		||||
		l_output->x = max_x;
 | 
			
		||||
		l_output->y = max_x_y;
 | 
			
		||||
		max_x += box->width;
 | 
			
		||||
		max_x += output_box.width;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wlr_signal_emit_safe(&layout->events.change, layout);
 | 
			
		||||
| 
						 | 
				
			
			@ -242,8 +242,9 @@ bool wlr_output_layout_contains_point(struct wlr_output_layout *layout,
 | 
			
		|||
	if (reference) {
 | 
			
		||||
		struct wlr_output_layout_output *l_output =
 | 
			
		||||
			wlr_output_layout_get(layout, reference);
 | 
			
		||||
		struct wlr_box *box = output_layout_output_get_box(l_output);
 | 
			
		||||
		return wlr_box_contains_point(box, lx, ly);
 | 
			
		||||
		struct wlr_box output_box;
 | 
			
		||||
		output_layout_output_get_box(l_output, &output_box);
 | 
			
		||||
		return wlr_box_contains_point(&output_box, lx, ly);
 | 
			
		||||
	} else {
 | 
			
		||||
		return !!wlr_output_layout_output_at(layout, lx, ly);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -256,9 +257,9 @@ bool wlr_output_layout_intersects(struct wlr_output_layout *layout,
 | 
			
		|||
	if (reference == NULL) {
 | 
			
		||||
		struct wlr_output_layout_output *l_output;
 | 
			
		||||
		wl_list_for_each(l_output, &layout->outputs, link) {
 | 
			
		||||
			struct wlr_box *output_box =
 | 
			
		||||
				output_layout_output_get_box(l_output);
 | 
			
		||||
			if (wlr_box_intersection(&out_box, output_box, target_lbox)) {
 | 
			
		||||
			struct wlr_box output_box;
 | 
			
		||||
			output_layout_output_get_box(l_output, &output_box);
 | 
			
		||||
			if (wlr_box_intersection(&out_box, &output_box, target_lbox)) {
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -270,8 +271,9 @@ bool wlr_output_layout_intersects(struct wlr_output_layout *layout,
 | 
			
		|||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		struct wlr_box *output_box = output_layout_output_get_box(l_output);
 | 
			
		||||
		return wlr_box_intersection(&out_box, output_box, target_lbox);
 | 
			
		||||
		struct wlr_box output_box;
 | 
			
		||||
		output_layout_output_get_box(l_output, &output_box);
 | 
			
		||||
		return wlr_box_intersection(&out_box, &output_box, target_lbox);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -279,8 +281,9 @@ struct wlr_output *wlr_output_layout_output_at(struct wlr_output_layout *layout,
 | 
			
		|||
		double lx, double ly) {
 | 
			
		||||
	struct wlr_output_layout_output *l_output;
 | 
			
		||||
	wl_list_for_each(l_output, &layout->outputs, link) {
 | 
			
		||||
		struct wlr_box *box = output_layout_output_get_box(l_output);
 | 
			
		||||
		if (wlr_box_contains_point(box, lx, ly)) {
 | 
			
		||||
		struct wlr_box output_box;
 | 
			
		||||
		output_layout_output_get_box(l_output, &output_box);
 | 
			
		||||
		if (wlr_box_contains_point(&output_box, lx, ly)) {
 | 
			
		||||
			return l_output->output;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -342,8 +345,9 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout,
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		double output_x, output_y, output_distance;
 | 
			
		||||
		struct wlr_box *box = output_layout_output_get_box(l_output);
 | 
			
		||||
		wlr_box_closest_point(box, lx, ly, &output_x, &output_y);
 | 
			
		||||
		struct wlr_box output_box;
 | 
			
		||||
		output_layout_output_get_box(l_output, &output_box);
 | 
			
		||||
		wlr_box_closest_point(&output_box, lx, ly, &output_x, &output_y);
 | 
			
		||||
 | 
			
		||||
		// calculate squared distance suitable for comparison
 | 
			
		||||
		output_distance =
 | 
			
		||||
| 
						 | 
				
			
			@ -368,17 +372,17 @@ void wlr_output_layout_closest_point(struct wlr_output_layout *layout,
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct wlr_box *wlr_output_layout_get_box(
 | 
			
		||||
		struct wlr_output_layout *layout, struct wlr_output *reference) {
 | 
			
		||||
void wlr_output_layout_get_box(struct wlr_output_layout *layout,
 | 
			
		||||
		struct wlr_output *reference, struct wlr_box *dest_box) {
 | 
			
		||||
	struct wlr_output_layout_output *l_output;
 | 
			
		||||
	if (reference) {
 | 
			
		||||
		// output extents
 | 
			
		||||
		l_output = wlr_output_layout_get(layout, reference);
 | 
			
		||||
 | 
			
		||||
		if (l_output) {
 | 
			
		||||
			return output_layout_output_get_box(l_output);
 | 
			
		||||
			output_layout_output_get_box(l_output, dest_box);
 | 
			
		||||
		} else {
 | 
			
		||||
			return NULL;
 | 
			
		||||
			dest_box->width = dest_box->height = 0;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		// layout extents
 | 
			
		||||
| 
						 | 
				
			
			@ -387,31 +391,28 @@ struct wlr_box *wlr_output_layout_get_box(
 | 
			
		|||
			min_x = min_y = INT_MAX;
 | 
			
		||||
			max_x = max_y = INT_MIN;
 | 
			
		||||
			wl_list_for_each(l_output, &layout->outputs, link) {
 | 
			
		||||
				struct wlr_box *box = output_layout_output_get_box(l_output);
 | 
			
		||||
				if (box->x < min_x) {
 | 
			
		||||
					min_x = box->x;
 | 
			
		||||
				struct wlr_box output_box;
 | 
			
		||||
				output_layout_output_get_box(l_output, &output_box);
 | 
			
		||||
				if (output_box.x < min_x) {
 | 
			
		||||
					min_x = output_box.x;
 | 
			
		||||
				}
 | 
			
		||||
				if (box->y < min_y) {
 | 
			
		||||
					min_y = box->y;
 | 
			
		||||
				if (output_box.y < min_y) {
 | 
			
		||||
					min_y = output_box.y;
 | 
			
		||||
				}
 | 
			
		||||
				if (box->x + box->width > max_x) {
 | 
			
		||||
					max_x = box->x + box->width;
 | 
			
		||||
				if (output_box.x + output_box.width > max_x) {
 | 
			
		||||
					max_x = output_box.x + output_box.width;
 | 
			
		||||
				}
 | 
			
		||||
				if (box->y + box->height > max_y) {
 | 
			
		||||
					max_y = box->y + box->height;
 | 
			
		||||
				if (output_box.y + output_box.height > max_y) {
 | 
			
		||||
					max_y = output_box.y + output_box.height;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		layout->state->_box.x = min_x;
 | 
			
		||||
		layout->state->_box.y = min_y;
 | 
			
		||||
		layout->state->_box.width = max_x - min_x;
 | 
			
		||||
		layout->state->_box.height = max_y - min_y;
 | 
			
		||||
 | 
			
		||||
		return &layout->state->_box;
 | 
			
		||||
		dest_box->x = min_x;
 | 
			
		||||
		dest_box->y = min_y;
 | 
			
		||||
		dest_box->width = max_x - min_x;
 | 
			
		||||
		dest_box->height = max_y - min_y;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// not reached
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void wlr_output_layout_add_auto(struct wlr_output_layout *layout,
 | 
			
		||||
| 
						 | 
				
			
			@ -442,9 +443,10 @@ struct wlr_output *wlr_output_layout_get_center_output(
 | 
			
		|||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct wlr_box *extents = wlr_output_layout_get_box(layout, NULL);
 | 
			
		||||
	double center_x = extents->width / 2. + extents->x;
 | 
			
		||||
	double center_y = extents->height / 2. + extents->y;
 | 
			
		||||
	struct wlr_box extents;
 | 
			
		||||
	wlr_output_layout_get_box(layout, NULL, &extents);
 | 
			
		||||
	double center_x = extents.width / 2. + extents.x;
 | 
			
		||||
	double center_y = extents.height / 2. + extents.y;
 | 
			
		||||
 | 
			
		||||
	double dest_x = 0, dest_y = 0;
 | 
			
		||||
	wlr_output_layout_closest_point(layout, NULL, center_x, center_y,
 | 
			
		||||
| 
						 | 
				
			
			@ -464,7 +466,8 @@ static struct wlr_output *wlr_output_layout_output_in_direction(
 | 
			
		|||
		enum distance_selection_method distance_method) {
 | 
			
		||||
	assert(reference);
 | 
			
		||||
 | 
			
		||||
	struct wlr_box *ref_box = wlr_output_layout_get_box(layout, reference);
 | 
			
		||||
	struct wlr_box ref_box;
 | 
			
		||||
	wlr_output_layout_get_box(layout, reference, &ref_box);
 | 
			
		||||
 | 
			
		||||
	double min_distance = (distance_method == NEAREST) ? DBL_MAX : DBL_MIN;
 | 
			
		||||
	struct wlr_output *closest_output = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -473,21 +476,23 @@ static struct wlr_output *wlr_output_layout_output_in_direction(
 | 
			
		|||
		if (reference != NULL && reference == l_output->output) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		struct wlr_box *box = output_layout_output_get_box(l_output);
 | 
			
		||||
 | 
			
		||||
		struct wlr_box box;
 | 
			
		||||
		output_layout_output_get_box(l_output, &box);
 | 
			
		||||
 | 
			
		||||
		bool match = false;
 | 
			
		||||
		// test to make sure this output is in the given direction
 | 
			
		||||
		if (direction & WLR_DIRECTION_LEFT) {
 | 
			
		||||
			match = box->x + box->width <= ref_box->x || match;
 | 
			
		||||
			match = box.x + box.width <= ref_box.x || match;
 | 
			
		||||
		}
 | 
			
		||||
		if (direction & WLR_DIRECTION_RIGHT) {
 | 
			
		||||
			match = box->x >= ref_box->x + ref_box->width || match;
 | 
			
		||||
			match = box.x >= ref_box.x + ref_box.width || match;
 | 
			
		||||
		}
 | 
			
		||||
		if (direction & WLR_DIRECTION_UP) {
 | 
			
		||||
			match = box->y + box->height <= ref_box->y || match;
 | 
			
		||||
			match = box.y + box.height <= ref_box.y || match;
 | 
			
		||||
		}
 | 
			
		||||
		if (direction & WLR_DIRECTION_DOWN) {
 | 
			
		||||
			match = box->y >= ref_box->y + ref_box->height || match;
 | 
			
		||||
			match = box.y >= ref_box.y + ref_box.height || match;
 | 
			
		||||
		}
 | 
			
		||||
		if (!match) {
 | 
			
		||||
			continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue