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

Erasing window content during resizing and moving and while popups are displayed - Win32 #1601

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

hobby8
Copy link
Contributor

@hobby8 hobby8 commented Jul 12, 2019

This feature will automatically erase the windows content to a user-requested color while it is being resized, dragged back into the screen, or a popup is being displayed (e.g. MessageBox or Open/Save dialog box).

The implementation aims to have as little impact on the existing SFML design as possible.
A new API was added to enable the feature and set the color.

Tested on Windows in the above-mentioned scenarios. Should have no effect on other platforms.

@Bromeon
Copy link
Member

Bromeon commented Jul 16, 2019

Is this a really needed use-case? I think a more popular request was that the window keeps updating even during resize, but I understand that may be much more complex to implement.

Also, why is the API based on separate sf::Uint8 parameters, when we have sf::Color?

@1aam2am1
Copy link
Contributor

Sf window can be updated when resized when event loop and drawing are in others threads. Event loop freeze when resizing. But drawing loop can get changed size change view and draw. And it works.

…opup is active - consistency with sRgbCapable setting
@hobby8
Copy link
Contributor Author

hobby8 commented Jul 18, 2019

@Bromeon - this feature provides a simple mitigation that does not require the user to factor out resize-handling or rendering code from their main loop, or to use a separate thread as @1aam2am1 suggested.

Off-hand, I don't think that a full implementation should be complex (and I may do it in the future).

As for sf::Color, it currently resides in Graphics, which Window cannot depend on. I can adjust the API to use it if it moves to System.

BTW the feature has since been tested on Windows 7 & 10, with/without DWM (composition), with/without high DPI and with/without sRGB.

@eXpl0it3r
Copy link
Member

I've seen people request this sort of feature and as such, I wouldn't mind adding it.

Some questions:

  • Since you changed the window classes, does this work fine with custom window styles or window recreation with different style (e.g. borderless, fullscreen -> non-fullscreen, etc.)?
  • Since there's currently no stub implementation for Linux, macOS, Android or iOS, wouldn't this lead to a linker or worse runtime error?
  • What's the default behavior when no color is set?
  • Once I've set a color, how can I return to the default behavior?
  • What about implementations for different OSs?

@hobby8
Copy link
Contributor Author

hobby8 commented Sep 7, 2019

Since you changed the window classes, does this work fine with custom window styles or window recreation with different style (e.g. borderless, fullscreen -> non-fullscreen, etc.)?

This change only affects which rectangles get invalidated when the window is resized (damage regions). Not passing CS_HREDRAW | CS_VREDRAW actually told Windows that the upper-left part of the window did not change upon resizes, so for example when the window got expanded, Windows could redraw only the right and bottom parts. That optimization could never have worked for SFML, but with the rendering loop running it did not matter much.

Since there's currently no stub implementation for Linux, macOS, Android or iOS, wouldn't this lead to a linker or worse runtime error?

There's a no-op default implementation in the base class. I'm adding a comment to make it more clear.

What's the default behavior when no color is set?

Same as without this feature.
In Windows, you can have the content and border of your window (or the popup window) smeared all over the place. The actual behavior depends on the OS version, whether composition is used, user settings, which operation is involved, the type of popup windows, how far the user drags windows, and more.

Once I've set a color, how can I return to the default behavior?

This can be implemented, but I believe that once a developer opts-in to this feature, they may only want to continue modifying the color (which is supported), not go back to having artifacts.

What about implementations for different OSs?

Windows is the most critical: first, only Windows runs its own message loop while windows are being dragged or resized. Secondly, Windows doesn't automatically erase the content of windows that do not repaint themselves, giving room for all these artifacts.

Having said that, I'm committing an implementation for X11 that I regard as purely cosmetic, so that instead of black the WM will use the supplied color.

@eliasdaler
Copy link
Contributor

Again, as in #1604 - the solution to use is to do multithreading and event processing in another thread.
Usually in games you have something like this:

while (running) {
    processEvents();
    update(dt);
    draw(window);
}

The drawing is sometimes implemented in another thread - and the fact that you might have drawing during event processing breaks this common pattern and takes you back to square one.

I understand that multithreading event processing and update/draw is very tricky, and I'd be happy to see a tutorial for that, instead of adding a very specific use case, which will couple event processing and drawing (and make it possible to do in a single thread only)

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

Successfully merging this pull request may close these issues.

6 participants