* 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).
*
- * Note that I took some shortcuts here. In a more fleshed-out
- * compositor, you'd wait for the client to prepare a buffer at the new
- * size, then commit any movement that was prepared.
+ * TODO: Wait for the client to prepare a buffer at the new size, then
+ * commit any movement that was prepared.
*/
struct 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_box.x;
+ int new_right = server->grab_box.x + server->grab_box.width;
+ int new_top = server->grab_box.y;
+ int new_bottom = server->grab_box.y + server->grab_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 server *server, uint32_t time)
* the compositor stops propegating pointer events to clients and
* instead consumes them itself, to move or resize windows. */
struct server *server = view->server;
- struct wlr_surface *focused_surface =
- server->seat->pointer_state.focused_surface;
server->grabbed_view = view;
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) {
server->grab_x = server->cursor->x - view->x;
server->grab_y = server->cursor->y - view->y;
} 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)
* the cursor. It relies on server->views being ordered from
* top-to-bottom.
*/
- struct wlr_box border_box = {
- .x = 0, .y = 0,
- .width = 0, .height = 0,
- };
struct view *view;
wl_list_for_each (view, &server->views, link) {
if (view_at(view, lx, ly, surface, sx, sy))