Bug 1732737 - Add VirtualDesktop handling to window occlusion on Windows r=gfx-reviewers,bradwerth

Implementation of WindowOcclusionCalculator::Initialize() is borrowed from InitializeVirtualDesktopManagerTask::Run().
And implementation of WindowOcclusionCalculator::IsWindowOnCurrentVirtualDesktop() is borrowed from chromium's WindowOcclusionCalculator::IsWindowOnCurrentVirtualDesktop()

Differential Revision: https://phabricator.services.mozilla.com/D133327
This commit is contained in:
sotaro 2022-02-08 00:13:09 +00:00
Родитель 3b43d19db5
Коммит 6d6928bdcf
2 изменённых файлов: 58 добавлений и 3 удалений

Просмотреть файл

@ -24,6 +24,7 @@
#include "mozilla/StaticPrefs_widget.h"
#include "mozilla/StaticPtr.h"
#include "nsBaseWidget.h"
#include "nsWindow.h"
#include "transport/runnable_utils.h"
#include "WinUtils.h"
@ -322,6 +323,12 @@ void WinWindowOcclusionTracker::Ensure() {
sTracker = new WinWindowOcclusionTracker(thread);
WindowOcclusionCalculator::CreateInstance();
RefPtr<Runnable> runnable =
WrapRunnable(RefPtr<WindowOcclusionCalculator>(
WindowOcclusionCalculator::GetInstance()),
&WindowOcclusionCalculator::Initialize);
sTracker->mSerializedTaskDispatcher->PostTaskToCalculator(runnable.forget());
}
/* static */
@ -765,6 +772,27 @@ void WinWindowOcclusionTracker::WindowOcclusionCalculator::ClearInstance() {
sCalculator = nullptr;
}
void WinWindowOcclusionTracker::WindowOcclusionCalculator::Initialize() {
MOZ_ASSERT(IsInWinWindowOcclusionThread());
MOZ_ASSERT(!mVirtualDesktopManager);
CALC_LOG(LogLevel::Info, "Initialize()");
#ifndef __MINGW32__
if (!IsWin10OrLater()) {
return;
}
RefPtr<IVirtualDesktopManager> desktopManager;
HRESULT hr = ::CoCreateInstance(
CLSID_VirtualDesktopManager, NULL, CLSCTX_INPROC_SERVER,
__uuidof(IVirtualDesktopManager), getter_AddRefs(desktopManager));
if (FAILED(hr)) {
return;
}
mVirtualDesktopManager = desktopManager;
#endif
}
void WinWindowOcclusionTracker::WindowOcclusionCalculator::Shutdown(
layers::SynchronousTask* aTask) {
MOZ_ASSERT(IsInWinWindowOcclusionThread());
@ -777,6 +805,7 @@ void WinWindowOcclusionTracker::WindowOcclusionCalculator::Shutdown(
mOcclusionUpdateRunnable->Cancel();
mOcclusionUpdateRunnable = nullptr;
}
mVirtualDesktopManager = nullptr;
}
void WinWindowOcclusionTracker::WindowOcclusionCalculator::
@ -1288,9 +1317,35 @@ Maybe<bool> WinWindowOcclusionTracker::WindowOcclusionCalculator::
return Some(true);
}
// XXX VirtualDesktopManager is going to be handled by Bug 1732737.
BOOL onCurrentDesktop;
HRESULT hr = mVirtualDesktopManager->IsWindowOnCurrentVirtualDesktop(
aHwnd, &onCurrentDesktop);
if (FAILED(hr)) {
// In this case, we do not know the window is in which virtual desktop.
return Nothing();
}
return Nothing();
if (onCurrentDesktop) {
return Some(true);
}
GUID workspaceGuid;
hr = mVirtualDesktopManager->GetWindowDesktopId(aHwnd, &workspaceGuid);
if (FAILED(hr)) {
// In this case, we do not know the window is in which virtual desktop.
return Nothing();
}
// IsWindowOnCurrentVirtualDesktop() is flaky for newly opened windows,
// which causes test flakiness. Occasionally, it incorrectly says a window
// is not on the current virtual desktop when it is. In this situation,
// it also returns GUID_NULL for the desktop id.
if (workspaceGuid == GUID_NULL) {
// In this case, we do not know the window is in which virtual desktop.
return Nothing();
}
return Some(false);
}
#undef LOG

Просмотреть файл

@ -99,6 +99,7 @@ class WinWindowOcclusionTracker final : public DisplayStatusListener,
// Returns existing WindowOcclusionCalculator instance.
static WindowOcclusionCalculator* GetInstance() { return sCalculator; }
void Initialize();
void Shutdown(layers::SynchronousTask* aTask);
void EnableOcclusionTrackingForWindow(HWND hwnd);
@ -236,7 +237,6 @@ class WinWindowOcclusionTracker final : public DisplayStatusListener,
HWND mMovingWindow = 0;
// Only used on Win10+.
// XXX VirtualDesktopManager is going to be handled by Bug 1732737.
RefPtr<IVirtualDesktopManager> mVirtualDesktopManager;
// Used to serialize tasks related to mRootWindowHwndsOcclusionState.