Bug 1405210 - Part 2: Move native printing dialog code to windows widget. r?jimm draft
authorMantaroh Yoshinaga <mantaroh@gmail.com>
Thu, 19 Oct 2017 11:04:30 +0900
changeset 682923 389f337fb9c76f097d9177e1aafe29be402f20d3
parent 682922 9e0a9e3614520f021efca8070819786b8c7a09d0
child 682924 075ed3f2e94ccfd88d90a6925e11c5249f72865b
push id85208
push usermantaroh@gmail.com
push dateThu, 19 Oct 2017 02:07:22 +0000
reviewersjimm
bugs1405210
milestone58.0a1
Bug 1405210 - Part 2: Move native printing dialog code to windows widget. r?jimm This patch will * Move native print dialog code to the PrintDialogService of widget. * Toolkit call PrintDialogService instead of calling the native print dialog. * Change SetWindowText/CreateWindow to SetWindowTextW/CreateWindowW in order to treat localized string correctly. MozReview-Commit-ID: DOgp3STaJ4t
toolkit/components/printingui/win/moz.build
toolkit/components/printingui/win/nsPrintDialogUtil.cpp
toolkit/components/printingui/win/nsPrintDialogUtil.h
toolkit/components/printingui/win/nsPrintingPromptService.cpp
toolkit/components/printingui/win/nsPrintingPromptService.h
widget/windows/moz.build
widget/windows/nsPrintDialogUtil.cpp
widget/windows/nsPrintDialogUtil.h
widget/windows/nsPrintDialogWin.cpp
widget/windows/nsPrintDialogWin.h
--- a/toolkit/components/printingui/win/moz.build
+++ b/toolkit/components/printingui/win/moz.build
@@ -1,18 +1,13 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 UNIFIED_SOURCES += [
-    'nsPrintDialogUtil.cpp',
     'nsPrintingPromptService.cpp',
     'nsPrintProgress.cpp',
     'nsPrintProgressParams.cpp',
 ]
 
-EXPORTS += [
-    'nsPrintDialogUtil.h',
-]
-
 FINAL_LIBRARY = 'xul'
--- a/toolkit/components/printingui/win/nsPrintingPromptService.cpp
+++ b/toolkit/components/printingui/win/nsPrintingPromptService.cpp
@@ -1,77 +1,27 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  *
  * 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/. */
 
-#include "nsCOMPtr.h"
+#include "nsPrintingPromptService.h"
 
-#include "nsPrintingPromptService.h"
 #include "nsIPrintingPromptService.h"
-#include "nsIFactory.h"
-#include "nsPIDOMWindow.h"
-#include "nsReadableUtils.h"
-#include "nsIEmbeddingSiteWindow.h"
 #include "nsIServiceManager.h"
-#include "nsIWebBrowserChrome.h"
-#include "nsIWindowWatcher.h"
-#include "nsPrintDialogUtil.h"
+#include "nsIPrintDialogService.h"
 
 // Printing Progress Includes
 #include "nsPrintProgress.h"
 #include "nsPrintProgressParams.h"
 #include "nsIWebProgressListener.h"
 
-// XP Dialog includes
-#include "nsArray.h"
-#include "nsIDialogParamBlock.h"
-#include "nsISupportsUtils.h"
-
-// Includes need to locate the native Window
-#include "nsIWidget.h"
-#include "nsIBaseWindow.h"
-#include "nsIWebBrowserChrome.h"
-#include "nsIDocShellTreeOwner.h"
-#include "nsIDocShellTreeItem.h"
-#include "nsIDocShell.h"
-#include "nsIInterfaceRequestorUtils.h"
-
-
 static const char *kPrintProgressDialogURL  = "chrome://global/content/printProgress.xul";
 static const char *kPrtPrvProgressDialogURL = "chrome://global/content/printPreviewProgress.xul";
-static const char *kPageSetupDialogURL      = "chrome://global/content/printPageSetup.xul";
-
-/****************************************************************
- ************************* ParamBlock ***************************
- ****************************************************************/
-
-class ParamBlock {
-
-public:
-    ParamBlock()
-    {
-        mBlock = 0;
-    }
-    ~ParamBlock()
-    {
-        NS_IF_RELEASE(mBlock);
-    }
-    nsresult Init() {
-      return CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &mBlock);
-    }
-    nsIDialogParamBlock * operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mBlock; }
-    operator nsIDialogParamBlock * const ()  { return mBlock; }
-
-private:
-    nsIDialogParamBlock *mBlock;
-};
-
-//*****************************************************************************
 
 NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener)
 
 nsPrintingPromptService::nsPrintingPromptService()
 {
 }
 
 //-----------------------------------------------------------
@@ -83,82 +33,32 @@ nsPrintingPromptService::~nsPrintingProm
 nsresult
 nsPrintingPromptService::Init()
 {
     nsresult rv;
     mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
     return rv;
 }
 
-//-----------------------------------------------------------
-HWND
-nsPrintingPromptService::GetHWNDForDOMWindow(mozIDOMWindowProxy *aWindow)
-{
-    nsCOMPtr<nsIWebBrowserChrome> chrome;
-
-    // We might be embedded so check this path first
-    if (mWatcher) {
-        nsCOMPtr<mozIDOMWindowProxy> fosterParent;
-        if (!aWindow)
-        {   // it will be a dependent window. try to find a foster parent.
-            mWatcher->GetActiveWindow(getter_AddRefs(fosterParent));
-            aWindow = fosterParent;
-        }
-        mWatcher->GetChromeForWindow(aWindow, getter_AddRefs(chrome));
-    }
-
-    if (chrome) {
-        nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome));
-        if (site)
-        {
-            HWND w;
-            site->GetSiteWindow(reinterpret_cast<void **>(&w));
-            return w;
-        }
-    }
-
-    // Now we might be the Browser so check this path
-    nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
-
-    nsCOMPtr<nsIDocShellTreeItem> treeItem =
-        do_QueryInterface(window->GetDocShell());
-    if (!treeItem) return nullptr;
-
-    nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
-    treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
-    if (!treeOwner) return nullptr;
-
-    nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome(do_GetInterface(treeOwner));
-    if (!webBrowserChrome) return nullptr;
-
-    nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(webBrowserChrome));
-    if (!baseWin) return nullptr;
-
-    nsCOMPtr<nsIWidget> widget;
-    baseWin->GetMainWidget(getter_AddRefs(widget));
-    if (!widget) return nullptr;
-
-    return (HWND)widget->GetNativeData(NS_NATIVE_TMP_WINDOW);
-
-}
-
-
 ///////////////////////////////////////////////////////////////////////////////
 // nsIPrintingPromptService
 
 //-----------------------------------------------------------
 NS_IMETHODIMP
 nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
 {
     NS_ENSURE_ARG(parent);
 
-    HWND hWnd = GetHWNDForDOMWindow(parent);
-    NS_ASSERTION(hWnd, "Couldn't get native window for PRint Dialog!");
+    nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
+                                             NS_PRINTDIALOGSERVICE_CONTRACTID));
+    if (dlgPrint)
+      return dlgPrint->Show(nsPIDOMWindowOuter::From(parent),
+                            printSettings, webBrowserPrint);
 
-    return NativeShowPrintDialog(hWnd, webBrowserPrint, printSettings);
+    return NS_ERROR_FAILURE;
 }
 
 
 NS_IMETHODIMP
 nsPrintingPromptService::ShowProgress(mozIDOMWindowProxy*      parent,
                                       nsIWebBrowserPrint*      webBrowserPrint,    // ok to be null
                                       nsIPrintSettings*        printSettings,      // ok to be null
                                       nsIObserver*             openDialogObserver, // ok to be null
@@ -202,87 +102,31 @@ nsPrintingPromptService::ShowProgress(mo
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent, nsIPrintSettings *printSettings, nsIObserver *aObs)
 {
     NS_ENSURE_ARG(printSettings);
 
-    ParamBlock block;
-    nsresult rv = block.Init();
-    if (NS_FAILED(rv))
-      return rv;
-
-    block->SetInt(0, 0);
-    rv = DoDialog(parent, block, printSettings, kPageSetupDialogURL);
+    nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
+                                             NS_PRINTDIALOGSERVICE_CONTRACTID));
+    if (dlgPrint)
+      return dlgPrint->ShowPageSetup(nsPIDOMWindowOuter::From(parent),
+                                     printSettings);
 
-    // if aWebBrowserPrint is not null then we are printing
-    // so we want to pass back NS_ERROR_ABORT on cancel
-    if (NS_SUCCEEDED(rv))
-    {
-      int32_t status;
-      block->GetInt(0, &status);
-      return status == 0?NS_ERROR_ABORT:NS_OK;
-    }
-
-    return rv;
+    return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsPrintingPromptService::ShowPrinterProperties(mozIDOMWindowProxy *parent, const char16_t *printerName, nsIPrintSettings *printSettings)
 {
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-//-----------------------------------------------------------
-// Helper to Fly XP Dialog
-nsresult
-nsPrintingPromptService::DoDialog(mozIDOMWindowProxy *aParent,
-                                  nsIDialogParamBlock *aParamBlock,
-                                  nsIPrintSettings* aPS,
-                                  const char *aChromeURL)
-{
-    NS_ENSURE_ARG(aParamBlock);
-    NS_ENSURE_ARG(aPS);
-    NS_ENSURE_ARG(aChromeURL);
-
-    if (!mWatcher)
-        return NS_ERROR_FAILURE;
-
-    // get a parent, if at all possible
-    // (though we'd rather this didn't fail, it's OK if it does. so there's
-    // no failure or null check.)
-    nsCOMPtr<mozIDOMWindowProxy> activeParent; // retain ownership for method lifetime
-    if (!aParent)
-    {
-        mWatcher->GetActiveWindow(getter_AddRefs(activeParent));
-        aParent = activeParent;
-    }
-
-    // create a nsIMutableArray of the parameters
-    // being passed to the window
-    nsCOMPtr<nsIMutableArray> array = nsArray::Create();
-
-    nsCOMPtr<nsISupports> psSupports(do_QueryInterface(aPS));
-    NS_ASSERTION(psSupports, "PrintSettings must be a supports");
-    array->AppendElement(psSupports, /*weak =*/ false);
-
-    nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(aParamBlock));
-    NS_ASSERTION(blkSupps, "IOBlk must be a supports");
-    array->AppendElement(blkSupps, /*weak =*/ false);
-
-    nsCOMPtr<mozIDOMWindowProxy> dialog;
-    nsresult rv = mWatcher->OpenWindow(aParent, aChromeURL, "_blank",
-                              "centerscreen,chrome,modal,titlebar", array,
-                              getter_AddRefs(dialog));
-
-    return rv;
-}
-
 //////////////////////////////////////////////////////////////////////
 // nsIWebProgressListener
 //////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
 nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
 {
     if ((aStateFlags & STATE_STOP) && mWebProgressListener)
--- a/toolkit/components/printingui/win/nsPrintingPromptService.h
+++ b/toolkit/components/printingui/win/nsPrintingPromptService.h
@@ -37,22 +37,16 @@ public:
 
     nsresult Init();
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIPRINTINGPROMPTSERVICE
     NS_DECL_NSIWEBPROGRESSLISTENER
 
 private:
-    HWND GetHWNDForDOMWindow(mozIDOMWindowProxy *parent);
-    nsresult DoDialog(mozIDOMWindowProxy *aParent,
-                      nsIDialogParamBlock *aParamBlock,
-                      nsIPrintSettings* aPS,
-                      const char *aChromeURL);
-
     nsCOMPtr<nsIWindowWatcher> mWatcher;
     nsCOMPtr<nsIPrintProgress> mPrintProgress;
     nsCOMPtr<nsIWebProgressListener> mWebProgressListener;
 
 };
 
 #endif
 
--- a/widget/windows/moz.build
+++ b/widget/windows/moz.build
@@ -90,27 +90,28 @@ SOURCES += [
 if CONFIG['MOZ_CRASHREPORTER']:
     UNIFIED_SOURCES += [
         'LSPAnnotator.cpp',
     ]
 
 if CONFIG['NS_PRINTING']:
     UNIFIED_SOURCES += [
         'nsDeviceContextSpecWin.cpp',
+        'nsPrintDialogUtil.cpp',
         'nsPrintDialogWin.cpp',
         'nsPrintOptionsWin.cpp',
         'nsPrintSettingsWin.cpp',
     ]
-    if CONFIG['MOZ_ENABLE_SKIA_PDF']:
-        DIRS += ['/modules/pdfium']
-        UNIFIED_SOURCES += [
-            'PDFiumEngineShim.cpp',
-            'PDFViaEMFPrintHelper.cpp',
-            'WindowsEMF.cpp',
-        ]
+if CONFIG['MOZ_ENABLE_SKIA_PDF']:
+    DIRS += ['/modules/pdfium']
+    UNIFIED_SOURCES += [
+        'PDFiumEngineShim.cpp',
+        'PDFViaEMFPrintHelper.cpp',
+        'WindowsEMF.cpp',
+    ]
 
 if CONFIG['NS_ENABLE_TSF']:
     SOURCES += [
         'TSFTextStore.cpp',
     ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
rename from toolkit/components/printingui/win/nsPrintDialogUtil.cpp
rename to widget/windows/nsPrintDialogUtil.cpp
--- a/toolkit/components/printingui/win/nsPrintDialogUtil.cpp
+++ b/widget/windows/nsPrintDialogUtil.cpp
@@ -54,19 +54,19 @@ WIN_LIBS=                               
 
 // This is for extending the dialog
 #include <dlgs.h>
 
 #include "nsWindowsHelpers.h"
 #include "WinUtils.h"
 
 // Default labels for the radio buttons
-static const char* kAsLaidOutOnScreenStr = "As &laid out on the screen";
-static const char* kTheSelectedFrameStr  = "The selected &frame";
-static const char* kEachFrameSeparately  = "&Each frame separately";
+static const wchar_t* kAsLaidOutOnScreenStr = L"As &laid out on the screen";
+static const wchar_t* kTheSelectedFrameStr  = L"The selected &frame";
+static const wchar_t* kEachFrameSeparately  = L"&Each frame separately";
 
 
 //-----------------------------------------------
 // Global Data
 //-----------------------------------------------
 // Identifies which new radio btn was cliked on
 static UINT gFrameSelectedRadioBtn = 0;
 
@@ -115,22 +115,20 @@ GetLocalizedString(nsIStringBundle* aStr
   } else {
     oVal.Truncate();
   }
   return rv;
 }
 
 //--------------------------------------------------------
 // Set a multi-byte string in the control
-static void SetTextOnWnd(HWND aControl, const nsString& aStr)
+static void SetTextOnWnd(HWND aControl, const nsAString& aStr)
 {
-  nsAutoCString text;
-  if (NS_SUCCEEDED(NS_CopyUnicodeToNative(aStr, text))) {
-    ::SetWindowText(aControl, text.get());
-  }
+  ::SetWindowTextW(aControl,
+                   reinterpret_cast<const wchar_t*>(aStr.BeginReading()));
 }
 
 //--------------------------------------------------------
 // Will get the control and localized string by "key"
 static void SetText(HWND             aParent,
                     UINT             aId,
                     nsIStringBundle* aStrBundle,
                     const char*      aKey)
@@ -214,29 +212,25 @@ static void Show(HWND aWnd, bool bState)
 {
   if (aWnd) {
     ::ShowWindow(aWnd, bState?SW_SHOW:SW_HIDE);
   }
 }
 
 //--------------------------------------------------------
 // Create a child window "control"
-static HWND CreateControl(LPCTSTR          aType,
+static HWND CreateControl(LPCWSTR          aType,
                           DWORD            aStyle,
                           HINSTANCE        aHInst,
                           HWND             aHdlg,
                           int              aId,
-                          const nsAString& aStr,
+                          LPCWSTR           aStr,
                           const nsIntRect& aRect)
 {
-  nsAutoCString str;
-  if (NS_FAILED(NS_CopyUnicodeToNative(aStr, str)))
-    return nullptr;
-
-  HWND hWnd = ::CreateWindow (aType, str.get(),
+  HWND hWnd = ::CreateWindowW(aType, aStr,
                               WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | aStyle,
                               aRect.x, aRect.y, aRect.width, aRect.height,
                               (HWND)aHdlg, (HMENU)(intptr_t)aId,
                               aHInst, nullptr);
   if (hWnd == nullptr) return nullptr;
 
   // get the native font for the dialog and
   // set it into the new control
@@ -247,33 +241,31 @@ static HWND CreateControl(LPCTSTR       
   return hWnd;
 }
 
 //--------------------------------------------------------
 // Create a Radio Button
 static HWND CreateRadioBtn(HINSTANCE        aHInst,
                            HWND             aHdlg,
                            int              aId,
-                           const char*      aStr,
+                           LPCWSTR          aStr,
                            const nsIntRect& aRect)
 {
-  nsString str;
-  CopyASCIItoUTF16(aStr, str);
-  return CreateControl("BUTTON", BS_RADIOBUTTON, aHInst, aHdlg, aId, str, aRect);
+  return CreateControl(L"BUTTON", BS_RADIOBUTTON, aHInst, aHdlg, aId, aStr, aRect);
 }
 
 //--------------------------------------------------------
 // Create a Group Box
 static HWND CreateGroupBox(HINSTANCE        aHInst,
                            HWND             aHdlg,
                            int              aId,
-                           const nsAString& aStr,
+                           LPCWSTR          aStr,
                            const nsIntRect& aRect)
 {
-  return CreateControl("BUTTON", BS_GROUPBOX, aHInst, aHdlg, aId, aStr, aRect);
+  return CreateControl(L"BUTTON", BS_GROUPBOX, aHInst, aHdlg, aId, aStr, aRect);
 }
 
 //--------------------------------------------------------
 // Localizes and initializes the radio buttons and group
 static void InitializeExtendedDialog(HWND hdlg, int16_t aHowToEnableFrameUI)
 {
   MOZ_ASSERT(aHowToEnableFrameUI != nsIPrintSettings::kFrameEnableNone,
              "should not be called");
@@ -400,17 +392,17 @@ static UINT CALLBACK PrintHookProc(HWND 
       Show(rad4Wnd, FALSE); // hide
       Show(rad5Wnd, FALSE); // hide
       return 0L;
     }
     y += radHgt + grpBotGap;
 
     // Create and position the group box
     rect.SetRect (dlgRect.left, top, dlgRect.right-dlgRect.left+1, y-top+1);
-    HWND grpBoxWnd = CreateGroupBox(hInst, hdlg, grp3, NS_LITERAL_STRING("Print Frame"), rect);
+    HWND grpBoxWnd = CreateGroupBox(hInst, hdlg, grp3, L"Print Frame", rect);
     if (grpBoxWnd == nullptr) {
       Show(rad4Wnd, FALSE); // hide
       Show(rad5Wnd, FALSE); // hide
       Show(rad6Wnd, FALSE); // hide
       return 0L;
     }
 
     // Here we figure out the old height of the dlg
rename from toolkit/components/printingui/win/nsPrintDialogUtil.h
rename to widget/windows/nsPrintDialogUtil.h
--- a/widget/windows/nsPrintDialogWin.cpp
+++ b/widget/windows/nsPrintDialogWin.cpp
@@ -1,43 +1,203 @@
 /* -*- Mode: C++; tab-width: 2; 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/. */
 
 #include "nsPrintDialogWin.h"
 
+#include "nsArray.h"
+#include "nsCOMPtr.h"
 #include "nsIBaseWindow.h"
+#include "nsIDialogParamBlock.h"
+#include "nsIDocShellTreeOwner.h"
+#include "nsIDocShellTreeItem.h"
+#include "nsIDocShell.h"
+#include "nsIEmbeddingSiteWindow.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIPrintSettings.h"
+#include "nsIWebBrowserChrome.h"
+#include "nsIWidget.h"
+#include "nsPrintDialogUtil.h"
 #include "nsIPrintSettings.h"
 #include "nsIWebBrowserChrome.h"
+#include "nsQueryObject.h"
+
+static const char *kPageSetupDialogURL = "chrome://global/content/printPageSetup.xul";
 
 using namespace mozilla;
+using namespace mozilla::widget;
+
+/**
+ * ParamBlock
+ */
+
+class ParamBlock {
+
+public:
+  ParamBlock()
+  {
+    mBlock = 0;
+  }
+  ~ParamBlock()
+  {
+    NS_IF_RELEASE(mBlock);
+  }
+  nsresult Init() {
+    return CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &mBlock);
+  }
+  nsIDialogParamBlock * operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mBlock; }
+  operator nsIDialogParamBlock * const ()  { return mBlock; }
+
+private:
+  nsIDialogParamBlock *mBlock;
+};
 
 NS_IMPL_ISUPPORTS(nsPrintDialogServiceWin, nsIPrintDialogService)
 
 nsPrintDialogServiceWin::nsPrintDialogServiceWin()
 {
 }
 
 nsPrintDialogServiceWin::~nsPrintDialogServiceWin()
 {
 }
 
 NS_IMETHODIMP
 nsPrintDialogServiceWin::Init()
 {
-  return NS_OK;
+  nsresult rv;
+  mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
+  return rv;
 }
 
 NS_IMETHODIMP
 nsPrintDialogServiceWin::Show(nsPIDOMWindowOuter *aParent,
                               nsIPrintSettings *aSettings,
                               nsIWebBrowserPrint *aWebBrowserPrint)
 {
-  return NS_OK;
+  NS_ENSURE_ARG(aParent);
+  HWND hWnd = GetHWNDForDOMWindow(aParent);
+  NS_ASSERTION(hWnd, "Couldn't get native window for PRint Dialog!");
+
+  return NativeShowPrintDialog(hWnd, aWebBrowserPrint, aSettings);
 }
 
 NS_IMETHODIMP
 nsPrintDialogServiceWin::ShowPageSetup(nsPIDOMWindowOuter *aParent,
                                        nsIPrintSettings *aNSSettings)
 {
-  return NS_OK;
+  NS_ENSURE_ARG(aParent);
+  NS_ENSURE_ARG(aNSSettings);
+
+  ParamBlock block;
+  nsresult rv = block.Init();
+  if (NS_FAILED(rv)) return rv;
+
+  block->SetInt(0, 0);
+  rv = DoDialog(aParent, block, aNSSettings, kPageSetupDialogURL);
+
+  // if aWebBrowserPrint is not null then we are printing
+  // so we want to pass back NS_ERROR_ABORT on cancel
+  if (NS_SUCCEEDED(rv)) {
+    int32_t status;
+    block->GetInt(0, &status);
+    return status == 0?NS_ERROR_ABORT:NS_OK;
+  }
+
+  return rv;
 }
+
+nsresult
+nsPrintDialogServiceWin::DoDialog(mozIDOMWindowProxy *aParent,
+                                  nsIDialogParamBlock *aParamBlock,
+                                  nsIPrintSettings* aPS,
+                                  const char *aChromeURL)
+{
+  NS_ENSURE_ARG(aParamBlock);
+  NS_ENSURE_ARG(aPS);
+  NS_ENSURE_ARG(aChromeURL);
+
+  if (!mWatcher)
+    return NS_ERROR_FAILURE;
+
+  // get a parent, if at all possible
+  // (though we'd rather this didn't fail, it's OK if it does. so there's
+  // no failure or null check.)
+  // retain ownership for method lifetime
+  nsCOMPtr<mozIDOMWindowProxy> activeParent;
+  if (!aParent) {
+    mWatcher->GetActiveWindow(getter_AddRefs(activeParent));
+    aParent = activeParent;
+  }
+
+  // create a nsIMutableArray of the parameters
+  // being passed to the window
+  nsCOMPtr<nsIMutableArray> array = nsArray::Create();
+
+  nsCOMPtr<nsISupports> psSupports(do_QueryInterface(aPS));
+  NS_ASSERTION(psSupports, "PrintSettings must be a supports");
+  array->AppendElement(psSupports, /*weak =*/ false);
+
+  nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(aParamBlock));
+  NS_ASSERTION(blkSupps, "IOBlk must be a supports");
+  array->AppendElement(blkSupps, /*weak =*/ false);
+
+  nsCOMPtr<mozIDOMWindowProxy> dialog;
+  nsresult rv = mWatcher->OpenWindow(aParent,
+                                     aChromeURL,
+                                     "_blank",
+                                     "centerscreen,chrome,modal,titlebar",
+                                     array,
+                                     getter_AddRefs(dialog));
+
+    return rv;
+}
+
+HWND
+nsPrintDialogServiceWin::GetHWNDForDOMWindow(mozIDOMWindowProxy *aWindow)
+{
+  nsCOMPtr<nsIWebBrowserChrome> chrome;
+
+  // We might be embedded so check this path first
+  if (mWatcher) {
+    nsCOMPtr<mozIDOMWindowProxy> fosterParent;
+    // it will be a dependent window. try to find a foster parent.
+    if (!aWindow) {
+        mWatcher->GetActiveWindow(getter_AddRefs(fosterParent));
+        aWindow = fosterParent;
+    }
+    mWatcher->GetChromeForWindow(aWindow, getter_AddRefs(chrome));
+  }
+
+  if (chrome) {
+    nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome));
+    if (site) {
+      HWND w;
+      site->GetSiteWindow(reinterpret_cast<void **>(&w));
+      return w;
+    }
+  }
+
+  // Now we might be the Browser so check this path
+  nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
+
+  nsCOMPtr<nsIDocShellTreeItem> treeItem =
+    do_QueryInterface(window->GetDocShell());
+  if (!treeItem) return nullptr;
+
+  nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
+  treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
+  if (!treeOwner) return nullptr;
+
+  nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome(do_GetInterface(treeOwner));
+  if (!webBrowserChrome) return nullptr;
+
+  nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(webBrowserChrome));
+  if (!baseWin) return nullptr;
+
+  nsCOMPtr<nsIWidget> widget;
+  baseWin->GetMainWidget(getter_AddRefs(widget));
+  if (!widget) return nullptr;
+
+  return (HWND)widget->GetNativeData(NS_NATIVE_TMP_WINDOW);
+}
--- a/widget/windows/nsPrintDialogWin.h
+++ b/widget/windows/nsPrintDialogWin.h
@@ -3,28 +3,41 @@
  * 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 nsPrintDialog_h__
 #define nsPrintDialog_h__
 
 #include "nsIPrintDialogService.h"
 
+#include "nsCOMPtr.h"
+#include "nsIWindowWatcher.h"
+
 class nsIPrintSettings;
+class nsIDialogParamBlock;
 
 class nsPrintDialogServiceWin : public nsIPrintDialogService
 {
   virtual ~nsPrintDialogServiceWin();
 
 public:
   nsPrintDialogServiceWin();
 
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD Init() override;
   NS_IMETHOD Show(nsPIDOMWindowOuter *aParent, nsIPrintSettings *aSettings,
                   nsIWebBrowserPrint *aWebBrowserPrint) override;
   NS_IMETHOD ShowPageSetup(nsPIDOMWindowOuter *aParent,
                            nsIPrintSettings *aSettings) override;
 
+private:
+  nsresult DoDialog(mozIDOMWindowProxy *aParent,
+                    nsIDialogParamBlock *aParamBlock,
+                    nsIPrintSettings* aPS,
+                    const char *aChromeURL);
+
+  HWND GetHWNDForDOMWindow(mozIDOMWindowProxy *aWindow);
+
+  nsCOMPtr<nsIWindowWatcher> mWatcher;
 };
 
 #endif