swayfx-mosaic/tooling/probes/step20c-valid-grab/hidden-guard.patch

32 lines
1.4 KiB
Diff

--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -1069,6 +1069,29 @@
wlr_scene_tree_set_clip(popup_tree, &empty);
return;
}
+ // EXPERIMENTAL INVARIANT: the viewport alone does not imply that its
+ // popup owner is visible. Use the already-applied scene position and size,
+ // not pending layout geometry, to suppress a fully hidden owner's popup.
+ int owner_x = INT_MIN, owner_y = INT_MIN;
+ struct wlr_box owner_visible;
+ if (!wlr_scene_node_coords(&owner->scene_tree->node, &owner_x, &owner_y) ||
+ owner->animation_state.current_width <= 0 ||
+ owner->animation_state.current_height <= 0 ||
+ !wlr_box_intersection(&owner_visible, &global,
+ &(struct wlr_box){
+ .x = owner_x, .y = owner_y,
+ .width = owner->animation_state.current_width,
+ .height = owner->animation_state.current_height,
+ })) {
+ struct wlr_box empty = {0};
+ wlr_scene_tree_set_clip(popup_tree, &empty);
+ sway_log(SWAY_INFO, "PROBE_POPUP_HIDDEN_OWNER owner=%p applied=%d,%d %dx%d viewport=%d,%d %dx%d",
+ (void *)con, owner_x, owner_y,
+ owner->animation_state.current_width,
+ owner->animation_state.current_height,
+ global.x, global.y, global.width, global.height);
+ return;
+ }
int64_t px = (int64_t)global.x - popup_x;
int64_t py = (int64_t)global.y - popup_y;
if (px < INT_MIN || px > INT_MAX || py < INT_MIN || py > INT_MAX) {