fix: non-responsive WINGs widgets on Wayland (overlapping sibling views + cascade compositing)
This commit is contained in:
parent
6e902db869
commit
86f7510a13
|
|
@ -531,6 +531,52 @@ static void wl_redisplay(void *vctx, W_View *view)
|
|||
0, 0, 0, 0,
|
||||
view->pos.x, view->pos.y, cw, ch);
|
||||
}
|
||||
|
||||
/* Cascade: composite all the way up to the toplevel.
|
||||
*
|
||||
* When wl_redisplay is called directly (depth==1, e.g. from
|
||||
* W_RedisplayView for a slider widget), only the IMMEDIATE
|
||||
* parent's backing is updated above. The toplevel's backing
|
||||
* (shared-memory wl_buffer) remains STALE, so the subsequent
|
||||
* wl_surface.commit shows the old content — widget visual
|
||||
* updates are invisible.
|
||||
*
|
||||
* By continuing the composite up the tree here we propagate
|
||||
* the child's pixel change all the way to the toplevel before
|
||||
* the commit below. We skip the cascade when depth > 1
|
||||
* (recursive call during a full parent→child redisplay)
|
||||
* because the parent will composite all siblings in order
|
||||
* and the depth-1 invocation will handle the cascade once. */
|
||||
if (wl_redisplay_depth == 1) {
|
||||
W_View *v = view->parent;
|
||||
while (v->parent && !v->flags.topLevel) {
|
||||
pixman_image_t *v_src = W_GetViewBacking(v->window);
|
||||
pixman_image_t *v_dst = W_GetViewBacking(v->parent->window);
|
||||
if (v_src && v_dst) {
|
||||
int v_sw = pixman_image_get_width(v_src);
|
||||
int v_sh = pixman_image_get_height(v_src);
|
||||
int v_dw = pixman_image_get_width(v_dst);
|
||||
int v_dh = pixman_image_get_height(v_dst);
|
||||
if (v_sw < 1 || v_sh < 1 || v_dw < 1 || v_dh < 1) {
|
||||
fprintf(stderr, "wl_redisplay cascade: skip zero backing (%p src=%dx%d dst=%dx%d)\n",
|
||||
(void*)v, v_sw, v_sh, v_dw, v_dh);
|
||||
v = v->parent;
|
||||
continue;
|
||||
}
|
||||
int v_cw = v_sw < (int)v->size.width ? v_sw : (int)v->size.width;
|
||||
int v_ch = v_sh < (int)v->size.height ? v_sh : (int)v->size.height;
|
||||
if (v->pos.x + v_cw > v_dw) v_cw = v_dw - v->pos.x;
|
||||
if (v->pos.y + v_ch > v_dh) v_ch = v_dh - v->pos.y;
|
||||
if (v_cw < 0) v_cw = 0;
|
||||
if (v_ch < 0) v_ch = 0;
|
||||
if (v_cw > 0 && v_ch > 0 && v->pos.x >= 0 && v->pos.y >= 0)
|
||||
pixman_image_composite32(PIXMAN_OP_OVER, v_src, NULL, v_dst,
|
||||
0, 0, 0, 0,
|
||||
v->pos.x, v->pos.y, v_cw, v_ch);
|
||||
}
|
||||
v = v->parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Notify WM backend to commit the top-level view's backing buffer */
|
||||
|
|
@ -546,23 +592,32 @@ static void wl_redisplay(void *vctx, W_View *view)
|
|||
wl_redisplay_depth--;
|
||||
}
|
||||
|
||||
/* Find the deepest child view at (x, y) relative to the given view. */
|
||||
/* Find the deepest child view at (x, y) relative to the given view.
|
||||
* When multiple children overlap the same point, prefer the one that
|
||||
* has children (or deeper descendents) over a leaf view, so that
|
||||
* widgets nested inside a sibling that overlaps a parent container
|
||||
* are found correctly on Wayland where subwindows are absent. */
|
||||
W_View *W_FindViewAtPoint(W_View *parent, int x, int y)
|
||||
{
|
||||
if (!parent) return NULL;
|
||||
W_View *best = NULL;
|
||||
W_View *child = parent->childrenList;
|
||||
while (child) {
|
||||
if (child->flags.mapped && child->flags.realized &&
|
||||
x >= child->pos.x && x < child->pos.x + child->size.width &&
|
||||
y >= child->pos.y && y < child->pos.y + child->size.height) {
|
||||
/* Recurse into this child with local coordinates */
|
||||
W_View *deeper = W_FindViewAtPoint(child,
|
||||
x - child->pos.x, y - child->pos.y);
|
||||
return deeper ? deeper : child;
|
||||
if (deeper)
|
||||
return deeper;
|
||||
if (!best)
|
||||
best = child;
|
||||
/* Keep looking — a later sibling at the same coords
|
||||
* may have deeper children. */
|
||||
}
|
||||
child = child->nextSister;
|
||||
}
|
||||
return NULL;
|
||||
return best;
|
||||
}
|
||||
|
||||
static WMPoint wl_get_screen_position(void *vctx, W_View *view)
|
||||
|
|
|
|||
Loading…
Reference in New Issue