Which windows appear in the Alt+Tab list?


Commenter Phil Quirk wants to know what the rules are for determining which windows appear in the Alt+Tab list. It's actually pretty simple although hardly anything you'd be able to guess on your own. Note: The details of this algorithm are an implementation detail. It can change at any time, so don't rely on it. In fact, it already changed with Flip and Flip3D; I'm just talking about the Classic Alt+Tab window here.

For each visible window, walk up its owner chain until you find the root owner. Then walk back down the visible last active popup chain until you find a visible window. If you're back to where you're started, then put the window in the Alt+Tab list. In pseudo-code:

BOOL IsAltTabWindow(HWND hwnd)
{
 // Start at the root owner
 HWND hwndWalk = GetAncestor(hwnd, GA_ROOTOWNER);

 // See if we are the last active visible popup
 HWND hwndTry;
 while ((hwndTry = GetLastActivePopup(hwndWalk)) != hwndTry) {
  if (IsWindowVisible(hwndTry)) break;
  hwndWalk = hwndTry;
 }
 return hwndWalk == hwnd;
}

The purpose of this algorithm is to assign the most meaningful representative winow from each cluster of windows related by ownership. (Notice that the algorithm doesn't care whether the owned window is modal or non-modal.)

At least that's the simple rule if you're not playing crazy window style games. The WS_EX_TOOLWINDOW and WS_EX_APPWINDOW extended styles were created so people can play games and put their window in the Alt+Tab list or take it out even if the simple rule would normally have decided otherwise. This is one of those "Okay, if you think you're smarter than Windows, here's your chance to prove it" options. Personally, I would avoid them since it makes your window behave differently from the rest of the windows in the system.

A window with the WS_EX_TOOLWINDOW extended style is treated as if it weren't visible, even if it is. A window with the WS_EX_APPWINDOW extended style is treated as if it has no owner, even if it does.

Once you start adding these extended styles, you enter the world of "I'm trying to work around the rules" and the result is typically even worse confusion than what you had without them.

I'm not sure what the original commenter is getting at. The window hierarchy described in the suggestion (which doesn't make it so much a suggestion as it is a request for me to debug their problem) says that window C is modal on both windows A and B, which doesn't make sense to me, since a window has only one owner.

The algorithm for choosing the Alt+Tab representative from each cluster of windows may not be the best, but it's what we have. I wouldn't be surprised if the details are tweaked from time to time. No, wait, let me rephrase that. I know that the details are tweaked from time to time. The spirit of the operation is preserved (to show the windows the user can switch to, using the most "natural" candidate for each cluster of windows), but the specific details may be fined-tuned as the concept of "naturalness" is refined.

Comments (16)
  1. Sohail says:

    while ((hwndTry = GetLastActivePopup(hwndWalk)) != hwndTry) {

    Isn’t this undefined behaviour?

    [I leave fixing this error as an exercise for the reader. -Raymond]
  2. Tyberius Prime says:

    I would love if there was a public api for this. My quest in alt-tab replacement has

    struggled to find the right windows for a long time now.

  3. Neil says:

    I particularly hated the Windows 95 Alt+Tab list which skipped dialogs with invisible parents. It seems to basically use the same list that the task bar did.

    Tyberius, Windows 3.x used to have an undocumented export named GetNextQueueWindow which provided this functionality. (My problem was trying to work out which window will activate after the current window is minimised, which skips minimised windows, then looks for topmost windows, but if there are no other windows then I give up… desktop perhaps?)

  4. A. Skrobov says:

    2Marvin: the order in the sequence is the Z-order. Same as for tabbing through controls in a dialog box.

  5. Robert says:

    I am wondering, what do you need the while loop for? If GetLastActivePopup returns the *last* active popup, will you get anything different if you call it again? In particular, the second GetLastActivePopup call is applied to an owned window, and the documentation states that you won’t get anything new, which is also confirmed by my testing. (Another question came up while testing: Why does GetAncestor(hwnd, GA_ROOTOWNER) return hwnd instead of the owner for owned windows without the WS_POPUP style?)

  6. Marvin says:

    What is the *order* of Windows in Alt-Tab sequence? I constantly hit situations where some windows are moved far away in the sequence without any apparent (to me) reason. Usually I have 3 actively used windows: Program A, Program B and a browser. There also might be a lot of other rarely used windows open. When I try to switch between Program A, Program B and/or browser quite often one of them will appear far in the queue instead of being close to others. I think it might have something to do with minimizing a window but I am not positive.

  7. MathiasR says:

    A few days ago I had a strange bug… suddenly, the task list and alt+tab seemed to show *all* windows, even windows which are not supposed to be visible in the task list or alt+tab. I had to reboot to fix the problem. (Vista + SP1 beta)

  8. Grijan says:

    Yes, AFAIK, the Alt+Tab order is the same as the Z-order, which makes sense, because that way you can quickly reach the last two or three tasks, which are the ones you mos probably need, if you are working with a group of applications (IMHO, one of the most common scenarios for Alt+Tab use).

    But I, being myself a hard Alt+Tab user, have found an annoyance that sometimes drives me nuts, and that may be what Marvin refers to. Most times, when you minimize a window (I’m also used to do that with Alt+Space, M), it goes to the bottom of the ZOrder. But sometimes (about one out of five times), it just goes back the second active window, and gets activated by the next "blind" Alt+Tab. I haven’t been able to find any rule for this. I use the same applications all time (mostly Windows Explorer, Firefox, Thundebird, and Visual Basic 6), and this can happen with any app.

    Also, there is another annoying behavior I can’t understand. Visual Studio 6’s version of MSDN, when opened from the VB IDE, behaves as if it were a child of VB’s main window, but also get shown in the Alt+Tab list, and guess what? It also makes strange things with the switch order. It seems to happen too with topmost windows, which stay at the start of the list, no matter what you do, but at least this time it has some sense…

  9. sucky proggy says:

    Program XYZ also tamper with the alt+tab order.

  10. Chris J says:

    I’ve had a few instances (although I forget which apps have triggered it) where I minimise an application, and then Alt-Tab completely misbehaves – for example, say I have apps A, B and C: say I’m on A and hit alt-tab once takes me to B in the chain, hit alt-tab again, and it takes me to C, then another Alt-Tab takes me back to A and it the cycle continues. Worth adding that when Alt-Tab starts doing this, focus and auto-raise stop working. I’ve sometimes been able to fix it by minimising all running apps with Win-D, Alt-Tab’ing the cycle one, clicking on one window on taskbar to bring it up and everything rights itself… but this doesn’t always work.

    Odd.

  11. Grijan says:

    To sucky proggy: I wasn’t complaining about a determinate program bug, but trying to explain a couple of scenarios in which many programs are involved. I don’t believe we have to blame any of those programs. On the other hand, the algorithm that determines the Z-order of minimized windows or out-of-process child windows seems to act weirdly sometimes. That’s what I wanted to expose. And IMHO that is completely on-topic, because it’s directly related to the way Alt+Tab works.

  12. Pierre B. says:

    Raymond, you have mis-read the original commentor:

    "For example, if you have window A owns window B owns window C, they are all visible, and C is modal to the rest, then suddenly all three disappear from the ALT+TAB."

    A owns B owns C, C is modal. C only has one owner.

  13. Good Point says:

    So, is Excel 2003’s behavior with regards to Alt+Tab, designed to be annoying, or is it just a coincidence?

  14. Good Point says:

    "I constantly hit situations where some windows are moved far away in the sequence without any apparent (to me) reason….

    I think it might have something to do with minimizing a window but I am not positive."

    I see this when moving windows to the background (Alt+Esc), especially with Office apps.

  15. Marvin says:

    Thanks to everybody who confirmed I am not insane.

    With regards to the Z-order this is nuts. Can you look at somebody’s monitor and determine what the Z-order of his windows is? The user expectation, I think, is that Alt-Tab would favor MRU windows and not rely on some invisible and hard to determine order. It shouldn’t matter how I switched from application A to application B: through a mouse click, minimizing A, Alt-Tab or anything else. When I click Alt-Tab I want to see A as the nearest choice.

    Am I unreasonable?

  16. Johan Thelin says:

    As Acer seems to be having some problems with this – I added a small fix to remove one of their windows from the Alt-Tab list. Thanks to Raymond for hinting me on how to get it done.

    http://www.thelins.se/johan/2007/01/efficient-month-starts-now.html

Comments are closed.