Fix menu rendering: create real frame_bufs for child windows
Child windows (menu content area, titlebar, resizebar) need their own pixman buffers for painting. Previously frame_create_child returned a bare synthetic ID with no buffer, so menu_paint_entry found nothing. Also add parent-child tracking: when a parent frame moves or maps, all children are repositioned/enabled automatically. Children store their relative offset and parent ID.
This commit is contained in:
parent
01bed8bdd3
commit
7921d2def8
|
|
@ -282,7 +282,9 @@ struct wl_frame_buf {
|
|||
pixman_image_t *image; /* ARGB32 pixel data */
|
||||
struct wlr_scene_buffer *scene_buf; /* scene graph node */
|
||||
WNativeWindow id; /* synthetic ID (>= 0x10000000) */
|
||||
WNativeWindow parent_id; /* parent frame_buf ID (0 = root) */
|
||||
int x, y; /* position in output coords */
|
||||
int rel_x, rel_y; /* position relative to parent */
|
||||
int width, height;
|
||||
struct wl_list link; /* wl_state.frame_list */
|
||||
};
|
||||
|
|
@ -3596,12 +3598,51 @@ static WNativeWindow
|
|||
wl_frame_create_child(WNativeWindow parent_win, WScreen *scr,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
(void)parent_win; (void)scr;
|
||||
(void)x; (void)y; (void)width; (void)height;
|
||||
/* Child windows (titlebar, buttons, resizebar) are sub-regions of the
|
||||
* parent frame buffer. Return a synthetic ID so context_save works,
|
||||
* but no separate buffer is needed — frame_paint renders everything. */
|
||||
return wl_state.next_synthetic_id++;
|
||||
(void)scr;
|
||||
|
||||
if (width <= 0) width = 1;
|
||||
if (height <= 0) height = 1;
|
||||
|
||||
/* Compute absolute position from parent */
|
||||
int abs_x = x, abs_y = y;
|
||||
struct wl_frame_buf *parent = frame_buf_find(parent_win);
|
||||
if (parent) {
|
||||
abs_x = parent->x + x;
|
||||
abs_y = parent->y + y;
|
||||
}
|
||||
|
||||
struct wl_frame_buf *fb = wmalloc(sizeof(*fb));
|
||||
memset(fb, 0, sizeof(*fb));
|
||||
|
||||
fb->image = pixman_image_create_bits(PIXMAN_a8r8g8b8,
|
||||
width, height, NULL, 0);
|
||||
if (!fb->image) {
|
||||
wfree(fb);
|
||||
return WNATIVE_NONE;
|
||||
}
|
||||
|
||||
wlr_buffer_init(&fb->base, &frame_buf_impl, width, height);
|
||||
|
||||
fb->id = wl_state.next_synthetic_id++;
|
||||
fb->parent_id = parent_win;
|
||||
fb->rel_x = x;
|
||||
fb->rel_y = y;
|
||||
fb->x = abs_x;
|
||||
fb->y = abs_y;
|
||||
fb->width = width;
|
||||
fb->height = height;
|
||||
|
||||
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_position(&fb->scene_buf->node, abs_x, abs_y);
|
||||
wlr_scene_node_set_enabled(&fb->scene_buf->node, false);
|
||||
}
|
||||
}
|
||||
|
||||
wl_list_insert(&wl_state.frame_list, &fb->link);
|
||||
return fb->id;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -5294,10 +5335,16 @@ wl_window_map(WNativeWindow win)
|
|||
wlr_scene_node_set_enabled(&v->scene_node->node, true);
|
||||
return;
|
||||
}
|
||||
/* Frame buffer: enable its scene node. */
|
||||
/* Frame buffer: enable its scene node and children. */
|
||||
struct wl_frame_buf *fb = frame_buf_find(win);
|
||||
if (fb && fb->scene_buf) {
|
||||
wlr_scene_node_set_enabled(&fb->scene_buf->node, true);
|
||||
/* Also enable children */
|
||||
struct wl_frame_buf *child;
|
||||
wl_list_for_each(child, &wl_state.frame_list, link) {
|
||||
if (child->parent_id == win && child->scene_buf)
|
||||
wlr_scene_node_set_enabled(&child->scene_buf->node, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -5355,6 +5402,17 @@ 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 */
|
||||
struct wl_frame_buf *child;
|
||||
wl_list_for_each(child, &wl_state.frame_list, link) {
|
||||
if (child->parent_id == win) {
|
||||
child->x = x + child->rel_x;
|
||||
child->y = y + child->rel_y;
|
||||
if (child->scene_buf)
|
||||
wlr_scene_node_set_position(&child->scene_buf->node,
|
||||
child->x, child->y);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue