-
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
Allow sharing of individual windows. #107
Comments
Some discussion can be found here |
True, thanks. Also worth linking to the corresponding wlr-protocols issue, which I would consider a prerequisite/blocker for this feature. |
Hello. What is a current state of this feature? |
Here's the link to the same issue mentioned by danshick in the new forge: https://gitlab.freedesktop.org/wlroots/wlr-protocols/-/issues/93 |
I'd really like to see a feature like this implemented. My streaming setup on X11 involves having a game in a window on one side of the screen with stuff like terminals and twitch's dashboard on the other side of the screen. Since I'm stuck with a single-monitor setup, I don't have the option of just running the game fullscreen on one monitor and using fullscreen capture, with everything else on the other monitor. It sounds like some other Wayland compositors like GNOME already provide the ability for single-window capture? Maybe I'm misunderstanding, but if that's the case then what are they doing that makes that possible that wlroots doesn't do? |
GNOME/mutter uses a completely different base. There is currently no way to export a toplevel buffer in wlroots. The current roadmap (and take this with a grain of salt is):
For the meantime there is #156 to share a region of the screen. |
Unfortunately specifying the cropping region ahead of time isn't really practical without a way to precisely move and resize a window into that region (like what If that's not feasible, I've been thinking of just hacking whatever compositor I settle on to keep a tmpfile with a full list of windows and their size/position, then pass those into |
@tm512 Another concern is that a window is not always in the foreground, like when using workspaces or a tabbed container in Sway. |
This feature would be great to have, because it's on virtually every platform other than wlroots compositors. |
It's bad, but it's able to share only "a few things" if you need. For me it solved the biggest problem, not wanting to show my full output. it seems to work just "fine", but did not test it enough. You will need to run a nested Wayland session.. i tested with sway what i did to make it work:
as I said, it's ugly.. I just did some initial testing, did not check audio etc etc yet. I don't know if nested session work with all the apps and etc.. but if it's only one instance of it, and it's running in the nested, should be fine. There is a lot of improvement and tests that can be made, i just wanted to share something i just got working. Hope that helps people =] |
You see, this nesting should naturally derive from "surfaces" as a first-class abstraction of rendered regions, indifferent to whether it's a desktop, a window, or whatever else. A tree of surfaces should be enumerable and visible from anywhere in it, globally but probably with some sort of access control scheme. The issue is this was not considered initially in the design of wlroots, which will haunt it for a very long time because of a little something called technical debt. |
I wonder why nested Sway is a functioning workaround but it's not possible to share individual windows. For now I just share via xwayland, which works okay and is more easy to use than having nested WMs. |
@cmprmsd can you expand on this - do you mean the specific window you want to share is what you launch via xwayland? |
Sure thing. In Chromium you'll notice that for example in Teams you will see all xwayland windows. The monitor share tabs will show black screens. But if you switch to single window, than you can select windows started under xwayland. Hope this helps for the time being. |
Following up on the roadmap above:
This will be covered by ext-foreign-toplevel-info. |
My workaround does not work any more since some weeks. I don't know why but some component been updated and now only the "Wayland-dialog" is visible even for Chromium or Firefox which have been started with xWayland instead of Wayland. :/ I looked at the pipewire settings and some other flags but nothing did work. 😢 |
Thanks @sfrique for your idea. I'm quite happy with that solution. Changing the nested sway window size will automatically resize the screen-sharing appropriately. If you are sharing a window and move to another space, the content that is getting shared won't update while it's not visible for you. Really feels like sharing a window, it's quite perfect for me. Hope this helps others who want to share a window/part of their screen. Here is how I've accomplished everything: A script to allow using the sway shortcuts in either the main session or the sub-session if that one is selected:
#!/usr/bin/env bash
set -ueo pipefail
if pid="$(swaymsg -t get_tree | jq -e '.. | select(.type?) | select(.focused==true) | select(.app_id=="wlroots").pid')"; then
export SWAYSOCK="/run/user/${UID}/sway-ipc.${UID}.${pid}.sock"
fi
swaymsg "${@}" I just check if the window is wlroots which is the window of the nested session, if that's the case I already have the PID of that session an can set it as a socket and then pass it to swaymsg in my Only difficulty is that I forward everything to that window, which means I can't control it like other windows 😆 not sure what to do about that yet. For starting the nested session I just have to make sure to later restore. I'm doing that in a script
#!/usr/bin/env bash
set -ueo pipefail
sway -c ~/.config/sway/nested || true
dbus-update-activation-environment --systemd WAYLAND_DISPLAY SWAYSOCK
systemctl --user restart xdg-desktop-portal.service xdg-desktop-portal-wlr.service and in the
Now I can simply start the sway nested session, share that nested window via Firefox/Chromium from the main (since the connection happens via dbus which is shared for both instances). If I wanted to share a whole browser, I'd have to close it and then re-open it inside the nested session. |
A workaround for this is to create a virtual output (
The command By default, when I try to share an output, the cursor turns a cross ( |
@jalvesaq Oh cool, so the idea is to overlay a headless output (what you are doing by picking the right pixel position on creation) with a regular output and then to share that headless output? I just tested it quickly by using |
Thanks for the tip on how to remove the I can use
But I can also see it in Google Meet (if I'm sharing the output) or preview it in OBS as a "Screen Capture (PipeWire)" source. |
Very nice! I'll have to try this method out.
Another way that I've found is to use
Keyboard capture becomes somewhat of an obstacle with this method, but usually I can switch back out of the |
I am curious to know if other portals have found a solution to this problem? |
Hyprland supports this, so at least their portal started as a fork of this one: #253. |
@paolomainardi Hyperland uses the Based on the roadmap above, the current state is:
Still in progress, lots of unsolved discussion there.
Done. Implemented via the ext-foreign-toplevel-list protocol.
This could be implemented experimentally in zwlr_screencopy_manager_v1. Although I'd ask the wlroots devs if they'd merge such a change at this stage or would rather wait for ext-screencopy.
The OUTPUT CHOOSER protocol can be extended to take a value matching a ext_foreign_toplevel_handle_v1::identifier. Given that, potentially, and output name can match a toplevel name (it would be terrible, but nothing explicitly forbids this), I think a prefix of
Blocked by the items above |
Wow, thanks, @WhyNotHugo. That's a great summary. So we have to help to push |
Is hyprland already more mature than sway? I already found a few things that work properly only in hyprland. |
Still nothing with Sway? |
I have this little script to start a new headless output for screen sharing: #!/usr/bin/env bash
# Step 1: Create a new output
swaymsg create_output
# Step 2: Find the name of the newly created output
NEW_OUTPUT=$(swaymsg -t get_outputs | jq -r '.[] | select(.name | startswith("HEADLESS-")) | .name' | sort | tail -n 1)
# Check if the output was successfully created
if [ -z "$NEW_OUTPUT" ]; then
echo "Failed to create a new output."
exit 1
fi
# Step 3: Assign a workspace to the new output
swaymsg workspace sshr output "$NEW_OUTPUT"
# Step 4: Set the resolution for the new output
swaymsg output "$NEW_OUTPUT" resolution 1280x720
# Step 5: Set the background color for the new output
swaymsg output "$NEW_OUTPUT" bg "#220900" solid_color
# Step 6: Switch to workspace sshr and then back to the previous workspace
CURRENT_WORKSPACE=$(swaymsg -t get_workspaces | jq -r '.[] | select(.focused) | .name')
swaymsg workspace sshr
swaymsg workspace "$CURRENT_WORKSPACE"
wl-mirror "$NEW_OUTPUT"
notify-send "Created new output $NEW_OUTPUT." with keybindings in my sway config for It creates the new output, assign the |
Nice, the problem is that now Chrome doesn't let me share windows, only tabs. Pressing on windows returns me to the tabs section. |
@rmasad, you can share the whole virtual (headless) output and use |
Hyprland uses a fork of wlroots, the question of why they haven't migrated these changes to upstream is valid, though I think just a boring answer where they just want to move fast and break things without worrying about compatibility till designs are stable or trying be considerate of ever potential use case, I also have a suspicion that wlroots/wayland devs have other priorities, hyprland has a focus on features that make using OBS good, like global hotkey support, that's been a stagnant in wayland for about 8 years, and hyprland is the only wl-wm with support for it. |
A awesome script! just one question, how do i delete the virtual output (the "headless" one) after i'm done recording/sharing screen? |
I use this script for stopping the screenshare: #!/usr/bin/env bash
# Get all outputs with names starting with HEADLESS-
headless_outputs=$(swaymsg -t get_outputs | jq -r '.[] | select(.name | startswith("HEADLESS-")) | .name')
# Check if there are any HEADLESS outputs
if [ -z "$headless_outputs" ]; then
echo "No HEADLESS outputs found."
exit 0
fi
# Unplug each HEADLESS output
for output in $headless_outputs; do
echo "Unplugging $output..."
swaymsg output "$output" unplug
done
notify-send "All HEADLESS outputs have been unplugged." |
@WhyNotHugo so now things just need to be implemented in wlroots and integrate OUTPUT CHOOSER and finally there's a generic way to share windows on wlroots based compositors right? :) |
Indeed. An updated version of the previous roadmap is:
|
This doesn't actually implement ext_foreign_toplevel_image_capture_source_manager_v1 so that's not sufficient btw. |
Adding the option to share individual windows was discussed in different issues/PRs but there is no corresponding open issue right now.
The text was updated successfully, but these errors were encountered: