diff --git a/include/wlr/types/wlr_output_layout.h b/include/wlr/types/wlr_output_layout.h index 9094f02f..144c2d5a 100644 --- a/include/wlr/types/wlr_output_layout.h +++ b/include/wlr/types/wlr_output_layout.h @@ -47,9 +47,12 @@ bool wlr_output_layout_intersects(struct wlr_output_layout *layout, struct wlr_output *reference, int x1, int y1, int x2, int y2); /** - * Get the closest boundary point of this layout from the given point. + * Get the closest boundary point of this layout from the given point from the + * reference output. If reference is NULL, gets the closest boundary point from + * the entire layout. */ void wlr_output_layout_closest_boundary(struct wlr_output_layout *layout, - int x, int y, int *dest_x, int *dest_y); + struct wlr_output *reference, double x, double y, double *dest_x, + double *dest_y); #endif diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index c9937c73..affdcdeb 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -22,6 +22,7 @@ struct wlr_cursor_state { struct wl_list devices; struct wlr_output_layout *layout; struct wlr_xcursor *xcursor; + struct wlr_output *mapped_output; }; struct wlr_cursor *wlr_cursor_init() { @@ -37,6 +38,8 @@ struct wlr_cursor *wlr_cursor_init() { return NULL; } + cur->state->mapped_output = NULL; + wl_list_init(&cur->state->devices); wl_signal_init(&cur->events.motion); @@ -66,7 +69,16 @@ void wlr_cursor_set_xcursor(struct wlr_cursor *cur, struct wlr_xcursor *xcur) { bool wlr_cursor_warp(struct wlr_cursor *cur, double x, double y) { assert(cur->state->layout); - if (!wlr_output_layout_output_at(cur->state->layout, x, y)) { + struct wlr_output *output; + output = wlr_output_layout_output_at(cur->state->layout, x, y); + + if (!output) { + return false; + } + + if (cur->state->mapped_output && + !wlr_output_layout_contains_point(cur->state->layout, + cur->state->mapped_output, x, y)) { return false; } @@ -97,13 +109,16 @@ bool wlr_cursor_warp(struct wlr_cursor *cur, double x, double y) { void wlr_cursor_move(struct wlr_cursor *cur, double delta_x, double delta_y) { assert(cur->state->layout); - int x = cur->x + delta_x; - int y = cur->y + delta_y; + double x = cur->x + delta_x; + double y = cur->y + delta_y; - if (!wlr_output_layout_output_at(cur->state->layout, x, y)) { - int closest_x, closest_y; - wlr_output_layout_closest_boundary(cur->state->layout, x, y, &closest_x, - &closest_y); + struct wlr_output *output; + output = wlr_output_layout_output_at(cur->state->layout, x, y); + + if (!output || (cur->state->mapped_output && cur->state->mapped_output != output)) { + double closest_x, closest_y; + wlr_output_layout_closest_boundary(cur->state->layout, + cur->state->mapped_output, x, y, &closest_x, &closest_y); x = closest_x; y = closest_y; } @@ -210,7 +225,7 @@ void wlr_cursor_attach_output_layout(struct wlr_cursor *cur, void wlr_cursor_map_to_output(struct wlr_cursor *cur, struct wlr_output *output) { - wlr_log(L_DEBUG, "TODO: map to output"); + cur->state->mapped_output = output; } void wlr_cursor_map_input_to_output(struct wlr_cursor *cur, diff --git a/types/wlr_output_layout.c b/types/wlr_output_layout.c index a26a4794..5e2067da 100644 --- a/types/wlr_output_layout.c +++ b/types/wlr_output_layout.c @@ -135,11 +135,17 @@ static double get_distance(double x1, double y1, double x2, double y2) { } void wlr_output_layout_closest_boundary(struct wlr_output_layout *layout, - int x, int y, int *dest_x, int *dest_y) { - int min_x = INT_MAX, min_y = INT_MAX, min_distance = INT_MAX; + struct wlr_output *reference, double x, double y, double *dest_x, + double *dest_y) { + double min_x = INT_MAX, min_y = INT_MAX, min_distance = INT_MAX; struct wlr_output_layout_output *l_output; wl_list_for_each(l_output, &layout->outputs, link) { - int width, height, output_x, output_y, output_distance; + if (reference != NULL && reference != l_output->output) { + continue; + } + + int width, height; + double output_x, output_y, output_distance; wlr_output_effective_resolution(l_output->output, &width, &height); // find the closest x point