diff options
Diffstat (limited to 'rootston/xdg_shell.c')
| -rw-r--r-- | rootston/xdg_shell.c | 188 | 
1 files changed, 92 insertions, 96 deletions
| diff --git a/rootston/xdg_shell.c b/rootston/xdg_shell.c index 918f90ab..5686b3d7 100644 --- a/rootston/xdg_shell.c +++ b/rootston/xdg_shell.c @@ -10,25 +10,28 @@  #include "rootston/desktop.h"  #include "rootston/input.h"  #include "rootston/server.h" +#include "rootston/view.h" + +static const struct roots_view_child_interface popup_impl;  static void popup_destroy(struct roots_view_child *child) { -	assert(child->destroy == popup_destroy); +	assert(child->impl == &popup_impl);  	struct roots_xdg_popup *popup = (struct roots_xdg_popup *)child; -	if (popup == NULL) { -		return; -	}  	wl_list_remove(&popup->destroy.link);  	wl_list_remove(&popup->new_popup.link);  	wl_list_remove(&popup->map.link);  	wl_list_remove(&popup->unmap.link); -	view_child_finish(&popup->view_child);  	free(popup);  } +static const struct roots_view_child_interface popup_impl = { +	.destroy = popup_destroy, +}; +  static void popup_handle_destroy(struct wl_listener *listener, void *data) {  	struct roots_xdg_popup *popup =  		wl_container_of(listener, popup, destroy); -	popup_destroy((struct roots_view_child *)popup); +	view_child_destroy(&popup->view_child);  }  static void popup_handle_map(struct wl_listener *listener, void *data) { @@ -113,8 +116,8 @@ static struct roots_xdg_popup *popup_create(struct roots_view *view,  		return NULL;  	}  	popup->wlr_popup = wlr_popup; -	popup->view_child.destroy = popup_destroy; -	view_child_init(&popup->view_child, view, wlr_popup->base->surface); +	view_child_init(&popup->view_child, &popup_impl, +		view, wlr_popup->base->surface);  	popup->destroy.notify = popup_handle_destroy;  	wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy);  	popup->map.notify = popup_handle_map; @@ -130,31 +133,31 @@ static struct roots_xdg_popup *popup_create(struct roots_view *view,  } -static void get_size(const struct roots_view *view, struct wlr_box *box) { -	assert(view->type == ROOTS_XDG_SHELL_VIEW); -	struct wlr_xdg_surface *surface = view->xdg_surface; +static void get_size(struct roots_view *view, struct wlr_box *box) { +	struct wlr_xdg_surface *xdg_surface = +		roots_xdg_surface_from_view(view)->xdg_surface;  	struct wlr_box geo_box; -	wlr_xdg_surface_get_geometry(surface, &geo_box); +	wlr_xdg_surface_get_geometry(xdg_surface, &geo_box);  	box->width = geo_box.width;  	box->height = geo_box.height;  }  static void activate(struct roots_view *view, bool active) { -	assert(view->type == ROOTS_XDG_SHELL_VIEW); -	struct wlr_xdg_surface *surface = view->xdg_surface; -	if (surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) { -		wlr_xdg_toplevel_set_activated(surface, active); +	struct wlr_xdg_surface *xdg_surface = +		roots_xdg_surface_from_view(view)->xdg_surface; +	if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL) { +		wlr_xdg_toplevel_set_activated(xdg_surface, active);  	}  } -static void apply_size_constraints(struct wlr_xdg_surface *surface, +static void apply_size_constraints(struct wlr_xdg_surface *xdg_surface,  		uint32_t width, uint32_t height, uint32_t *dest_width,  		uint32_t *dest_height) {  	*dest_width = width;  	*dest_height = height; -	struct wlr_xdg_toplevel_state *state = &surface->toplevel->current; +	struct wlr_xdg_toplevel_state *state = &xdg_surface->toplevel->current;  	if (width < state->min_width) {  		*dest_width = state->min_width;  	} else if (state->max_width > 0 && @@ -170,26 +173,26 @@ static void apply_size_constraints(struct wlr_xdg_surface *surface,  }  static void resize(struct roots_view *view, uint32_t width, uint32_t height) { -	assert(view->type == ROOTS_XDG_SHELL_VIEW); -	struct wlr_xdg_surface *surface = view->xdg_surface; -	if (surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) { +	struct wlr_xdg_surface *xdg_surface = +		roots_xdg_surface_from_view(view)->xdg_surface; +	if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {  		return;  	}  	uint32_t constrained_width, constrained_height; -	apply_size_constraints(surface, width, height, &constrained_width, +	apply_size_constraints(xdg_surface, width, height, &constrained_width,  		&constrained_height); -	wlr_xdg_toplevel_set_size(surface, constrained_width, +	wlr_xdg_toplevel_set_size(xdg_surface, constrained_width,  		constrained_height);  }  static void move_resize(struct roots_view *view, double x, double y,  		uint32_t width, uint32_t height) { -	assert(view->type == ROOTS_XDG_SHELL_VIEW); -	struct roots_xdg_surface *roots_surface = view->roots_xdg_surface; -	struct wlr_xdg_surface *surface = view->xdg_surface; -	if (surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) { +	struct roots_xdg_surface *xdg_surface = +		roots_xdg_surface_from_view(view); +	struct wlr_xdg_surface *wlr_xdg_surface = xdg_surface->xdg_surface; +	if (wlr_xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {  		return;  	} @@ -197,7 +200,7 @@ static void move_resize(struct roots_view *view, double x, double y,  	bool update_y = y != view->box.y;  	uint32_t constrained_width, constrained_height; -	apply_size_constraints(surface, width, height, &constrained_width, +	apply_size_constraints(wlr_xdg_surface, width, height, &constrained_width,  		&constrained_height);  	if (update_x) { @@ -214,48 +217,48 @@ static void move_resize(struct roots_view *view, double x, double y,  	view->pending_move_resize.width = constrained_width;  	view->pending_move_resize.height = constrained_height; -	uint32_t serial = wlr_xdg_toplevel_set_size(surface, constrained_width, -		constrained_height); +	uint32_t serial = wlr_xdg_toplevel_set_size(wlr_xdg_surface, +		constrained_width, constrained_height);  	if (serial > 0) { -		roots_surface->pending_move_resize_configure_serial = serial; -	} else if (roots_surface->pending_move_resize_configure_serial == 0) { +		xdg_surface->pending_move_resize_configure_serial = serial; +	} else if (xdg_surface->pending_move_resize_configure_serial == 0) {  		view_update_position(view, x, y);  	}  }  static void maximize(struct roots_view *view, bool maximized) { -	assert(view->type == ROOTS_XDG_SHELL_VIEW); -	struct wlr_xdg_surface *surface = view->xdg_surface; -	if (surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) { +	struct wlr_xdg_surface *xdg_surface = +		roots_xdg_surface_from_view(view)->xdg_surface; +	if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {  		return;  	} -	wlr_xdg_toplevel_set_maximized(surface, maximized); +	wlr_xdg_toplevel_set_maximized(xdg_surface, maximized);  }  static void set_fullscreen(struct roots_view *view, bool fullscreen) { -	assert(view->type == ROOTS_XDG_SHELL_VIEW); -	struct wlr_xdg_surface *surface = view->xdg_surface; -	if (surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) { +	struct wlr_xdg_surface *xdg_surface = +		roots_xdg_surface_from_view(view)->xdg_surface; +	if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {  		return;  	} -	wlr_xdg_toplevel_set_fullscreen(surface, fullscreen); +	wlr_xdg_toplevel_set_fullscreen(xdg_surface, fullscreen);  }  static void close(struct roots_view *view) { -	assert(view->type == ROOTS_XDG_SHELL_VIEW); -	struct wlr_xdg_surface *surface = view->xdg_surface; +	struct wlr_xdg_surface *xdg_surface = +		roots_xdg_surface_from_view(view)->xdg_surface;  	struct wlr_xdg_popup *popup = NULL; -	wl_list_for_each(popup, &surface->popups, link) { +	wl_list_for_each(popup, &xdg_surface->popups, link) {  		wlr_xdg_popup_destroy(popup->base);  	} -	wlr_xdg_toplevel_send_close(surface); +	wlr_xdg_toplevel_send_close(xdg_surface);  }  static void destroy(struct roots_view *view) { -	assert(view->type == ROOTS_XDG_SHELL_VIEW); -	struct roots_xdg_surface *roots_xdg_surface = view->roots_xdg_surface; +	struct roots_xdg_surface *roots_xdg_surface = +		roots_xdg_surface_from_view(view);  	wl_list_remove(&roots_xdg_surface->surface_commit.link);  	wl_list_remove(&roots_xdg_surface->destroy.link);  	wl_list_remove(&roots_xdg_surface->new_popup.link); @@ -267,14 +270,24 @@ static void destroy(struct roots_view *view) {  	wl_list_remove(&roots_xdg_surface->request_fullscreen.link);  	wl_list_remove(&roots_xdg_surface->set_title.link);  	wl_list_remove(&roots_xdg_surface->set_app_id.link); -	roots_xdg_surface->view->xdg_surface->data = NULL; +	roots_xdg_surface->xdg_surface->data = NULL;  	free(roots_xdg_surface);  } +static const struct roots_view_interface view_impl = { +	.activate = activate, +	.resize = resize, +	.move_resize = move_resize, +	.maximize = maximize, +	.set_fullscreen = set_fullscreen, +	.close = close, +	.destroy = destroy, +}; +  static void handle_request_move(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface *roots_xdg_surface =  		wl_container_of(listener, roots_xdg_surface, request_move); -	struct roots_view *view = roots_xdg_surface->view; +	struct roots_view *view = &roots_xdg_surface->view;  	struct roots_input *input = view->desktop->server->input;  	struct wlr_xdg_toplevel_move_event *e = data;  	struct roots_seat *seat = input_seat_from_wlr_seat(input, e->seat->seat); @@ -288,7 +301,7 @@ static void handle_request_move(struct wl_listener *listener, void *data) {  static void handle_request_resize(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface *roots_xdg_surface =  		wl_container_of(listener, roots_xdg_surface, request_resize); -	struct roots_view *view = roots_xdg_surface->view; +	struct roots_view *view = &roots_xdg_surface->view;  	struct roots_input *input = view->desktop->server->input;  	struct wlr_xdg_toplevel_resize_event *e = data;  	// TODO verify event serial @@ -303,8 +316,8 @@ static void handle_request_resize(struct wl_listener *listener, void *data) {  static void handle_request_maximize(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface *roots_xdg_surface =  		wl_container_of(listener, roots_xdg_surface, request_maximize); -	struct roots_view *view = roots_xdg_surface->view; -	struct wlr_xdg_surface *surface = view->xdg_surface; +	struct roots_view *view = &roots_xdg_surface->view; +	struct wlr_xdg_surface *surface = roots_xdg_surface->xdg_surface;  	if (surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {  		return; @@ -317,8 +330,8 @@ static void handle_request_fullscreen(struct wl_listener *listener,  		void *data) {  	struct roots_xdg_surface *roots_xdg_surface =  		wl_container_of(listener, roots_xdg_surface, request_fullscreen); -	struct roots_view *view = roots_xdg_surface->view; -	struct wlr_xdg_surface *surface = view->xdg_surface; +	struct roots_view *view = &roots_xdg_surface->view; +	struct wlr_xdg_surface *surface = roots_xdg_surface->xdg_surface;  	struct wlr_xdg_toplevel_set_fullscreen_event *e = data;  	if (surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) { @@ -332,23 +345,23 @@ static void handle_set_title(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface *roots_xdg_surface =  		wl_container_of(listener, roots_xdg_surface, set_title); -	view_set_title(roots_xdg_surface->view, -			roots_xdg_surface->view->xdg_surface->toplevel->title); +	view_set_title(&roots_xdg_surface->view, +			roots_xdg_surface->xdg_surface->toplevel->title);  }  static void handle_set_app_id(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface *roots_xdg_surface =  		wl_container_of(listener, roots_xdg_surface, set_app_id); -	view_set_app_id(roots_xdg_surface->view, -			roots_xdg_surface->view->xdg_surface->toplevel->app_id); +	view_set_app_id(&roots_xdg_surface->view, +			roots_xdg_surface->xdg_surface->toplevel->app_id);  }  static void handle_surface_commit(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface *roots_surface =  		wl_container_of(listener, roots_surface, surface_commit); -	struct roots_view *view = roots_surface->view; -	struct wlr_xdg_surface *surface = view->xdg_surface; +	struct roots_view *view = &roots_surface->view; +	struct wlr_xdg_surface *surface = roots_surface->xdg_surface;  	if (!surface->mapped) {  		return; @@ -385,38 +398,38 @@ static void handle_new_popup(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface *roots_xdg_surface =  		wl_container_of(listener, roots_xdg_surface, new_popup);  	struct wlr_xdg_popup *wlr_popup = data; -	popup_create(roots_xdg_surface->view, wlr_popup); +	popup_create(&roots_xdg_surface->view, wlr_popup);  }  static void handle_map(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface *roots_xdg_surface =  		wl_container_of(listener, roots_xdg_surface, map); -	struct roots_view *view = roots_xdg_surface->view; +	struct roots_view *view = &roots_xdg_surface->view;  	struct wlr_box box;  	get_size(view, &box);  	view->box.width = box.width;  	view->box.height = box.height; -	view_map(view, view->xdg_surface->surface); +	view_map(view, roots_xdg_surface->xdg_surface->surface);  	view_setup(view);  	wlr_foreign_toplevel_handle_v1_set_title(view->toplevel_handle, -			view->xdg_surface->toplevel->title ?: "none"); +			roots_xdg_surface->xdg_surface->toplevel->title ?: "none");  	wlr_foreign_toplevel_handle_v1_set_app_id(view->toplevel_handle, -			view->xdg_surface->toplevel->app_id ?: "none"); +			roots_xdg_surface->xdg_surface->toplevel->app_id ?: "none");  }  static void handle_unmap(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface *roots_xdg_surface =  		wl_container_of(listener, roots_xdg_surface, unmap); -	view_unmap(roots_xdg_surface->view); +	view_unmap(&roots_xdg_surface->view);  }  static void handle_destroy(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface *roots_xdg_surface =  		wl_container_of(listener, roots_xdg_surface, destroy); -	view_destroy(roots_xdg_surface->view); +	view_destroy(&roots_xdg_surface->view);  }  void handle_xdg_shell_surface(struct wl_listener *listener, void *data) { @@ -440,6 +453,11 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {  	if (!roots_surface) {  		return;  	} + +	view_init(&roots_surface->view, &view_impl, ROOTS_XDG_SHELL_VIEW, desktop); +	roots_surface->xdg_surface = surface; +	surface->data = roots_surface; +  	roots_surface->surface_commit.notify = handle_surface_commit;  	wl_signal_add(&surface->surface->events.commit,  		&roots_surface->surface_commit); @@ -468,43 +486,16 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {  			&roots_surface->set_app_id);  	roots_surface->new_popup.notify = handle_new_popup;  	wl_signal_add(&surface->events.new_popup, &roots_surface->new_popup); -	surface->data = roots_surface; - -	struct roots_view *view = view_create(desktop); -	if (!view) { -		free(roots_surface); -		return; -	} -	view->type = ROOTS_XDG_SHELL_VIEW; - -	view->xdg_surface = surface; -	view->roots_xdg_surface = roots_surface; -	view->activate = activate; -	view->resize = resize; -	view->move_resize = move_resize; -	view->maximize = maximize; -	view->set_fullscreen = set_fullscreen; -	view->close = close; -	view->destroy = destroy; -	roots_surface->view = view; - -	if (surface->toplevel->client_pending.maximized) { -		view_maximize(view, true); -	} -	if (surface->toplevel->client_pending.fullscreen) { -		view_set_fullscreen(view, true, NULL); -	}  } -  static void decoration_handle_destroy(struct wl_listener *listener,  		void *data) {  	struct roots_xdg_toplevel_decoration *decoration =  		wl_container_of(listener, decoration, destroy);  	decoration->surface->xdg_toplevel_decoration = NULL; -	view_update_decorated(decoration->surface->view, false); +	view_update_decorated(&decoration->surface->view, false);  	wl_list_remove(&decoration->destroy.link);  	wl_list_remove(&decoration->request_mode.link);  	wl_list_remove(&decoration->surface_commit.link); @@ -531,7 +522,7 @@ static void decoration_handle_surface_commit(struct wl_listener *listener,  	bool decorated = decoration->wlr_decoration->current_mode ==  		WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; -	view_update_decorated(decoration->surface->view, decorated); +	view_update_decorated(&decoration->surface->view, decorated);  }  void handle_xdg_toplevel_decoration(struct wl_listener *listener, void *data) { @@ -541,7 +532,7 @@ void handle_xdg_toplevel_decoration(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface *xdg_surface = wlr_decoration->surface->data;  	assert(xdg_surface != NULL); -	struct wlr_xdg_surface *wlr_xdg_surface = xdg_surface->view->xdg_surface; +	struct wlr_xdg_surface *wlr_xdg_surface = xdg_surface->xdg_surface;  	struct roots_xdg_toplevel_decoration *decoration =  		calloc(1, sizeof(struct roots_xdg_toplevel_decoration)); @@ -563,3 +554,8 @@ void handle_xdg_toplevel_decoration(struct wl_listener *listener, void *data) {  	decoration_handle_request_mode(&decoration->request_mode, wlr_decoration);  } + +struct roots_xdg_surface *roots_xdg_surface_from_view(struct roots_view *view) { +	assert(view->impl == &view_impl); +	return (struct roots_xdg_surface *)view; +} | 
