Fix wrong resize anchor point

Previously, when dragging the left border of a window with the mouse, there
was a bug where it would snap the top level surface's geometry X coordinate
directly to the position of the mouse, as if you started the resize right on the border. This also affected the other (right, bottom, and top) borders.

I think that the previous resize code was hard to understand. Honestly I
have not spent a lot of time trying to understand why t didn't work and
I wrote another resize algorithm instead. Now instead of working directly
with widths and heights which are complicated we work with the borders (left,
right, top and bottom). This is easier to understand IMO.
This commit is contained in:
Greg Depoire--Ferrer 2020-04-26 16:17:09 +02:00
parent 114e265eef
commit 8265eda78a
3 changed files with 46 additions and 28 deletions

View file

@ -37,7 +37,7 @@ struct wb_server {
struct wb_view *grabbed_view;
double grab_x, grab_y;
int grab_width, grab_height;
struct wlr_box grab_geo_box;
uint32_t resize_edges;
struct wlr_xdg_shell *xdg_shell;

View file

@ -10,33 +10,44 @@ static void process_cursor_move(struct wb_server *server) {
static void process_cursor_resize(struct wb_server *server) {
struct wb_view *view = server->grabbed_view;
double dx = server->cursor->cursor->x - server->grab_x;
double dy = server->cursor->cursor->y - server->grab_y;
double x = view->x;
double y = view->y;
int width = server->grab_width;
int height = server->grab_height;
double border_x = server->cursor->cursor->x - server->grab_x;
double border_y = server->cursor->cursor->y - server->grab_y;
int new_left = server->grab_geo_box.x;
int new_right = server->grab_geo_box.x + server->grab_geo_box.width;
int new_top = server->grab_geo_box.y;
int new_bottom = server->grab_geo_box.y + server->grab_geo_box.height;
if (server->resize_edges & WLR_EDGE_TOP) {
y = server->grab_y + dy;
height -= dy;
if (height < 1) {
y += height;
new_top = border_y;
if (new_top >= new_bottom) {
new_top = new_bottom - 1;
}
} else if (server->resize_edges & WLR_EDGE_BOTTOM) {
height += dy;
new_bottom = border_y;
if (new_bottom <= new_top) {
new_bottom = new_top + 1;
}
}
if (server->resize_edges & WLR_EDGE_LEFT) {
x = server->grab_x + dx;
width -= dx;
if (width < 1) {
x += width;
new_left = border_x;
if (new_left >= new_right) {
new_left = new_right - 1;
}
} else if (server->resize_edges & WLR_EDGE_RIGHT) {
width += dx;
new_right = border_x;
if (new_right <= new_left) {
new_right = new_left + 1;
}
}
view->x = x;
view->y = y;
wlr_xdg_toplevel_set_size(view->xdg_surface, width, height);
struct wlr_box geo_box;
wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box);
view->x = new_left - geo_box.x;
view->y = new_top - geo_box.y;
int new_width = new_right - new_left;
int new_height = new_bottom - new_top;
wlr_xdg_toplevel_set_size(view->xdg_surface, new_width, new_height);
}
static void process_cursor_motion(struct wb_server *server, uint32_t time) {

View file

@ -84,18 +84,25 @@ static void begin_interactive(struct wb_view *view,
}
server->grabbed_view = view;
server->cursor->cursor_mode = mode;
struct wlr_box geo_box;
wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box);
if (mode == WB_CURSOR_MOVE) {
server->grab_x = server->cursor->cursor->x - view->x;
server->grab_y = server->cursor->cursor->y - view->y;
} else {
server->grab_x = server->cursor->cursor->x + geo_box.x;
server->grab_y = server->cursor->cursor->y + geo_box.y;
} else if (mode == WB_CURSOR_RESIZE) {
struct wlr_box geo_box;
wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box);
double border_x = (view->x + geo_box.x) + ((edges & WLR_EDGE_RIGHT) ? geo_box.width : 0);
double border_y = (view->y + geo_box.y) + ((edges & WLR_EDGE_BOTTOM) ? geo_box.height : 0);
server->grab_x = server->cursor->cursor->x - border_x;
server->grab_y = server->cursor->cursor->y - border_y;
server->grab_geo_box = geo_box;
server->grab_geo_box.x += view->x;
server->grab_geo_box.y += view->y;
server->resize_edges = edges;
}
server->grab_width = geo_box.width;
server->grab_height = geo_box.height;
server->resize_edges = edges;
}
static void xdg_toplevel_request_move(