diff options
| -rw-r--r-- | include/rootston/view.h | 1 | ||||
| -rw-r--r-- | include/wlr/types/wlr_wl_shell.h | 2 | ||||
| -rw-r--r-- | include/wlr/xwayland.h | 16 | ||||
| -rw-r--r-- | rootston/xwayland.c | 29 | ||||
| -rw-r--r-- | xwayland/xwm.c | 48 | 
5 files changed, 77 insertions, 19 deletions
diff --git a/include/rootston/view.h b/include/rootston/view.h index da3b189d..2bd71104 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -31,6 +31,7 @@ struct roots_xwayland_surface {  	struct roots_view *view;  	// TODO: Maybe destroy listener should go in roots_view  	struct wl_listener destroy; +	struct wl_listener request_configure;  };  enum roots_view_type { diff --git a/include/wlr/types/wlr_wl_shell.h b/include/wlr/types/wlr_wl_shell.h index 0b18a131..0db99989 100644 --- a/include/wlr/types/wlr_wl_shell.h +++ b/include/wlr/types/wlr_wl_shell.h @@ -106,7 +106,7 @@ void wlr_wl_shell_destroy(struct wlr_wl_shell *wlr_wl_shell);  void wlr_wl_shell_surface_ping(struct wlr_wl_shell_surface *surface);  void wlr_wl_shell_surface_configure(struct wlr_wl_shell_surface *surface, -	uint32_t edges, int32_t width, int32_t height); +	enum wl_shell_surface_resize edges, int32_t width, int32_t height);  void wlr_wl_shell_surface_popup_done(struct wlr_wl_shell_surface *surface);  #endif diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index ebb6efb7..4e59d9c5 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -47,18 +47,28 @@ struct wlr_xwayland_surface {  	struct {  		struct wl_signal destroy; + +		struct wl_signal request_configure; + +		struct wl_signal set_title; +		struct wl_signal set_class;  	} events;  	void *data;  }; +struct wlr_xwayland_surface_configure_event { +	struct wlr_xwayland_surface *surface; +	int16_t x, y; +	uint16_t width, height; +}; +  void wlr_xwayland_destroy(struct wlr_xwayland *wlr_xwayland);  struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display,  	struct wlr_compositor *compositor);  void wlr_xwayland_surface_activate(struct wlr_xwayland *wlr_xwayland,  	struct wlr_xwayland_surface *surface); -void wlr_xwayland_surface_configure(struct wlr_xwm *xwm, -	struct wlr_xwayland_surface *surface, uint32_t x, uint32_t y, -	uint32_t width, uint32_t height); +void wlr_xwayland_surface_configure(struct wlr_xwayland *wlr_xwayland, +	struct wlr_xwayland_surface *surface);  #endif diff --git a/rootston/xwayland.c b/rootston/xwayland.c index aaf55b37..685681d9 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -17,7 +17,25 @@ static void handle_destroy(struct wl_listener *listener, void *data) {  	free(roots_surface);  } -static void x11_activate(struct roots_view *view, bool active) { +static void handle_configure(struct wl_listener *listener, void *data) { +	struct roots_xwayland_surface *roots_surface = +		wl_container_of(listener, roots_surface, destroy); +	struct wlr_xwayland_surface_configure_event *event = data; +	struct wlr_xwayland_surface *xwayland_surface = event->surface; + +	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); +} + +static void activate(struct roots_view *view, bool active) {  	wlr_xwayland_surface_activate(view->desktop->xwayland,  		view->xwayland_surface);  } @@ -35,15 +53,20 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {  	wl_list_init(&roots_surface->destroy.link);  	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; +	wl_signal_add(&surface->events.request_configure, +		&roots_surface->request_configure);  	struct roots_view *view = calloc(1, sizeof(struct roots_view));  	view->type = ROOTS_XWAYLAND_VIEW; -	view->x = view->y = 200; +	view->x = (double) surface->x; +	view->y = (double) surface->y;  	view->xwayland_surface = surface;  	view->roots_xwayland_surface = roots_surface;  	view->wlr_surface = surface->surface;  	view->desktop = desktop; -	view->activate = x11_activate; +	view->activate = activate;  	roots_surface->view = view;  	list_add(desktop->views, view);  } diff --git a/xwayland/xwm.c b/xwayland/xwm.c index e316d8fa..b8eefa4b 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -61,6 +61,9 @@ static struct wlr_xwayland_surface *wlr_xwayland_surface_create(  	surface->override_redirect = override_redirect;  	wl_list_insert(&xwm->new_surfaces, &surface->link);  	wl_signal_init(&surface->events.destroy); +	wl_signal_init(&surface->events.request_configure); +	wl_signal_init(&surface->events.set_class); +	wl_signal_init(&surface->events.set_title);  	return surface;  } @@ -112,6 +115,7 @@ static void read_surface_class(struct wlr_xwm *xwm,  	}  	wlr_log(L_DEBUG, "XCB_ATOM_WM_CLASS: %s %s", surface->instance, surface->class); +	wl_signal_emit(&surface->events.set_class, surface);  }  static void read_surface_title(struct wlr_xwm *xwm, @@ -135,6 +139,7 @@ static void read_surface_title(struct wlr_xwm *xwm,  	}  	wlr_log(L_DEBUG, "XCB_ATOM_WM_NAME: %s", surface->title); +	wl_signal_emit(&surface->events.set_title, surface);  }  static void read_surface_parent(struct wlr_xwm *xwm, @@ -233,14 +238,32 @@ static void handle_configure_request(struct wlr_xwm *xwm,  		return;  	} -	surface->x = ev->x; -	surface->y = ev->y; -	surface->width = ev->width; -	surface->height = ev->height; -	// TODO: handle parent/sibling? +	// TODO: handle ev->{parent,sibling}? -	wlr_xwayland_surface_configure(xwm, surface, ev->x, ev->y, ev->width, -		ev->height); +	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); +	} else { +		struct wlr_xwayland_surface_configure_event *wlr_event = +			calloc(1, sizeof(struct wlr_xwayland_surface_configure_event)); +		if (wlr_event == NULL) { +			return; +		} + +		wlr_event->surface = surface; +		wlr_event->x = ev->x; +		wlr_event->y = ev->y; +		wlr_event->width = ev->width; +		wlr_event->height = ev->height; + +		wl_signal_emit(&surface->events.request_configure, wlr_event); + +		free(wlr_event); +	}  }  static void handle_map_request(struct wlr_xwm *xwm, @@ -369,7 +392,7 @@ static void create_surface_handler(struct wl_listener *listener, void *data) {  		return;  	} -	wlr_log(L_DEBUG, "New x11 surface: %p", surface); +	wlr_log(L_DEBUG, "New xwayland surface: %p", surface);  	uint32_t surface_id = wl_resource_get_id(surface->resource);  	struct wlr_xwayland_surface *xwayland_surface; @@ -465,13 +488,14 @@ void wlr_xwayland_surface_activate(struct wlr_xwayland *wlr_xwayland,  	xcb_flush(xwm->xcb_conn);  } -void wlr_xwayland_surface_configure(struct wlr_xwm *xwm, -		struct wlr_xwayland_surface *surface, uint32_t x, uint32_t y, -		uint32_t width, uint32_t height) { +void wlr_xwayland_surface_configure(struct wlr_xwayland *wlr_xwayland, +		struct wlr_xwayland_surface *surface) { +	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[] = {x, y, width, height, 0}; +	uint32_t values[] = {surface->x, surface->y, surface->width, +		surface->height, 0};  	xcb_configure_window(xwm->xcb_conn, surface->window_id, mask, values);  }  | 
