-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Getting Zoom to screen share #319
Comments
zoom and wayland screen share is rather messy in my experience. my preferred method to work around this is to use obs to capture the screen and output it using v4l2loopback (load this before starting obs) and then share a second camera from zoom (note that you may have to make sure to select your primary camera for video first, or stick it on top of the screen share in obs before opening zoom). you can also just use the virtual camera as your primary camera, but zoom will blur it since it doesnt treat it as a screen share and uses an unsuitable lossy compression algorithm. second camera shares fix this (you can share your primary camera by first disabling your video in zoom and then initiating a share) its quite messy but it worked well enough for me back when I regularly used zoom. unfortunately, i think the screen sharing issues are a general problem with zoom on wayland. |
I assume you are using the Zoom Electron app? As an alternative the Zoom PWA works well for screen share in Sway. |
yes this is what I do now, but still would prefer to use it normally.
Yes but it has some other issues |
I took a quick look at DBUS logs and apparently Zoom just gives up if it doesn't find the RemoteDesktop protocol... (I guess it wants it for the remote control feature?). So adding #263 to my installation, Zoom now at least manages to bring up the screen selector. After choosing a screen though it crashes. From DBUS it seems it never calls the ScreenCast Start method, only the RemoteDesktop.Start, maybe it gets confused there? The sequence looks like this:
Which seems weird to me since there's a reply to the "Start" followed by an error that the method doesn't exist. Anyways, I don't know much about dbus and Zoom just seems to have a policy of "make it work on one computer and ignore any error paths" instead of correctly implementing any protocols. It's very annoying and time consuming to try to figure out where they went wrong again so let's hope they fix it at some point? |
I have no idea if this will help, but running zoom through Gamescope "allows" me to successfully screen share. However, since gamescope doesn't have any other windows, it just displays a black screen, but I think it works otherwise. Since gamescope is OS, maybe we can see what is different between our and their implementations of the protocol? |
I'm not certain if this will help, but looking through the zoom logs (
There's unrelated output before and after it, but at some point it seems something is running I'm on sway on Gentoo. I have previously (earlier this year and on an older version) been able to screen share with zoom, but it doesn't seem to work anymore. |
This precisely. I can definitely remember screen sharing on Wayland (dwl), but don't remember how. |
Yup, the issue happens because Zoom started using RemoteDesktop protocol. There's no proper implementation of it in xdg-desktop-portal-wlr :(. |
So #2 ? |
zoom calls
all with the same session. This is supported and the reply to the start method must also create a screencast and send the stream in the reply as it would with a pure screencast session. The clue is in the error log:
and then looking at which start method was called and what part of the reply contains an empty array. I've implemented this in my portal and confirmed that it works: mahkoh/jay@260d241 I only support version 2 of the RDP though. I don't know if it would also work with an implementation that only supports version 1. |
Yes, looking at the protocol a bit closer I also realized that RemoteDesktop.start is supposed to start the screencast session as well. I wasn't aware of your compositor @mahkoh , but it seems like its portal is tightly integrated into the compositor and not using the wayland protocols? If it were, it would be a nice alternative to this portal implementation, that's why I'm checking. The patch: diff --git a/include/screencast.h b/include/screencast.h
index 99b7411..4fc18c1 100644
--- a/include/screencast.h
+++ b/include/screencast.h
@@ -6,4 +6,6 @@
void xdpw_screencast_instance_destroy(struct xdpw_screencast_instance *cast);
void xdpw_screencast_instance_teardown(struct xdpw_screencast_instance *cast);
+int start_screencast(struct xdpw_screencast_instance *cast);
+
#endif
diff --git a/src/remotedesktop/remotedesktop.c b/src/remotedesktop/remotedesktop.c
index 51f4ddb..0eac0bd 100644
--- a/src/remotedesktop/remotedesktop.c
+++ b/src/remotedesktop/remotedesktop.c
@@ -1,7 +1,10 @@
#include "remotedesktop.h"
#include <time.h>
+#include <spa/utils/result.h>
+#include "screencast.h"
+#include "screencast_common.h"
#include "wlr_virtual_pointer.h"
#include "xdpw.h"
@@ -191,6 +194,25 @@ static int method_remotedesktop_start(sd_bus_message *msg, void *data, sd_bus_er
return -1;
}
logprint(DEBUG, "remotedesktop: start: session found");
+ struct xdpw_screencast_instance *cast = sess->screencast_data.screencast_instance;
+ logprint(DEBUG, "remotedesktop: screencast instance %x", cast);
+
+ if (cast) {
+ logprint(DEBUG, "remotedesktop: starting screencast");
+ if (!cast->initialized) {
+ ret = start_screencast(cast);
+ }
+ while (cast->node_id == SPA_ID_INVALID) {
+ int ret = pw_loop_iterate(state->pw_loop, 0);
+ if (ret < 0) {
+ logprint(ERROR, "pipewire_loop_iterate failed: %s", spa_strerror(ret));
+ return ret;
+ }
+ }
+ }
+ if (ret < 0) {
+ return ret;
+ }
remote = &sess->remotedesktop_data;
remote->virtual_pointer = zwlr_virtual_pointer_manager_v1_create_virtual_pointer(
@@ -229,11 +251,107 @@ static int method_remotedesktop_start(sd_bus_message *msg, void *data, sd_bus_er
return ret;
}
- ret = sd_bus_reply_method_return(msg, "ua{sv}", PORTAL_RESPONSE_SUCCESS,
- 1, "devices", "u", POINTER | KEYBOARD);
+ sd_bus_message *reply = NULL;
+ ret = sd_bus_message_new_method_return(msg, &reply);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_append(reply, "u", PORTAL_RESPONSE_SUCCESS);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_open_container(reply, 'a', "{sv}");
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = sd_bus_message_append(reply, "{sv}",
+ "devices", "u", POINTER | KEYBOARD);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = sd_bus_message_open_container(reply, 'e', "sv");
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_append(reply, "s", "streams");
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_open_container(reply, 'v', "a(ua{sv})");
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_open_container(reply, 'a', "(ua{sv})");
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_open_container(reply, 'r', "ua{sv}");
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_append(reply, "u", cast->node_id);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_open_container(reply, 'a', "{sv}");
+ if (ret < 0) {
+ return ret;
+ }
+ if (cast->target->output->xdg_output) {
+ ret = sd_bus_message_append(reply, "{sv}",
+ "position", "(ii)", cast->target->output->x, cast->target->output->y);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_append(reply, "{sv}",
+ "size", "(ii)", cast->target->output->width, cast->target->output->height);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+ ret = sd_bus_message_append(reply, "{sv}", "source_type", "u", MONITOR);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_close_container(reply);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_close_container(reply);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_close_container(reply);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_close_container(reply);
+ if (ret < 0) {
+ return ret;
+ }
+ ret = sd_bus_message_close_container(reply);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = sd_bus_message_append(reply, "{sv}",
+ "devices", "u", KEYBOARD | POINTER);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = sd_bus_message_close_container(reply);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = sd_bus_send(NULL, reply, NULL);
if (ret < 0) {
return ret;
}
+ sd_bus_message_unref(reply);
return 0;
}
diff --git a/src/screencast/screencast.c b/src/screencast/screencast.c
index 43a7b80..889e70a 100644
--- a/src/screencast/screencast.c
+++ b/src/screencast/screencast.c
@@ -186,7 +186,7 @@ bool setup_target(struct xdpw_screencast_context *ctx, struct xdpw_session *sess
}
-static int start_screencast(struct xdpw_screencast_instance *cast) {
+int start_screencast(struct xdpw_screencast_instance *cast) {
int ret;
ret = xdpw_wlr_session_init(cast);
if (ret < 0) { |
It doesn't crash on my system but I'm using the flatpak.
Yes, I only posted the commit for reference. |
Where did you get that from by the way? Looks like it includes zoom debug symbols?! That would make things so much easier if they break things again! |
|
Hmm, I'm aware of that file but it never included such detailed error messages for me. Maybe the version flatpak uses has some additional logging 🤔 |
You're kind of implying you actually work for Zoom so just in case something I would really appreciate: Don't fail silently! Yes, Linux is difficult because it is so diverse. Not every desktop supports every protocol. When using something like RemoteDesktop/Screencast, please check whether it is supported first (best not by using heuristics like XDG_CURRENT_DESKTOP but by actually querying dbus) and tell the user if it is not! Be specific in the message and mention the exact protocol, this way no one has to play a game of guessing what's missing and we can just implement the missing feature. In this case, Zoom actually seems to have done most things right by using a protocol the way it is documented. It would be even better of course if Zoom wouldn't crash if the portal misbehaves. That being said, I'm using Zoom now with my fork (https://github.com/David96/xdg-desktop-portal-wlr/commits/remotedesktop) and screencasting works. Still crashing when screen sharing is being stopped though. |
That's it works :). Can you create a PR? It would be great of other users can just install xdg-desktop-portal-wlr from repo with your changes. This one looks dead #263 :). |
In principle yes, but the RemoteDesktop protocol is much bigger than just adding this hack to make Zoom work. I don't have the time to spent a huge amount of effort here, maybe @columbarius or @emersion could have a look at my branch (https://github.com/David96/xdg-desktop-portal-wlr/commits/remotedesktop) and give a rough estimate of how much would have to be changed for it to get merged into main? Would e.g. not implementing touchscreen support be a reason to not merge it at all? Or the fact, that the keyboard code is fully copied from wayvnc? |
I don't think any PR needs to be a complete RemoteDesktop impl before it can be merged. In fact, breaking the work into smaller chunks would make it easier to review. |
Hi, I use dwl which is built on wlroots, and would like to screen share on Zoom 6.2.0 (after Zoom said they fixed screen share on wayland). When trying to screen share, I get the share dialog from zoom as expected, but selecting "System Share" or the other doesn't do anything, not even share a black screen. It is clear screen share is not active from UI or behaviour.
I have checked the wiki and made sure that
XDG_CURRENT_DESKTOP=wlroots
for dbus, systemd and terminal shell.zoomus.conf
hasxwayland=false
, andenableWaylandShare=true
.slurp
is installed, and gUM check works well. The one time gamescope was running (now gamescope doesn't run due to unrelated issue), zoom was able to share, but shared only a black screen, probably because nothing else was running in gamescope? I tried starting Zoom withXDG_CURRENT_DESKTOP=GNOME
, to no avail.Does anyone have a clue as to why it doesn't work?
The text was updated successfully, but these errors were encountered: