* 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);
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)
{
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 *
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)
{
.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,
};
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)
{
.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,