diff options
-rw-r--r-- | include/wlr/xwayland.h | 9 | ||||
-rw-r--r-- | rootston/desktop.c | 8 | ||||
-rw-r--r-- | xwayland/xwm.c | 55 | ||||
-rw-r--r-- | xwayland/xwm.h | 3 |
4 files changed, 56 insertions, 19 deletions
diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index c25d0eb0..0398ff28 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -66,14 +66,16 @@ struct wlr_xwayland_surface_size_hints { struct wlr_xwayland_surface { xcb_window_t window_id; + struct wlr_xwm *xwm; uint32_t surface_id; struct wl_list link; struct wlr_surface *surface; - struct wl_listener surface_destroy_listener; int16_t x, y; uint16_t width, height; bool override_redirect; + bool mapped; + bool added; char *title; char *class; @@ -95,9 +97,7 @@ struct wlr_xwayland_surface { struct { struct wl_signal destroy; - struct wl_signal request_configure; - struct wl_signal set_title; struct wl_signal set_class; struct wl_signal set_parent; @@ -106,6 +106,9 @@ struct wlr_xwayland_surface { struct wl_signal set_window_type; } events; + struct wl_listener surface_destroy; + struct wl_listener surface_commit; + void *data; }; diff --git a/rootston/desktop.c b/rootston/desktop.c index 40d088b8..30b5a519 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -99,10 +99,10 @@ bool view_center(struct roots_view *view) { int width, height; wlr_output_effective_resolution(output, &width, &height); - view->x = (double)(width - size.width) / 2 - + l_output->x; - view->y = (double)(height - size.height) / 2 - + l_output->y; + double view_x = (double)(width - size.width) / 2 + l_output->x; + double view_y = (double)(height - size.height) / 2 + l_output->y; + + view_set_position(view, view_x, view_y); return true; } diff --git a/xwayland/xwm.c b/xwayland/xwm.c index ee04f734..2d88c2cb 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -67,6 +67,7 @@ static struct wlr_xwayland_surface *wlr_xwayland_surface_create( wlr_log(L_ERROR, "Could not allocate wlr xwayland surface"); return NULL; } + surface->xwm = xwm; surface->window_id = window_id; surface->x = x; surface->y = y; @@ -92,6 +93,12 @@ static void wlr_xwayland_surface_destroy(struct wlr_xwayland_surface *surface) { for (size_t i = 0; i < surface->state->length; i++) { free(surface->state->items[i]); } + + if (surface->surface) { + wl_list_remove(&surface->surface_destroy.link); + wl_list_remove(&surface->surface_commit.link); + } + free(surface->title); free(surface->class); free(surface->instance); @@ -412,11 +419,30 @@ static void read_surface_property(struct wlr_xwm *xwm, free(reply); } +static void handle_surface_commit(struct wl_listener *listener, void *data) { + struct wlr_xwayland_surface *xsurface = + wl_container_of(listener, xsurface, surface_commit); + + if (!xsurface->added && + wlr_surface_has_buffer(xsurface->surface) && + xsurface->mapped) { + wl_signal_emit(&xsurface->xwm->xwayland->events.new_surface, xsurface); + xsurface->added = true; + } +} + +static void handle_surface_destroy(struct wl_listener *listener, void *data) { + struct wlr_xwayland_surface *xsurface = + wl_container_of(listener, xsurface, surface_destroy); + + // TODO destroy xwayland surface? +} + static void map_shell_surface(struct wlr_xwm *xwm, - struct wlr_xwayland_surface *xwayland_surface, + struct wlr_xwayland_surface *xsurface, struct wlr_surface *surface) { // get xcb geometry for depth = alpha channel - xwayland_surface->surface = surface; + xsurface->surface = surface; // read all surface properties const xcb_atom_t props[] = { @@ -433,13 +459,20 @@ static void map_shell_surface(struct wlr_xwm *xwm, xwm->atoms[NET_WM_PID], }; for (size_t i = 0; i < sizeof(props)/sizeof(xcb_atom_t); i++) { - read_surface_property(xwm, xwayland_surface, props[i]); + read_surface_property(xwm, xsurface, props[i]); } - wl_list_remove(&xwayland_surface->link); + wl_list_remove(&xsurface->link); wl_list_insert(&xwm->xwayland->displayable_surfaces, - &xwayland_surface->link); - wl_signal_emit(&xwm->xwayland->events.new_surface, xwayland_surface); + &xsurface->link); + + xsurface->surface_commit.notify = handle_surface_commit; + wl_signal_add(&surface->events.commit, &xsurface->surface_commit); + + xsurface->surface_destroy.notify = handle_surface_destroy; + wl_signal_add(&surface->events.destroy, &xsurface->surface_destroy); + + xsurface->mapped = true; } /* xcb event handlers */ @@ -620,10 +653,10 @@ static int x11_event_handler(int fd, uint32_t mask, void *data) { return count; } -static void create_surface_handler(struct wl_listener *listener, void *data) { +static void handle_compositor_surface_create(struct wl_listener *listener, void *data) { struct wlr_surface *surface = data; struct wlr_xwm *xwm = - wl_container_of(listener, xwm, surface_create_listener); + wl_container_of(listener, xwm, compositor_surface_create); if (wl_resource_get_client(surface->resource) != xwm->xwayland->client) { return; } @@ -757,7 +790,7 @@ void xwm_destroy(struct wlr_xwm *xwm) { wl_list_for_each_safe(surface, tmp, &xwm->unpaired_surfaces, link) { wlr_xwayland_surface_destroy(surface); } - wl_list_remove(&xwm->surface_create_listener.link); + wl_list_remove(&xwm->compositor_surface_create.link); xcb_disconnect(xwm->xcb_conn); free(xwm); @@ -875,9 +908,9 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { free(xfixes_reply); - xwm->surface_create_listener.notify = create_surface_handler; + xwm->compositor_surface_create.notify = handle_compositor_surface_create; wl_signal_add(&wlr_xwayland->compositor->events.create_surface, - &xwm->surface_create_listener); + &xwm->compositor_surface_create); return xwm; } diff --git a/xwayland/xwm.h b/xwayland/xwm.h index d8857eb8..b557a331 100644 --- a/xwayland/xwm.h +++ b/xwayland/xwm.h @@ -36,7 +36,6 @@ enum net_wm_state_action { struct wlr_xwm { struct wlr_xwayland *xwayland; struct wl_event_source *event_source; - struct wl_listener surface_create_listener; xcb_atom_t atoms[ATOM_LAST]; xcb_connection_t *xcb_conn; @@ -49,6 +48,8 @@ struct wlr_xwm { struct wl_list unpaired_surfaces; const xcb_query_extension_reply_t *xfixes; + + struct wl_listener compositor_surface_create; }; void xwm_destroy(struct wlr_xwm *xwm); |