Implement popup_during_fullscreen

This introduces a new view_impl function: is_transient_for. Similar to
container_has_ancestor but works using the surface parents rather than
the tree.

This patch modifies view_is_visible, container_at and so on to allow
transient views to function normally when they're in front of a
fullscreen view.
This commit is contained in:
Ryan Dwyer 2018-10-07 20:40:05 +10:00
parent 6cb0e58c6d
commit 832ebc8966
16 changed files with 192 additions and 2 deletions

View file

@ -192,6 +192,21 @@ static void for_each_popup(struct sway_view *view,
wlr_xdg_surface_for_each_popup(view->wlr_xdg_surface, iterator, user_data);
}
static bool is_transient_for(struct sway_view *child,
struct sway_view *ancestor) {
if (xdg_shell_view_from_view(child) == NULL) {
return false;
}
struct wlr_xdg_surface *surface = child->wlr_xdg_surface;
while (surface) {
if (surface->toplevel->parent == ancestor->wlr_xdg_surface) {
return true;
}
surface = surface->toplevel->parent;
}
return false;
}
static void _close(struct sway_view *view) {
if (xdg_shell_view_from_view(view) == NULL) {
return;
@ -233,6 +248,7 @@ static const struct sway_view_impl view_impl = {
.wants_floating = wants_floating,
.for_each_surface = for_each_surface,
.for_each_popup = for_each_popup,
.is_transient_for = is_transient_for,
.close = _close,
.close_popups = close_popups,
.destroy = destroy,
@ -385,6 +401,18 @@ static void handle_map(struct wl_listener *listener, void *data) {
view_update_csd_from_client(view, csd);
}
if (config->popup_during_fullscreen == POPUP_LEAVE &&
view->container->workspace &&
view->container->workspace->fullscreen &&
xdg_surface->toplevel->parent) {
struct wlr_xdg_surface *psurface = xdg_surface->toplevel->parent;
struct sway_xdg_shell_view *parent = psurface->data;
struct sway_view *sway_view = &parent->view;
if (sway_view->container && sway_view->container->is_fullscreen) {
container_set_fullscreen(sway_view->container, false);
}
}
if (xdg_surface->toplevel->client_pending.fullscreen) {
container_set_fullscreen(view->container, true);
arrange_workspace(view->container->workspace);
@ -395,6 +423,7 @@ static void handle_map(struct wl_listener *listener, void *data) {
arrange_workspace(view->container->workspace);
}
}
transaction_commit_dirty();
xdg_shell_view->commit.notify = handle_commit;