From 870df28bda2ae8022ce2df17886bc253c2a92cb1 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 14 Dec 2020 22:36:48 +0000 Subject: [PATCH] Improve screen sharing with PipeWire on Linux Wayland session Current scenario when PipeWire desktop capturer is used: Chromium picker dialog is created with screen and window capturer. Each capturer makes an xdg-desktop-portal call, showing another picker dialog. Once user confirms both pickers on xdg-desktop-portal side, yet another picker is shown as a new capturer is created for the web page itself. With this change: Chromium picker dialog is created, but only screen capturer will be created as with xdg-desktop-portal the picker will handle both screens and windows. Also in the chromium picker, the "window" tab creating window capturer expects a list of windows and doesn't show previews, but we need actually to behave exactly like the "screen" tab and show preview of selected window. Then again, yet another picker from xdg-desktop-portal is shown as a new capturer is created for the web page itself. Bug: chromium:1157006 Change-Id: I39eafc72eb46da7868d1114b5c106030c22787a4 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2578840 Commit-Queue: mark a. foltz Reviewed-by: mark a. foltz Reviewed-by: Wez Reviewed-by: Guido Urdaneta Reviewed-by: Avi Drissman Cr-Commit-Position: refs/heads/master@{#836814} --- AUTHORS | 1 + .../api/desktop_capture/desktop_capture_base.cc | 8 ++++++++ .../browser/media/webrtc/display_media_access_handler.cc | 8 ++++++++ content/public/browser/desktop_capture.cc | 9 +++++++++ content/public/browser/desktop_capture.h | 6 ++++++ 5 files changed, 32 insertions(+) diff --git a/AUTHORS b/AUTHORS index c0b2771655df5..a4f042fa7bc32 100644 --- a/AUTHORS +++ b/AUTHORS @@ -441,6 +441,7 @@ James Stanley James Vega James Wei James Willcox +Jan Grulich Jan Rucka Jan Sauer Janusz Majnert diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc index fa790782b3ee0..a9708300d2c32 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc @@ -120,6 +120,14 @@ DesktopCaptureChooseDesktopMediaFunctionBase::Execute( } } + // Avoid offering window-capture as a separate source, since PipeWire's + // content-picker will offer both screen and window sources. + // See crbug.com/1157006. + if (content::desktop_capture::CanUsePipeWire() && + base::Contains(media_types, content::DesktopMediaID::TYPE_SCREEN)) { + base::Erase(media_types, content::DesktopMediaID::TYPE_WINDOW); + } + DesktopMediaPickerController::DoneCallback callback = base::BindOnce( &DesktopCaptureChooseDesktopMediaFunctionBase::OnPickerDialogResults, this, origin, web_contents); diff --git a/chrome/browser/media/webrtc/display_media_access_handler.cc b/chrome/browser/media/webrtc/display_media_access_handler.cc index 3026674525bf5..e837e5ca1ed06 100644 --- a/chrome/browser/media/webrtc/display_media_access_handler.cc +++ b/chrome/browser/media/webrtc/display_media_access_handler.cc @@ -216,6 +216,14 @@ void DisplayMediaAccessHandler::ProcessQueuedAccessRequest( content::DesktopMediaID::TYPE_SCREEN, content::DesktopMediaID::TYPE_WINDOW, content::DesktopMediaID::TYPE_WEB_CONTENTS}; + + // Avoid offering window-capture as a separate source, since PipeWire's + // content-picker will offer both screen and window sources. + // See crbug.com/1157006. + if (content::desktop_capture::CanUsePipeWire()) { + base::Erase(media_types, content::DesktopMediaID::TYPE_WINDOW); + } + auto source_lists = picker_factory_->CreateMediaList(media_types); DesktopMediaPicker::DoneCallback done_callback = diff --git a/content/public/browser/desktop_capture.cc b/content/public/browser/desktop_capture.cc index 60065d125ff5d..c3b8f474cfb77 100644 --- a/content/public/browser/desktop_capture.cc +++ b/content/public/browser/desktop_capture.cc @@ -65,5 +65,14 @@ std::unique_ptr CreateWindowCapturer() { #endif } +bool CanUsePipeWire() { +#if defined(WEBRTC_USE_PIPEWIRE) + return webrtc::DesktopCapturer::IsRunningUnderWayland() && + base::FeatureList::IsEnabled(features::kWebRtcPipeWireCapturer); +#else + return false; +#endif +} + } // namespace desktop_capture } // namespace content diff --git a/content/public/browser/desktop_capture.h b/content/public/browser/desktop_capture.h index c90997a8762a5..700d5c46aed5c 100644 --- a/content/public/browser/desktop_capture.h +++ b/content/public/browser/desktop_capture.h @@ -19,6 +19,12 @@ CONTENT_EXPORT webrtc::DesktopCaptureOptions CreateDesktopCaptureOptions(); CONTENT_EXPORT std::unique_ptr CreateScreenCapturer(); CONTENT_EXPORT std::unique_ptr CreateWindowCapturer(); +// Returns whether we can use PipeWire capturer based on: +// 1) We run Linux Wayland session +// 2) WebRTC is built with PipeWire enabled +// 3) Chromium has features::kWebRtcPipeWireCapturer enabled +CONTENT_EXPORT bool CanUsePipeWire(); + } // namespace desktop_capture } // namespace content