Merge branch 'master' into feature/subcompositor
This commit is contained in:
		
						commit
						8f41c497a7
					
				|  | @ -53,6 +53,13 @@ enum roots_cursor_mode { | |||
| 	ROOTS_CURSOR_ROTATE = 3, | ||||
| }; | ||||
| 
 | ||||
| enum roots_cursor_resize_edge { | ||||
| 	ROOTS_CURSOR_RESIZE_EDGE_TOP = 1, | ||||
| 	ROOTS_CURSOR_RESIZE_EDGE_BOTTOM = 2, | ||||
| 	ROOTS_CURSOR_RESIZE_EDGE_LEFT = 4, | ||||
| 	ROOTS_CURSOR_RESIZE_EDGE_RIGHT = 8, | ||||
| }; | ||||
| 
 | ||||
| struct roots_input_event { | ||||
| 	uint32_t serial; | ||||
| 	struct wlr_cursor *cursor; | ||||
|  | @ -71,6 +78,8 @@ struct roots_input { | |||
| 	enum roots_cursor_mode mode; | ||||
| 	struct roots_view *active_view; | ||||
| 	int offs_x, offs_y; | ||||
| 	int view_x, view_y, view_width, view_height; | ||||
| 	uint32_t resize_edges; | ||||
| 
 | ||||
| 	// Ring buffer of input events that could trigger move/resize/rotate
 | ||||
| 	int input_events_idx; | ||||
|  | @ -110,5 +119,7 @@ const struct roots_input_event *get_input_event(struct roots_input *input, | |||
| 		uint32_t serial); | ||||
| void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, | ||||
| 		struct roots_view *view); | ||||
| void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, | ||||
| 		struct roots_view *view, uint32_t edges); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -61,11 +61,15 @@ struct roots_view { | |||
| 	// configure event from the xdg_shell
 | ||||
| 	// If not then this should follow the typical type/impl pattern we use
 | ||||
| 	// elsewhere
 | ||||
| 	void (*get_size)(struct roots_view *view, struct wlr_box *box); | ||||
| 	void (*get_input_bounds)(struct roots_view *view, struct wlr_box *box); | ||||
| 	void (*activate)(struct roots_view *view, bool active); | ||||
| 	void (*resize)(struct roots_view *view, uint32_t width, uint32_t height); | ||||
| }; | ||||
| 
 | ||||
| void view_get_size(struct roots_view *view, struct wlr_box *box); | ||||
| void view_get_input_bounds(struct roots_view *view, struct wlr_box *box); | ||||
| void view_activate(struct roots_view *view, bool active); | ||||
| void view_resize(struct roots_view *view, uint32_t width, uint32_t height); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -81,7 +81,8 @@ struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display, | |||
| void wlr_xwayland_surface_activate(struct wlr_xwayland *wlr_xwayland, | ||||
| 	struct wlr_xwayland_surface *surface); | ||||
| void wlr_xwayland_surface_configure(struct wlr_xwayland *wlr_xwayland, | ||||
| 	struct wlr_xwayland_surface *surface); | ||||
| 	struct wlr_xwayland_surface *surface, int16_t x, int16_t y, | ||||
| 	uint16_t width, uint16_t height); | ||||
| void wlr_xwayland_surface_close(struct wlr_xwayland *wlr_xwayland, | ||||
| 	struct wlr_xwayland_surface *surface); | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,6 +29,22 @@ void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, | |||
| 	wlr_seat_pointer_clear_focus(input->wl_seat); | ||||
| } | ||||
| 
 | ||||
| void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, | ||||
| 		struct roots_view *view, uint32_t edges) { | ||||
| 	input->mode = ROOTS_CURSOR_RESIZE; | ||||
| 	wlr_log(L_DEBUG, "begin resize"); | ||||
| 	input->offs_x = cursor->x; | ||||
| 	input->offs_y = cursor->y; | ||||
| 	input->view_x = view->x; | ||||
| 	input->view_y = view->y; | ||||
| 	struct wlr_box size; | ||||
| 	view_get_size(view, &size); | ||||
| 	input->view_width = size.width; | ||||
| 	input->view_height = size.height; | ||||
| 	input->resize_edges = edges; | ||||
| 	wlr_seat_pointer_clear_focus(input->wl_seat); | ||||
| } | ||||
| 
 | ||||
| void cursor_update_position(struct roots_input *input, uint32_t time) { | ||||
| 	struct roots_desktop *desktop = input->server->desktop; | ||||
| 	struct roots_view *view; | ||||
|  | @ -52,6 +68,27 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { | |||
| 		} | ||||
| 		break; | ||||
| 	case ROOTS_CURSOR_RESIZE: | ||||
| 		if (input->active_view) { | ||||
| 			int dx = input->cursor->x - input->offs_x; | ||||
| 			int dy = input->cursor->y - input->offs_y; | ||||
| 			int width = input->view_width; | ||||
| 			int height = input->view_height; | ||||
| 			if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { | ||||
| 				input->active_view->y = input->view_y + dy; | ||||
| 				height -= dy; | ||||
| 			} | ||||
| 			if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_BOTTOM) { | ||||
| 				height += dy; | ||||
| 			} | ||||
| 			if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_LEFT) { | ||||
| 				input->active_view->x = input->view_x + dx; | ||||
| 				width -= dx; | ||||
| 			} | ||||
| 			if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_RIGHT) { | ||||
| 				width += dx; | ||||
| 			} | ||||
| 			view_resize(input->active_view, width, height); | ||||
| 		} | ||||
| 		break; | ||||
| 	case ROOTS_CURSOR_ROTATE: | ||||
| 		break; | ||||
|  |  | |||
|  | @ -25,6 +25,16 @@ void view_destroy(struct roots_view *view) { | |||
| 	free(view); | ||||
| } | ||||
| 
 | ||||
| void view_get_size(struct roots_view *view, struct wlr_box *box) { | ||||
| 	if (view->get_size) { | ||||
| 		view->get_size(view, box); | ||||
| 		return; | ||||
| 	} | ||||
| 	box->x = box->y = 0; | ||||
| 	box->width = view->wlr_surface->current->width; | ||||
| 	box->height = view->wlr_surface->current->height; | ||||
| } | ||||
| 
 | ||||
| void view_get_input_bounds(struct roots_view *view, struct wlr_box *box) { | ||||
| 	if (view->get_input_bounds) { | ||||
| 		view->get_input_bounds(view, box); | ||||
|  | @ -41,6 +51,12 @@ void view_activate(struct roots_view *view, bool activate) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| void view_resize(struct roots_view *view, uint32_t width, uint32_t height) { | ||||
| 	if (view->resize) { | ||||
| 		view->resize(view, width, height); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static struct wlr_subsurface *subsurface_at(struct wlr_surface *surface, | ||||
| 		double sx, double sy, double *sub_x, double *sub_y) { | ||||
| 	struct wlr_subsurface *subsurface; | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ | |||
| #include "rootston/server.h" | ||||
| #include "rootston/input.h" | ||||
| 
 | ||||
| static void handle_move(struct wl_listener *listener, void *data) { | ||||
| static void handle_request_move(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_wl_shell_surface *roots_surface = | ||||
| 		wl_container_of(listener, roots_surface, request_move); | ||||
| 	struct roots_view *view = roots_surface->view; | ||||
|  | @ -53,7 +53,7 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) { | |||
| 	wl_signal_add(&surface->events.destroy, &roots_surface->destroy); | ||||
| 	wl_list_init(&roots_surface->ping_timeout.link); | ||||
| 	wl_list_init(&roots_surface->request_move.link); | ||||
| 	roots_surface->request_move.notify = handle_move; | ||||
| 	roots_surface->request_move.notify = handle_request_move; | ||||
| 	wl_signal_add(&surface->events.request_move, &roots_surface->request_move); | ||||
| 	wl_list_init(&roots_surface->request_resize.link); | ||||
| 	wl_list_init(&roots_surface->request_set_fullscreen.link); | ||||
|  |  | |||
|  | @ -10,9 +10,10 @@ | |||
| #include "rootston/server.h" | ||||
| #include "rootston/input.h" | ||||
| 
 | ||||
| static void get_input_bounds(struct roots_view *view, struct wlr_box *box) { | ||||
| static void get_size(struct roots_view *view, struct wlr_box *box) { | ||||
| 	assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); | ||||
| 	struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; | ||||
| 	// TODO: surf->geometry can be NULL
 | ||||
| 	memcpy(box, surf->geometry, sizeof(struct wlr_box)); | ||||
| } | ||||
| 
 | ||||
|  | @ -24,6 +25,14 @@ static void activate(struct roots_view *view, bool active) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void resize(struct roots_view *view, uint32_t width, uint32_t height) { | ||||
| 	assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); | ||||
| 	struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; | ||||
| 	if (surf->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { | ||||
| 		wlr_xdg_toplevel_v6_set_size(surf, width, height); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void handle_request_move(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_xdg_surface_v6 *roots_xdg_surface = | ||||
| 		wl_container_of(listener, roots_xdg_surface, request_move); | ||||
|  | @ -37,6 +46,19 @@ static void handle_request_move(struct wl_listener *listener, void *data) { | |||
| 	view_begin_move(input, event->cursor, view); | ||||
| } | ||||
| 
 | ||||
| static void handle_request_resize(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_xdg_surface_v6 *roots_xdg_surface = | ||||
| 		wl_container_of(listener, roots_xdg_surface, request_resize); | ||||
| 	struct roots_view *view = roots_xdg_surface->view; | ||||
| 	struct roots_input *input = view->desktop->server->input; | ||||
| 	struct wlr_xdg_toplevel_v6_resize_event *e = data; | ||||
| 	const struct roots_input_event *event = get_input_event(input, e->serial); | ||||
| 	if (!event || input->mode != ROOTS_CURSOR_PASSTHROUGH) { | ||||
| 		return; | ||||
| 	} | ||||
| 	view_begin_resize(input, event->cursor, view, e->edges); | ||||
| } | ||||
| 
 | ||||
| static void handle_destroy(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_xdg_surface_v6 *roots_xdg_surface = | ||||
| 		wl_container_of(listener, roots_xdg_surface, destroy); | ||||
|  | @ -71,6 +93,9 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | |||
| 	roots_surface->request_move.notify = handle_request_move; | ||||
| 	wl_signal_add(&surface->events.request_move, &roots_surface->request_move); | ||||
| 	wl_list_init(&roots_surface->request_resize.link); | ||||
| 	roots_surface->request_resize.notify = handle_request_resize; | ||||
| 	wl_signal_add(&surface->events.request_resize, | ||||
| 		&roots_surface->request_resize); | ||||
| 	wl_list_init(&roots_surface->request_show_window_menu.link); | ||||
| 
 | ||||
| 	struct roots_view *view = calloc(1, sizeof(struct roots_view)); | ||||
|  | @ -79,8 +104,9 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | |||
| 	view->xdg_surface_v6 = surface; | ||||
| 	view->roots_xdg_surface_v6 = roots_surface; | ||||
| 	view->wlr_surface = surface->surface; | ||||
| 	view->get_input_bounds = get_input_bounds; | ||||
| 	view->get_size = get_size; | ||||
| 	view->activate = activate; | ||||
| 	view->resize = resize; | ||||
| 	view->desktop = desktop; | ||||
| 	roots_surface->view = view; | ||||
| 	list_add(desktop->views, view); | ||||
|  |  | |||
|  | @ -9,6 +9,13 @@ | |||
| #include "rootston/desktop.h" | ||||
| #include "rootston/server.h" | ||||
| 
 | ||||
| static void resize(struct roots_view *view, uint32_t width, uint32_t height) { | ||||
| 	assert(view->type == ROOTS_XWAYLAND_VIEW); | ||||
| 	struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; | ||||
| 	wlr_xwayland_surface_configure(view->desktop->xwayland, xwayland_surface, | ||||
| 		xwayland_surface->x, xwayland_surface->y, width, height); | ||||
| } | ||||
| 
 | ||||
| static void handle_destroy(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_xwayland_surface *roots_surface = | ||||
| 		wl_container_of(listener, roots_surface, destroy); | ||||
|  | @ -17,23 +24,18 @@ static void handle_destroy(struct wl_listener *listener, void *data) { | |||
| 	free(roots_surface); | ||||
| } | ||||
| 
 | ||||
| static void handle_configure(struct wl_listener *listener, void *data) { | ||||
| static void handle_request_configure(struct wl_listener *listener, void *data) { | ||||
| 	struct roots_xwayland_surface *roots_surface = | ||||
| 		wl_container_of(listener, roots_surface, request_configure); | ||||
| 	struct wlr_xwayland_surface *xwayland_surface = | ||||
| 		roots_surface->view->xwayland_surface; | ||||
| 	struct wlr_xwayland_surface_configure_event *event = data; | ||||
| 
 | ||||
| 	xwayland_surface->x = event->x; | ||||
| 	xwayland_surface->y = event->y; | ||||
| 	xwayland_surface->width = event->width; | ||||
| 	xwayland_surface->height = event->height; | ||||
| 
 | ||||
| 	roots_surface->view->x = (double)event->x; | ||||
| 	roots_surface->view->y = (double)event->y; | ||||
| 
 | ||||
| 	wlr_xwayland_surface_configure(roots_surface->view->desktop->xwayland, | ||||
| 		xwayland_surface); | ||||
| 		xwayland_surface, event->x, event->y, event->width, event->height); | ||||
| } | ||||
| 
 | ||||
| static void activate(struct roots_view *view, bool active) { | ||||
|  | @ -58,7 +60,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
| 	roots_surface->destroy.notify = handle_destroy; | ||||
| 	wl_signal_add(&surface->events.destroy, &roots_surface->destroy); | ||||
| 	wl_list_init(&roots_surface->request_configure.link); | ||||
| 	roots_surface->request_configure.notify = handle_configure; | ||||
| 	roots_surface->request_configure.notify = handle_request_configure; | ||||
| 	wl_signal_add(&surface->events.request_configure, | ||||
| 		&roots_surface->request_configure); | ||||
| 
 | ||||
|  | @ -75,6 +77,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { | |||
| 	view->wlr_surface = surface->surface; | ||||
| 	view->desktop = desktop; | ||||
| 	view->activate = activate; | ||||
| 	view->resize = resize; | ||||
| 	roots_surface->view = view; | ||||
| 	list_add(desktop->views, view); | ||||
| } | ||||
|  |  | |||
|  | @ -355,11 +355,8 @@ static void handle_configure_request(struct wlr_xwm *xwm, | |||
| 
 | ||||
| 	if (surface->surface == NULL) { | ||||
| 		// Surface has not been mapped yet
 | ||||
| 		surface->x = ev->x; | ||||
| 		surface->y = ev->y; | ||||
| 		surface->width = ev->width; | ||||
| 		surface->height = ev->height; | ||||
| 		wlr_xwayland_surface_configure(xwm->xwayland, surface); | ||||
| 		wlr_xwayland_surface_configure(xwm->xwayland, surface, ev->x, ev->y, | ||||
| 			ev->width, ev->height); | ||||
| 	} else { | ||||
| 		struct wlr_xwayland_surface_configure_event *wlr_event = | ||||
| 			calloc(1, sizeof(struct wlr_xwayland_surface_configure_event)); | ||||
|  | @ -610,13 +607,18 @@ void wlr_xwayland_surface_activate(struct wlr_xwayland *wlr_xwayland, | |||
| } | ||||
| 
 | ||||
| void wlr_xwayland_surface_configure(struct wlr_xwayland *wlr_xwayland, | ||||
| 		struct wlr_xwayland_surface *surface) { | ||||
| 		struct wlr_xwayland_surface *surface, int16_t x, int16_t y, | ||||
| 		uint16_t width, uint16_t height) { | ||||
| 	surface->x = x; | ||||
| 	surface->y = y; | ||||
| 	surface->width = width; | ||||
| 	surface->height = height; | ||||
| 
 | ||||
| 	struct wlr_xwm *xwm = wlr_xwayland->xwm; | ||||
| 	uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | | ||||
| 		XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | | ||||
| 		XCB_CONFIG_WINDOW_BORDER_WIDTH; | ||||
| 	uint32_t values[] = {surface->x, surface->y, surface->width, | ||||
| 		surface->height, 0}; | ||||
| 	uint32_t values[] = {x, y, width, height, 0}; | ||||
| 	xcb_configure_window(xwm->xcb_conn, surface->window_id, mask, values); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue