How do I suppress the default animation that occurs when I hide or show a window?


A customer wanted to know how they can disable the default fade-in/fade-out animation that occurs when a window is hidden or shown. "I don't want to use WS_EX_TOOL­WINDOW because that causes my window to disappear from the taskbar. I tried Dwm­Enable­Composition but that affects the entire desktop and is too jarring. We want to suppress the effect because our program replaces one window with another, and we want the operation to be invisible to the user."

Whoa, heading straight for Dwm­Enable­Composition? That's using a global solution to a local problem.

To disable the animations on a specific window, use something like this:

HRESULT DisableDwmAnimations(HWND hwnd)
{
    BOOL fDisable = TRUE;
    return DwmSetWindowAttribute(hwnd,
                DWMWA_TRANSITIONS_FORCEDISABLED,
                &fDisable,
                sizeof(fDisable));
}

Re-enabling the animations is left as an exercise for the reader.

Comments (18)
  1. Adam Rosenfield says:

    Is that reader exercise a wry joke?

  2. Sam says:

    @Aeee

    I think you are doing something wrong in your code.

    Such animations are blocking on the main window thread if i remember correctly.

    1- Bad solution would be to cheat / be lazy and turn off the animations without fixing the problem. Essentially hiding the problem for it to later popup. (microsoft seem to really like this method too)

    2- Good solution, what a proper developer would do: trace down the problem and permanently fix it.

  3. aherm again ? says:

    To Raymond

    "replaces one window with another"

    Microsoft helping malware authors again ?

    So microsoft can promote their own anti-malware solution when people call support center ?

    Why not just nuke the human race and get it over with already.

    What! i'm not allowed to be cranky ? Should i have written that with a sarcastic twist instead, raymond style ?

    2 months with windows 8 using metro on a desktop computer made me this way. 'You reap what you sow' yet again…sigh

  4. Rick C says:

    @aherm again?: we know nothing about what the customer is doing.  It could be the case that they are replacing one of their own windows with a new one.

    [That's how I interpreted it. -Raymond]
  5. Rick C says:

    Raymond, I notice that DwmEnableComposition is deprecated in Windows 8–the documentation says it cannot be turned off and the function will return success but nothing will happen.  DwmSetWindowAttribute doesn't mention this.  I would guess that your code won't do anything under Windows 8, because it seems pointless to disable DwmEnableComposition if you're going to leave DwmSetWindowAttribute as a back door.  I sent feedback via the page link.

  6. @Sam says:

    > Good solution, what a proper developer would do: trace down the problem and permanently fix it.

    BTW what a proper developer would do:

    1) Triage the bug

    2) A priority is assigned depending on the severity (low – known workaround, plus possible difficult/long solution)

    3) To be done when/if there are no other items in the backlog with higher priority, if budget permits

  7. Joshua says:

    @Aeee

    It's GPU contention. Windows is trying to use the GPU for composition at the same time you're using it. Task switching on a GPU is very slow.

  8. @Joshua says:

    First of all thanks, but I think we are hijacking Raymond thread.. my fault of course.

    Anyway I doubt it's that because it's happening on XP.

  9. Joshua says:

    [That's how I interpreted it. -Raymond]

    Been there, done that. Your interpretation could be correct.

    We eventually swapped the mechanism out with a saner one (so far as SetParent could be considered sane) to prevent window order changing when we swapped panes.

  10. Aeee says:

    As an aside – we have an OpenGL renderer that must run always at 60fps for television broadcast reasons.

    For some reasons the 2D(*) title bar animations would completely block the rendering until the animation is finished – even if the rendering is on an off-screen buffer (odd and not nice). The solution is of course to disable those animations (they are dedicated machines, don't complain).

    (*) – With 2D I mean the animation in Windows XP and in Vista/7 with Aero disabled.

  11. Eric C Brown says:

    Rick C:  Since DwmEnableComposition and DwmSetWindowAttribute do completely different things, I don't find it at all surprising that one is disabled on Windows 8 and the other is not.

    Just as an example, DwmSetWindowAttribute is *local* – it only applies to a single HWND, and DwmEnableComposition is global.

  12. @Sam says:

    The rendering is correctly on a parallel thread. It usually blocks in the call to glReadPixels applied to a PBO (which normally returns in zero time because it just schedules the read-back on the GPU for later access). In very rare occasions it blocks on glFinish calls we use to load textures (in yet another thread). We know it's not blocking the message loop, since blocking that "artificially" does not manifest the same symptoms.

    Also a detail that probably I have not clarified enough: it does not happen when I (say) minimize my window. It happens when *any* window is minimized (say, open notepad and minimize it).

  13. Brennan says:

    This is the sort of thing that red flags when someone asks me..  "How do I disable the animation so I can seamlessly replace one window with another?" Whoa there, not that we can't do that, but lets take a step back and reanalyze the problem.  Chances are you're solving it the wrong way.  Of course support isn't really in a position to say that.

  14. @Rick C: Windows 8 still uses desktop composition, although with no transparency on window border and title bar. Windows have the same fade in/fade out animation as in Vista/7 when a window is shown or hidden. Thus disabling this animation is still applicable scenario. And this local solution provided by Raymond will work whereas changing the global setting through DwmEnableComposition will not.

  15. @Aeee: Maybe you're observing the same thing as me.  It's very odd.  At this moment, I have RealPlayer playing some music with a visualization.  If composition is enabled, I can minimize/maximize all I want and the music keeps playing without interruption.  If composition is disabled, the music stops for the duration of the animation.  This happens for minimize/maximize animations in any app, not just RealPlayer.  It still happens even if I disable the visualization such that the only updates in the RealPlayer window are the trackbar/timer showing my position in the audio.  And it still happens if I designate RealPlayer as "high" priority in Task Manager.  I'm really curious why this is.

    Oddly enough, Windows Media Player doesn't have this problem and always plays smoothly.  I wonder what tricks they figured out to work around this?

    It's interesting you are running into the same thing but involving 3D rendering instead of audio.

    I guess if Windows 8 requires composition, they'll probably never fix this issue in the older versions of Windows that don't require composition.

  16. Gabe says:

    JamesJohnston: If RealPlayer is pausing the audio during animations, it's quite likely that they are using the GPU to decode audio. Or they are using the GPU to do the visualization synchronously, so if the video stops the audio stops too.

  17. "I tried Dwm­Enable­Composition but that affects the entire desktop" – at least this guy understood that was the wrong approach to use, for the reason Raymond states underneath!

    In fact, "We want to suppress the effect because our program replaces one window with another, and we want the operation to be invisible to the user" makes perfect sense to me: this is exactly what Task Manager does when you elevate it, for one thing (the new, elevated Task Manager replaces the non-elevated predecessor window); the malware theory doesn't fit at all here, since the original request would seem to involve just a single process replacing one of its own windows with another – in-process malware would surely want to intercept information displayed, keystrokes etc rather than replace a whole window.

    Of course, having a single window with two different panes of content would probably be neater, but there may be a good reason they can't do that – like in Task Manager's case, where the two windows are owned by different processes, even though the user sees them as two modes of a single window. Perhaps their software self-updates, so they want the updated version to replace the old one's window seamlessly.

  18. James Schend says:

    Late on the post, but a very popular multi-IM program does exactly this when either a one-user window turns into a tabbed window (for example, when you receive an IM from a second person), and also when a tabbed window turns back into a one-user window (when you close the second-to-last tab). They don't disable the animations, and it's very jarring and weird-looking.

    It's certainly not malware. Just kind of a weird design.

Comments are closed.