Virtual desktops are an end-user window management feature, not a programmatic one

Raymond Chen

Virtual desktops are a window management feature, not a security feature or a performance feature. Furthermore, they are for end users to organize their windows, not for other programs to organize the windows.

The purpose of the IVirtual­Desktop­Manager interface is to allow applications to take the virtual desktop state into account in a few application scenarios.

One such scenario is deciding whether to reuse an existing window or to create a new one.

For example, suppose you’re a multi-window tabbed application, and the user launches a new document. You have a few options.

  • Create a new window with a single tab containing that document.
  • Find an existing window and create a new tab within the existing window for the new document.

The recommendation is to stay on the current virtual desktop if possible.

The application can enumerate all of its windows and call IVirtual­Desktop­Manager::Is­Window­On­Current­Virtual­Desktop for each one, so that it can build a set of target window candidates on the current virtual desktop. It can then choose one of those target window candidates (say, the one most recently active) as the one in which to create a new tab for the document. If there are no candidates on the current virtual desktop, then create a new window with a single tab for the document.

There’s no reason for the application to know, say, the names of all of the virtual desktops. The goal is to avoid switching virtual desktops. It’s not so an application can say, “Okay, when opening a document, I’ll always open it on a virtual desktop named Planning.” The application has no control over the virtual desktop names anyway. The user picked those. And you can’t expect all users to have a virtual desktop called Planning.”¹

Another scenario that the IVirtual­Desktop­Manager interface is intended to cover is that of an application that consists of multiple windows that operate together, like a main window and a bunch of auxiliary windows. The virtual desktop manager already recognizes many types of auxiliary windows and automatically keeps them on the same virtual desktop as the main window. But an application may have an unusual window structure that eludes this automatic detection.

For those cases, you can call IVirtual­Desktop­Manager::Get­Window­Desktop­Id for your main window to get an ID for its current virtual desktop, and then use IVirtual­Desktop­Manager::Move­WindowsTo­Desktop to move the auxiliary windows to that same virtual desktop.

The purpose of Move­WindowsTo­Desktop is specifically not to let a program grab all of the user’s windows and scatter them across all their virtual desktops. Note, for example, that the only thing you can do is make one window join another window’s virtual desktop. You can bring windows together, but you can’t, say, split a window into a new virtual desktop.

Because the point is to let you move your auxiliary windows so they follow the main window. It is not a general purpose interface for moving windows onto arbitrary virtual desktops. That’s for the user to do.

¹ If you want, you can have the user pick a window and say “Use this window for opening new documents, even if it means switching virtual desktops.” Then the user is still in control of when virtual desktop switches occur. (And they can move that window to another virtual desktop later.)

10 comments

Discussion is closed. Login to edit/delete existing comments.

  • Jonathan Potter 2

    What if the user has moved your windows onto arbitrary virtual desktops, and then expects your program to reopen in the same configuration next time?

    • Raymond ChenMicrosoft employee 0

      Virtual desktops are ephemeral. There is no “same configuration”. The next time the program runs, virtual desktop {1268aaa6-a8ca-4702-a4e9-24c5a9d7b229} almost certainly does not exist any more.

      • Jonathan Potter 2

        Unfortunately to the user it’s not “virtual desktop {1268aaa6-a8ca-4702-a4e9-24c5a9d7b229}”, it’s “Desktop 3”, and their question “Why can’t your app reopen window X on ‘Desktop 3’ when I had it there before?” seems fairly reasonable from a user’s point of view.

        • switchdesktopwithfade@hotmail.com 0

          Jonathan your question is more academic because MoveWindowToDesktop() and GetWindowDesktopId() already do exactly what you ask for. As far as I know the GUIDs and names do persist between reboots and they forever ought to until the user deletes them. It has always been this way going all back to the NT and Unix days (the philosophy not the APIs) because ephemeral virtual desktops have no practical value.

          It would be unfortunate if Sets & Activities went mainstream one day and remembered every little detail of X,Y coordinates and tab order but forgot what desktop they were on. You know those memes that go “You had one job!”

          IMO applications need to know about virtual desktops for two legitimate reasons:

          1. To remember the last desktop they were moved to by the user. (documented)
          2. To manage desktops on behalf of the user. (undocumented)

          Also I’m curious about the hard rules for virtual desktops. For example, a window that toggles WS_VISIBLE may jump from a background desktop to the active desktop, which should never be the case.

  • Mark Brents 0

    I would like to have a way to have the list of desktops always on top so I can always see what I have and switch between them with a click.

  • cheong00 0

    I would imagine maybe some “suite-like” LOB applications will want to create separate virtual desktop that’ll run all the application it contains there, and have it’s own clipboard not shared with other virtual desktops except with certain “clipboard manager” in the suite (actually this is easy, just share data via named pipe and pretend you’re using clipboard, and only use clipboard in that “clipboard manager”). It will help them create environment that feels super secure.

  • Paul Jackson 0

    Semi-related: Can you tell me why, when we finally can re-order taskbar items since Windows 7, this order is scrambled when I switch to a different virtual desktop and come back? How come such a basic functionality is malfunctioning? That’s exactly the kind of “You had one job!” thing that was mentioned in another comment here.
    So it happens that I’m lucky and some software fixes it, but it resorts to memory hacking (Googel for “virtual desktops – preserve taskbar order”). Now, if there was enough exposed API, somebody could at least fix it properly or perhaps allow more customization. But you always have this “it’s not for other programs” attitude. That might have been OK if it would work properly out of the box!

    • cheong00 0

      In your case you should have filed bug report at Feedback Hub (which I heard some other forum users complained being less responsive than before but I have no idea because all I have ever received is automatic reply of they got the feedback)

      Using third party software to “fix a bug” is never the right way, especially if it involves direct memory manipulation. I would not be surprised in future Windows Update it’ll cause the shell crash due to internal memory structure changes, perhaps just to fix the issue you described.

      • Paul Jackson 0

        > Using third party software to “fix a bug” is never the right way

        Well, it’s the only way.

        > I would not be surprised in future Windows Update it’ll cause the shell crash

        That happens from time to time, but the tool is being maintained.

        > perhaps just to fix the issue you described.

        You wish. It’s been like that since the introduction of the feature in 2015.

  • David Adam 0

    “For example, suppose you’re a multi-window tabbed application, and the user launches a new document.”

    I have been surprised recently to find that there’s not a straightforward way of implementing a single-instance application. In Win32 creating a custom window class and messaging with WM_COPYDATA seems fine, and WinForms in .NET Framework contains a working implementation using shared memory, but all the answers on StackOverflow are wrong (usually by using machine-global, not session-local synchronization methods) and the implementation in .NET 5 is wrong too. Perhaps a topic for a future post?

Feedback usabilla icon