diff --git a/modules/desktop_capture/desktop_capture_options.h b/modules/desktop_capture/desktop_capture_options.h index 0364517405..67dffee08a 100644 --- a/modules/desktop_capture/desktop_capture_options.h +++ b/modules/desktop_capture/desktop_capture_options.h @@ -105,6 +105,17 @@ class RTC_EXPORT DesktopCaptureOptions { detect_updated_region_ = detect_updated_region; } + // Indicates that the capturer should try to include the cursor in the frame. + // If it is able to do so it will set `DesktopFrame::may_contain_cursor()`. + // Not all capturers will support including the cursor. If this value is false + // or the cursor otherwise cannot be included in the frame, then cursor + // metadata will be sent, though the capturer may choose to always send cursor + // metadata. + bool prefer_cursor_embedded() const { return prefer_cursor_embedded_; } + void set_prefer_cursor_embedded(bool prefer_cursor_embedded) { + prefer_cursor_embedded_ = prefer_cursor_embedded; + } + #if defined(WEBRTC_WIN) // Enumerating windows owned by the current process on Windows has some // complications due to |GetWindowText*()| APIs potentially causing a @@ -237,6 +248,7 @@ class RTC_EXPORT DesktopCaptureOptions { #endif bool disable_effects_ = true; bool detect_updated_region_ = false; + bool prefer_cursor_embedded_ = false; #if defined(WEBRTC_USE_PIPEWIRE) bool allow_pipewire_ = false; bool pipewire_use_damage_region_ = true; diff --git a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc index e9e45b57d2..fce023782f 100644 --- a/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc +++ b/modules/desktop_capture/linux/wayland/base_capturer_pipewire.cc @@ -72,7 +72,8 @@ void BaseCapturerPipeWire::OnScreenCastRequestResult(RequestResponse result, capturer_failed_ = false; if (result != RequestResponse::kSuccess || !options_.screencast_stream()->StartScreenCastStream( - stream_node_id, fd, options_.get_width(), options_.get_height())) { + stream_node_id, fd, options_.get_width(), options_.get_height(), + options_.prefer_cursor_embedded())) { capturer_failed_ = true; RTC_LOG(LS_ERROR) << "ScreenCastPortal failed: " << static_cast(result); diff --git a/modules/desktop_capture/linux/wayland/screencast_portal.cc b/modules/desktop_capture/linux/wayland/screencast_portal.cc index 9848004363..abfade56e7 100644 --- a/modules/desktop_capture/linux/wayland/screencast_portal.cc +++ b/modules/desktop_capture/linux/wayland/screencast_portal.cc @@ -56,9 +56,12 @@ ScreenCastPortal::ScreenCastPortal( PortalNotifier* notifier, ProxyRequestResponseHandler proxy_request_response_handler, SourcesRequestResponseSignalHandler sources_request_response_signal_handler, - gpointer user_data) + gpointer user_data, + bool prefer_cursor_embedded) : notifier_(notifier), capture_source_type_(ToCaptureSourceType(type)), + cursor_mode_(prefer_cursor_embedded ? CursorMode::kEmbedded + : CursorMode::kMetadata), proxy_request_response_handler_(proxy_request_response_handler), sources_request_response_signal_handler_( sources_request_response_signal_handler), diff --git a/modules/desktop_capture/linux/wayland/screencast_portal.h b/modules/desktop_capture/linux/wayland/screencast_portal.h index c54d4821b4..ffb198f387 100644 --- a/modules/desktop_capture/linux/wayland/screencast_portal.h +++ b/modules/desktop_capture/linux/wayland/screencast_portal.h @@ -84,7 +84,10 @@ class ScreenCastPortal : public xdg_portal::ScreenCapturePortalInterface { ProxyRequestResponseHandler proxy_request_response_handler, SourcesRequestResponseSignalHandler sources_request_response_signal_handler, - gpointer user_data); + gpointer user_data, + // TODO(chromium:1291247): Remove the default option once + // downstream has been adjusted. + bool prefer_cursor_embedded = false); ~ScreenCastPortal(); @@ -140,7 +143,7 @@ class ScreenCastPortal : public xdg_portal::ScreenCapturePortalInterface { CaptureSourceType capture_source_type_ = ScreenCastPortal::CaptureSourceType::kScreen; - CursorMode cursor_mode_ = ScreenCastPortal::CursorMode::kMetadata; + CursorMode cursor_mode_ = CursorMode::kMetadata; PersistMode persist_mode_ = ScreenCastPortal::PersistMode::kDoNotPersist; diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc index 53e6fd401d..71bde9b212 100644 --- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc +++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc @@ -77,7 +77,8 @@ class SharedScreenCastStreamPrivate { bool StartScreenCastStream(uint32_t stream_node_id, int fd, uint32_t width = 0, - uint32_t height = 0); + uint32_t height = 0, + bool is_cursor_embedded = false); void UpdateScreenCastStreamResolution(uint32_t width, uint32_t height); void SetUseDamageRegion(bool use_damage_region) { use_damage_region_ = use_damage_region; @@ -143,6 +144,10 @@ class SharedScreenCastStreamPrivate { bool use_damage_region_ = true; + // Specifies whether the pipewire stream has been initialized with a request + // to embed cursor into the captured frames. + bool is_cursor_embedded_ = false; + // event handlers pw_core_events pw_core_events_ = {}; pw_stream_events pw_stream_events_ = {}; @@ -380,9 +385,11 @@ bool SharedScreenCastStreamPrivate::StartScreenCastStream( uint32_t stream_node_id, int fd, uint32_t width, - uint32_t height) { + uint32_t height, + bool is_cursor_embedded) { width_ = width; height_ = height; + is_cursor_embedded_ = is_cursor_embedded; if (!InitializePipeWire()) { RTC_LOG(LS_ERROR) << "Unable to open PipeWire library"; return false; @@ -875,6 +882,7 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) { queue_.current_frame()->mutable_updated_region()->SetRect( DesktopRect::MakeSize(queue_.current_frame()->size())); } + queue_.current_frame()->set_may_contain_cursor(is_cursor_embedded_); } void SharedScreenCastStreamPrivate::ConvertRGBxToBGRx(uint8_t* frame, @@ -906,8 +914,10 @@ bool SharedScreenCastStream::StartScreenCastStream(uint32_t stream_node_id) { bool SharedScreenCastStream::StartScreenCastStream(uint32_t stream_node_id, int fd, uint32_t width, - uint32_t height) { - return private_->StartScreenCastStream(stream_node_id, fd, width, height); + uint32_t height, + bool is_cursor_embedded) { + return private_->StartScreenCastStream(stream_node_id, fd, width, height, + is_cursor_embedded); } void SharedScreenCastStream::UpdateScreenCastStreamResolution(uint32_t width, diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.h b/modules/desktop_capture/linux/wayland/shared_screencast_stream.h index ba29525224..9cdd3d89be 100644 --- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.h +++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.h @@ -47,7 +47,8 @@ class RTC_EXPORT SharedScreenCastStream bool StartScreenCastStream(uint32_t stream_node_id, int fd, uint32_t width = 0, - uint32_t height = 0); + uint32_t height = 0, + bool is_cursor_embedded = false); void UpdateScreenCastStreamResolution(uint32_t width, uint32_t height); void SetUseDamageRegion(bool use_damage_region); void SetObserver(SharedScreenCastStream::Observer* observer);