Skip to content

Conversation

@glamberson
Copy link

@glamberson glamberson commented Jan 10, 2026

Implements ext-image-capture-source-v1 and ext-image-copy-capture-v1 protocols for screen capture functionality.

Design uses callback-based extensibility with UserDataMap, allowing compositors to attach custom data to capture sources. This enables COSMIC-style workspace capture through custom globals without infecting the core API with generics.

Key changes:

  • Full session/frame lifecycle with RAII cleanup
  • Buffer validation (size, format, modifier) before frame callbacks
  • Cursor session support for pointer capture
  • Anvil integration demonstrating handler implementation

This implementation is adapted from cosmic-comp's screencopy module, originally authored by Victoria Brekenfeld (@Drakulix) and Ian Douglas Scott (@ids1024) at System76. Re-licensed to MIT with their approval per discussion in #1900.

Closes #1900

Implements ext-image-capture-source-v1 and ext-image-copy-capture-v1
protocols for screen capture functionality.

Design uses callback-based extensibility with UserDataMap, allowing
compositors to attach custom data to capture sources. This enables
COSMIC-style workspace capture through custom globals without
infecting the core API with generics.

Key features:
- Full session/frame lifecycle with RAII cleanup
- Buffer validation (size, format, modifier) before frame callbacks
- Cursor session support for pointer capture
- Anvil integration demonstrating handler implementation

Based on cosmic-comp's screencopy implementation by Victoria Brekenfeld
and Ian Douglas Scott at System76.

Closes Smithay#1900
@glamberson glamberson marked this pull request as draft January 10, 2026 15:50
@glamberson glamberson changed the title feat(wayland): implement ext-image-copy-capture-v1 protocol feat(wayland): implement ext-image-capture-source-v1 and ext-image-copy-capture-v1 protocols Jan 10, 2026
@glamberson glamberson marked this pull request as ready for review January 10, 2026 22:31
@glamberson glamberson marked this pull request as draft January 10, 2026 22:31
The get_dmabuf import is only used in validate_dmabuf() which is
gated by #[cfg(feature = "backend_drm")]. Without this gate, the
import is unused when building with use_system_lib but without
backend_drm, causing a compile error with -D warnings.
Split image_capture_source into separate State + Handler per source type:

- ImageCaptureSourceState + ImageCaptureSourceHandler: Core source handling
- OutputCaptureSourceState + OutputCaptureSourceHandler: Output capture
- ToplevelCaptureSourceState + ToplevelCaptureSourceHandler: Toplevel capture

This allows compositors to choose which source types to support independently.
Compositors with custom foreign-toplevel implementations can skip the toplevel
module entirely and handle the protocol directly.

Each module has its own delegate macro for cleaner integration.
Copy link
Member

@Drakulix Drakulix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks mostly good for, I think the latest design iteration covers everything we need for custom implementations.

For merging this still needs a more in-depth review to make sure this covers everything cosmic-comp and potentially niri need.

Which clients did you test the anvil implementation with?

@HigherOrderLogic
Copy link

For merging this still needs a more in-depth review to make sure this covers everything cosmic-comp and potentially niri need.

So is this PR in a "ready" state to implement the protocol in other compositor? I want to implement this protocol in Niri and maybe I'll give it a go with this PR.

@glamberson
Copy link
Author

So is this PR in a "ready" state to implement the protocol in other compositor? I want to implement this protocol in Niri and maybe I'll give it a go with this PR.

Well, yes, presumably, although I"m testing still and can't probably get through all of it until morning.

@ids1024
Copy link
Member

ids1024 commented Jan 14, 2026

So far this looks good. I'm working on updating cosmic-comp's implementation to use this.

@glamberson glamberson marked this pull request as ready for review January 14, 2026 20:30
@glamberson
Copy link
Author

@ids1024 Great. I wanted to run this through testing but I just haven't had a minute to get to it. So I'm going to mark it as ready with the proviso it should undergo more testing.

The BufferConstraints.dma field only exists when smithay is built with
backend_drm. Gate the field assignment in anvil behind the features
that enable backend_drm (udev or winit) to fix --no-default-features build.
@ids1024
Copy link
Member

ids1024 commented Jan 14, 2026

pop-os/cosmic-comp#1995

Seems to be working (though that's not surprising given this is based on the cosmic-comp version).

I was able to adopt the image_capture_source helpers here before the image_copy_capture, so the implementation of image_capture_source is usable even if not using the image_copy_capture support here, which is nice. It also works fine to add our custom workspace capture source on top of it.

So it seems to meet our requirements, and I think should suit the requirements of other compositors.

@chrisduerr
Copy link
Contributor

It also works fine to add our custom workspace capture source on top of it.
So it seems to meet our requirements, and I think should suit the requirements of other compositors.

I've actually been contemplating this for a bit since I'm using screencopy-v1 and I think that's an important feature. While I haven't tried using it there seem to be a lot of desktop abstractions built in by default, so I appreciate that there seems to be an option to bypass that without having to just write the protocol implementation myself.

@glamberson
Copy link
Author

Seems to be working (though that's not surprising given this is based on the cosmic-comp version).
So it seems to meet our requirements, and I think should suit the requirements of other compositors.

Yes this is going to save me a lot of time. Thanks @ids1024 and @Drakulix for allowing me to adapt your work!

External source implementations (e.g., workspace capture) need to call
add_instance() to associate protocol resources with custom sources.
Copy link
Member

@Drakulix Drakulix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR looks good to me and is imo okay to merge now.

Slight but however:

  1. I'd love to see a proper anvil implementation, that doesn't just fail the actual capture. Anvil has a standable render_output-function and the implementation doesn't have to be perfect (anvil itself is far from it). It could simply re-render the output, which would work for all backends.

But our merge-requirement has always been an implementation proving the code works in any compositor. And since @ids1024 already adopted cosmic-comp, this has been done.

  1. I'd like to hear some input on this from @YaLTeR, given niri seems to have some interest in implementing the protocol eventually. Just to hear if the overall design seems to be a good fit for niri now as well.

The x11 feature enables smithay/backend_vulkan which pulls in backend_drm,
so the dma field exists and must be initialized.
@YaLTeR
Copy link
Contributor

YaLTeR commented Jan 15, 2026

I'd like to hear some input on this from @YaLTeR, given niri seems to have some interest in implementing the protocol eventually. Just to hear if the overall design seems to be a good fit for niri now as well.

Looks alright at a glance. I was adding some weird code to my wlr-screencopy impl over the past days but it seems that none of that code is necessary for these ext protocols because of the much improved protocol design. So I expect I'll be able to use this Smithay impl. Can't say definitively without trying though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implementing ext-image-capture-source-v1 and ext-image-copy-capture-v1

7 participants