Skip to content

Role re-assignment Before Destruction Not Detected #1679

@Riolku

Description

@Riolku

Coming from YaLTeR/niri#1274.

Smithay doesn't detect when surfaces are re-assigned the same role, without the old role object being destroyed.

A MWE is attached below that crashes latest Niri. A similar MWE is in the linked issue for XDG surfaces.

The issue is that PrivateSurfaceData::set_role does not ensure that the role object attached to this surface has since been destroyed. I was going to file a PR, but I don't see how to access the active role object (is this not exposed?).

More seriously, Smithay is outside of spec for XDG surfaces as far as I can tell.

It is illegal to create an xdg_surface for a wl_surface which already has an assigned role and this will result in a role error.

But we don't deny this, even if the old XDG surface is destroyed.

[package]
name = "mwe"
version = "0.1.0"
edition = "2021"

[dependencies]
wayrs-client = "1.3.0"
wayrs-protocols = { version = "0.14.7", features = ["wlr-layer-shell-unstable-v1", "xdg-shell"] }

XDG Shell MWE:

use wayrs_protocols::xdg_shell::XdgWmBase;
use wayrs_client::protocol::WlCompositor;
use wayrs_client::Connection;

fn main() {
    let mut conn: Connection<()> = Connection::connect().expect("Connection failed");
    conn.blocking_roundtrip().expect("Roundtrip failed");

    let compositor: WlCompositor = conn.bind_singleton(1..=6).expect("Failed to bind compositor");
    let wm_base: XdgWmBase = conn.bind_singleton(1).expect("Failed to bind wm_base");

    let surface = compositor.create_surface(&mut conn);
    wm_base.get_xdg_surface(&mut conn, surface);
    wm_base.get_xdg_surface(&mut conn, surface);

    surface.commit(&mut conn);

    conn.blocking_roundtrip().expect("Roundtrip failed");
}

Layer Shell MWE:

use wayrs_protocols::wlr_layer_shell_unstable_v1::zwlr_layer_shell_v1::Layer;
use wayrs_protocols::wlr_layer_shell_unstable_v1::ZwlrLayerShellV1;
use wayrs_client::protocol::WlCompositor;
use wayrs_client::Connection;

fn main() {
    let mut conn: Connection<()> = Connection::connect().expect("Connection failed");
    conn.blocking_roundtrip().expect("Roundtrip failed");

    let compositor: WlCompositor = conn.bind_singleton(1..=6).expect("Failed to bind compositor");
    let layer_shell: ZwlrLayerShellV1 = conn.bind_singleton(1).expect("Failed to bind layershell");

    let surface = compositor.create_surface(&mut conn);
    layer_shell.get_layer_surface(&mut conn, surface, None, Layer::Background, c"background".into());

    layer_shell.get_layer_surface(&mut conn, surface, None, Layer::Background, c"background".into());

    conn.blocking_roundtrip().expect("Roundtrip failed");
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions