mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	cursor: use NAN for unspecified axes, refactor absolute warping code
This commit is contained in:
		
							parent
							
								
									4d7877420d
								
							
						
					
					
						commit
						6e7c0b57f6
					
				
					 3 changed files with 73 additions and 80 deletions
				
			
		| 
						 | 
					@ -69,16 +69,34 @@ void wlr_cursor_destroy(struct wlr_cursor *cur);
 | 
				
			||||||
 * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
 | 
					 * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
 | 
				
			||||||
 * device mapping constraints will be ignored.
 | 
					 * device mapping constraints will be ignored.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Returns true when the mouse warp was successful.
 | 
					 * Returns true when the cursor warp was successful.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
 | 
					bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
 | 
				
			||||||
	double x, double y);
 | 
						double lx, double ly);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Convert absolute 0..1 coordinates to layout coordinates.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
 | 
				
			||||||
 | 
					 * device mapping constraints will be ignored.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur,
 | 
				
			||||||
 | 
						struct wlr_input_device *dev, double x, double y, double *lx, double *ly);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Warp the cursor to the given x and y in absolute 0..1 coordinates. If the
 | 
				
			||||||
 | 
					 * given point is out of the layout boundaries or constraints, the closest point
 | 
				
			||||||
 | 
					 * will be used. If one coordinate is NAN, it will be ignored.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
 | 
				
			||||||
 | 
					 * device mapping constraints will be ignored.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void wlr_cursor_warp_absolute(struct wlr_cursor *cur,
 | 
					void wlr_cursor_warp_absolute(struct wlr_cursor *cur,
 | 
				
			||||||
	struct wlr_input_device *dev, double x, double y);
 | 
						struct wlr_input_device *dev, double x, double y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Move the cursor in the direction of the given x and y coordinates.
 | 
					 * Move the cursor in the direction of the given x and y layout coordinates. If
 | 
				
			||||||
 | 
					 * one coordinate is NAN, it will be ignored.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
 | 
					 * `dev` may be passed to respect device mapping constraints. If `dev` is NULL,
 | 
				
			||||||
 * device mapping constraints will be ignored.
 | 
					 * device mapping constraints will be ignored.
 | 
				
			||||||
| 
						 | 
					@ -153,11 +171,4 @@ void wlr_cursor_map_to_region(struct wlr_cursor *cur, struct wlr_box *box);
 | 
				
			||||||
void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
 | 
					void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
 | 
				
			||||||
	struct wlr_input_device *dev, struct wlr_box *box);
 | 
						struct wlr_input_device *dev, struct wlr_box *box);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Convert absolute coordinates to layout coordinates for the device.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
