Keep overlay popups above top-layer surfaces

9b10a62777d5b7f43f7a9a470a500e0f4f69c5c2
Alexis Sellier committed ago 1 parent 48e74466
swm.c +9 -4
2480 2480
    if (!is_virtual)
2481 2481
        wlr_seat_set_keyboard(seat, &group->wlr_group->keyboard);
2482 2482
    return group;
2483 2483
}
2484 2484
2485 +
/* Choose the layer that contains popups belonging to a layer-shell surface. */
2486 +
static struct wlr_scene_tree *layer_popup_parent(struct wlr_layer_surface_v1 *layer_surface) {
2487 +
    struct wlr_scene_tree *scene_layer = layers[layermap[layer_surface->pending.layer]];
2488 +
2489 +
    return layer_surface->pending.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP ? layers[LAYER_TOP]
2490 +
                                                                        : scene_layer;
2491 +
}
2492 +
2485 2493
/* Add a new panel, background, or overlay surface to its display. */
2486 2494
void create_layer_surface(struct wl_listener *listener, void *data) {
2487 2495
    struct wlr_layer_surface_v1 *layer_surface = data;
2488 2496
    layer_surface_t             *l;
2489 2497
    const layer_rule_t          *r;
2529 2537
        }
2530 2538
        wlr_scene_node_place_below(&l->dim->node, &l->scene->node);
2531 2539
        wlr_scene_node_set_enabled(&l->dim->node, 0);
2532 2540
        break;
2533 2541
    }
2534 -
    l->popups = wlr_scene_tree_create(
2535 -
        layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP ? layers[LAYER_TOP]
2536 -
                                                                     : scene_layer
2537 -
    );
2542 +
    l->popups = wlr_scene_tree_create(layer_popup_parent(layer_surface));
2538 2543
2539 2544
    if (!l->popups) {
2540 2545
        if (l->dim)
2541 2546
            wlr_scene_node_destroy(&l->dim->node);
2542 2547
        wlr_scene_node_destroy(&l->scene->node);
test/unit.c +13 -0
349 349
    assert(fractional_scale == 2.5f);
350 350
    assert(buffer_scale == 3);
351 351
    wl_list_remove(&client.link);
352 352
}
353 353
354 +
/* Verify overlay surfaces create their popups in the overlay scene layer. */
355 +
static void test_layer_popup_parent(void) {
356 +
    struct wlr_layer_surface_v1 layer = {};
357 +
    struct wlr_scene_tree       top = {}, overlay = {};
358 +
359 +
    layers[LAYER_TOP]     = &top;
360 +
    layers[LAYER_OVERLAY] = &overlay;
361 +
    layer.current.layer   = ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND;
362 +
    layer.pending.layer   = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY;
363 +
    assert(layer_popup_parent(&layer) == &overlay);
364 +
}
365 +
354 366
/* Verify matching rules update client state and workspace assignment. */
355 367
static void test_rule_application(void) {
356 368
    client_t                client;
357 369
    struct wlr_xdg_surface  surface;
358 370
    struct wlr_xdg_toplevel toplevel;
1051 1063
        { "paths-and-borders", test_paths_and_border_policy },
1052 1064
        { "rules", test_rule_application },
1053 1065
        { "focus", test_focus_queries },
1054 1066
        { "workspace-scale", test_workspace_scale },
1055 1067
        { "output-scale-change", test_output_scale_change },
1068 +
        { "layer-popup-parent", test_layer_popup_parent },
1056 1069
        { "window-state", test_window_state_storage },
1057 1070
        { "child-reaping", test_child_reaping },
1058 1071
        { "spawn-tracking", test_spawn_tracking },
1059 1072
        { "layer-unmap-monitor", test_layer_unmap_monitor },
1060 1073
        { "command-failure-notification", test_command_failure_notification },