diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 477dddc4..11aedc37 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -98,7 +98,6 @@ struct wlr_xwayland_surface { uint16_t saved_width, saved_height; bool override_redirect; bool mapped; - bool added; char *title; char *class; diff --git a/rootston/xwayland.c b/rootston/xwayland.c index 27a27b65..b7dbab54 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -228,19 +228,31 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { static void handle_map(struct wl_listener *listener, void *data) { struct roots_xwayland_surface *roots_surface = wl_container_of(listener, roots_surface, map); - struct wlr_xwayland_surface *xsurface = data; + struct wlr_xwayland_surface *surface = data; struct roots_view *view = roots_surface->view; - view->x = xsurface->x; - view->y = xsurface->y; - view->width = xsurface->surface->current->width; - view->height = xsurface->surface->current->height; - - view_map(view, xsurface->surface); + view->x = surface->x; + view->y = surface->y; + view->width = surface->surface->current->width; + view->height = surface->surface->current->height; roots_surface->surface_commit.notify = handle_surface_commit; - wl_signal_add(&xsurface->surface->events.commit, + wl_signal_add(&surface->surface->events.commit, &roots_surface->surface_commit); + + view_map(view, surface->surface); + + if (!surface->override_redirect) { + if (surface->decorations == WLR_XWAYLAND_SURFACE_DECORATIONS_ALL) { + view->decorated = true; + view->border_width = 4; + view->titlebar_height = 12; + } + + view_setup(view); + } else { + view_initial_focus(view); + } } static void handle_unmap(struct wl_listener *listener, void *data) { @@ -289,10 +301,6 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { wl_signal_add(&surface->events.request_fullscreen, &roots_surface->request_fullscreen); - roots_surface->surface_commit.notify = handle_surface_commit; - wl_signal_add(&surface->surface->events.commit, - &roots_surface->surface_commit); - struct roots_view *view = view_create(desktop); if (view == NULL) { free(roots_surface); @@ -301,8 +309,6 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { view->type = ROOTS_XWAYLAND_VIEW; view->x = (double)surface->x; view->y = (double)surface->y; - view->width = surface->surface->current->width; - view->height = surface->surface->current->height; view->xwayland_surface = surface; view->roots_xwayland_surface = roots_surface; @@ -315,18 +321,4 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { view->close = close; view->destroy = destroy; roots_surface->view = view; - - view_map(view, surface->surface); - - if (!surface->override_redirect) { - if (surface->decorations == WLR_XWAYLAND_SURFACE_DECORATIONS_ALL) { - view->decorated = true; - view->border_width = 4; - view->titlebar_height = 12; - } - - view_setup(view); - } else { - view_initial_focus(view); - } } diff --git a/xwayland/xwm.c b/xwayland/xwm.c index e755c9d4..77dc0797 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -109,7 +109,7 @@ static int xwayland_surface_handle_ping_timeout(void *data) { return 1; } -static struct wlr_xwayland_surface *wlr_xwayland_surface_create( +static struct wlr_xwayland_surface *xwayland_surface_create( struct wlr_xwm *xwm, xcb_window_t window_id, int16_t x, int16_t y, uint16_t width, uint16_t height, bool override_redirect) { struct wlr_xwayland_surface *surface = @@ -171,6 +171,8 @@ static struct wlr_xwayland_surface *wlr_xwayland_surface_create( return NULL; } + wlr_signal_emit_safe(&xwm->xwayland->events.new_surface, surface); + return surface; } @@ -297,6 +299,8 @@ static void wlr_xwayland_surface_destroy( wlr_surface_set_role_committed(xsurface->surface, NULL, NULL); } + wl_event_source_remove(xsurface->ping_timer); + free(xsurface->title); free(xsurface->class); free(xsurface->instance); @@ -617,26 +621,22 @@ static void read_surface_property(struct wlr_xwm *xwm, static void handle_surface_commit(struct wlr_surface *wlr_surface, void *role_data) { - struct wlr_xwayland_surface *xsurface = role_data; + struct wlr_xwayland_surface *surface = role_data; - if (!xsurface->added && - wlr_surface_has_buffer(xsurface->surface) && - xsurface->mapped) { - wlr_signal_emit_safe(&xsurface->xwm->xwayland->events.new_surface, - xsurface); - xsurface->added = true; + if (!surface->mapped && wlr_surface_has_buffer(surface->surface)) { + wlr_signal_emit_safe(&surface->events.map, surface); + surface->mapped = true; } } static void handle_surface_destroy(struct wl_listener *listener, void *data) { - struct wlr_xwayland_surface *xsurface = - wl_container_of(listener, xsurface, surface_destroy); - xsurface_unmap(xsurface); + struct wlr_xwayland_surface *surface = + wl_container_of(listener, surface, surface_destroy); + xsurface_unmap(surface); } static void xwm_map_shell_surface(struct wlr_xwm *xwm, - struct wlr_xwayland_surface *xsurface, - struct wlr_surface *surface) { + struct wlr_xwayland_surface *xsurface, struct wlr_surface *surface) { xsurface->surface = surface; // read all surface properties @@ -663,9 +663,6 @@ static void xwm_map_shell_surface(struct wlr_xwm *xwm, xsurface->surface_destroy.notify = handle_surface_destroy; wl_signal_add(&surface->events.destroy, &xsurface->surface_destroy); - - xsurface->mapped = true; - wlr_signal_emit_safe(&xsurface->events.map, xsurface); } static void xsurface_unmap(struct wlr_xwayland_surface *surface) { @@ -692,7 +689,14 @@ static void xsurface_unmap(struct wlr_xwayland_surface *surface) { static void xwm_handle_create_notify(struct wlr_xwm *xwm, xcb_create_notify_event_t *ev) { wlr_log(L_DEBUG, "XCB_CREATE_NOTIFY (%u)", ev->window); - wlr_xwayland_surface_create(xwm, ev->window, ev->x, ev->y, + + if (ev->window == xwm->window || + ev->window == xwm->selection_window || + ev->window == xwm->dnd_window) { + return; + } + + xwayland_surface_create(xwm, ev->window, ev->x, ev->y, ev->width, ev->height, ev->override_redirect); }