xwayland: support views that change override-redirect status
This commit is contained in:
parent
392d4808c3
commit
657587964e
|
@ -162,6 +162,7 @@ struct sway_xwayland_view {
|
||||||
struct wl_listener map;
|
struct wl_listener map;
|
||||||
struct wl_listener unmap;
|
struct wl_listener unmap;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
|
struct wl_listener override_redirect;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sway_xwayland_unmanaged {
|
struct sway_xwayland_unmanaged {
|
||||||
|
@ -176,6 +177,7 @@ struct sway_xwayland_unmanaged {
|
||||||
struct wl_listener map;
|
struct wl_listener map;
|
||||||
struct wl_listener unmap;
|
struct wl_listener unmap;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
|
struct wl_listener override_redirect;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
struct sway_view_child;
|
struct sway_view_child;
|
||||||
|
|
|
@ -118,12 +118,36 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) {
|
||||||
static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) {
|
static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
struct sway_xwayland_unmanaged *surface =
|
struct sway_xwayland_unmanaged *surface =
|
||||||
wl_container_of(listener, surface, destroy);
|
wl_container_of(listener, surface, destroy);
|
||||||
|
wl_list_remove(&surface->request_configure.link);
|
||||||
wl_list_remove(&surface->map.link);
|
wl_list_remove(&surface->map.link);
|
||||||
wl_list_remove(&surface->unmap.link);
|
wl_list_remove(&surface->unmap.link);
|
||||||
wl_list_remove(&surface->destroy.link);
|
wl_list_remove(&surface->destroy.link);
|
||||||
|
wl_list_remove(&surface->override_redirect.link);
|
||||||
free(surface);
|
free(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_map(struct wl_listener *listener, void *data);
|
||||||
|
|
||||||
|
struct sway_xwayland_view *create_xwayland_view(struct wlr_xwayland_surface *xsurface);
|
||||||
|
|
||||||
|
static void unmanaged_handle_override_redirect(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_xwayland_unmanaged *surface =
|
||||||
|
wl_container_of(listener, surface, override_redirect);
|
||||||
|
struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
|
||||||
|
|
||||||
|
bool mapped = xsurface->mapped;
|
||||||
|
if (mapped) {
|
||||||
|
unmanaged_handle_unmap(&surface->unmap, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
unmanaged_handle_destroy(&surface->destroy, NULL);
|
||||||
|
xsurface->data = NULL;
|
||||||
|
struct sway_xwayland_view *xwayland_view = create_xwayland_view(xsurface);
|
||||||
|
if (mapped) {
|
||||||
|
handle_map(&xwayland_view->map, xsurface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct sway_xwayland_unmanaged *create_unmanaged(
|
static struct sway_xwayland_unmanaged *create_unmanaged(
|
||||||
struct wlr_xwayland_surface *xsurface) {
|
struct wlr_xwayland_surface *xsurface) {
|
||||||
struct sway_xwayland_unmanaged *surface =
|
struct sway_xwayland_unmanaged *surface =
|
||||||
|
@ -144,6 +168,8 @@ static struct sway_xwayland_unmanaged *create_unmanaged(
|
||||||
surface->unmap.notify = unmanaged_handle_unmap;
|
surface->unmap.notify = unmanaged_handle_unmap;
|
||||||
wl_signal_add(&xsurface->events.destroy, &surface->destroy);
|
wl_signal_add(&xsurface->events.destroy, &surface->destroy);
|
||||||
surface->destroy.notify = unmanaged_handle_destroy;
|
surface->destroy.notify = unmanaged_handle_destroy;
|
||||||
|
wl_signal_add(&xsurface->events.set_override_redirect, &surface->override_redirect);
|
||||||
|
surface->override_redirect.notify = unmanaged_handle_override_redirect;
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
@ -418,6 +444,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
wl_list_remove(&xwayland_view->set_decorations.link);
|
wl_list_remove(&xwayland_view->set_decorations.link);
|
||||||
wl_list_remove(&xwayland_view->map.link);
|
wl_list_remove(&xwayland_view->map.link);
|
||||||
wl_list_remove(&xwayland_view->unmap.link);
|
wl_list_remove(&xwayland_view->unmap.link);
|
||||||
|
wl_list_remove(&xwayland_view->override_redirect.link);
|
||||||
view_begin_destroy(&xwayland_view->view);
|
view_begin_destroy(&xwayland_view->view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,16 +468,6 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_xwayland_surface *xsurface = data;
|
struct wlr_xwayland_surface *xsurface = data;
|
||||||
struct sway_view *view = &xwayland_view->view;
|
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);
|
|
||||||
xsurface->data = NULL;
|
|
||||||
struct sway_xwayland_unmanaged *unmanaged = create_unmanaged(xsurface);
|
|
||||||
unmanaged_handle_map(&unmanaged->map, xsurface);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
view->natural_width = xsurface->width;
|
view->natural_width = xsurface->width;
|
||||||
view->natural_height = xsurface->height;
|
view->natural_height = xsurface->height;
|
||||||
|
|
||||||
|
@ -465,6 +482,25 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_override_redirect(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_xwayland_view *xwayland_view =
|
||||||
|
wl_container_of(listener, xwayland_view, override_redirect);
|
||||||
|
struct wlr_xwayland_surface *xsurface = data;
|
||||||
|
struct sway_view *view = &xwayland_view->view;
|
||||||
|
|
||||||
|
bool mapped = xsurface->mapped;
|
||||||
|
if (mapped) {
|
||||||
|
handle_unmap(&xwayland_view->unmap, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_destroy(&xwayland_view->destroy, view);
|
||||||
|
xsurface->data = NULL;
|
||||||
|
struct sway_xwayland_unmanaged *unmanaged = create_unmanaged(xsurface);
|
||||||
|
if (mapped) {
|
||||||
|
unmanaged_handle_map(&unmanaged->map, xsurface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_request_configure(struct wl_listener *listener, void *data) {
|
static void handle_request_configure(struct wl_listener *listener, void *data) {
|
||||||
struct sway_xwayland_view *xwayland_view =
|
struct sway_xwayland_view *xwayland_view =
|
||||||
wl_container_of(listener, xwayland_view, request_configure);
|
wl_container_of(listener, xwayland_view, request_configure);
|
||||||
|
@ -637,22 +673,14 @@ struct sway_view *view_from_wlr_xwayland_surface(
|
||||||
return xsurface->data;
|
return xsurface->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_xwayland_surface(struct wl_listener *listener, void *data) {
|
struct sway_xwayland_view *create_xwayland_view(struct wlr_xwayland_surface *xsurface) {
|
||||||
struct wlr_xwayland_surface *xsurface = data;
|
|
||||||
|
|
||||||
if (xsurface->override_redirect) {
|
|
||||||
sway_log(SWAY_DEBUG, "New xwayland unmanaged surface");
|
|
||||||
create_unmanaged(xsurface);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sway_log(SWAY_DEBUG, "New xwayland surface title='%s' class='%s'",
|
sway_log(SWAY_DEBUG, "New xwayland surface title='%s' class='%s'",
|
||||||
xsurface->title, xsurface->class);
|
xsurface->title, xsurface->class);
|
||||||
|
|
||||||
struct sway_xwayland_view *xwayland_view =
|
struct sway_xwayland_view *xwayland_view =
|
||||||
calloc(1, sizeof(struct sway_xwayland_view));
|
calloc(1, sizeof(struct sway_xwayland_view));
|
||||||
if (!sway_assert(xwayland_view, "Failed to allocate view")) {
|
if (!sway_assert(xwayland_view, "Failed to allocate view")) {
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
view_init(&xwayland_view->view, SWAY_VIEW_XWAYLAND, &view_impl);
|
view_init(&xwayland_view->view, SWAY_VIEW_XWAYLAND, &view_impl);
|
||||||
|
@ -711,7 +739,25 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
|
||||||
wl_signal_add(&xsurface->events.map, &xwayland_view->map);
|
wl_signal_add(&xsurface->events.map, &xwayland_view->map);
|
||||||
xwayland_view->map.notify = handle_map;
|
xwayland_view->map.notify = handle_map;
|
||||||
|
|
||||||
|
wl_signal_add(&xsurface->events.set_override_redirect,
|
||||||
|
&xwayland_view->override_redirect);
|
||||||
|
xwayland_view->override_redirect.notify = handle_override_redirect;
|
||||||
|
|
||||||
xsurface->data = xwayland_view;
|
xsurface->data = xwayland_view;
|
||||||
|
|
||||||
|
return xwayland_view;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_xwayland_surface(struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_xwayland_surface *xsurface = data;
|
||||||
|
|
||||||
|
if (xsurface->override_redirect) {
|
||||||
|
sway_log(SWAY_DEBUG, "New xwayland unmanaged surface");
|
||||||
|
create_unmanaged(xsurface);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_xwayland_view(xsurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_xwayland_ready(struct wl_listener *listener, void *data) {
|
void handle_xwayland_ready(struct wl_listener *listener, void *data) {
|
||||||
|
|
Loading…
Reference in a new issue