diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index dc7c2bd04ca5..ad4de771c717 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -401,6 +401,8 @@ nsWindow::nsWindow() : nsWindowBase() mIdleService = nullptr; + ::InitializeCriticalSection(&mPresentLock); + sInstanceCount++; } @@ -434,6 +436,7 @@ nsWindow::~nsWindow() sIsOleInitialized = FALSE; } } + ::DeleteCriticalSection(&mPresentLock); NS_IF_RELEASE(mNativeDragTarget); } @@ -4676,12 +4679,19 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam, { // From msdn, the way around this is to disable the visible state // temporarily. We need the text to be set but we don't want the - // redraw to occur. + // redraw to occur. However, we need to make sure that we don't + // do this at the same time that a Present is happening. + // + // To do this we take mPresentLock in nsWindow::PreRender and + // if that lock is taken we wait before doing WM_SETTEXT + EnterCriticalSection(&mPresentLock); DWORD style = GetWindowLong(mWnd, GWL_STYLE); SetWindowLong(mWnd, GWL_STYLE, style & ~WS_VISIBLE); *aRetValue = CallWindowProcW(GetPrevWindowProc(), mWnd, msg, wParam, lParam); SetWindowLong(mWnd, GWL_STYLE, style); + LeaveCriticalSection(&mPresentLock); + return true; } @@ -7523,6 +7533,21 @@ void nsWindow::PickerClosed() } } +bool nsWindow::PreRender(LayerManagerComposite*) +{ + // This can block waiting for WM_SETTEXT to finish + // Using PreRender is unnecessarily pessimistic because + // we technically only need to block during the present call + // not all of compositor rendering + EnterCriticalSection(&mPresentLock); + return true; +} + +void nsWindow::PostRender(LayerManagerComposite*) +{ + LeaveCriticalSection(&mPresentLock); +} + /************************************************************** ************************************************************** ** diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 085f5977c7d6..a41207e150ac 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -443,6 +443,8 @@ protected: void ClearCachedResources(); nsIWidgetListener* GetPaintListener(); static bool IsRenderMode(gfxWindowsPlatform::RenderMode aMode); + virtual bool PreRender(LayerManagerComposite*) override; + virtual void PostRender(LayerManagerComposite*) override; protected: nsCOMPtr mParent; @@ -576,6 +578,8 @@ protected: static bool sNeedsToInitMouseWheelSettings; static void InitMouseWheelScrollData(); + + CRITICAL_SECTION mPresentLock; }; /**