Make dialogs visible: fake_leader, recursive reparent/map/move

- fake_leader_create: return a real frame_buf ID (was returning 0)
- client_reparent: handle frame_buf-to-frame_buf reparenting
- client_reparent: get WINGs view size from view table
- window_map: enable grandchildren (dialog content is grandchild of frame)
- window_move: move grandchildren when parent moves
- dialog.c: guard scr->w_visual for Wayland mode in Info panel
This commit is contained in:
Levi Neely 2026-05-13 19:45:41 +02:00
parent 9191f12913
commit 6d9450ea8b
1 changed files with 64 additions and 7 deletions

View File

@ -5431,11 +5431,18 @@ wl_window_map(WNativeWindow win)
return; /* parent not visible yet */
}
wlr_scene_node_set_enabled(&fb->scene_buf->node, true);
/* Also enable children */
/* Also enable children (and grandchildren) */
struct wl_frame_buf *child;
wl_list_for_each(child, &wl_state.frame_list, link) {
if (child->parent_id == win && child->scene_buf)
if (child->parent_id == win && child->scene_buf) {
wlr_scene_node_set_enabled(&child->scene_buf->node, true);
/* Enable grandchildren */
struct wl_frame_buf *gc;
wl_list_for_each(gc, &wl_state.frame_list, link) {
if (gc->parent_id == child->id && gc->scene_buf)
wlr_scene_node_set_enabled(&gc->scene_buf->node, true);
}
}
}
return;
}
@ -5500,7 +5507,7 @@ static void wl_window_move(WNativeWindow win, int x, int y)
fb->x = x; fb->y = y;
if (fb->scene_buf)
wlr_scene_node_set_position(&fb->scene_buf->node, x, y);
/* Move children that track this parent */
/* Move children and grandchildren */
struct wl_frame_buf *child;
wl_list_for_each(child, &wl_state.frame_list, link) {
if (child->parent_id == win) {
@ -5509,6 +5516,17 @@ static void wl_window_move(WNativeWindow win, int x, int y)
if (child->scene_buf)
wlr_scene_node_set_position(&child->scene_buf->node,
child->x, child->y);
/* Grandchildren */
struct wl_frame_buf *gc;
wl_list_for_each(gc, &wl_state.frame_list, link) {
if (gc->parent_id == child->id) {
gc->x = child->x + gc->rel_x;
gc->y = child->y + gc->rel_y;
if (gc->scene_buf)
wlr_scene_node_set_position(&gc->scene_buf->node,
gc->x, gc->y);
}
}
}
}
return;
@ -5714,6 +5732,7 @@ wl_client_adopt_attributes(WNativeWindow win, unsigned long event_mask)
static void
wl_client_reparent(WNativeWindow client, WNativeWindow new_parent, int x, int y)
{
/* For WINGs internal windows: create a child frame_buf so the dialog
* content is visible in the scene graph. */
if (client >= 0x20000000 && new_parent >= 0x10000000) {
@ -5737,9 +5756,11 @@ wl_client_reparent(WNativeWindow client, WNativeWindow new_parent, int x, int y)
}
/* Create a new frame_buf for this WINGs view.
* We don't know the size yet — use parent's content area. */
int w = parent_fb->width;
int h = parent_fb->height - y;
* Get size from the view itself. */
extern W_View *W_GetViewForWindow(unsigned long id);
W_View *view = W_GetViewForWindow((unsigned long)client);
int w = view ? view->size.width : parent_fb->width;
int h = view ? view->size.height : (parent_fb->height - y);
if (w <= 0) w = 1;
if (h <= 0) h = 1;
@ -5775,6 +5796,20 @@ wl_client_reparent(WNativeWindow client, WNativeWindow new_parent, int x, int y)
extern void W_SetViewBacking(unsigned long id, void *img);
W_SetViewBacking((unsigned long)client, fb->image);
}
/* Reparent an existing frame_buf into a new parent */
else if (client >= 0x10000000 && new_parent >= 0x10000000) {
struct wl_frame_buf *fb = frame_buf_find(client);
struct wl_frame_buf *parent_fb = frame_buf_find(new_parent);
if (fb && parent_fb) {
fb->parent_id = new_parent;
fb->rel_x = x;
fb->rel_y = y;
fb->x = parent_fb->x + x;
fb->y = parent_fb->y + y;
if (fb->scene_buf)
wlr_scene_node_set_position(&fb->scene_buf->node, fb->x, fb->y);
}
}
}
/* Called by WINGs after a view repaints — commit its frame_buf to scene graph */
@ -5923,7 +5958,29 @@ wl_icccm_free_command(char **argv)
/* Fake leader */
/* ------------------------------------------------------------------ */
static WNativeWindow wl_fake_leader_create(WScreen *scr) { (void)scr; return WNATIVE_NONE; }
static WNativeWindow wl_fake_leader_create(WScreen *scr)
{
(void)scr;
/* Create a frame_buf to act as the dialog's content container */
struct wl_frame_buf *fb = wmalloc(sizeof(*fb));
memset(fb, 0, sizeof(*fb));
fb->id = wl_state.next_synthetic_id++;
fb->parent_id = 0;
fb->width = 1;
fb->height = 1;
fb->image = pixman_image_create_bits(PIXMAN_a8r8g8b8, 1, 1, NULL, 0);
wlr_buffer_init(&fb->base, &frame_buf_impl, 1, 1);
if (wl_state.scene) {
fb->scene_buf = wlr_scene_buffer_create(&wl_state.scene->tree, &fb->base);
if (fb->scene_buf)
wlr_scene_node_set_enabled(&fb->scene_buf->node, false);
}
wl_list_insert(&wl_state.frame_list, &fb->link);
return fb->id;
}
static void wl_fake_leader_destroy(WNativeWindow win) { (void)win; }
/* ------------------------------------------------------------------ */