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

Capture gets offset when window changes border style #26

Open
elvissteinjr opened this issue Nov 22, 2020 · 6 comments
Open

Capture gets offset when window changes border style #26

elvissteinjr opened this issue Nov 22, 2020 · 6 comments
Labels
api-bug A bug in the underlying Windows APIs

Comments

@elvissteinjr
Copy link

I know this pretty much on the Graphics Capture API implementation and not this sample, but I really have more hope in this ever getting read here than anywhere else to be honest.

The gist is that the window captures can be permanently offset when some border style changes happen. By having an application switch into "fullscreen" for example, where it'd remove the window borders temporarily. This usually results in the window in the capture texture being offset to the right by a couple of pixels, with the right end being cut off. Other times there's a padding around the window except at the top side or all around. This offset stays for the rest of the capture session unless some other border changes occur. It doesn't go back to normal for the windowed appearance, however.
If I had to guess, it might be using the window rect with the shadows in them after the window decorations re-appear.

Okay, to make this a little bit more relevant to this repository: What would be the recommended way to deal with this?
What kind of works is recreating the whole capture session when I detect capture frame's content size to not match the window's DWM frame bounds. Might be overkill, though.
Is there a better way to handle it?

Oh and thanks a lot for this sample code! It's been very helpful to me.

@robmikh
Copy link
Owner

robmikh commented Nov 22, 2020

No worries! People end up asking questions about the API here all the time 🙂 I'm hoping to put together a more official looking sample repo up instead of something under my personal account, hopefully it will help centralize these questions. But until then, you're welcome to ask questions on the various capture related repos I have.

Do you have some examples that exhibit this behavior? I tried to put together an application that changes its window style from WS_OVERLAPPED to WS_POPUP and back, but it seems like we register it as a window close event when the style changes and the capture ends. I also tried Dota 2 swapping between windowed and fullscreen-borderless modes. I do know we have some bugs related to windows that draw their own non-client area, and there are sometimes inconsistencies with applications like VS Code depending on if you start the capture when VS Code is in the maximized state or not. But I haven't seen the described shifted behavior before.

Additionally, what build of Windows are you on?

After I can reproduce this, I can help give some guidance to work around it. Thanks for reporting this bug!

I'm glad you find the sample useful!

@elvissteinjr
Copy link
Author

The window style changes themselves were more of a guess I'll admit. But I've been able to reproduce the effect in many programs offering some kind of fullscreen functionality, including Edge, Vivaldi, mpv, Notepad++. As long as they keep the window up it seems to happen universally.

I've tried on both Windows 10 1809 and 2004. They behave pretty much the same here.
I went ahead and checked what exactly mpv is doing and they're pretty much just swapping WS_OVERLAPPEDWINDOW with WS_POPUP in their code back and forth. And indeed, that's enough to trigger that behavior on my end, doesn't even need to try to cover the entire screen.
I'm surprised setting the window style drops the capture on your end. Is there something system specific that could cause this?

Thanks for the fast response. That's already way more than I've had hoped for.

@robmikh
Copy link
Owner

robmikh commented Nov 22, 2020

Hmmmm, on version 2004 I tried both Edge (Chromium) and Notepad++. I'm going full-screen by pressing F11 in each. Edge seemed to be fine. Notepad++ on the other hand would have (1) the Closed event on the GraphicsCaptureItem fire and (2) any buffers that were still coming in were not live and have the last moments of the window being destructed. This is usually the case when applications destroy their window and create a new one when switching states. To the capture API, it's a different window and the old window is destroyed. Having said that, I can't explain why my repro application behaves this way without explicitly destroying its window. I'll have to debug that as well as give some of those other applications a try when I get some time.

Do you primarily see this with applications going full-screen? There are some historical behaviors around window rects and applications going into a "full-screen mode" by changing their size and removing their non-client area. So what you're describing wouldn't be completely out of the ordinary, I just can't reproduce it for some reason. Are you running on a single monitor system? Can't reproduce this with a single monitor either. But knowing about your display topology would be interesting.

@robmikh
Copy link
Owner

robmikh commented Nov 22, 2020

Could you give CaptureAdHocTest a shot?

CaptureAdHocTest.exe window-style -auto

What's the output? Does it save a failure image?

@elvissteinjr
Copy link
Author

I'm getting "Window Style test failed! 0x800ffff - Window should not have closed during test!" there. Capture does indeed get dropped when running this with -ah too.
However, I noticed this happens because it overrides the full style when switching instead of only swapping out the relevant parts. WS_VISIBLE needs to be preserved for the capture to not be dropped.

If I change it to do that then I get a failure image and the capture doesn't get dropped anymore either. The window is very much blue in the image, though. The code reads ( B: 0, G: 0, R: 0, A: 16 ) on my end.

Also my bad about notepad++. This one does indeed drop the capture when switching to fullscreen.
Checking that again did make me notice that I can trigger similar behavior from just starting a capture maximized and then restore normal window sizing again, however. Works in Explorer too, so I guess it's a bit of a more general bug then. It's cut off at the top, so it's slightly different, but related I suppose.

@robmikh
Copy link
Owner

robmikh commented Nov 22, 2020

Ah, thanks for catching that WS_VISIBLE issue. I'm now able to reproduce what you're seeing. The window is blue in the image, but it has a transparent-ish border:

image

This breaks the assumption the test makes about where the client area is. This coordinate space mapping would make it difficult to reliably inject input in these scenarios. It looks similar to the rect you would get when asking for a window's size using Win32K instead of DWM. I'll put this on my list of bugs to investigate.

Thanks for reaching out about this and helping me get a repro!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-bug A bug in the underlying Windows APIs
Projects
None yet
Development

No branches or pull requests

2 participants