From 8265eda78a83597a97a820d871e3abd756c10863 Mon Sep 17 00:00:00 2001 From: Greg Depoire--Ferrer Date: Sun, 26 Apr 2020 16:17:09 +0200 Subject: [PATCH] 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. --- include/waybox/server.h | 2 +- waybox/cursor.c | 49 +++++++++++++++++++++++++---------------- waybox/xdg_shell.c | 23 ++++++++++++------- 3 files changed, 46 insertions(+), 28 deletions(-) diff --git a/include/waybox/server.h b/include/waybox/server.h index ecad2a6..62293e2 100644 --- a/include/waybox/server.h +++ b/include/waybox/server.h @@ -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; diff --git a/waybox/cursor.c b/waybox/cursor.c index 1b12949..2ccc41a 100644 --- a/waybox/cursor.c +++ b/waybox/cursor.c @@ -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) { diff --git a/waybox/xdg_shell.c b/waybox/xdg_shell.c index c8e4c2b..5f8304d 100644 --- a/waybox/xdg_shell.c +++ b/waybox/xdg_shell.c @@ -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(