
See this doc: go/chromium-coil-change for more info BUG=1210385 Change-Id: I6cd8548301e360bae8e71384dbd8ef11aa6c985f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2902904 Reviewed-by: My Nguyen <myy@chromium.org> Commit-Queue: My Nguyen <myy@chromium.org> Auto-Submit: John Palmer <jopalmer@chromium.org> Cr-Commit-Position: refs/heads/master@{#885851}
70 lines
4.9 KiB
Markdown
70 lines
4.9 KiB
Markdown
# Windows 10 Virtual Desktop support
|
|
|
|
Windows 10 introduced Virtual Desktop support. Virtual Desktops are similar to
|
|
Chrome OS and Mac workspaces. A virtual desktop is a collection of windows.
|
|
Every window belongs to a virtual desktop. When a virtual desktop is selected
|
|
to be active, the windows associated with that virtual desktop are displayed on
|
|
the screen. When a virtual desktop is hidden, all of its windows are also
|
|
hidden. This enables the user to create multiple working environments and to
|
|
switch between them. An app (e.g., Chromium) can have windows open on
|
|
different virtual desktops, and thus may need to be Virtual Desktop-aware.
|
|
|
|
The user-facing Chromium support for virtual desktops consists of two things:
|
|
|
|
* When launching the browser with session restore, browser windows are moved
|
|
to the virtual desktop they were on when the browser shutdown.
|
|
* When opening a URL with the browser, either open it in a window on the
|
|
current virtual desktop, or open a new window on the current virtual desktop.
|
|
Don't open it in a tab in a window on another virtual desktop.
|
|
|
|
The core UI principles are that windows should be restored to the desktop they
|
|
were shut down on, and opening an app window shouldn't change the current
|
|
virtual desktop. Only the user should be able to change virtual desktops, or
|
|
move windows between virtual desktops.
|
|
|
|
Windows 10 exposes the COM interface
|
|
[IVirtualDesktopManager](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ivirtualdesktopmanager)
|
|
to access the Virtual Desktop functionality. To make sure that opening a URL
|
|
stays on the current virtual desktop,
|
|
[BrowserView::IsOnCurrentWorkspace](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/browser_view.cc?q=%20BrowserView::IsOnCurrentWorkspace)
|
|
uses the IVirtualDesktopManager method
|
|
[IsWindowOnCurrentVirtualDesktop](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ivirtualdesktopmanager-iswindowoncurrentvirtualdesktop).
|
|
[BrowserMatches](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/browser_finder.cc?q=BrowserMatches)
|
|
in browser_finder.cc only returns a browser window on the current desktop.
|
|
|
|
To restore browser windows to the desktop they were last open on,
|
|
[BrowserDesktopWindowTreeHostWin](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc)
|
|
implements GetWorkspace by using the
|
|
[GetWindowDesktopId](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ivirtualdesktopmanager-getwindowdesktopid) method on
|
|
IVirtualDesktopManager, and restores the workspace using
|
|
[MoveWindowToDesktop](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ivirtualdesktopmanager-movewindowtodesktop),
|
|
in its ::Init method.
|
|
|
|
The actual implementation is a bit more complicated in order to avoid
|
|
calling COM methods on the UI thread, or destroying COM objects on the UI
|
|
thread, since doing so can cause nested message loops and re-entrant calls,
|
|
leading to blocked UI threads and crashes. The
|
|
[VirtualDesktopHelper](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc?q=VirtualDesktopHelper&sq=&ss=chromium%2Fchromium%2Fsrc)
|
|
class does the workspace handling for BrowserDesktopWindowTreeHostWin, including
|
|
doing all the COM operations on a separate COM task runner. The GetWorkspace
|
|
method is synchronous so VirtualDesktopHelper has to remember and return the
|
|
most recent virtual desktop. Windows has no notification of a window changing
|
|
virtual desktops, so BrowserDesktopWindowTreeHostWin updates the virtual desktop
|
|
of a window whenever it gets focus, and if it has changed, calls
|
|
WindowTreeHost::OnHostWorkspaceChanged. This means that if a window is moved
|
|
to a different virtual desktop, but doesn't get focus before the browser is shut
|
|
down, the browser window will be restored to the previous virtual desktop.
|
|
|
|
Windows on different virtual desktops share the same coordinate system, so code
|
|
that iterates over windows generally needs to be Virtual Desktop-aware.
|
|
For example, the following places in code ignore windows not on the current
|
|
virtual desktop:
|
|
|
|
* [LocalProcessWindowFinder::GetProcessWindowAtPoint](https://source.chromium.org/chromium/chromium/src/+/main:ui/display/win/local_process_window_finder_win.cc?q=LocalProcessWindowFinder::ShouldStopIterating&ss=chromium%2Fchromium%2Fsrc)
|
|
* third_party/webrtc/modules/desktop_capture/win/window_capture_utils.cc
|
|
* [Native Window occlusion tracker](https://source.chromium.org/chromium/chromium/src/+/main:ui/aura/native_window_occlusion_tracker_win.cc?q=WindowCanOccludeOtherWindowsOnCurrentVirtualDesktop&ss=chromium%2Fchromium%2Fsrc),
|
|
when determining if a Chromium window is occluded/covered by other windows.
|
|
Windows not on the current virtual desktop are considered occluded.
|
|
|
|
|