mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	Fix resize bug
Based on tinywl's 21397e2b
This commit is contained in:
		
							parent
							
								
									dd32e712ae
								
							
						
					
					
						commit
						48e47fe8f9
					
				
					 4 changed files with 54 additions and 50 deletions
				
			
		| 
						 | 
				
			
			@ -4,7 +4,7 @@ Aiming to become a light-weight openbox alternative for Wayland
 | 
			
		|||
 | 
			
		||||
## Dependencies
 | 
			
		||||
 | 
			
		||||
- wlroots
 | 
			
		||||
- wlroots (>=0.10.0)
 | 
			
		||||
- wayland-protocols
 | 
			
		||||
 | 
			
		||||
## Background
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								labwc.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								labwc.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -66,7 +66,7 @@ struct server {
 | 
			
		|||
	enum cursor_mode cursor_mode;
 | 
			
		||||
	struct view *grabbed_view;
 | 
			
		||||
	double grab_x, grab_y;
 | 
			
		||||
	int grab_width, grab_height;
 | 
			
		||||
	struct wlr_box grab_box;
 | 
			
		||||
	uint32_t resize_edges;
 | 
			
		||||
 | 
			
		||||
	struct wlr_output_layout *output_layout;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										54
									
								
								server.c
									
										
									
									
									
								
							
							
						
						
									
										54
									
								
								server.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
	 * 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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										46
									
								
								view.c
									
										
									
									
									
								
							
							
						
						
									
										46
									
								
								view.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
	 * 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)
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
	 * 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))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue