From 22d6b8c708ccc445a9595f1014216c016f5e610d Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Wed, 12 Jul 2017 18:01:43 -0600 Subject: [PATCH] Bug 1380471: Move follow-up initialization for emulated windows into a callback invoked by the emulated window's WM_CREATE handler; r=yzen --HG-- extra : rebase_source : d8742fc08cea75e994c9ee4f7c5eca50d40aeac1 --- accessible/ipc/DocAccessibleParent.cpp | 33 +++++++++------- accessible/windows/msaa/DocAccessibleWrap.cpp | 11 ++++-- accessible/windows/msaa/nsWinUtils.cpp | 39 ++++++++++++------- accessible/windows/msaa/nsWinUtils.h | 21 +++++++++- 4 files changed, 71 insertions(+), 33 deletions(-) diff --git a/accessible/ipc/DocAccessibleParent.cpp b/accessible/ipc/DocAccessibleParent.cpp index 5595e8119909..b3334c8b0dda 100644 --- a/accessible/ipc/DocAccessibleParent.cpp +++ b/accessible/ipc/DocAccessibleParent.cpp @@ -623,26 +623,31 @@ DocAccessibleParent::MaybeInitWindowEmulation() tab->GetDocShellIsActive(&isActive); } - IAccessibleHolder hWndAccHolder; - HWND parentWnd = reinterpret_cast(rootDocument->GetNativeWindow()); - HWND hWnd = nsWinUtils::CreateNativeWindow(kClassNameTabContent, - parentWnd, rect.x, rect.y, - rect.width, rect.height, - isActive); - if (hWnd) { - // Attach accessible document to the emulated native window - ::SetPropW(hWnd, kPropNameDocAccParent, (HANDLE)this); - SetEmulatedWindowHandle(hWnd); + nsWinUtils::NativeWindowCreateProc onCreate([this](HWND aHwnd) -> void { + IAccessibleHolder hWndAccHolder; + + ::SetPropW(aHwnd, kPropNameDocAccParent, reinterpret_cast(this)); + + SetEmulatedWindowHandle(aHwnd); + IAccessible* rawHWNDAcc = nullptr; - if (SUCCEEDED(::AccessibleObjectFromWindow(hWnd, OBJID_WINDOW, + if (SUCCEEDED(::AccessibleObjectFromWindow(aHwnd, OBJID_WINDOW, IID_IAccessible, (void**)&rawHWNDAcc))) { hWndAccHolder.Set(IAccessibleHolder::COMPtrType(rawHWNDAcc)); } - } - Unused << SendEmulatedWindow(reinterpret_cast(mEmulatedWindowHandle), - hWndAccHolder); + Unused << SendEmulatedWindow(reinterpret_cast(mEmulatedWindowHandle), + hWndAccHolder); + }); + + HWND parentWnd = reinterpret_cast(rootDocument->GetNativeWindow()); + DebugOnly hWnd = nsWinUtils::CreateNativeWindow(kClassNameTabContent, + parentWnd, + rect.x, rect.y, + rect.width, rect.height, + isActive, &onCreate); + MOZ_ASSERT(hWnd); } /** diff --git a/accessible/windows/msaa/DocAccessibleWrap.cpp b/accessible/windows/msaa/DocAccessibleWrap.cpp index 9daad7617e9c..1acf750f1315 100644 --- a/accessible/windows/msaa/DocAccessibleWrap.cpp +++ b/accessible/windows/msaa/DocAccessibleWrap.cpp @@ -163,13 +163,16 @@ DocAccessibleWrap::DoInitialUpdate() docShell->GetIsActive(&isActive); } + RefPtr self(this); + nsWinUtils::NativeWindowCreateProc onCreate([self](HWND aHwnd) -> void { + ::SetPropW(aHwnd, kPropNameDocAcc, reinterpret_cast(self.get())); + }); + HWND parentWnd = reinterpret_cast(rootDocument->GetNativeWindow()); mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent, parentWnd, rect.x, rect.y, - rect.width, rect.height, isActive); - - ::SetPropW(static_cast(mHWND), kPropNameDocAcc, (HANDLE)this); - + rect.width, rect.height, isActive, + &onCreate); } else { DocAccessible* parentDocument = ParentDocument(); if (parentDocument) diff --git a/accessible/windows/msaa/nsWinUtils.cpp b/accessible/windows/msaa/nsWinUtils.cpp index 2ee162937151..5f54234db2c2 100644 --- a/accessible/windows/msaa/nsWinUtils.cpp +++ b/accessible/windows/msaa/nsWinUtils.cpp @@ -110,21 +110,17 @@ nsWinUtils::RegisterNativeWindow(LPCWSTR aWindowClass) HWND nsWinUtils::CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd, int aX, int aY, int aWidth, int aHeight, - bool aIsActive) + bool aIsActive, + NativeWindowCreateProc* aOnCreateProc) { - HWND hwnd = ::CreateWindowExW(WS_EX_TRANSPARENT, aWindowClass, - L"NetscapeDispatchWnd", - WS_CHILD | (aIsActive ? WS_VISIBLE : 0), - aX, aY, aWidth, aHeight, - aParentWnd, - nullptr, - GetModuleHandle(nullptr), - nullptr); - if (hwnd) { - // Mark this window so that ipc related code can identify it. - ::SetPropW(hwnd, kPropNameTabContent, (HANDLE)1); - } - return hwnd; + return ::CreateWindowExW(WS_EX_TRANSPARENT, aWindowClass, + L"NetscapeDispatchWnd", + WS_CHILD | (aIsActive ? WS_VISIBLE : 0), + aX, aY, aWidth, aHeight, + aParentWnd, + nullptr, + GetModuleHandle(nullptr), + aOnCreateProc); } void @@ -149,6 +145,21 @@ WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) // message semantics. switch (msg) { + case WM_CREATE: + { + // Mark this window so that ipc related code can identify it. + ::SetPropW(hWnd, kPropNameTabContent, reinterpret_cast(1)); + + auto createStruct = reinterpret_cast(lParam); + auto createProc = reinterpret_cast( + createStruct->lpCreateParams); + + if (createProc && *createProc) { + (*createProc)(hWnd); + } + + return 0; + } case WM_GETOBJECT: { // Do explicit casting to make it working on 64bit systems (see bug 649236 diff --git a/accessible/windows/msaa/nsWinUtils.h b/accessible/windows/msaa/nsWinUtils.h index 55ff21a2636a..3491dc486b71 100644 --- a/accessible/windows/msaa/nsWinUtils.h +++ b/accessible/windows/msaa/nsWinUtils.h @@ -8,6 +8,7 @@ #ifndef nsWinUtils_h_ #define nsWinUtils_h_ +#include #include #include "nsIDOMCSSStyleDeclaration.h" @@ -57,12 +58,30 @@ public: */ static void RegisterNativeWindow(LPCWSTR aWindowClass); + typedef std::function NativeWindowCreateProc; + /** * Helper to create a window. + * + * NB: If additional setup needs to be done once the window has been created, + * you should do so via aOnCreateProc. Hooks will fire during the + * CreateNativeWindow call, thus triggering events in the AT. + * Using aOnCreateProc guarantees that your additional initialization will + * have completed prior to the AT receiving window creation events. + * + * For example: + * + * nsWinUtils::NativeWindowCreateProc onCreate([](HWND aHwnd) -> void { + * DoSomeAwesomeInitializationStuff(aHwnd); + * DoMoreAwesomeInitializationStuff(aHwnd); + * }); + * HWND hwnd = nsWinUtils::CreateNativeWindow(..., &onCreate); + * // Doing further initialization work to hwnd on this line is too late! */ static HWND CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd, int aX, int aY, int aWidth, int aHeight, - bool aIsActive); + bool aIsActive, + NativeWindowCreateProc* aOnCreateProc = nullptr); /** * Helper to show window.