1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
diff -up firefox-83.0/browser/actors/WebRTCParent.jsm.pw6 firefox-83.0/browser/actors/WebRTCParent.jsm
--- firefox-83.0/browser/actors/WebRTCParent.jsm.pw6 2020-11-12 19:04:30.000000000 +0100
+++ firefox-83.0/browser/actors/WebRTCParent.jsm 2020-11-25 10:28:32.492865982 +0100
@@ -45,6 +45,9 @@ XPCOMUtils.defineLazyServiceGetter(
"nsIOSPermissionRequest"
);
+const PIPEWIRE_PORTAL_NAME = "####_PIPEWIRE_PORTAL_####";
+const PIPEWIRE_ID = 0xaffffff;
+
class WebRTCParent extends JSWindowActorParent {
didDestroy() {
webrtcUI.forgetStreamsFromBrowserContext(this.browsingContext);
@@ -753,6 +756,8 @@ function prompt(aActor, aBrowser, aReque
);
menupopup.appendChild(doc.createXULElement("menuseparator"));
+ let isPipeWire = false;
+
// Build the list of 'devices'.
let monitorIndex = 1;
for (let i = 0; i < devices.length; ++i) {
@@ -774,6 +779,29 @@ function prompt(aActor, aBrowser, aReque
}
} else {
name = device.name;
+ // When we share content by PipeWire add only one item to the device
+ // list. When it's selected PipeWire portal dialog is opened and
+ // user confirms actual window/screen sharing there.
+ // Don't mark it as scary as there's an extra confirmation step by
+ // PipeWire portal dialog.
+ if (name == PIPEWIRE_PORTAL_NAME && device.id == PIPEWIRE_ID) {
+ isPipeWire = true;
+ let name;
+ try {
+ name = stringBundle.getString("getUserMedia.sharePipeWirePortal.label");
+ } catch (err) {
+ name = "Use operating system settings"
+ }
+ let item = addDeviceToList(
+ menupopup,
+ name,
+ i,
+ type
+ );
+ item.deviceId = device.id;
+ item.mediaSource = type;
+ break;
+ }
if (type == "application") {
// The application names returned by the platform are of the form:
// <window count>\x1e<application name>
@@ -888,39 +916,41 @@ function prompt(aActor, aBrowser, aReque
perms.EXPIRE_SESSION
);
- video.deviceId = deviceId;
- let constraints = {
- video: { mediaSource: type, deviceId: { exact: deviceId } },
- };
- chromeWin.navigator.mediaDevices.getUserMedia(constraints).then(
- stream => {
- if (video.deviceId != deviceId) {
- // The user has selected a different device or closed the panel
- // before getUserMedia finished.
- stream.getTracks().forEach(t => t.stop());
- return;
- }
- video.srcObject = stream;
- video.stream = stream;
- doc.getElementById("webRTC-preview").hidden = false;
- video.onloadedmetadata = function(e) {
- video.play();
- };
- },
- err => {
- if (
- err.name == "OverconstrainedError" &&
- err.constraint == "deviceId"
- ) {
- // Window has disappeared since enumeration, which can happen.
- // No preview for you.
- return;
+ if (!isPipeWire) {
+ video.deviceId = deviceId;
+ let constraints = {
+ video: { mediaSource: type, deviceId: { exact: deviceId } },
+ };
+ chromeWin.navigator.mediaDevices.getUserMedia(constraints).then(
+ stream => {
+ if (video.deviceId != deviceId) {
+ // The user has selected a different device or closed the panel
+ // before getUserMedia finished.
+ stream.getTracks().forEach(t => t.stop());
+ return;
+ }
+ video.srcObject = stream;
+ video.stream = stream;
+ doc.getElementById("webRTC-preview").hidden = false;
+ video.onloadedmetadata = function(e) {
+ video.play();
+ };
+ },
+ err => {
+ if (
+ err.name == "OverconstrainedError" &&
+ err.constraint == "deviceId"
+ ) {
+ // Window has disappeared since enumeration, which can happen.
+ // No preview for you.
+ return;
+ }
+ Cu.reportError(
+ `error in preview: ${err.message} ${err.constraint}`
+ );
}
- Cu.reportError(
- `error in preview: ${err.message} ${err.constraint}`
- );
- }
- );
+ );
+ }
};
menupopup.addEventListener("command", menupopup._commandEventListener);
}
diff -up firefox-83.0/browser/locales/en-US/chrome/browser/browser.properties.pw6 firefox-83.0/browser/locales/en-US/chrome/browser/browser.properties
--- firefox-83.0/browser/locales/en-US/chrome/browser/browser.properties.pw6 2020-11-12 19:04:30.000000000 +0100
+++ firefox-83.0/browser/locales/en-US/chrome/browser/browser.properties 2020-11-25 09:24:26.378857626 +0100
@@ -764,6 +764,7 @@ getUserMedia.selectWindowOrScreen.label=
getUserMedia.selectWindowOrScreen.accesskey=W
getUserMedia.pickWindowOrScreen.label = Select Window or Screen
getUserMedia.shareEntireScreen.label = Entire screen
+getUserMedia.sharePipeWirePortal.label = Use operating system settings
# LOCALIZATION NOTE (getUserMedia.shareMonitor.label):
# %S is screen number (digits 1, 2, etc)
# Example: Screen 1, Screen 2,..
diff -up firefox-83.0/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc.pw6 firefox-83.0/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
--- firefox-83.0/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc.pw6 2020-11-25 09:24:26.358857788 +0100
+++ firefox-83.0/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc 2020-11-25 09:24:26.378857626 +0100
@@ -879,17 +879,17 @@ void BaseCapturerPipeWire::CaptureFrame(
callback_->OnCaptureResult(Result::SUCCESS, std::move(result));
}
+#define PIPEWIRE_ID 0xaffffff
+#define PIPEWIRE_NAME "####_PIPEWIRE_PORTAL_####"
+
bool BaseCapturerPipeWire::GetSourceList(SourceList* sources) {
- RTC_DCHECK(sources->size() == 0);
- // List of available screens is already presented by the xdg-desktop-portal.
- // But we have to add an empty source as the code expects it.
- sources->push_back({0});
+ sources->push_back({PIPEWIRE_ID, 0, PIPEWIRE_NAME});
return true;
}
bool BaseCapturerPipeWire::SelectSource(SourceId id) {
// Screen selection is handled by the xdg-desktop-portal.
- return true;
+ return id == PIPEWIRE_ID;
}
// static
|