aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Depoire--Ferrer <greg.depoire@gmail.com>2020-04-26 17:45:45 +0200
committerDrew DeVault <sir@cmpwn.com>2020-04-28 21:44:27 +0200
commit21397e2b4a86443dde31ba36cf4f6b7fbb1b662c (patch)
treefda1650fe62adf8e896967d6a781b433e7e5b31d
parent321537ee92e2a9eeb115434181c12b4ccf8f9ef9 (diff)
tinywl: Fix wrong anchor point while resizing a window
Previously, when dragging the left border of a window with the mouse in tinywl, there was a bug where it 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, top and bottom) 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 it 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, bottom). This is easier to understand IMO. Note: I originally fixed this [in the waybox compositor](https://github.com/wizbright/waybox/pull/23) but then I realized that the code was taken from tinywl and that it had the same issues so I copied my fix for tinywl.
-rw-r--r--tinywl/tinywl.c72
1 files changed, 45 insertions, 27 deletions
diff --git a/tinywl/tinywl.c b/tinywl/tinywl.c
index 70e13233..84a7636b 100644
--- a/tinywl/tinywl.c
+++ b/tinywl/tinywl.c
@@ -55,8 +55,7 @@ struct tinywl_server {
enum tinywl_cursor_mode cursor_mode;
struct tinywl_view *grabbed_view;
double grab_x, grab_y;
- struct wlr_box grab_geo_box;
- int grab_width, grab_height;
+ struct wlr_box grab_geobox;
uint32_t resize_edges;
struct wlr_output_layout *output_layout;
@@ -370,33 +369,44 @@ static void process_cursor_resize(struct tinywl_server *server, uint32_t time) {
* commit any movement that was prepared.
*/
struct tinywl_view *view = server->grabbed_view;
- double dx = server->cursor->x - server->grab_x;
- double dy = server->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->x - server->grab_x;
+ double border_y = server->cursor->y - server->grab_y;
+ int new_left = server->grab_geobox.x;
+ int new_right = server->grab_geobox.x + server->grab_geobox.width;
+ int new_top = server->grab_geobox.y;
+ int new_bottom = server->grab_geobox.y + server->grab_geobox.height;
+
if (server->resize_edges & WLR_EDGE_TOP) {
- y = server->grab_y + dy - server->grab_geo_box.y;
- height -= dy + server->grab_geo_box.y;
- 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 + server->grab_geo_box.y;
+ 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 - server->grab_geo_box.x;
- width -= dx + server->grab_geo_box.x;
- 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 + server->grab_geo_box.x;
+ 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 tinywl_server *server, uint32_t time) {
@@ -725,17 +735,25 @@ static void begin_interactive(struct tinywl_view *view,
}
server->grabbed_view = view;
server->cursor_mode = mode;
- wlr_xdg_surface_get_geometry(view->xdg_surface, &server->grab_geo_box);
+
if (mode == TINYWL_CURSOR_MOVE) {
server->grab_x = server->cursor->x - view->x;
server->grab_y = server->cursor->y - view->y;
} else {
- server->grab_x = server->cursor->x + server->grab_geo_box.x;
- server->grab_y = server->cursor->y + server->grab_geo_box.y;
+ 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->x - border_x;
+ server->grab_y = server->cursor->y - border_y;
+
+ server->grab_geobox = geo_box;
+ server->grab_geobox.x += view->x;
+ server->grab_geobox.y += view->y;
+
+ server->resize_edges = edges;
}
- server->grab_width = server->grab_geo_box.width;
- server->grab_height = server->grab_geo_box.height;
- server->resize_edges = edges;
}
static void xdg_toplevel_request_move(