Fix resize bug

Based on tinywl's 21397e2b
This commit is contained in:
Johan Malm 2020-05-12 20:37:05 +01:00
parent dd32e712ae
commit 48e47fe8f9
4 changed files with 54 additions and 50 deletions

View file

@ -4,7 +4,7 @@ Aiming to become a light-weight openbox alternative for Wayland
## Dependencies ## Dependencies
- wlroots - wlroots (>=0.10.0)
- wayland-protocols - wayland-protocols
## Background ## Background

View file

@ -66,7 +66,7 @@ struct server {
enum cursor_mode cursor_mode; enum cursor_mode cursor_mode;
struct view *grabbed_view; struct view *grabbed_view;
double grab_x, grab_y; double grab_x, grab_y;
int grab_width, grab_height; struct wlr_box grab_box;
uint32_t resize_edges; uint32_t resize_edges;
struct wlr_output_layout *output_layout; struct wlr_output_layout *output_layout;

View file

@ -202,38 +202,44 @@ static void process_cursor_resize(struct server *server, uint32_t time)
* view on one or two axes, but can also move the view if you resize * view on one or two axes, but can also move the view if you resize
* from the top or left edges (or top-left corner). * from the top or left edges (or top-left corner).
* *
* Note that I took some shortcuts here. In a more fleshed-out * TODO: Wait for the client to prepare a buffer at the new size, then
* compositor, you'd wait for the client to prepare a buffer at the new * commit any movement that was prepared.
* size, then commit any movement that was prepared.
*/ */
struct view *view = server->grabbed_view; struct view *view = server->grabbed_view;
double dx = server->cursor->x - server->grab_x; double border_x = server->cursor->x - server->grab_x;
double dy = server->cursor->y - server->grab_y; double border_y = server->cursor->y - server->grab_y;
double x = view->x; int new_left = server->grab_box.x;
double y = view->y; int new_right = server->grab_box.x + server->grab_box.width;
int width = server->grab_width; int new_top = server->grab_box.y;
int height = server->grab_height; int new_bottom = server->grab_box.y + server->grab_box.height;
if (server->resize_edges & WLR_EDGE_TOP) { if (server->resize_edges & WLR_EDGE_TOP) {
y = server->grab_y + dy; new_top = border_y;
height -= dy; if (new_top >= new_bottom)
if (height < 1) { new_top = new_bottom - 1;
y += height;
}
} else if (server->resize_edges & WLR_EDGE_BOTTOM) { } 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) { if (server->resize_edges & WLR_EDGE_LEFT) {
x = server->grab_x + dx; new_left = border_x;
width -= dx; if (new_left >= new_right)
if (width < 1) { new_left = new_right - 1;
x += width;
}
} else if (server->resize_edges & WLR_EDGE_RIGHT) { } 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; struct wlr_box geo_box;
wlr_xdg_toplevel_set_size(view->xdg_surface, width, height); 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 server *server, uint32_t time) static void process_cursor_motion(struct server *server, uint32_t time)

46
view.c
View file

@ -141,34 +141,36 @@ void begin_interactive(struct view *view, enum cursor_mode mode, uint32_t edges)
* the compositor stops propegating pointer events to clients and * the compositor stops propegating pointer events to clients and
* instead consumes them itself, to move or resize windows. */ * instead consumes them itself, to move or resize windows. */
struct server *server = view->server; struct server *server = view->server;
struct wlr_surface *focused_surface =
server->seat->pointer_state.focused_surface;
server->grabbed_view = view; server->grabbed_view = view;
server->cursor_mode = mode; server->cursor_mode = mode;
struct wlr_box geo_box;
switch (view->type) {
case LAB_XDG_SHELL_VIEW:
wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box);
break;
case LAB_XWAYLAND_VIEW:
geo_box.x = view->xwayland_surface->x;
geo_box.y = view->xwayland_surface->y;
geo_box.width = view->xwayland_surface->width;
geo_box.height = view->xwayland_surface->height;
break;
}
if (mode == TINYWL_CURSOR_MOVE) { if (mode == TINYWL_CURSOR_MOVE) {
server->grab_x = server->cursor->x - view->x; server->grab_x = server->cursor->x - view->x;
server->grab_y = server->cursor->y - view->y; server->grab_y = server->cursor->y - view->y;
} else { } else {
server->grab_x = server->cursor->x + geo_box.x;
server->grab_y = server->cursor->y + geo_box.y; struct wlr_box geo_box;
switch (view->type) {
case LAB_XDG_SHELL_VIEW:
wlr_xdg_surface_get_geometry(view->xdg_surface, &geo_box);
break;
case LAB_XWAYLAND_VIEW:
geo_box.x = view->xwayland_surface->x;
geo_box.y = view->xwayland_surface->y;
geo_box.width = view->xwayland_surface->width;
geo_box.height = view->xwayland_surface->height;
break;
}
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_box = geo_box;
server->grab_box.x += view->x;
server->grab_box.y += view->y;
server->resize_edges = edges;
} }
server->grab_width = geo_box.width;
server->grab_height = geo_box.height;
server->resize_edges = edges;
} }
bool is_toplevel(struct view *view) bool is_toplevel(struct view *view)
@ -246,10 +248,6 @@ struct view *desktop_view_at(struct server *server, double lx, double ly,
* the cursor. It relies on server->views being ordered from * the cursor. It relies on server->views being ordered from
* top-to-bottom. * top-to-bottom.
*/ */
struct wlr_box border_box = {
.x = 0, .y = 0,
.width = 0, .height = 0,
};
struct view *view; struct view *view;
wl_list_for_each (view, &server->views, link) { wl_list_for_each (view, &server->views, link) {
if (view_at(view, lx, ly, surface, sx, sy)) if (view_at(view, lx, ly, surface, sx, sy))