bool wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur,
 | 
					 | 
				
			||||||
		struct wlr_input_device *device, double x, double y,
 | 
					 | 
				
			||||||
		double *lx, double *ly);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -320,11 +320,9 @@ void roots_cursor_handle_touch_down(struct roots_cursor *cursor,
 | 
				
			||||||
		struct wlr_event_touch_down *event) {
 | 
							struct wlr_event_touch_down *event) {
 | 
				
			||||||
	struct roots_desktop *desktop = cursor->seat->input->server->desktop;
 | 
						struct roots_desktop *desktop = cursor->seat->input->server->desktop;
 | 
				
			||||||
	double lx, ly;
 | 
						double lx, ly;
 | 
				
			||||||
	bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor,
 | 
						wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device,
 | 
				
			||||||
			event->device, event->x, event->y, &lx, &ly);
 | 
							event->x, event->y, &lx, &ly);
 | 
				
			||||||
	if (!result) {
 | 
					
 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	double sx, sy;
 | 
						double sx, sy;
 | 
				
			||||||
	struct wlr_surface *surface = desktop_surface_at(
 | 
						struct wlr_surface *surface = desktop_surface_at(
 | 
				
			||||||
			desktop, lx, ly, &sx, &sy, NULL);
 | 
								desktop, lx, ly, &sx, &sy, NULL);
 | 
				
			||||||
| 
						 | 
					@ -371,11 +369,8 @@ void roots_cursor_handle_touch_motion(struct roots_cursor *cursor,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	double lx, ly;
 | 
						double lx, ly;
 | 
				
			||||||
	bool result = wlr_cursor_absolute_to_layout_coords(cursor->cursor,
 | 
						wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device,
 | 
				
			||||||
			event->device, event->x, event->y, &lx, &ly);
 | 
							event->x, event->y, &lx, &ly);
 | 
				
			||||||
	if (!result) {
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	double sx, sy;
 | 
						double sx, sy;
 | 
				
			||||||
	struct wlr_surface *surface = desktop_surface_at(
 | 
						struct wlr_surface *surface = desktop_surface_at(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
#include <limits.h>
 | 
					#include <limits.h>
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <wayland-server.h>
 | 
					#include <wayland-server.h>
 | 
				
			||||||
#include <wlr/types/wlr_cursor.h>
 | 
					#include <wlr/types/wlr_cursor.h>
 | 
				
			||||||
| 
						 | 
					@ -175,21 +176,20 @@ static struct wlr_cursor_device *get_cursor_device(struct wlr_cursor *cur,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void cursor_warp_unchecked(struct wlr_cursor *cur,
 | 
					static void cursor_warp_unchecked(struct wlr_cursor *cur,
 | 
				
			||||||
		double x, double y) {
 | 
							double lx, double ly) {
 | 
				
			||||||
	assert(cur->state->layout);
 | 
						assert(cur->state->layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_cursor_output_cursor *output_cursor;
 | 
						struct wlr_cursor_output_cursor *output_cursor;
 | 
				
			||||||
	wl_list_for_each(output_cursor, &cur->state->output_cursors, link) {
 | 
						wl_list_for_each(output_cursor, &cur->state->output_cursors, link) {
 | 
				
			||||||
		double output_x = x;
 | 
							double output_x = lx, output_y = ly;
 | 
				
			||||||
		double output_y = y;
 | 
					 | 
				
			||||||
		wlr_output_layout_output_coords(cur->state->layout,
 | 
							wlr_output_layout_output_coords(cur->state->layout,
 | 
				
			||||||
			output_cursor->output_cursor->output, &output_x, &output_y);
 | 
								output_cursor->output_cursor->output, &output_x, &output_y);
 | 
				
			||||||
		wlr_output_cursor_move(output_cursor->output_cursor, output_x,
 | 
							wlr_output_cursor_move(output_cursor->output_cursor,
 | 
				
			||||||
			output_y);
 | 
								output_x, output_y);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cur->x = x;
 | 
						cur->x = lx;
 | 
				
			||||||
	cur->y = y;
 | 
						cur->y = ly;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -233,28 +233,41 @@ static struct wlr_box *get_mapping(struct wlr_cursor *cur,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
 | 
					bool wlr_cursor_warp(struct wlr_cursor *cur, struct wlr_input_device *dev,
 | 
				
			||||||
		double x, double y) {
 | 
							double lx, double ly) {
 | 
				
			||||||
	assert(cur->state->layout);
 | 
						assert(cur->state->layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool result = false;
 | 
						bool result = false;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct wlr_box *mapping = get_mapping(cur, dev);
 | 
						struct wlr_box *mapping = get_mapping(cur, dev);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (mapping) {
 | 
						if (mapping) {
 | 
				
			||||||
		if (wlr_box_contains_point(mapping, x, y)) {
 | 
							result = wlr_box_contains_point(mapping, lx, ly);
 | 
				
			||||||
			cursor_warp_unchecked(cur, x, y);
 | 
						} else {
 | 
				
			||||||
			result = true;
 | 
							result = wlr_output_layout_contains_point(cur->state->layout, NULL,
 | 
				
			||||||
 | 
								lx, ly);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	} else if (wlr_output_layout_contains_point(cur->state->layout, NULL,
 | 
					
 | 
				
			||||||
				x, y)) {
 | 
						if (result) {
 | 
				
			||||||
		cursor_warp_unchecked(cur, x, y);
 | 
							cursor_warp_unchecked(cur, lx, ly);
 | 
				
			||||||
		result = true;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_cursor_warp_absolute(struct wlr_cursor *cur,
 | 
					static void cursor_warp_closest(struct wlr_cursor *cur,
 | 
				
			||||||
		struct wlr_input_device *dev, double x, double y) {
 | 
							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);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							wlr_output_layout_closest_point(cur->state->layout, NULL, lx, ly,
 | 
				
			||||||
 | 
								&lx, &ly);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cursor_warp_unchecked(cur, lx, ly);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur,
 | 
				
			||||||
 | 
							struct wlr_input_device *dev, double x, double y,
 | 
				
			||||||
 | 
							double *lx, double *ly) {
 | 
				
			||||||
	assert(cur->state->layout);
 | 
						assert(cur->state->layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_box *mapping = get_mapping(cur, dev);
 | 
						struct wlr_box *mapping = get_mapping(cur, dev);
 | 
				
			||||||
| 
						 | 
					@ -262,40 +275,28 @@ void wlr_cursor_warp_absolute(struct wlr_cursor *cur,
 | 
				
			||||||
		mapping = wlr_output_layout_get_box(cur->state->layout, NULL);
 | 
							mapping = wlr_output_layout_get_box(cur->state->layout, NULL);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	x = x >= 0 ? mapping->width * x + mapping->x : cur->x;
 | 
						*lx = !isnan(x) ? mapping->width * x + mapping->x : cur->x;
 | 
				
			||||||
	y = y >= 0 ? mapping->height * y + mapping->y : cur->y;
 | 
						*ly = !isnan(y) ? mapping->height * y + mapping->y : cur->y;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cursor_warp_unchecked(cur, x, y);
 | 
					void wlr_cursor_warp_absolute(struct wlr_cursor *cur,
 | 
				
			||||||
 | 
							struct wlr_input_device *dev, double x, double y) {
 | 
				
			||||||
 | 
						assert(cur->state->layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						double lx, ly;
 | 
				
			||||||
 | 
						wlr_cursor_absolute_to_layout_coords(cur, dev, x, y, &lx, &ly);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cursor_warp_closest(cur, dev, lx, ly);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
 | 
					void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
 | 
				
			||||||
		double delta_x, double delta_y) {
 | 
							double delta_x, double delta_y) {
 | 
				
			||||||
	assert(cur->state->layout);
 | 
						assert(cur->state->layout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	double x = cur->x + delta_x;
 | 
						double lx = !isnan(delta_x) ? cur->x + delta_x : cur->x;
 | 
				
			||||||
	double y = cur->y + delta_y;
 | 
						double ly = !isnan(delta_y) ? cur->y + delta_y : cur->y;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_box *mapping = get_mapping(cur, dev);
 | 
						cursor_warp_closest(cur, dev, lx, ly);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (mapping) {
 | 
					 | 
				
			||||||
		double closest_x, closest_y;
 | 
					 | 
				
			||||||
		if (!wlr_box_contains_point(mapping, x, y)) {
 | 
					 | 
				
			||||||
			wlr_box_closest_point(mapping, x, y, &closest_x,
 | 
					 | 
				
			||||||
				&closest_y);
 | 
					 | 
				
			||||||
			x = closest_x;
 | 
					 | 
				
			||||||
			y = closest_y;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		if (!wlr_output_layout_contains_point(cur->state->layout, NULL, x, y)) {
 | 
					 | 
				
			||||||
			double layout_x, layout_y;
 | 
					 | 
				
			||||||
			wlr_output_layout_closest_point(cur->state->layout, NULL, x, y,
 | 
					 | 
				
			||||||
				&layout_x, &layout_y);
 | 
					 | 
				
			||||||
			x = layout_x;
 | 
					 | 
				
			||||||
			y = layout_y;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cursor_warp_unchecked(cur, x, y);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels,
 | 
					void wlr_cursor_set_image(struct wlr_cursor *cur, const uint8_t *pixels,
 | 
				
			||||||
| 
						 | 
					@ -638,17 +639,3 @@ void wlr_cursor_map_input_to_region(struct wlr_cursor *cur,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c_device->mapped_box = box;
 | 
						c_device->mapped_box = box;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
bool wlr_cursor_absolute_to_layout_coords(struct wlr_cursor *cur,
 | 
					 | 
				
			||||||
		struct wlr_input_device *device, double x, double y,
 | 
					 | 
				
			||||||
		double *lx, double *ly) {
 | 
					 | 
				
			||||||
	struct wlr_box *mapping = get_mapping(cur, device);
 | 
					 | 
				
			||||||
	if (!mapping) {
 | 
					 | 
				
			||||||
		mapping = wlr_output_layout_get_box(cur->state->layout, NULL);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*lx = x > 0 ? mapping->width * x + mapping->x : cur->x;
 | 
					 | 
				
			||||||
	*ly = y > 0 ? mapping->height * y + mapping->y : cur->y;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue