Improve screen sharing with PipeWire on Wayland
Currently, sharing a screen or a window on Wayland opens unnecessary preview dialog on Chromium side, which is then followed by a similar dialog on xdg-desktop-portal side. The Chromium dialog is useless on Wayland, as it doesn't show anything. This is because Chromium doesn't have access to screen content as in case of X11 session. To fix this, we want to avoid showing the preview dialog in case we find that we run on Wayland and only pick a screen or a window from the dialog that comes from xdg-desktop-portal. This patch splits BaseCapturerPipeWire class, moving portal related code into XdgPortalBase, which does all the DBus communication and which is supposed to be reused by BaseCapturerPipeWire when the user confirms the dialog from xdg-desktop-portal. The XdgPortalBase is extended to support multiple calls at once, where each call is identified by Id. Relevant change on Chromium side will be in a different review. Bug: chromium:682122 Change-Id: If8afd36da66231eb154cdc00114908ac897ee4cf Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/160649 Commit-Queue: Tommi <tommi@webrtc.org> Reviewed-by: Tommi <tommi@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32342}
This commit is contained in:
@ -10,6 +10,7 @@
|
||||
#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_OPTIONS_H_
|
||||
#define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_OPTIONS_H_
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
@ -23,6 +24,10 @@
|
||||
|
||||
#include "modules/desktop_capture/full_screen_window_detector.h"
|
||||
|
||||
#if defined(WEBRTC_USE_PIPEWIRE)
|
||||
#include "modules/desktop_capture/linux/xdg_desktop_portal_base.h"
|
||||
#endif
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// An object that stores initialization parameters for screen and window
|
||||
@ -131,13 +136,68 @@ class RTC_EXPORT DesktopCaptureOptions {
|
||||
#if defined(WEBRTC_USE_PIPEWIRE)
|
||||
bool allow_pipewire() const { return allow_pipewire_; }
|
||||
void set_allow_pipewire(bool allow) { allow_pipewire_ = allow; }
|
||||
|
||||
// Provides a way how to identify portal call for a sharing request
|
||||
// made by the client. This allows to go through the preview dialog
|
||||
// and to the web page itself with just one xdg-desktop-portal call.
|
||||
// Client is supposed to:
|
||||
// 1) Call start_request(id) to tell us an identificator for the current
|
||||
// request
|
||||
// 2) Call close_request(id) in case the preview dialog was cancelled
|
||||
// or user picked a web page to be shared
|
||||
// Note: In case the current request is not finalized, we will close it for
|
||||
// safety reasons and client will need to ask the portal again
|
||||
// This was done primarily for chromium support as there was no way how to
|
||||
// identify a portal call made for the preview and later on continue with the
|
||||
// same content on the web page itself.
|
||||
|
||||
void start_request(int32_t request_id) {
|
||||
// In case we get a duplicit start_request call, which might happen when a
|
||||
// browser requests both screen and window sharing, we don't want to do
|
||||
// anything.
|
||||
if (request_id == xdp_base_->CurrentConnectionId()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// In case we are about to start a new request and the previous one is not
|
||||
// finalized and not stream to the web page itself we will just close it.
|
||||
if (!xdp_base_->IsConnectionStreamingOnWeb(absl::nullopt) &&
|
||||
xdp_base_->IsConnectionInitialized(absl::nullopt)) {
|
||||
xdp_base_->CloseConnection(absl::nullopt);
|
||||
}
|
||||
|
||||
xdp_base_->SetCurrentConnectionId(request_id);
|
||||
}
|
||||
|
||||
void close_request(int32_t request_id) {
|
||||
xdp_base_->CloseConnection(request_id);
|
||||
xdp_base_->SetCurrentConnectionId(absl::nullopt);
|
||||
}
|
||||
|
||||
absl::optional<int32_t> request_id() {
|
||||
// Reset request_id in case the connection is in final state, which means it
|
||||
// is streaming content to the web page itself and nobody should be asking
|
||||
// again for this ID.
|
||||
if (xdp_base_->IsConnectionStreamingOnWeb(absl::nullopt)) {
|
||||
xdp_base_->SetCurrentConnectionId(absl::nullopt);
|
||||
}
|
||||
|
||||
return xdp_base_->CurrentConnectionId();
|
||||
}
|
||||
|
||||
XdgDesktopPortalBase* xdp_base() const { return xdp_base_; }
|
||||
void set_xdp_base(rtc::scoped_refptr<XdgDesktopPortalBase> xdp_base) {
|
||||
xdp_base_ = std::move(xdp_base);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if defined(WEBRTC_USE_X11)
|
||||
rtc::scoped_refptr<SharedXDisplay> x_display_;
|
||||
#endif
|
||||
|
||||
#if defined(WEBRTC_USE_PIPEWIRE)
|
||||
rtc::scoped_refptr<XdgDesktopPortalBase> xdp_base_;
|
||||
#endif
|
||||
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
|
||||
rtc::scoped_refptr<DesktopConfigurationMonitor> configuration_monitor_;
|
||||
bool allow_iosurface_ = false;
|
||||
|
||||
Reference in New Issue
Block a user