diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 9df7977d..1ee3f660 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -69,7 +69,7 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) { surface->ly = xsurface->y; desktop_damage_surface(xsurface->surface, surface->lx, surface->ly, true); - if (!wlr_xwayland_surface_is_unmanaged(xsurface)) { + if (!xsurface->override_redirect) { struct sway_seat *seat = input_manager_current_seat(input_manager); struct wlr_xwayland *xwayland = seat->input->server->xwayland.wlr_xwayland; @@ -89,7 +89,7 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) { wl_list_remove(&surface->link); wl_list_remove(&surface->commit.link); - if (!wlr_xwayland_surface_is_unmanaged(xsurface)) { + if (!xsurface->override_redirect) { struct sway_seat *seat = input_manager_current_seat(input_manager); if (seat->wlr_seat->keyboard_state.focused_surface == xsurface->surface) { @@ -303,6 +303,27 @@ static void handle_commit(struct wl_listener *listener, void *data) { } } +static void handle_destroy(struct wl_listener *listener, void *data) { + struct sway_xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, destroy); + struct sway_view *view = &xwayland_view->view; + + if (view->surface) { + view_unmap(view); + wl_list_remove(&xwayland_view->commit.link); + } + + wl_list_remove(&xwayland_view->destroy.link); + wl_list_remove(&xwayland_view->request_configure.link); + wl_list_remove(&xwayland_view->request_fullscreen.link); + wl_list_remove(&xwayland_view->set_title.link); + wl_list_remove(&xwayland_view->set_class.link); + wl_list_remove(&xwayland_view->set_window_type.link); + wl_list_remove(&xwayland_view->map.link); + wl_list_remove(&xwayland_view->unmap.link); + view_destroy(&xwayland_view->view); +} + static void handle_unmap(struct wl_listener *listener, void *data) { struct sway_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, unmap); @@ -323,6 +344,15 @@ static void handle_map(struct wl_listener *listener, void *data) { struct wlr_xwayland_surface *xsurface = data; struct sway_view *view = &xwayland_view->view; + if (xsurface->override_redirect) { + // This window used not to have the override redirect flag and has it + // now. Switch to unmanaged. + handle_destroy(&xwayland_view->destroy, view); + struct sway_xwayland_unmanaged *unmanaged = create_unmanaged(xsurface); + unmanaged_handle_map(&unmanaged->map, xsurface); + return; + } + view->natural_width = xsurface->width; view->natural_height = xsurface->height; @@ -344,27 +374,6 @@ static void handle_map(struct wl_listener *listener, void *data) { transaction_commit_dirty(); } -static void handle_destroy(struct wl_listener *listener, void *data) { - struct sway_xwayland_view *xwayland_view = - wl_container_of(listener, xwayland_view, destroy); - struct sway_view *view = &xwayland_view->view; - - if (view->surface) { - view_unmap(view); - wl_list_remove(&xwayland_view->commit.link); - } - - wl_list_remove(&xwayland_view->destroy.link); - wl_list_remove(&xwayland_view->request_configure.link); - wl_list_remove(&xwayland_view->request_fullscreen.link); - wl_list_remove(&xwayland_view->set_title.link); - wl_list_remove(&xwayland_view->set_class.link); - wl_list_remove(&xwayland_view->set_window_type.link); - wl_list_remove(&xwayland_view->map.link); - wl_list_remove(&xwayland_view->unmap.link); - view_destroy(&xwayland_view->view); -} - static void handle_request_configure(struct wl_listener *listener, void *data) { struct sway_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, request_configure); @@ -445,8 +454,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { xwayland_surface); struct wlr_xwayland_surface *xsurface = data; - if (wlr_xwayland_surface_is_unmanaged(xsurface) || - xsurface->override_redirect) { + if (xsurface->override_redirect) { wlr_log(WLR_DEBUG, "New xwayland unmanaged surface"); create_unmanaged(xsurface); return;