diff --git a/clients/linux/src/app.rs b/clients/linux/src/app.rs index fe4315cd..33ebc540 100644 --- a/clients/linux/src/app.rs +++ b/clients/linux/src/app.rs @@ -23,6 +23,10 @@ pub const APP_ID: &str = "io.unom.Punktfunk"; /// named palette so dark mode just works. const CSS: &str = " .pf-host-card { padding: 16px; } +/* The FlowBoxChild draws the hover/selection highlight AROUND the card (it wraps it + with its own padding), so its corners must run concentric with the card's 12px — + radius = card radius + the child's padding ring. */ +.pf-host-grid > flowboxchild { border-radius: 15px; } .pf-pill { font-size: 0.72em; font-weight: bold; padding: 2px 10px; border-radius: 999px; color: alpha(currentColor, 0.8); background: alpha(currentColor, 0.1); } .pf-pill.pf-green { color: @success_color; background: alpha(@success_color, 0.15); } diff --git a/clients/linux/src/ui_hosts.rs b/clients/linux/src/ui_hosts.rs index 0e8ee553..847c5134 100644 --- a/clients/linux/src/ui_hosts.rs +++ b/clients/linux/src/ui_hosts.rs @@ -386,7 +386,7 @@ impl SimpleComponent for HostsPage { sender: ComponentSender, ) -> ComponentParts { let make_flow = || { - gtk::FlowBox::builder() + let f = gtk::FlowBox::builder() .selection_mode(gtk::SelectionMode::None) .activate_on_single_click(true) .homogeneous(true) @@ -394,7 +394,10 @@ impl SimpleComponent for HostsPage { .max_children_per_line(4) .column_spacing(12) .row_spacing(12) - .build() + .build(); + // Scopes the concentric hover-highlight radius (see app.rs CSS). + f.add_css_class("pf-host-grid"); + f }; let heading = |text: &str| { let l = gtk::Label::new(Some(text)); diff --git a/docs-site/content/docs/hyprland.md b/docs-site/content/docs/hyprland.md index fa6fcd06..d58c8182 100644 --- a/docs-site/content/docs/hyprland.md +++ b/docs-site/content/docs/hyprland.md @@ -50,12 +50,23 @@ For how long the virtual output lives, and extend-vs-exclusive topology, see ## Requirements -- A running Hyprland session (any recent release; validate on both a ≤ 0.54 and a ≥ 0.55 install). +- A running Hyprland session (the `hyprctl`/xdph contracts are verified on **0.55.4**; older + releases share the same `hyprctl` surface). - **xdg-desktop-portal-hyprland (xdph)** installed and running — the host captures through its ScreenCast portal, and steers its custom picker. Without it there is no video. - The ScreenCast interface routed to xdph — see `scripts/headless/portals.conf` (a `[Hyprland]` section pins `org.freedesktop.impl.portal.ScreenCast=hyprland`). +## Troubleshooting: black / no video (headless output at 0×0) + +A headless output only gets a framebuffer once the compositor can allocate one. On some GPU/driver +combinations (notably NVIDIA, and in nested test setups) that GBM/dmabuf allocation fails and the +output stays `0×0` — you'll see `GBM: Failed to allocate a GBM buffer: bo null` in the Hyprland log +(cf. [Sunshine #4197](https://github.com/LizardByte/Sunshine/issues/4197)). The host detects this +and fails the session with a clear error rather than streaming a blank surface. If you hit it, +capture the Hyprland log (`hyprctl` instance dir → `hyprland.log`) and check your GPU's GBM support; +running Hyprland as a real session (not nested) is the supported configuration. + ## Permission system Hyprland's permission system (`ecosystem.enforce_permissions`, 0.49+, **off by default**) can deny