diff --git a/src/backend/wayland/wl_screen.c b/src/backend/wayland/wl_screen.c index 5e8a355..c936e0f 100644 --- a/src/backend/wayland/wl_screen.c +++ b/src/backend/wayland/wl_screen.c @@ -503,8 +503,8 @@ wl_screen_create_internals(WScreen *scr) dsfb->id = wl_state.next_synthetic_id++; dsfb->width = sz; dsfb->height = sz; - struct wlr_scene_tree *ds_parent = wl_state.level_trees[WL_LAYER_NORMAL] - ? wl_state.level_trees[WL_LAYER_NORMAL] : &wl_state.scene->tree; + struct wlr_scene_tree *ds_parent = wl_state.level_trees[WL_LAYER_FLOATING] + ? wl_state.level_trees[WL_LAYER_FLOATING] : &wl_state.scene->tree; dsfb->tree = wlr_scene_tree_create(ds_parent); if (dsfb->tree) { dsfb->scene_buf = wlr_scene_buffer_create(dsfb->tree, &dsfb->base); diff --git a/src/backend/wayland/wl_stacking.c b/src/backend/wayland/wl_stacking.c index 320ab37..1c2b4e6 100644 --- a/src/backend/wayland/wl_stacking.c +++ b/src/backend/wayland/wl_stacking.c @@ -124,30 +124,36 @@ wl_stacking_restack(WNativeWindow *windows, int count) * Process bottom-to-top: last raise_to_top call wins, so the * window at index 0 ends up on top within its level bucket. * - * Each window is represented by its toplevel frame_buf ID. We - * raise fb->tree — the grouping tree that owns both the frame - * pixel buffer and the reparented client surface — so the entire - * window moves as one atomic unit. Child frame_bufs (titlebar, - * resizebar) are already children of fb->tree and move with it. */ + * When windows span different parent trees (level buckets), + * raise_to_top only orders within a parent. Use place_below + * for cross-parent ordering of adjacent entries. */ int i; - for (i = count - 1; i >= 0; i--) { + /* Collect nodes */ + struct wlr_scene_node *nodes[64]; + int n = 0; + for (i = 0; i < count && n < 64; i++) { WNativeWindow win = windows[i]; struct wl_frame_buf *fb = frame_buf_find(win); + struct wlr_scene_node *node = NULL; if (fb) { - /* Raise the grouping tree: moves frame + client together. */ - if (fb->tree) - wlr_scene_node_raise_to_top(&fb->tree->node); - else if (fb->scene_buf) - wlr_scene_node_raise_to_top(&fb->scene_buf->node); - continue; + node = fb->tree ? &fb->tree->node : (fb->scene_buf ? &fb->scene_buf->node : NULL); + } else { + struct wl_toplevel_view *v = wl_find_view_by_id(win); + if (v && v->scene_node) + node = &v->scene_node->node; } - /* Fallback: unframed toplevel view (no frame_buf). */ - struct wl_toplevel_view *v = wl_find_view_by_id(win); - if (v) { - wl_list_remove(&v->link); - wl_list_insert(&wl_state.toplevel_list, &v->link); - if (v->scene_node) - wlr_scene_node_raise_to_top(&v->scene_node->node); + if (node) nodes[n++] = node; + } + /* Place in order: nodes[0] on top, nodes[n-1] on bottom. + * Raise top node, then place each subsequent one below its predecessor. */ + for (i = 0; i < n; i++) { + if (i == 0) { + wlr_scene_node_raise_to_top(nodes[i]); + } else { + /* Reparent to same parent if needed for place_below to work */ + if (nodes[i]->parent != nodes[i-1]->parent) + wlr_scene_node_reparent(nodes[i], (struct wlr_scene_tree *)nodes[i-1]->parent); + wlr_scene_node_place_below(nodes[i], nodes[i-1]); } } } diff --git a/src/backend/wayland/wl_window.c b/src/backend/wayland/wl_window.c index 5bf93f5..21eac08 100644 --- a/src/backend/wayland/wl_window.c +++ b/src/backend/wayland/wl_window.c @@ -94,12 +94,9 @@ wl_window_map(WNativeWindow win) return; /* parent not visible yet */ } wlr_scene_node_set_enabled(&fb->scene_buf->node, true); - /* Raise the tree (raises entire window assembly together) */ if (fb->tree) { wlr_scene_node_set_enabled(&fb->tree->node, true); - wlr_scene_node_raise_to_top(&fb->tree->node); - } else if (!fb->parent_id) - wlr_scene_node_raise_to_top(&fb->scene_buf->node); + } /* Also enable children (and grandchildren) */ struct wl_frame_buf *child; wl_list_for_each(child, &wl_state.frame_list, link) {