mirror of
https://github.com/swaywm/sway.git
synced 2026-04-21 06:46:22 -04:00
Handle xwayland OR surfaces with a parent as popups
This commit is contained in:
parent
b757ef94ef
commit
229b7813fe
2 changed files with 56 additions and 1 deletions
|
|
@ -181,6 +181,7 @@ struct sway_xwayland_unmanaged {
|
||||||
struct wl_listener unmap;
|
struct wl_listener unmap;
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
struct wl_listener override_redirect;
|
struct wl_listener override_redirect;
|
||||||
|
struct wl_listener set_parent;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
struct sway_view_child;
|
struct sway_view_child;
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,11 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) {
|
||||||
wl_container_of(listener, surface, map);
|
wl_container_of(listener, surface, map);
|
||||||
struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
|
struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
|
||||||
|
|
||||||
wl_list_insert(root->xwayland_unmanaged.prev, &surface->link);
|
if (xsurface->parent == NULL) {
|
||||||
|
wl_list_insert(root->xwayland_unmanaged.prev, &surface->link);
|
||||||
|
} else {
|
||||||
|
wl_list_init(&surface->link);
|
||||||
|
};
|
||||||
|
|
||||||
wl_signal_add(&xsurface->events.set_geometry, &surface->set_geometry);
|
wl_signal_add(&xsurface->events.set_geometry, &surface->set_geometry);
|
||||||
surface->set_geometry.notify = unmanaged_handle_set_geometry;
|
surface->set_geometry.notify = unmanaged_handle_set_geometry;
|
||||||
|
|
@ -147,6 +151,7 @@ static void unmanaged_handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
wl_list_remove(&surface->destroy.link);
|
wl_list_remove(&surface->destroy.link);
|
||||||
wl_list_remove(&surface->override_redirect.link);
|
wl_list_remove(&surface->override_redirect.link);
|
||||||
wl_list_remove(&surface->request_activate.link);
|
wl_list_remove(&surface->request_activate.link);
|
||||||
|
wl_list_remove(&surface->set_parent.link);
|
||||||
free(surface);
|
free(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,6 +177,17 @@ static void unmanaged_handle_override_redirect(struct wl_listener *listener, voi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void unmanaged_handle_set_parent(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_xwayland_unmanaged *surface = wl_container_of(listener, surface, set_parent);
|
||||||
|
struct wlr_xwayland_surface *xsurface = surface->wlr_xwayland_surface;
|
||||||
|
|
||||||
|
bool mapped = xsurface->mapped;
|
||||||
|
if (mapped) {
|
||||||
|
unmanaged_handle_unmap(&surface->unmap, NULL);
|
||||||
|
unmanaged_handle_map(&surface->map, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 =
|
||||||
|
|
@ -196,6 +212,8 @@ static struct sway_xwayland_unmanaged *create_unmanaged(
|
||||||
surface->override_redirect.notify = unmanaged_handle_override_redirect;
|
surface->override_redirect.notify = unmanaged_handle_override_redirect;
|
||||||
wl_signal_add(&xsurface->events.request_activate, &surface->request_activate);
|
wl_signal_add(&xsurface->events.request_activate, &surface->request_activate);
|
||||||
surface->request_activate.notify = unmanaged_handle_request_activate;
|
surface->request_activate.notify = unmanaged_handle_request_activate;
|
||||||
|
wl_signal_add(&xsurface->events.set_parent, &surface->set_parent);
|
||||||
|
surface->set_parent.notify = unmanaged_handle_set_parent;
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
@ -335,6 +353,41 @@ static void handle_set_decorations(struct wl_listener *listener, void *data) {
|
||||||
view_update_csd_from_client(view, csd);
|
view_update_csd_from_client(view, csd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct xwayland_surface_iterator_data {
|
||||||
|
wlr_surface_iterator_func_t user_iterator;
|
||||||
|
void *user_data;
|
||||||
|
int x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void xwayland_surface_iterator(struct wlr_surface *surface,
|
||||||
|
int sx, int sy, void *data) {
|
||||||
|
struct xwayland_surface_iterator_data *iter_data = data;
|
||||||
|
iter_data->user_iterator(surface, iter_data->x + sx, iter_data->y + sy,
|
||||||
|
iter_data->user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void for_each_popup_surface(struct sway_view *view,
|
||||||
|
wlr_surface_iterator_func_t iterator, void *user_data) {
|
||||||
|
if (xwayland_view_from_view(view) == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
|
||||||
|
struct wlr_xwayland_surface *child;
|
||||||
|
sway_log(SWAY_INFO, "iterating popups for %d", xsurface->window_id);
|
||||||
|
wl_list_for_each(child, &xsurface->children, parent_link) {
|
||||||
|
if (!child->override_redirect || !child->mapped) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sway_log(SWAY_INFO, "found popup %d", child->window_id);
|
||||||
|
struct xwayland_surface_iterator_data data = {
|
||||||
|
.user_iterator = iterator,
|
||||||
|
.user_data = user_data,
|
||||||
|
.x = child->x - xsurface->x, .y = child->y - xsurface->y,
|
||||||
|
};
|
||||||
|
wlr_surface_for_each_surface(child->surface, xwayland_surface_iterator, &data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool is_transient_for(struct sway_view *child,
|
static bool is_transient_for(struct sway_view *child,
|
||||||
struct sway_view *ancestor) {
|
struct sway_view *ancestor) {
|
||||||
if (xwayland_view_from_view(child) == NULL) {
|
if (xwayland_view_from_view(child) == NULL) {
|
||||||
|
|
@ -393,6 +446,7 @@ static const struct sway_view_impl view_impl = {
|
||||||
.set_tiled = set_tiled,
|
.set_tiled = set_tiled,
|
||||||
.set_fullscreen = set_fullscreen,
|
.set_fullscreen = set_fullscreen,
|
||||||
.wants_floating = wants_floating,
|
.wants_floating = wants_floating,
|
||||||
|
.for_each_popup_surface = for_each_popup_surface,
|
||||||
.is_transient_for = is_transient_for,
|
.is_transient_for = is_transient_for,
|
||||||
.close = _close,
|
.close = _close,
|
||||||
.destroy = destroy,
|
.destroy = destroy,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue