David Bienvenu | 39104d5 | 2020-09-11 21:50:42 | [diff] [blame] | 1 | # Windows 10 Virtual Desktop support |
| 2 | |
| 3 | Windows 10 introduced Virtual Desktop support. Virtual Desktops are similar to |
| 4 | Chrome OS and Mac workspaces. A virtual desktop is a collection of windows. |
| 5 | Every window belongs to a virtual desktop. When a virtual desktop is selected |
| 6 | to be active, the windows associated with that virtual desktop are displayed on |
| 7 | the screen. When a virtual desktop is hidden, all of its windows are also |
| 8 | hidden. This enables the user to create multiple working environments and to |
| 9 | switch between them. An app (e.g., Chromium) can have windows open on |
| 10 | different virtual desktops, and thus may need to be Virtual Desktop-aware. |
| 11 | |
| 12 | The user-facing Chromium support for virtual desktops consists of two things: |
| 13 | |
| 14 | * When launching the browser with session restore, browser windows are moved |
| 15 | to the virtual desktop they were on when the browser shutdown. |
| 16 | * When opening a URL with the browser, either open it in a window on the |
| 17 | current virtual desktop, or open a new window on the current virtual desktop. |
| 18 | Don't open it in a tab in a window on another virtual desktop. |
| 19 | |
| 20 | The core UI principles are that windows should be restored to the desktop they |
| 21 | were shut down on, and opening an app window shouldn't change the current |
| 22 | virtual desktop. Only the user should be able to change virtual desktops, or |
| 23 | move windows between virtual desktops. |
| 24 | |
| 25 | Windows 10 exposes the COM interface |
| 26 | [IVirtualDesktopManager](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ivirtualdesktopmanager) |
| 27 | to access the Virtual Desktop functionality. To make sure that opening a URL |
| 28 | stays on the current virtual desktop, |
John Palmer | 046f987 | 2021-05-24 01:24:56 | [diff] [blame] | 29 | [BrowserView::IsOnCurrentWorkspace](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/browser_view.cc?q=%20BrowserView::IsOnCurrentWorkspace) |
David Bienvenu | 39104d5 | 2020-09-11 21:50:42 | [diff] [blame] | 30 | uses the IVirtualDesktopManager method |
| 31 | [IsWindowOnCurrentVirtualDesktop](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ivirtualdesktopmanager-iswindowoncurrentvirtualdesktop). |
John Palmer | 046f987 | 2021-05-24 01:24:56 | [diff] [blame] | 32 | [BrowserMatches](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/browser_finder.cc?q=BrowserMatches) |
David Bienvenu | 39104d5 | 2020-09-11 21:50:42 | [diff] [blame] | 33 | in browser_finder.cc only returns a browser window on the current desktop. |
| 34 | |
| 35 | To restore browser windows to the desktop they were last open on, |
John Palmer | 046f987 | 2021-05-24 01:24:56 | [diff] [blame] | 36 | [BrowserDesktopWindowTreeHostWin](https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/views/frame/browser_desktop_window_tree_host_win.cc) |
David Bienvenu | 39104d5 | 2020-09-11 21:50:42 | [diff] [blame] | 37 | implements GetWorkspace by using the |
| 38 | [GetWindowDesktopId](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ivirtualdesktopmanager-getwindowdesktopid) method on |
| 39 | IVirtualDesktopManager, and restores the workspace using |
| 40 | [MoveWindowToDesktop](https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ivirtualdesktopmanager-movewindowtodesktop), |
| 41 | in its ::Init method. |
| 42 | |
| 43 | The actual implementation is a bit more complicated in order to avoid |
| 44 | calling COM methods on the UI thread, or destroying COM objects on the UI |
| 45 | thread, since doing so can cause nested message loops and re-entrant calls, |
| 46 | leading to blocked UI threads and crashes. The |
John Palmer | 046f987 | 2021-05-24 01:24:56 | [diff] [blame] | 47 | [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) |
David Bienvenu | 39104d5 | 2020-09-11 21:50:42 | [diff] [blame] | 48 | class does the workspace handling for BrowserDesktopWindowTreeHostWin, including |
| 49 | doing all the COM operations on a separate COM task runner. The GetWorkspace |
| 50 | method is synchronous so VirtualDesktopHelper has to remember and return the |
| 51 | most recent virtual desktop. Windows has no notification of a window changing |
| 52 | virtual desktops, so BrowserDesktopWindowTreeHostWin updates the virtual desktop |
| 53 | of a window whenever it gets focus, and if it has changed, calls |
| 54 | WindowTreeHost::OnHostWorkspaceChanged. This means that if a window is moved |
| 55 | to a different virtual desktop, but doesn't get focus before the browser is shut |
| 56 | down, the browser window will be restored to the previous virtual desktop. |
| 57 | |
| 58 | Windows on different virtual desktops share the same coordinate system, so code |
| 59 | that iterates over windows generally needs to be Virtual Desktop-aware. |
| 60 | For example, the following places in code ignore windows not on the current |
| 61 | virtual desktop: |
| 62 | |
John Palmer | 046f987 | 2021-05-24 01:24:56 | [diff] [blame] | 63 | * [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) |
David Bienvenu | 39104d5 | 2020-09-11 21:50:42 | [diff] [blame] | 64 | * third_party/webrtc/modules/desktop_capture/win/window_capture_utils.cc |
John Palmer | 046f987 | 2021-05-24 01:24:56 | [diff] [blame] | 65 | * [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), |
David Bienvenu | 39104d5 | 2020-09-11 21:50:42 | [diff] [blame] | 66 | when determining if a Chromium window is occluded/covered by other windows. |
| 67 | Windows not on the current virtual desktop are considered occluded. |
| 68 | |
| 69 | |