mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-12-24 02:49:48 +01:00
intersect cursor and device regions
This commit is contained in:
parent
dc7e32552d
commit
ac503a47a7
3 changed files with 82 additions and 11 deletions
|
@ -1,5 +1,6 @@
|
||||||
#ifndef _WLR_TYPES_GEOMETRY_H
|
#ifndef _WLR_TYPES_GEOMETRY_H
|
||||||
#define _WLR_TYPES_GEOMETRY_H
|
#define _WLR_TYPES_GEOMETRY_H
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
struct wlr_geometry {
|
struct wlr_geometry {
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -9,4 +10,9 @@ struct wlr_geometry {
|
||||||
void wlr_geometry_closest_boundary(struct wlr_geometry *geo, double x, double y,
|
void wlr_geometry_closest_boundary(struct wlr_geometry *geo, double x, double y,
|
||||||
int *dest_x, int *dest_y, double *distance);
|
int *dest_x, int *dest_y, double *distance);
|
||||||
|
|
||||||
|
bool wlr_geometry_intersection(struct wlr_geometry *geo_a,
|
||||||
|
struct wlr_geometry *geo_b, struct wlr_geometry **dest);
|
||||||
|
|
||||||
|
bool wlr_geometry_contains_point(struct wlr_geometry *geo, int x, int y);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -147,19 +147,20 @@ void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
|
||||||
double x = cur->x + delta_x;
|
double x = cur->x + delta_x;
|
||||||
double y = cur->y + delta_y;
|
double y = cur->y + delta_y;
|
||||||
|
|
||||||
// cursor geometry constraints
|
// geometry constraints
|
||||||
if (cur->state->mapped_geometry) {
|
struct wlr_geometry *constraints = NULL;
|
||||||
int closest_x, closest_y;
|
if (cur->state->mapped_geometry != NULL ||
|
||||||
wlr_geometry_closest_boundary(cur->state->mapped_geometry, x, y,
|
c_device->mapped_geometry != NULL) {
|
||||||
&closest_x, &closest_y, NULL);
|
constraints = calloc(1, sizeof(struct wlr_geometry));
|
||||||
x = closest_x;
|
|
||||||
y = closest_y;
|
if (!wlr_geometry_intersection(cur->state->mapped_geometry,
|
||||||
|
c_device->mapped_geometry, &constraints)) {
|
||||||
|
// TODO handle no possible movement
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// device constraints
|
|
||||||
if (c_device->mapped_geometry) {
|
|
||||||
int closest_x, closest_y;
|
int closest_x, closest_y;
|
||||||
wlr_geometry_closest_boundary(c_device->mapped_geometry, x, y,
|
wlr_geometry_closest_boundary(constraints, x, y,
|
||||||
&closest_x, &closest_y, NULL);
|
&closest_x, &closest_y, NULL);
|
||||||
x = closest_x;
|
x = closest_x;
|
||||||
y = closest_y;
|
y = closest_y;
|
||||||
|
@ -177,10 +178,20 @@ void wlr_cursor_move(struct wlr_cursor *cur, struct wlr_input_device *dev,
|
||||||
y = closest_y;
|
y = closest_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (constraints && !wlr_geometry_contains_point(constraints, x, y)) {
|
||||||
|
// TODO handle no possible movement
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (wlr_cursor_warp(cur, dev, x, y)) {
|
if (wlr_cursor_warp(cur, dev, x, y)) {
|
||||||
cur->x = x;
|
cur->x = x;
|
||||||
cur->y = y;
|
cur->y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (constraints) {
|
||||||
|
free(constraints);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_pointer_motion(struct wl_listener *listener, void *data) {
|
static void handle_pointer_motion(struct wl_listener *listener, void *data) {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <wlr/types/wlr_geometry.h>
|
#include <wlr/types/wlr_geometry.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
|
||||||
static double get_distance(double x1, double y1, double x2, double y2) {
|
static double get_distance(double x1, double y1, double x2, double y2) {
|
||||||
double distance;
|
double distance;
|
||||||
|
@ -34,3 +36,55 @@ void wlr_geometry_closest_boundary(struct wlr_geometry *geo, double x, double y,
|
||||||
*distance = get_distance(*dest_x, *dest_y, x, y);
|
*distance = get_distance(*dest_x, *dest_y, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef max
|
||||||
|
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool wlr_geometry_empty(struct wlr_geometry *geo) {
|
||||||
|
return geo == NULL || geo->width < 0 || geo->height < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wlr_geometry_intersection(struct wlr_geometry *geo_a,
|
||||||
|
struct wlr_geometry *geo_b, struct wlr_geometry **geo_dest) {
|
||||||
|
struct wlr_geometry *dest = *geo_dest;
|
||||||
|
bool a_empty = wlr_geometry_empty(geo_a);
|
||||||
|
bool b_empty = wlr_geometry_empty(geo_b);
|
||||||
|
|
||||||
|
if (a_empty && b_empty) {
|
||||||
|
return false;
|
||||||
|
} else if (a_empty) {
|
||||||
|
dest->x = geo_b->x;
|
||||||
|
dest->y = geo_b->y;
|
||||||
|
dest->height = geo_b->height;
|
||||||
|
dest->width = geo_b->width;
|
||||||
|
return true;
|
||||||
|
} else if (b_empty) {
|
||||||
|
dest->x = geo_a->x;
|
||||||
|
dest->y = geo_a->y;
|
||||||
|
dest->height = geo_a->height;
|
||||||
|
dest->width = geo_a->width;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x1 = max(geo_a->x, geo_b->x);
|
||||||
|
int y1 = max(geo_a->y, geo_b->y);
|
||||||
|
int x2 = min(geo_a->x + geo_a->width, geo_b->x + geo_b->width);
|
||||||
|
int y2 = min(geo_a->y + geo_a->height, geo_b->y + geo_b->height);
|
||||||
|
|
||||||
|
dest->x = x1;
|
||||||
|
dest->y = y1;
|
||||||
|
dest->width = x2 - x1;
|
||||||
|
dest->height = y2 - y1;
|
||||||
|
|
||||||
|
return !wlr_geometry_empty(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wlr_geometry_contains_point(struct wlr_geometry *geo, int x, int y) {
|
||||||
|
return x >= geo->x && x <= geo->x + geo->width &&
|
||||||
|
y >= geo->y && y <= geo->y + geo->height;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue