Bug 785534 - Prep work for adding MetroWidget support to the TSF nsTextStore widget module, r=emk
authorJim Mathies <jmathies@mozilla.com>
Mon, 07 Jan 2013 09:18:11 -0600
changeset 117930 bad47c7f923925ac924ebd89139d2a33cfc5d4db
parent 117929 188622e5ffd5de6379834cf760a738227f8e1231
child 117931 9944f44aff85dea183ed7c1ebc7831c84197c084
push id20745
push userjmathies@mozilla.com
push dateMon, 07 Jan 2013 15:18:25 +0000
treeherdermozilla-inbound@bad47c7f9239 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemk
bugs785534
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 785534 - Prep work for adding MetroWidget support to the TSF nsTextStore widget module, r=emk
widget/windows/nsTextStore.cpp
widget/windows/nsTextStore.h
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/windows/nsWindowBase.h
--- a/widget/windows/nsTextStore.cpp
+++ b/widget/windows/nsTextStore.cpp
@@ -8,16 +8,19 @@
 #ifdef MOZ_LOGGING
 #define FORCE_PR_LOG /* Allow logging in the release build */
 #endif // MOZ_LOGGING
 #include "prlog.h"
 
 #include "nscore.h"
 #include "nsTextStore.h"
 #include "nsWindow.h"
+#ifdef MOZ_METRO
+#include "winrt/MetroWidget.h"
+#endif
 #include "nsPrintfCString.h"
 #include "WinUtils.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
 /******************************************************************/
@@ -334,45 +337,44 @@ GetDisplayAttrStr(const TF_DISPLAYATTRIB
 nsTextStore::nsTextStore()
 {
   PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
     ("TSF: 0x%p nsTextStore::nsTestStore(): instance is created", this));
 
   mRefCnt = 1;
   mEditCookie = 0;
   mSinkMask = 0;
-  mWindow = nullptr;
   mLock = 0;
   mLockQueued = 0;
   mTextChange.acpStart = INT32_MAX;
   mTextChange.acpOldEnd = mTextChange.acpNewEnd = 0;
   mLastDispatchedTextEvent = nullptr;
 }
 
 nsTextStore::~nsTextStore()
 {
   PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
     ("TSF: 0x%p nsTextStore instance is destroyed, "
-     "mWindow=0x%p, mDocumentMgr=0x%p, mContext=0x%p",
-     this, mWindow, mDocumentMgr.get(), mContext.get()));
+     "mWidget=0x%p, mDocumentMgr=0x%p, mContext=0x%p",
+     this, mWidget, mDocumentMgr, mContext));
 
   if (mCompositionTimer) {
     mCompositionTimer->Cancel();
     mCompositionTimer = nullptr;
   }
   SaveTextEvent(nullptr);
 }
 
 bool
-nsTextStore::Create(nsWindow* aWindow,
+nsTextStore::Create(nsWindowBase* aWidget,
                     IMEState::Enabled aIMEEnabled)
 {
   PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
-    ("TSF: 0x%p nsTextStore::Create(aWindow=0x%p, aIMEEnabled=%s)",
-     this, aWindow, GetIMEEnabledName(aIMEEnabled)));
+    ("TSF: 0x%p nsTextStore::Create(aWidget=0x%p, aIMEEnabled=%s)",
+     this, aWidget, GetIMEEnabledName(aIMEEnabled)));
 
   if (mDocumentMgr) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
       ("TSF: 0x%p   nsTextStore::Create() FAILED due to already initialized",
        this));
     return false;
   }
 
@@ -380,17 +382,18 @@ nsTextStore::Create(nsWindow* aWindow,
   HRESULT hr = sTsfThreadMgr->CreateDocumentMgr(
                                   getter_AddRefs(mDocumentMgr));
   if (FAILED(hr)) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
       ("TSF: 0x%p   nsTextStore::Create() FAILED to create DocumentMgr "
        "(0x%08X)", this, hr));
     return false;
   }
-  mWindow = aWindow;
+  mWidget = aWidget;
+
   // Create context and add it to document manager
   hr = mDocumentMgr->CreateContext(sTsfClientId, 0,
                                    static_cast<ITextStoreACP*>(this),
                                    getter_AddRefs(mContext), &mEditCookie);
   if (FAILED(hr)) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
       ("TSF: 0x%p   nsTextStore::Create() FAILED to create the context "
        "(0x%08X)", this, hr));
@@ -420,35 +423,35 @@ nsTextStore::Create(nsWindow* aWindow,
 }
 
 bool
 nsTextStore::Destroy(void)
 {
   PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
     ("TSF: 0x%p nsTextStore::Destroy()", this));
 
-  if (mWindow) {
+  if (mWidget) {
     // When blurred, Tablet Input Panel posts "blur" messages
     // and try to insert text when the message is retrieved later.
     // But by that time the text store is already destroyed,
     // so try to get the message early
     MSG msg;
-    if (::PeekMessageW(&msg, mWindow->GetWindowHandle(),
+    if (::PeekMessageW(&msg, mWidget->GetWindowHandle(),
                        sFlushTIPInputMessage, sFlushTIPInputMessage,
                        PM_REMOVE)) {
       ::DispatchMessageW(&msg);
     }
   }
   mContext = NULL;
   if (mDocumentMgr) {
     mDocumentMgr->Pop(TF_POPF_ALL);
     mDocumentMgr = NULL;
   }
   mSink = NULL;
-  mWindow = NULL;
+  mWidget = nullptr;
 
   PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
     ("TSF: 0x%p   nsTextStore::Destroy() succeeded", this));
   return true;
 }
 
 STDMETHODIMP
 nsTextStore::QueryInterface(REFIID riid,
@@ -751,19 +754,19 @@ nsTextStore::GetSelectionInternal(TS_SEL
     // Emulate selection during compositions
     aSelectionACP = mCompositionSelection;
   } else {
     PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
            ("TSF: 0x%p   nsTextStore::GetSelectionInternal(), "
             "try to get normal selection...", this));
 
     // Construct and initialize an event to get selection info
-    nsQueryContentEvent event(true, NS_QUERY_SELECTED_TEXT, mWindow);
-    mWindow->InitEvent(event);
-    mWindow->DispatchWindowEvent(&event);
+    nsQueryContentEvent event(true, NS_QUERY_SELECTED_TEXT, mWidget);
+    mWidget->InitEvent(event);
+    mWidget->DispatchWindowEvent(&event);
     if (!event.mSucceeded) {
       PR_LOG(sTextStoreLog, PR_LOG_ERROR,
              ("TSF: 0x%p   nsTextStore::GetSelectionInternal() FAILED to "
               "query selected text", this));
       return false;
     }
     // Usually the selection anchor (beginning) position corresponds to the
     // TSF start and the selection focus (ending) position corresponds to
@@ -1082,18 +1085,18 @@ nsTextStore::SendTextEventForComposition
   if (FAILED(hr) || !attrPropetry) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::SendTextEventForCompositionString() FAILED "
             "due to mContext->GetProperty() failure", this));
     return FAILED(hr) ? hr : E_FAIL;
   }
 
   // Use NS_TEXT_TEXT to set composition string
-  nsTextEvent event(true, NS_TEXT_TEXT, mWindow);
-  mWindow->InitEvent(event);
+  nsTextEvent event(true, NS_TEXT_TEXT, mWidget);
+  mWidget->InitEvent(event);
 
   nsRefPtr<ITfRange> composingRange;
   hr = mCompositionView->GetRange(getter_AddRefs(composingRange));
   if (FAILED(hr)) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::SendTextEventForCompositionString() FAILED "
             "due to mCompositionView->GetRange() failure", this));
     return hr;
@@ -1213,28 +1216,28 @@ nsTextStore::SendTextEventForComposition
     return S_OK;
   }
 
   if (mCompositionString != mLastDispatchedCompositionString) {
     PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
            ("TSF: 0x%p   nsTextStore::SendTextEventForCompositionString() "
             "dispatching compositionupdate event...", this));
     nsCompositionEvent compositionUpdate(true, NS_COMPOSITION_UPDATE,
-                                         mWindow);
-    mWindow->InitEvent(compositionUpdate);
+                                         mWidget);
+    mWidget->InitEvent(compositionUpdate);
     compositionUpdate.data = mCompositionString;
     mLastDispatchedCompositionString = mCompositionString;
-    mWindow->DispatchWindowEvent(&compositionUpdate);
+    mWidget->DispatchWindowEvent(&compositionUpdate);
   }
 
-  if (mWindow && !mWindow->Destroyed()) {
+  if (mWidget && !mWidget->Destroyed()) {
     PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
            ("TSF: 0x%p   nsTextStore::SendTextEventForCompositionString() "
             "dispatching text event...", this));
-    mWindow->DispatchWindowEvent(&event);
+    mWidget->DispatchWindowEvent(&event);
   }
 
   PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
          ("TSF: 0x%p   nsTextStore::SendTextEventForCompositionString() "
           "succeeded", this));
 
   return SaveTextEvent(&event);
 }
@@ -1277,22 +1280,22 @@ nsTextStore::SetSelectionInternal(const 
         PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::SetSelectionInternal() FAILED due to "
             "SendTextEventForCompositionString() failure", this));
         return hr;
       }
     }
     return S_OK;
   } else {
-    nsSelectionEvent event(true, NS_SELECTION_SET, mWindow);
+    nsSelectionEvent event(true, NS_SELECTION_SET, mWidget);
     event.mOffset = pSelection->acpStart;
     event.mLength = uint32_t(pSelection->acpEnd - pSelection->acpStart);
     event.mReversed = pSelection->style.ase == TS_AE_START;
-    mWindow->InitEvent(event);
-    mWindow->DispatchWindowEvent(&event);
+    mWidget->InitEvent(event);
+    mWidget->DispatchWindowEvent(&event);
     if (!event.mSucceeded) {
       PR_LOG(sTextStoreLog, PR_LOG_ERROR,
          ("TSF: 0x%p   nsTextStore::SetSelectionInternal() FAILED due to "
           "NS_SELECTION_SET failure", this));
       return E_FAIL;
     }
   }
   return S_OK;
@@ -1410,20 +1413,20 @@ nsTextStore::GetText(LONG acpStart,
       // Check if the range is affected
       if (compOldEnd > compNewStart || compNewEnd > compNewStart) {
         NS_ASSERTION(compOldEnd >= mCompositionStart &&
             compNewEnd >= mCompositionStart, "Range end is less than start\n");
         length = uint32_t(LONG(length) + compOldEnd - compNewEnd);
       }
     }
     // Send NS_QUERY_TEXT_CONTENT to get text content
-    nsQueryContentEvent event(true, NS_QUERY_TEXT_CONTENT, mWindow);
-    mWindow->InitEvent(event);
+    nsQueryContentEvent event(true, NS_QUERY_TEXT_CONTENT, mWidget);
+    mWidget->InitEvent(event);
     event.InitForQueryTextContent(uint32_t(acpStart), length);
-    mWindow->DispatchWindowEvent(&event);
+    mWidget->DispatchWindowEvent(&event);
     if (!event.mSucceeded) {
       PR_LOG(sTextStoreLog, PR_LOG_ERROR,
              ("TSF: 0x%p   nsTextStore::GetText() FAILED due to "
               "NS_QUERY_TEXT_CONTENT failure: length=%lu", this, length));
       return E_FAIL;
     }
 
     if (compOldEnd > compNewStart || compNewEnd > compNewStart) {
@@ -1688,21 +1691,21 @@ nsTextStore::GetEndACP(LONG *pacp)
   if (!pacp) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::GetEndACP() FAILED due to "
             "null argument", this));
     return E_INVALIDARG;
   }
 
   // Flattened text is retrieved and its length returned
-  nsQueryContentEvent event(true, NS_QUERY_TEXT_CONTENT, mWindow);
-  mWindow->InitEvent(event);
+  nsQueryContentEvent event(true, NS_QUERY_TEXT_CONTENT, mWidget);
+  mWidget->InitEvent(event);
   // Return entire text
   event.InitForQueryTextContent(0, INT32_MAX);
-  mWindow->DispatchWindowEvent(&event);
+  mWidget->DispatchWindowEvent(&event);
   if (!event.mSucceeded) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::GetEndACP() FAILED due to "
             "NS_QUERY_TEXT_CONTENT failure", this));
     return E_FAIL;
   }
   *pacp = LONG(event.mReply.mString.Length());
   return S_OK;
@@ -1796,46 +1799,48 @@ nsTextStore::GetTextExt(TsViewCookie vcV
   if (acpStart < 0 || acpEnd < acpStart) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::GetTextExt() FAILED due to "
             "invalid position", this));
     return TS_E_INVALIDPOS;
   }
 
   // use NS_QUERY_TEXT_RECT to get rect in system, screen coordinates
-  nsQueryContentEvent event(true, NS_QUERY_TEXT_RECT, mWindow);
-  mWindow->InitEvent(event);
+  nsQueryContentEvent event(true, NS_QUERY_TEXT_RECT, mWidget);
+  mWidget->InitEvent(event);
   event.InitForQueryTextRect(acpStart, acpEnd - acpStart);
-  mWindow->DispatchWindowEvent(&event);
+  mWidget->DispatchWindowEvent(&event);
   if (!event.mSucceeded) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::GetTextExt() FAILED due to "
             "NS_QUERY_TEXT_RECT failure", this));
     return TS_E_INVALIDPOS; // but unexpected failure, maybe.
   }
   // IMEs don't like empty rects, fix here
   if (event.mReply.mRect.width <= 0)
     event.mReply.mRect.width = 1;
   if (event.mReply.mRect.height <= 0)
     event.mReply.mRect.height = 1;
 
-  // convert to unclipped screen rect
-  nsWindow* refWindow = static_cast<nsWindow*>(
-      event.mReply.mFocusedWidget ? event.mReply.mFocusedWidget : mWindow);
-  // Result rect is in top level widget coordinates
-  refWindow = refWindow->GetTopLevelWindow(false);
-  if (!refWindow) {
-    PR_LOG(sTextStoreLog, PR_LOG_ERROR,
-           ("TSF: 0x%p   nsTextStore::GetTextExt() FAILED due to "
-            "no top level window", this));
-    return E_FAIL;
+  if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop) {
+    // convert to unclipped screen rect
+    nsWindow* refWindow = static_cast<nsWindow*>(
+      event.mReply.mFocusedWidget ? event.mReply.mFocusedWidget : mWidget);
+    // Result rect is in top level widget coordinates
+    refWindow = refWindow->GetTopLevelWindow(false);
+    if (!refWindow) {
+      PR_LOG(sTextStoreLog, PR_LOG_ERROR,
+             ("TSF: 0x%p   nsTextStore::GetTextExt() FAILED due to "
+              "no top level window", this));
+      return E_FAIL;
+    }
+
+    event.mReply.mRect.MoveBy(refWindow->WidgetToScreenOffset());
   }
 
-  event.mReply.mRect.MoveBy(refWindow->WidgetToScreenOffset());
-
   // get bounding screen rect to test for clipping
   if (!GetScreenExtInternal(*prc)) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::GetTextExt() FAILED due to "
             "GetScreenExtInternal() failure", this));
     return E_FAIL;
   }
 
@@ -1897,88 +1902,104 @@ nsTextStore::GetScreenExt(TsViewCookie v
 
 bool
 nsTextStore::GetScreenExtInternal(RECT &aScreenExt)
 {
   PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
          ("TSF: 0x%p   nsTextStore::GetScreenExtInternal()", this));
 
   // use NS_QUERY_EDITOR_RECT to get rect in system, screen coordinates
-  nsQueryContentEvent event(true, NS_QUERY_EDITOR_RECT, mWindow);
-  mWindow->InitEvent(event);
-  mWindow->DispatchWindowEvent(&event);
+  nsQueryContentEvent event(true, NS_QUERY_EDITOR_RECT, mWidget);
+  mWidget->InitEvent(event);
+  mWidget->DispatchWindowEvent(&event);
   if (!event.mSucceeded) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::GetScreenExtInternal() FAILED due to "
             "NS_QUERY_EDITOR_RECT failure", this));
     return false;
   }
 
-  nsWindow* refWindow = static_cast<nsWindow*>(
-      event.mReply.mFocusedWidget ? event.mReply.mFocusedWidget : mWindow);
-  // Result rect is in top level widget coordinates
-  refWindow = refWindow->GetTopLevelWindow(false);
-  if (!refWindow) {
-    PR_LOG(sTextStoreLog, PR_LOG_ERROR,
-           ("TSF: 0x%p   nsTextStore::GetScreenExtInternal() FAILED due to "
-            "no top level window", this));
-    return false;
-  }
-
-  nsIntRect boundRect;
-  if (NS_FAILED(refWindow->GetClientBounds(boundRect))) {
-    PR_LOG(sTextStoreLog, PR_LOG_ERROR,
-           ("TSF: 0x%p   nsTextStore::GetScreenExtInternal() FAILED due to "
-            "failed to get the client bounds", this));
-    return false;
-  }
-
-  boundRect.MoveTo(0, 0);
-
-  // Clip frame rect to window rect
-  boundRect.IntersectRect(event.mReply.mRect, boundRect);
-  if (!boundRect.IsEmpty()) {
-    boundRect.MoveBy(refWindow->WidgetToScreenOffset());
+  if (XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Metro) {
+    nsIntRect boundRect;
+    if (NS_FAILED(mWidget->GetClientBounds(boundRect))) {
+      PR_LOG(sTextStoreLog, PR_LOG_ERROR,
+             ("TSF: 0x%p   nsTextStore::GetScreenExtInternal() FAILED due to "
+              "failed to get the client bounds", this));
+      return false;
+    }
     ::SetRect(&aScreenExt, boundRect.x, boundRect.y,
               boundRect.XMost(), boundRect.YMost());
   } else {
-    ::SetRectEmpty(&aScreenExt);
+    NS_ASSERTION(XRE_GetWindowsEnvironment() == WindowsEnvironmentType_Desktop,
+                 "environment isn't WindowsEnvironmentType_Desktop!");
+    nsWindow* refWindow = static_cast<nsWindow*>(
+      event.mReply.mFocusedWidget ?
+        event.mReply.mFocusedWidget : mWidget);
+    // Result rect is in top level widget coordinates
+    refWindow = refWindow->GetTopLevelWindow(false);
+    if (!refWindow) {
+      PR_LOG(sTextStoreLog, PR_LOG_ERROR,
+             ("TSF: 0x%p   nsTextStore::GetScreenExtInternal() FAILED due to "
+              "no top level window", this));
+      return false;
+    }
+
+    nsIntRect boundRect;
+    if (NS_FAILED(refWindow->GetClientBounds(boundRect))) {
+      PR_LOG(sTextStoreLog, PR_LOG_ERROR,
+             ("TSF: 0x%p   nsTextStore::GetScreenExtInternal() FAILED due to "
+              "failed to get the client bounds", this));
+      return false;
+    }
+
+    boundRect.MoveTo(0, 0);
+
+    // Clip frame rect to window rect
+    boundRect.IntersectRect(event.mReply.mRect, boundRect);
+    if (!boundRect.IsEmpty()) {
+      boundRect.MoveBy(refWindow->WidgetToScreenOffset());
+      ::SetRect(&aScreenExt, boundRect.x, boundRect.y,
+                boundRect.XMost(), boundRect.YMost());
+    } else {
+      ::SetRectEmpty(&aScreenExt);
+    }
   }
 
   PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
          ("TSF: 0x%p   nsTextStore::GetScreenExtInternal() succeeded: "
           "aScreenExt={ left=%ld, top=%ld, right=%ld, bottom=%ld }",
           this, aScreenExt.left, aScreenExt.top,
           aScreenExt.right, aScreenExt.bottom));
   return true;
 }
 
 STDMETHODIMP
 nsTextStore::GetWnd(TsViewCookie vcView,
                     HWND *phwnd)
 {
   PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
-         ("TSF: 0x%p nsTextStore::GetWnd(vcView=%ld, phwnd=0x%p), mWindow=0x%p",
-          this, vcView, phwnd, mWindow));
+         ("TSF: 0x%p nsTextStore::GetWnd(vcView=%ld, phwnd=0x%p), "
+          "mWidget=0x%p",
+          this, vcView, phwnd, mWidget));
 
   if (vcView != TEXTSTORE_DEFAULT_VIEW) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::GetWnd() FAILED due to "
             "called with invalid view", this));
     return E_INVALIDARG;
   }
 
   if (!phwnd) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::GetScreenExt() FAILED due to "
             "null argument", this));
     return E_INVALIDARG;
   }
 
-  *phwnd = mWindow->GetWindowHandle();
+  *phwnd = mWidget->GetWindowHandle();
 
   PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
          ("TSF: 0x%p   nsTextStore::GetWnd() succeeded: *phwnd=0x%p",
           this, static_cast<void*>(*phwnd)));
   return S_OK;
 }
 
 STDMETHODIMP
@@ -2130,65 +2151,67 @@ nsTextStore::InsertTextAtSelectionIntern
               "due to GetSelectionInternal() failure", this));
       return false;
     }
 
     // Use a temporary composition to contain the text
     PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
            ("TSF: 0x%p   nsTextStore::InsertTextAtSelectionInternal() "
             "dispatching a compositionstart event...", this));
-    nsCompositionEvent compStartEvent(true, NS_COMPOSITION_START, mWindow);
-    mWindow->InitEvent(compStartEvent);
-    mWindow->DispatchWindowEvent(&compStartEvent);
-    if (!mWindow || mWindow->Destroyed()) {
+    nsCompositionEvent compStartEvent(true, NS_COMPOSITION_START,
+                                      mWidget);
+    mWidget->InitEvent(compStartEvent);
+    mWidget->DispatchWindowEvent(&compStartEvent);
+    if (!mWidget || mWidget->Destroyed()) {
       PR_LOG(sTextStoreLog, PR_LOG_ERROR,
              ("TSF: 0x%p   nsTextStore::InsertTextAtSelectionInternal() FAILED "
               "due to the widget destroyed by compositionstart event", this));
       return false;
     }
 
     if (!aInsertStr.IsEmpty()) {
     PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
            ("TSF: 0x%p   nsTextStore::InsertTextAtSelectionInternal() "
             "dispatching a compositionupdate event...", this));
-      nsCompositionEvent compUpdateEvent(true, NS_COMPOSITION_UPDATE, mWindow);
+      nsCompositionEvent compUpdateEvent(true, NS_COMPOSITION_UPDATE,
+                                         mWidget);
       compUpdateEvent.data = aInsertStr;
-      mWindow->DispatchWindowEvent(&compUpdateEvent);
-      if (!mWindow || mWindow->Destroyed()) {
+      mWidget->DispatchWindowEvent(&compUpdateEvent);
+      if (!mWidget || mWidget->Destroyed()) {
         PR_LOG(sTextStoreLog, PR_LOG_ERROR,
                ("TSF: 0x%p   nsTextStore::InsertTextAtSelectionInternal() "
                 "FAILED due to the widget destroyed by compositionupdate event",
                 this));
         return false;
       }
     }
 
     PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
            ("TSF: 0x%p   nsTextStore::InsertTextAtSelectionInternal() "
             "dispatching a text event...", this));
-    nsTextEvent textEvent(true, NS_TEXT_TEXT, mWindow);
-    mWindow->InitEvent(textEvent);
+    nsTextEvent textEvent(true, NS_TEXT_TEXT, mWidget);
+    mWidget->InitEvent(textEvent);
     textEvent.theText = aInsertStr;
     textEvent.theText.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
                                        NS_LITERAL_STRING("\n"));
-    mWindow->DispatchWindowEvent(&textEvent);
-    if (!mWindow || mWindow->Destroyed()) {
+    mWidget->DispatchWindowEvent(&textEvent);
+    if (!mWidget || mWidget->Destroyed()) {
       PR_LOG(sTextStoreLog, PR_LOG_ERROR,
              ("TSF: 0x%p   nsTextStore::InsertTextAtSelectionInternal() FAILED "
               "due to the widget destroyed by text event", this));
       return false;
     }
 
     PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
            ("TSF: 0x%p   nsTextStore::InsertTextAtSelectionInternal() "
             "dispatching a compositionend event...", this));
-    nsCompositionEvent compEndEvent(true, NS_COMPOSITION_END, mWindow);
+    nsCompositionEvent compEndEvent(true, NS_COMPOSITION_END, mWidget);
     compEndEvent.data = aInsertStr;
-    mWindow->DispatchWindowEvent(&compEndEvent);
-    if (!mWindow || mWindow->Destroyed()) {
+    mWidget->DispatchWindowEvent(&compEndEvent);
+    if (!mWidget || mWidget->Destroyed()) {
       PR_LOG(sTextStoreLog, PR_LOG_ERROR,
              ("TSF: 0x%p   nsTextStore::InsertTextAtSelectionInternal() FAILED "
               "due to the widget destroyed by compositionend event", this));
       return false;
     }
   }
 
   if (aTextChange) {
@@ -2204,19 +2227,19 @@ nsTextStore::InsertTextAtSelectionIntern
               this));
       return false;
     }
     aTextChange->acpNewEnd = newSelection.acpEnd;
   }
 
   PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
          ("TSF: 0x%p   nsTextStore::InsertTextAtSelectionInternal() succeeded: "
-          "mWindow=0x%p, mWindow->Destroyed()=%s, aTextChange={ acpStart=%ld, "
+          "mWidget=0x%p, mWidget->Destroyed()=%s, aTextChange={ acpStart=%ld, "
           "acpOldEnd=%ld, acpNewEnd=%ld }",
-          this, mWindow, GetBoolName(mWindow ? mWindow->Destroyed() : true),
+          this, mWidget, GetBoolName(mWidget ? mWidget->Destroyed() : true),
           aTextChange ? aTextChange->acpStart : 0,
           aTextChange ? aTextChange->acpOldEnd : 0,
           aTextChange ? aTextChange->acpNewEnd : 0));
   return true;
 }
 
 STDMETHODIMP
 nsTextStore::InsertEmbeddedAtSelection(DWORD dwFlags,
@@ -2259,33 +2282,33 @@ nsTextStore::OnStartCompositionInternal(
           "mCompositionStart=%ld, mCompositionLength=%ld",
           this, mCompositionStart, mCompositionLength));
 
   PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
          ("TSF: 0x%p   nsTextStore::OnStartCompositionInternal(), "
           "dispatching selectionset event..."));
 
   // Select composition range so the new composition replaces the range
-  nsSelectionEvent selEvent(true, NS_SELECTION_SET, mWindow);
-  mWindow->InitEvent(selEvent);
+  nsSelectionEvent selEvent(true, NS_SELECTION_SET, mWidget);
+  mWidget->InitEvent(selEvent);
   selEvent.mOffset = uint32_t(mCompositionStart);
   selEvent.mLength = uint32_t(mCompositionLength);
   selEvent.mReversed = false;
-  mWindow->DispatchWindowEvent(&selEvent);
+  mWidget->DispatchWindowEvent(&selEvent);
   if (!selEvent.mSucceeded) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::OnStartCompositionInternal() FAILED due "
             "to NS_SELECTION_SET failure", this));
     return E_FAIL;
   }
 
   // Set up composition
-  nsQueryContentEvent queryEvent(true, NS_QUERY_SELECTED_TEXT, mWindow);
-  mWindow->InitEvent(queryEvent);
-  mWindow->DispatchWindowEvent(&queryEvent);
+  nsQueryContentEvent queryEvent(true, NS_QUERY_SELECTED_TEXT, mWidget);
+  mWidget->InitEvent(queryEvent);
+  mWidget->DispatchWindowEvent(&queryEvent);
   if (!queryEvent.mSucceeded) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::OnStartCompositionInternal() FAILED due "
             "to NS_QUERY_SELECTED_TEXT failure", this));
     return E_FAIL;
   }
 
   PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
@@ -2294,19 +2317,19 @@ nsTextStore::OnStartCompositionInternal(
 
   mCompositionString = queryEvent.mReply.mString;
   if (!aPreserveSelection) {
     mCompositionSelection.acpStart = mCompositionStart;
     mCompositionSelection.acpEnd = mCompositionStart + mCompositionLength;
     mCompositionSelection.style.ase = TS_AE_END;
     mCompositionSelection.style.fInterimChar = FALSE;
   }
-  nsCompositionEvent event(true, NS_COMPOSITION_START, mWindow);
-  mWindow->InitEvent(event);
-  mWindow->DispatchWindowEvent(&event);
+  nsCompositionEvent event(true, NS_COMPOSITION_START, mWidget);
+  mWidget->InitEvent(event);
+  mWidget->DispatchWindowEvent(&event);
 
   PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
          ("TSF: 0x%p   nsTextStore::OnStartCompositionInternal() succeeded: "
           "mCompositionStart=%ld, mCompositionLength=%ld, "
           "mCompositionSelection={ acpStart=%ld, acpEnd=%ld, style.ase=%s, "
           "style.iInterimChar=%s }",
           this, mCompositionStart, mCompositionLength,
           mCompositionSelection.acpStart, mCompositionSelection.acpEnd,
@@ -2471,58 +2494,58 @@ nsTextStore::OnEndComposition(ITfComposi
     mCompositionTimer = nullptr;
   }
 
   if (mCompositionString != mLastDispatchedCompositionString) {
     PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
            ("TSF: 0x%p   nsTextStore::OnEndComposition(), "
             "dispatching compositionupdate event...", this));
     nsCompositionEvent compositionUpdate(true, NS_COMPOSITION_UPDATE,
-                                         mWindow);
-    mWindow->InitEvent(compositionUpdate);
+                                         mWidget);
+    mWidget->InitEvent(compositionUpdate);
     compositionUpdate.data = mCompositionString;
     mLastDispatchedCompositionString = mCompositionString;
-    mWindow->DispatchWindowEvent(&compositionUpdate);
-    if (!mWindow || mWindow->Destroyed()) {
+    mWidget->DispatchWindowEvent(&compositionUpdate);
+    if (!mWidget || mWidget->Destroyed()) {
       PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
              ("TSF: 0x%p   nsTextStore::OnEndComposition(), "
               "succeeded, but the widget has gone", this));
       return S_OK;
     }
   }
 
   PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
          ("TSF: 0x%p   nsTextStore::OnEndComposition(), "
           "dispatching text event...", this));
 
   // Use NS_TEXT_TEXT to commit composition string
-  nsTextEvent textEvent(true, NS_TEXT_TEXT, mWindow);
-  mWindow->InitEvent(textEvent);
+  nsTextEvent textEvent(true, NS_TEXT_TEXT, mWidget);
+  mWidget->InitEvent(textEvent);
   textEvent.theText = mCompositionString;
   textEvent.theText.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
                                      NS_LITERAL_STRING("\n"));
-  mWindow->DispatchWindowEvent(&textEvent);
+  mWidget->DispatchWindowEvent(&textEvent);
 
-  if (!mWindow || mWindow->Destroyed()) {
+  if (!mWidget || mWidget->Destroyed()) {
     PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
            ("TSF: 0x%p   nsTextStore::OnEndComposition(), "
             "succeeded, but the widget has gone", this));
     return S_OK;
   }
 
   PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
          ("TSF: 0x%p   nsTextStore::OnEndComposition(), "
           "dispatching compositionend event...", this));
 
-  nsCompositionEvent event(true, NS_COMPOSITION_END, mWindow);
+  nsCompositionEvent event(true, NS_COMPOSITION_END, mWidget);
   event.data = mLastDispatchedCompositionString;
-  mWindow->InitEvent(event);
-  mWindow->DispatchWindowEvent(&event);
+  mWidget->InitEvent(event);
+  mWidget->DispatchWindowEvent(&event);
 
-  if (!mWindow || mWindow->Destroyed()) {
+  if (!mWidget || mWidget->Destroyed()) {
     PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
            ("TSF: 0x%p   nsTextStore::OnEndComposition(), "
             "succeeded, but the widget has gone", this));
     return S_OK;
   }
 
   mCompositionView = NULL;
   mCompositionString.Truncate(0);
@@ -2533,32 +2556,34 @@ nsTextStore::OnEndComposition(ITfComposi
 
   PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
          ("TSF: 0x%p   nsTextStore::OnEndComposition(), succeeded", this));
   return S_OK;
 }
 
 // static
 nsresult
-nsTextStore::OnFocusChange(bool aFocus,
-                           nsWindow* aWindow,
+nsTextStore::OnFocusChange(bool aGotFocus,
+                           nsWindowBase* aFocusedWidget,
                            IMEState::Enabled aIMEEnabled)
 {
   PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
-         ("TSF: nsTextStore::OnFocusChange(aFocus=%s, aWindow=0x%p, "
-          "aIMEEnabled=%s), sTsfThreadMgr=0x%p, sTsfTextStore=0x%p",
-          GetBoolName(aFocus), aWindow, GetIMEEnabledName(aIMEEnabled),
-          sTsfThreadMgr, sTsfTextStore));
+         ("TSF: nsTextStore::OnFocusChange(aGotFocus=%s, "
+          "aFocusedWidget=0x%p, aIMEEnabled=%s), sTsfThreadMgr=0x%p, "
+          "sTsfTextStore=0x%p",
+          GetBoolName(aGotFocus), aFocusedWidget,
+          GetIMEEnabledName(aIMEEnabled), sTsfThreadMgr, sTsfTextStore));
 
   // no change notifications if TSF is disabled
-  if (!sTsfThreadMgr || !sTsfTextStore)
+  if (!sTsfThreadMgr || !sTsfTextStore) {
     return NS_ERROR_NOT_AVAILABLE;
+  }
 
-  if (aFocus) {
-    bool bRet = sTsfTextStore->Create(aWindow, aIMEEnabled);
+  if (aGotFocus) {
+    bool bRet = sTsfTextStore->Create(aFocusedWidget, aIMEEnabled);
     NS_ENSURE_TRUE(bRet, NS_ERROR_FAILURE);
     NS_ENSURE_TRUE(sTsfTextStore->mDocumentMgr, NS_ERROR_FAILURE);
     HRESULT hr = sTsfThreadMgr->SetFocus(sTsfTextStore->mDocumentMgr);
     NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
   } else {
     sTsfTextStore->Destroy();
   }
   return NS_OK;
@@ -2589,17 +2614,17 @@ nsTextStore::OnTextChangeInternal(uint32
           this, aStart, aOldEnd, aNewEnd, GetLockFlagNameStr(mLock).get(),
           mSink.get(), GetSinkMaskNameStr(mSinkMask).get(),
           mTextChange.acpStart, mTextChange.acpOldEnd, mTextChange.acpNewEnd));
 
   if (!mLock && mSink && 0 != (mSinkMask & TS_AS_TEXT_CHANGE)) {
     mTextChange.acpStart = NS_MIN(mTextChange.acpStart, LONG(aStart));
     mTextChange.acpOldEnd = NS_MAX(mTextChange.acpOldEnd, LONG(aOldEnd));
     mTextChange.acpNewEnd = NS_MAX(mTextChange.acpNewEnd, LONG(aNewEnd));
-    ::PostMessageW(mWindow->GetWindowHandle(),
+    ::PostMessageW(mWidget->GetWindowHandle(),
                    WM_USER_TSF_TEXTCHANGE, 0, 0);
   }
   return NS_OK;
 }
 
 void
 nsTextStore::OnTextChangeMsgInternal(void)
 {
--- a/widget/windows/nsTextStore.h
+++ b/widget/windows/nsTextStore.h
@@ -6,27 +6,31 @@
 #ifndef NSTEXTSTORE_H_
 #define NSTEXTSTORE_H_
 
 #include "nsAutoPtr.h"
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "nsITimer.h"
 #include "nsIWidget.h"
+#include "nsWindowBase.h"
 #include "mozilla/Attributes.h"
 
 #include <msctf.h>
 #include <textstor.h>
 
 struct ITfThreadMgr;
 struct ITfDocumentMgr;
 struct ITfDisplayAttributeMgr;
 struct ITfCategoryMgr;
 class nsWindow;
 class nsTextEvent;
+#ifdef MOZ_METRO
+class MetroWidget;
+#endif
 
 // It doesn't work well when we notify TSF of text change
 // during a mutation observer call because things get broken.
 // So we post a message and notify TSF when we get it later.
 #define WM_USER_TSF_TEXTCHANGE  (WM_USER + 0x100)
 
 /*
  * Text Services Framework text store
@@ -95,18 +99,19 @@ public:
   }
 
   static void     SetInputContext(const InputContext& aContext)
   {
     if (!sTsfTextStore) return;
     sTsfTextStore->SetInputContextInternal(aContext.mIMEState.mEnabled);
   }
 
-  static nsresult OnFocusChange(bool, nsWindow*, IMEState::Enabled);
-
+  static nsresult OnFocusChange(bool aGotFocus,
+                                nsWindowBase* aFocusedWidget,
+                                IMEState::Enabled aIMEEnabled);
   static nsresult OnTextChange(uint32_t aStart,
                                uint32_t aOldEnd,
                                uint32_t aNewEnd)
   {
     if (!sTsfTextStore) return NS_OK;
     return sTsfTextStore->OnTextChangeInternal(aStart, aOldEnd, aNewEnd);
   }
 
@@ -149,17 +154,18 @@ public:
   {
     return (void*) & sDisplayAttrMgr;
   }
 
 protected:
   nsTextStore();
   ~nsTextStore();
 
-  bool     Create(nsWindow*, IMEState::Enabled);
+  bool     Create(nsWindowBase* aWidget,
+                  IMEState::Enabled aIMEEnabled);
   bool     Destroy(void);
 
   bool     IsReadLock(DWORD aLock) const
   {
     return (TS_LF_READ == (aLock & TS_LF_READ));
   }
   bool     IsReadWriteLock(DWORD aLock) const
   {
@@ -187,28 +193,28 @@ protected:
   HRESULT  GetDisplayAttribute(ITfProperty* aProperty,
                                ITfRange* aRange,
                                TF_DISPLAYATTRIBUTE* aResult);
   HRESULT  UpdateCompositionExtent(ITfRange* pRangeNew);
   HRESULT  SendTextEventForCompositionString();
   HRESULT  SaveTextEvent(const nsTextEvent* aEvent);
   nsresult OnCompositionTimer();
 
+  // Holds the pointer to our current win32 or metro widget
+  nsRefPtr<nsWindowBase>       mWidget;
   // Document manager for the currently focused editor
   nsRefPtr<ITfDocumentMgr>     mDocumentMgr;
   // Edit cookie associated with the current editing context
   DWORD                        mEditCookie;
   // Editing context at the bottom of mDocumentMgr's context stack
   nsRefPtr<ITfContext>         mContext;
   // Currently installed notification sink
   nsRefPtr<ITextStoreACPSink>  mSink;
   // TS_AS_* mask of what events to notify
   DWORD                        mSinkMask;
-  // Window containing the focused editor
-  nsWindow*                    mWindow;
   // 0 if not locked, otherwise TS_LF_* indicating the current lock
   DWORD                        mLock;
   // 0 if no lock is queued, otherwise TS_LF_* indicating the queue lock
   DWORD                        mLockQueued;
   // Cumulative text change offsets since the last notification
   TS_TEXTCHANGE                mTextChange;
   // NULL if no composition is active, otherwise the current composition
   nsRefPtr<ITfCompositionView> mCompositionView;
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -297,17 +297,17 @@ static const int32_t kResizableBorderMin
  **************************************************************/
 
 /**************************************************************
  *
  * SECTION: nsWindow construction and destruction
  *
  **************************************************************/
 
-nsWindow::nsWindow() : nsBaseWidget()
+nsWindow::nsWindow() : nsWindowBase()
 {
 #ifdef PR_LOGGING
   if (!gWindowsLog) {
     gWindowsLog = PR_NewLogModule("nsWindow");
   }
 #endif
 
   mIconSmall            = nullptr;
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -7,16 +7,17 @@
 #define Window_h__
 
 /*
  * nsWindow - Native window management and event handling.
  */
 
 #include "nsAutoPtr.h"
 #include "nsBaseWidget.h"
+#include "nsWindowBase.h"
 #include "nsdefs.h"
 #include "nsIdleService.h"
 #include "nsToolkit.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsEvent.h"
 #include "gfxWindowsSurface.h"
 #include "nsWindowDbg.h"
@@ -59,34 +60,36 @@ class NativeKey;
 class ModifierKeyState;
 } // namespace widget
 } // namespacw mozilla;
 
 /**
  * Native WIN32 window wrapper.
  */
 
-class nsWindow : public nsBaseWidget
+class nsWindow : public nsWindowBase
 {
   typedef mozilla::TimeStamp TimeStamp;
   typedef mozilla::TimeDuration TimeDuration;
   typedef mozilla::widget::WindowHook WindowHook;
   typedef mozilla::widget::TaskbarWindowPreview TaskbarWindowPreview;
   typedef mozilla::widget::NativeKey NativeKey;
 public:
   nsWindow();
   virtual ~nsWindow();
 
   NS_DECL_ISUPPORTS_INHERITED
 
   friend class nsWindowGfx;
 
-  /**
-   * nsIWidget interface
-   */
+  // nsWindowBase
+  virtual void InitEvent(nsGUIEvent& aEvent, nsIntPoint* aPoint = nullptr) MOZ_OVERRIDE;
+  virtual bool DispatchWindowEvent(nsGUIEvent* aEvent) MOZ_OVERRIDE;
+
+  // nsIWidget interface
   NS_IMETHOD              Create(nsIWidget *aParent,
                                  nsNativeWidget aNativeParent,
                                  const nsIntRect &aRect,
                                  nsDeviceContext *aContext,
                                  nsWidgetInitData *aInitData = nullptr);
   NS_IMETHOD              Destroy();
   NS_IMETHOD              SetParent(nsIWidget *aNewParent);
   virtual nsIWidget*      GetParent(void);
@@ -181,23 +184,21 @@ public:
 #endif // NS_ENABLE_TSF
   NS_IMETHOD              GetNonClientMargins(nsIntMargin &margins);
   NS_IMETHOD              SetNonClientMargins(nsIntMargin &margins);
   void                    SetDrawsInTitlebar(bool aState);
 
   /**
    * Event helpers
    */
-  void                    InitEvent(nsGUIEvent& event, nsIntPoint* aPoint = nullptr);
   virtual bool            DispatchMouseEvent(uint32_t aEventType, WPARAM wParam,
                                              LPARAM lParam,
                                              bool aIsContextMenuKey = false,
                                              int16_t aButton = nsMouseEvent::eLeftButton,
                                              uint16_t aInputSource = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE);
-  virtual bool            DispatchWindowEvent(nsGUIEvent* event);
   virtual bool            DispatchWindowEvent(nsGUIEvent*event, nsEventStatus &aStatus);
   void                    InitKeyEvent(nsKeyEvent& aKeyEvent,
                                        const NativeKey& aNativeKey,
                                        const mozilla::widget::ModifierKeyState &aModKeyState);
   virtual bool            DispatchKeyEvent(nsKeyEvent& aKeyEvent,
                                            const MSG *aMsgSentToPlugin);
   void                    DispatchPendingEvents();
   bool                    DispatchPluginEvent(UINT aMessage,
@@ -210,17 +211,16 @@ public:
 #ifdef ACCESSIBILITY
   mozilla::a11y::Accessible* GetRootAccessible();
 #endif // ACCESSIBILITY
 
   /**
    * Window utilities
    */
   nsWindow*               GetTopLevelWindow(bool aStopOnDialogOrPopup);
-  HWND                    GetWindowHandle() { return mWnd; }
   WNDPROC                 GetPrevWindowProc() { return mPrevWndProc; }
   WindowHook&             GetWindowHook() { return mWindowHook; }
   nsWindow*               GetParentWindow(bool aIncludeOwner);
   // Get an array of all nsWindow*s on the main thread.
   typedef void            (WindowEnumCallback)(nsWindow*);
   static void             EnumAllWindows(WindowEnumCallback aCallback);
 
   /**
new file mode 100644
--- /dev/null
+++ b/widget/windows/nsWindowBase.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsWindowBase_h_
+#define nsWindowBase_h_
+
+#include "nsBaseWidget.h"
+
+/*
+ * nsWindowBase - Base class of common methods other classes need to access
+ * in both win32 and winrt window classes.
+ */
+
+class nsWindowBase : public nsBaseWidget
+{
+public:
+  /*
+   * Return the HWND or null for this widget.
+   */
+  virtual HWND GetWindowHandle() MOZ_FINAL {
+    return static_cast<HWND>(GetNativeData(NS_NATIVE_WINDOW));
+  }
+
+  /*
+   * Init a standard gecko event for this widget.
+   */
+  virtual void InitEvent(nsGUIEvent& aEvent, nsIntPoint* aPoint = nullptr) = 0;
+
+  /*
+   * Dispatch a gecko event for this widget.
+   */
+  virtual bool DispatchWindowEvent(nsGUIEvent* aEvent) = 0;
+};
+
+#endif // nsWindowBase_h_