Skip to content
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

Xcomposite window capture not working for windows on other workspaces #412

Open
2 of 3 tasks
T-X opened this issue Jul 30, 2022 · 6 comments
Open
2 of 3 tasks

Xcomposite window capture not working for windows on other workspaces #412

T-X opened this issue Jul 30, 2022 · 6 comments

Comments

@T-X
Copy link

T-X commented Jul 30, 2022

Problem Description

Capturing a window with OBS Studio's Xcomposite window capture or gstreamer ximagesrc are not working when the according window is on a workspace which is currently not viewed on any monitor. The cause is probably that Xmonad is a non-reparenting window manager?

Initially I had reported the issue at OBS here: obsproject/obs-studio#4966. But after debugging we concluded that it is likely something Xmonad would need to tackle, something OBS cannot do anything about.

Steps to Reproduce

OBS:

  1. Start an application with a window in your current workspace (for example VLC)
  2. Start OBS on the same workspace next to it
  3. Create a scene in OBS
  4. Add a source to the scene of type "Window Capture (Xcomposite)" in OBS
  5. Select the VLC winodw for the window capture
    -> Video playback in VLC is captured fine in OBS
  6. Then either move VLC to a workspace not used by a monitor or switch the layout to "Full" so that OBS covers up VLC
    -> VLC capture freezes in OBS

OBS window capture recovers when captured window becomes visible on a monitor again.

gstreamer:

  1. Start an application with a window in your current workspace (for example VLC)
  2. Get the xid of the VLC window with xwininfo
  3. In the same workspace start gstreamer via:
$ sleep 3; timeout 20 gst-launch-1.0 ximagesrc xid=0x2200014 ! videoconvert ! queue ! x264enc qp-min=18 ! avimux ! filesink location=gstreamer-ximagesrc-3.avi
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Redistribute latency...
  1. Move VLC to a workspace not visible on any monitor
    -> gstreamer crashes as follows:
X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  73 (X_GetImage)
  Serial number of failed request:  501
  Current serial number in output stream:  501

Configuration File

A minimal configuration to reproduce the problem. ewmh is needed for the OBS window capture (or "wmctl" for instance, too) to detect any window at all.

import XMonad
import XMonad.Hooks.EwmhDesktops
import XMonad.Layout.NoBorders

main :: IO ()
main = xmonad $ ewmh defaultConfig { layoutHook = noBorders Full }

Checklist

  • I've read CONTRIBUTING.md

  • I tested my configuration

    • With xmonad version 0.17.0 (from Debian Sid, 0.17.0-2)
    • With xmonad-contrib version XXX (commit XXX if using git)
@T-X
Copy link
Author

T-X commented Jul 30, 2022

From a user perspective, ideally xmonad would be able to detect automatically if an application tries to capture a window through xcomposite and would take the necessary steps to allow it (but don't know much about X11/xmonad, not sure if that'd be easily possible?).

But I'd also be curious about potential workarounds, to enable capturing a window that is not visible on a monitor.

@geekosaur
Copy link
Contributor

This doesn't sound like something related to reparenting; it wouldn't be able to find the window at all in that case, regardless of visibility.

Does it work if you use a compositor like compton or picom?

@geekosaur
Copy link
Contributor

You could also try running the server with backing store enabled, but I don't think recent Xorg guarantees that it works.

@liskin
Copy link
Member

liskin commented Jul 30, 2022

I think this is because xmonad unmaps windows of hidden workspaces whereas some other WMs (GNOME in particular) just move the windows to some coordinates where they won't be seen.

Fixing this would mean changing how xmonad core works, and may result in increased cpu/battery usage. (Not saying whether it should or shouldn't be done, just that it can't be worked around in contrib and that it's a substantial change in core.)

@slotThe
Copy link
Member

slotThe commented Jul 31, 2022 via email

T-X added a commit to T-X/xmonad-config that referenced this issue Sep 9, 2022
This is a workaround for the following issue:

xmonad/xmonad#412

Where it would not be possible to capture window on another,
unfocused workspace with programs like OBS or gstreamer.

With the key combination Mod+Backspace one can mark a workspace for
recording, to set it "On the Air". This ensures that when the marked
workspace is not focused that it can still be captured.

The hack to ensure this: An unfocused workspace is moved to an unused
screen, here HDMI-1.

Current known issues:

* A few frames might leak from an unmarked workspace when switching
  from/to it.
* HDMI-1 won't be available for normal usage. HDMI-1 and the resolution
  are currently hardcoded.
* With OBS the "virtual" screen HDMI-1 needs a fixed position, here 0x0.
  So it needs to be left of the real screen to ensure that.
  Because OBS when using a screen capture will not update the position
  automatically and if the real screen and virtual screen were swapping
  back and forth for position 0x0, this could lead to OBS capturing a
  screen with a workspace you don't actually want to share.
... and many more, see TODOs in the code.
@T-X
Copy link
Author

T-X commented Sep 9, 2022

@geekosaur

Does it work if you use a compositor like compton or picom?

I installed and tried picom here on Debian and just ran "picom" with its default configuration. That does not seem to make a difference.

You could also try running the server with backing store enabled, but I don't think recent Xorg guarantees that it works.

It seems that backing store is already enabled here on Debian Sid for me:

$ grep "Backing store" /var/log/Xorg.0.log
[    21.744] (==) modeset(0): Backing store enabled

The really hacky workaround I came up with and am currently using is this one:

So with that I can use the shortcut Mod+Backspace to mark and toggle the currently focused workspace for recording on and off. And the hack I'm using is that I'm abusing my otherwise unused HDMI-1 port as a virtual screen which the marked workspace gets moved to ensure that OBS can keep recording it. And with xrandr I toggle this virtual and the real screen back and forth between a mirrored and split layout depending on whether I'm currently viewing the recorded workspace on my real screen or not.

Note though that this still sometimes leaks some frames from the new workspace though when switching the real screen away from the recorded workspace. So it's also a bit racy, couldn't find a proper fix for that yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants