diff --git a/src/backend/wayland/wl_client.c b/src/backend/wayland/wl_client.c index a919818..94349db 100644 --- a/src/backend/wayland/wl_client.c +++ b/src/backend/wayland/wl_client.c @@ -86,6 +86,15 @@ wl_client_reparent(WNativeWindow client, WNativeWindow new_parent, int x, int y) wlr_scene_node_reparent(&v->scene_node->node, parent_fb->tree); /* Position at relative offset within the tree */ wlr_scene_node_set_position(&v->scene_node->node, x, y); + /* Raise above frame decoration (icon tile background) */ + wlr_scene_node_raise_to_top(&v->scene_node->node); + wwarning("wl_client_reparent: view 0x%lx scene_node reparented to frame 0x%lx tree=%p at (%d,%d) enabled=%d", + (unsigned long)client, (unsigned long)new_parent, + (void*)parent_fb->tree, x, y, + v->scene_node->node.enabled); + } else { + wwarning("wl_client_reparent: view 0x%lx has NO scene_node, frame 0x%lx", + (unsigned long)client, (unsigned long)new_parent); } } return; @@ -108,6 +117,35 @@ wl_client_reparent(WNativeWindow client, WNativeWindow new_parent, int x, int y) } } + /* XWayland child window (e.g. dockapp icon_window 0x400011) that has + * no separate wlr_xwayland_surface. XWayland composites it into the + * parent surface. Find the parent toplevel whose children list + * contains this window ID and reparent it into the dock tile. */ + if (client > 0 && client < 0x10000000) { + struct wl_frame_buf *parent_fb = frame_buf_find(new_parent); + if (parent_fb && parent_fb->tree) { + struct wl_toplevel_view *tv; + wl_list_for_each(tv, &wl_state.toplevel_list, link) { + if (!tv->xw_surface || !tv->scene_node) + continue; + /* Check if 'client' is a child of this surface */ + struct wlr_xwayland_surface *child; + wl_list_for_each(child, &tv->xw_surface->children, parent_link) { + if (child->window_id == (xcb_window_t)client) { + wlr_scene_node_reparent(&tv->scene_node->node, parent_fb->tree); + wlr_scene_node_set_position(&tv->scene_node->node, x, y); + tv->frame_id = new_parent; + tv->frame_rel_x = x; + tv->frame_rel_y = y; + tv->x = parent_fb->x + x; + tv->y = parent_fb->y + y; + return; + } + } + } + } + } + /* Reparent to root = dialog teardown: destroy the child frame_buf */ diff --git a/src/backend/wayland/wl_window.c b/src/backend/wayland/wl_window.c index 1919039..ef59434 100644 --- a/src/backend/wayland/wl_window.c +++ b/src/backend/wayland/wl_window.c @@ -166,7 +166,10 @@ wl_window_unmap(WNativeWindow win) { struct wl_toplevel_view *v = wl_find_view_by_id(win); if (v && v->scene_node) { - wlr_scene_node_set_enabled(&v->scene_node->node, false); + /* Don't disable if reparented into a frame_buf (e.g. dockapp in + * dock tile) — the frame's tree controls visibility. */ + if (!v->frame_id) + wlr_scene_node_set_enabled(&v->scene_node->node, false); return; } struct wl_frame_buf *fb = frame_buf_find(win); diff --git a/src/icon.c b/src/icon.c index 4b7ed18..c77e131 100644 --- a/src/icon.c +++ b/src/icon.c @@ -811,10 +811,18 @@ static void set_dockapp_in_icon(WIcon *icon) /* Set the icon border */ wm_backend->window_set_border_width((WNativeWindow)icon->icon_win, 0); - /* Put the dock application in the icon */ - wm_backend->client_reparent((WNativeWindow)icon->icon_win, icon->core->window, - (wPreferences.icon_size - w) / 2, - (wPreferences.icon_size - h) / 2); + /* Put the dock application in the icon. + * On Wayland, the icon_win child window has no separate surface — + * XWayland composites it into the parent toplevel. Reparent the + * owner's main client_win instead so its surface appears in the tile. */ + { + WNativeWindow reparent_win = (WNativeWindow)icon->icon_win; + if (icon->owner && icon->owner->client_win) + reparent_win = icon->owner->client_win; + wm_backend->client_reparent(reparent_win, icon->core->window, + (wPreferences.icon_size - w) / 2, + (wPreferences.icon_size - h) / 2); + } /* Show it and save */ wm_backend->window_map((WNativeWindow)icon->icon_win);