From 47e80a488e6db7bcf2ed1275c969774f76711ec2 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Fri, 20 Oct 2023 21:34:29 -0400 Subject: [PATCH] view: commonize sub-view logic in view_move_to_front/back() The logic was the same for xdg-shell and xwayland views, so move it from the view->impl layer out to the view_move_to_front/back() functions. view->impl->move_to_front/back() still exist for now, in case we want to add xdg/xwayland-specific logic in future, but they now move only one view and not sub-views. --- include/view-impl-common.h | 6 ---- src/view-impl-common.c | 23 --------------- src/view.c | 60 +++++++++++++++++++++++++++++++++----- src/xdg.c | 32 ++------------------ src/xwayland.c | 26 ++--------------- 5 files changed, 57 insertions(+), 90 deletions(-) diff --git a/include/view-impl-common.h b/include/view-impl-common.h index 7e75b048..4b9569d2 100644 --- a/include/view-impl-common.h +++ b/include/view-impl-common.h @@ -8,16 +8,10 @@ * functions should call these functions. */ -enum z_direction { - LAB_TO_FRONT, - LAB_TO_BACK, -}; - struct view; void view_impl_move_to_front(struct view *view); void view_impl_move_to_back(struct view *view); -void view_impl_move_sub_views(struct view *parent, enum z_direction z_direction); void view_impl_map(struct view *view); void view_impl_unmap(struct view *view); diff --git a/src/view-impl-common.c b/src/view-impl-common.c index cc2109e0..f8bdb3ee 100644 --- a/src/view-impl-common.c +++ b/src/view-impl-common.c @@ -25,29 +25,6 @@ view_impl_move_to_back(struct view *view) wlr_scene_node_lower_to_bottom(&view->scene_tree->node); } -void -view_impl_move_sub_views(struct view *parent, enum z_direction z_direction) -{ - assert(parent); - if (!parent->impl->append_children) { - return; - } - - struct wl_array subviews; - wl_array_init(&subviews); - parent->impl->append_children(parent, &subviews); - - struct view **view; - wl_array_for_each(view, &subviews) { - if (z_direction == LAB_TO_FRONT) { - view_impl_move_to_front(*view); - } else if (z_direction == LAB_TO_BACK) { - view_impl_move_to_back(*view); - } - } - wl_array_release(&subviews); -} - void view_impl_map(struct view *view) { diff --git a/src/view.c b/src/view.c index e85ffab1..38cac17e 100644 --- a/src/view.c +++ b/src/view.c @@ -1325,24 +1325,70 @@ view_snap_to_region(struct view *view, struct region *region, view_apply_region_geometry(view); } +static void +for_each_subview(struct view *view, void (*action)(struct view *)) +{ + struct wl_array subviews; + struct view **subview; + + wl_array_init(&subviews); + view_append_children(view, &subviews); + wl_array_for_each(subview, &subviews) { + action(*subview); + } + wl_array_release(&subviews); +} + +static void +move_to_front(struct view *view) +{ + if (view->impl->move_to_front) { + view->impl->move_to_front(view); + } +} + +static void +move_to_back(struct view *view) +{ + if (view->impl->move_to_back) { + view->impl->move_to_back(view); + } +} + +/* + * In the view_move_to_{front,back} functions, a modal dialog is always + * shown above its parent window, and the two always move together, so + * other windows cannot come between them. + * This is consistent with GTK3/Qt5 applications on mutter and openbox. + */ void view_move_to_front(struct view *view) { assert(view); - if (view->impl->move_to_front) { - view->impl->move_to_front(view); - cursor_update_focus(view->server); + struct view *root = view_get_root(view); + assert(root); + + move_to_front(root); + for_each_subview(root, move_to_front); + /* make sure view is in front of other sub-views */ + if (view != root) { + move_to_front(view); } + + cursor_update_focus(view->server); } void view_move_to_back(struct view *view) { assert(view); - if (view->impl->move_to_back) { - view->impl->move_to_back(view); - cursor_update_focus(view->server); - } + struct view *root = view_get_root(view); + assert(root); + + for_each_subview(root, move_to_back); + move_to_back(root); + + cursor_update_focus(view->server); } struct view * diff --git a/src/xdg.c b/src/xdg.c index 6c4a87e8..f63647e1 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -341,34 +341,6 @@ xdg_toplevel_view_get_root(struct view *view) return (struct view *)surface->data; } -/* - * In the view_move_to_{front,back} functions, a modal dialog is always shown - * above its parent window, and the two always move together, so other window - * cannot come between them. - * This is consistent with GTK3/Qt5 applications on mutter and openbox. - */ -static void -xdg_toplevel_view_move_to_front(struct view *view) -{ - struct view *root = xdg_toplevel_view_get_root(view); - /* FIXME: this exact code is repeated in xwayland.c */ - view_impl_move_to_front(root); - view_impl_move_sub_views(root, LAB_TO_FRONT); - /* make sure view is in front of other sub-views */ - if (view != root) { - view_impl_move_to_front(view); - } -} - -static void -xdg_toplevel_view_move_to_back(struct view *view) -{ - struct view *root = xdg_toplevel_view_get_root(view); - /* FIXME: this exact code is repeated in xwayland.c */ - view_impl_move_sub_views(root, LAB_TO_BACK); - view_impl_move_to_back(root); -} - static void xdg_toplevel_view_append_children(struct view *self, struct wl_array *children) { @@ -576,8 +548,8 @@ static const struct view_impl xdg_toplevel_view_impl = { .unmap = xdg_toplevel_view_unmap, .maximize = xdg_toplevel_view_maximize, .minimize = xdg_toplevel_view_minimize, - .move_to_front = xdg_toplevel_view_move_to_front, - .move_to_back = xdg_toplevel_view_move_to_back, + .move_to_front = view_impl_move_to_front, + .move_to_back = view_impl_move_to_back, .get_root = xdg_toplevel_view_get_root, .append_children = xdg_toplevel_view_append_children, }; diff --git a/src/xwayland.c b/src/xwayland.c index e6dfe5ed..c0613551 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -642,28 +642,6 @@ xwayland_view_get_root(struct view *view) return (struct view *)root->data; } -static void -xwayland_view_move_to_front(struct view *view) -{ - struct view *root = xwayland_view_get_root(view); - /* FIXME: this exact code is repeated in xdg.c */ - view_impl_move_to_front(root); - view_impl_move_sub_views(root, LAB_TO_FRONT); - /* make sure view is in front of other sub-views */ - if (view != root) { - view_impl_move_to_front(view); - } -} - -static void -xwayland_view_move_to_back(struct view *view) -{ - struct view *root = xwayland_view_get_root(view); - /* FIXME: this exact code is repeated in xdg.c */ - view_impl_move_sub_views(root, LAB_TO_BACK); - view_impl_move_to_back(root); -} - static void xwayland_view_append_children(struct view *self, struct wl_array *children) { @@ -749,8 +727,8 @@ static const struct view_impl xwayland_view_impl = { .unmap = xwayland_view_unmap, .maximize = xwayland_view_maximize, .minimize = xwayland_view_minimize, - .move_to_front = xwayland_view_move_to_front, - .move_to_back = xwayland_view_move_to_back, + .move_to_front = view_impl_move_to_front, + .move_to_back = view_impl_move_to_back, .get_root = xwayland_view_get_root, .append_children = xwayland_view_append_children, .is_related = xwayland_view_is_related, -- 2.52.0