Break circular includes between fpdfsdk/ and fpdfsdk/pwl.

The CPWL_Wnd::PrivateData interface replaces all use of
CPDFSDK_Widget at the pwl/ layer. In turn, IPWL_SystemHandler
can no longer use a widget, so it must use PrivateData instead.
This then hits the "no forward declaration of nested classes"
gotcha, so PrivateData moves to IPWL_SystemHandler and is renamed
PerWindowData.

Change-Id: I98153e2def05cf2d582b96b2bec3dc905c97910a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/58814
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/BUILD.gn b/fpdfsdk/BUILD.gn
index 463d5ca..5909ada 100644
--- a/fpdfsdk/BUILD.gn
+++ b/fpdfsdk/BUILD.gn
@@ -95,7 +95,6 @@
   allow_circular_includes_from = [
     "../fxjs",
     "formfiller",
-    "pwl",
   ]
   visibility = [ "../*" ]
 
diff --git a/fpdfsdk/cfx_systemhandler.cpp b/fpdfsdk/cfx_systemhandler.cpp
index 6833693..d14834f 100644
--- a/fpdfsdk/cfx_systemhandler.cpp
+++ b/fpdfsdk/cfx_systemhandler.cpp
@@ -25,8 +25,13 @@
 
 CFX_SystemHandler::~CFX_SystemHandler() = default;
 
-void CFX_SystemHandler::InvalidateRect(CPDFSDK_Widget* widget,
+void CFX_SystemHandler::InvalidateRect(PerWindowData* pWidgetData,
                                        const CFX_FloatRect& rect) {
+  auto* pPrivateData = static_cast<CFFL_PrivateData*>(pWidgetData);
+  CPDFSDK_Widget* widget = pPrivateData->pWidget.Get();
+  if (!widget)
+    return;
+
   CPDFSDK_PageView* pPageView = widget->GetPageView();
   IPDF_Page* pPage = widget->GetPage();
   if (!pPage || !pPageView)
diff --git a/fpdfsdk/cfx_systemhandler.h b/fpdfsdk/cfx_systemhandler.h
index 733cce9..def797e 100644
--- a/fpdfsdk/cfx_systemhandler.h
+++ b/fpdfsdk/cfx_systemhandler.h
@@ -21,7 +21,7 @@
   explicit CFX_SystemHandler(CPDFSDK_FormFillEnvironment* pFormFillEnv);
   ~CFX_SystemHandler() override;
 
-  void InvalidateRect(CPDFSDK_Widget* widget,
+  void InvalidateRect(PerWindowData* pWidgetData,
                       const CFX_FloatRect& rect) override;
   void OutputSelectedRect(CFFL_FormFiller* pFormFiller,
                           const CFX_FloatRect& rect) override;
diff --git a/fpdfsdk/formfiller/cffl_checkbox.cpp b/fpdfsdk/formfiller/cffl_checkbox.cpp
index 3fbcd11..cb7ddd1 100644
--- a/fpdfsdk/formfiller/cffl_checkbox.cpp
+++ b/fpdfsdk/formfiller/cffl_checkbox.cpp
@@ -23,7 +23,7 @@
 
 std::unique_ptr<CPWL_Wnd> CFFL_CheckBox::NewPWLWindow(
     const CPWL_Wnd::CreateParams& cp,
-    std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) {
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData) {
   auto pWnd = pdfium::MakeUnique<CPWL_CheckBox>(cp, std::move(pAttachedData));
   pWnd->Realize();
   pWnd->SetCheck(m_pWidget->IsChecked());
diff --git a/fpdfsdk/formfiller/cffl_checkbox.h b/fpdfsdk/formfiller/cffl_checkbox.h
index d590b50..aff2762 100644
--- a/fpdfsdk/formfiller/cffl_checkbox.h
+++ b/fpdfsdk/formfiller/cffl_checkbox.h
@@ -21,7 +21,8 @@
   // CFFL_Button:
   std::unique_ptr<CPWL_Wnd> NewPWLWindow(
       const CPWL_Wnd::CreateParams& cp,
-      std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) override;
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
+      override;
   bool OnKeyDown(uint32_t nKeyCode, uint32_t nFlags) override;
   bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
   bool OnLButtonUp(CPDFSDK_PageView* pPageView,
diff --git a/fpdfsdk/formfiller/cffl_combobox.cpp b/fpdfsdk/formfiller/cffl_combobox.cpp
index 0a638f7..38f7a42 100644
--- a/fpdfsdk/formfiller/cffl_combobox.cpp
+++ b/fpdfsdk/formfiller/cffl_combobox.cpp
@@ -46,7 +46,7 @@
 
 std::unique_ptr<CPWL_Wnd> CFFL_ComboBox::NewPWLWindow(
     const CPWL_Wnd::CreateParams& cp,
-    std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) {
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData) {
   auto pWnd = pdfium::MakeUnique<CPWL_ComboBox>(cp, std::move(pAttachedData));
   pWnd->AttachFFLData(this);
   pWnd->Realize();
diff --git a/fpdfsdk/formfiller/cffl_combobox.h b/fpdfsdk/formfiller/cffl_combobox.h
index 52eb874..2e8cd37 100644
--- a/fpdfsdk/formfiller/cffl_combobox.h
+++ b/fpdfsdk/formfiller/cffl_combobox.h
@@ -31,7 +31,8 @@
   CPWL_Wnd::CreateParams GetCreateParam() override;
   std::unique_ptr<CPWL_Wnd> NewPWLWindow(
       const CPWL_Wnd::CreateParams& cp,
-      std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) override;
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
+      override;
   bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
   bool IsDataChanged(CPDFSDK_PageView* pPageView) override;
   void SaveData(CPDFSDK_PageView* pPageView) override;
diff --git a/fpdfsdk/formfiller/cffl_formfiller.cpp b/fpdfsdk/formfiller/cffl_formfiller.cpp
index e5a7d60..0384468 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_formfiller.cpp
@@ -411,7 +411,7 @@
 }
 
 CFX_Matrix CFFL_FormFiller::GetWindowMatrix(
-    const CPWL_Wnd::PrivateData* pAttached) {
+    const IPWL_SystemHandler::PerWindowData* pAttached) {
   const auto* pPrivateData = static_cast<const CFFL_PrivateData*>(pAttached);
   if (!pPrivateData || !pPrivateData->pPageView)
     return CFX_Matrix();
diff --git a/fpdfsdk/formfiller/cffl_formfiller.h b/fpdfsdk/formfiller/cffl_formfiller.h
index 88c32d8..4cdf1a2 100644
--- a/fpdfsdk/formfiller/cffl_formfiller.h
+++ b/fpdfsdk/formfiller/cffl_formfiller.h
@@ -89,7 +89,8 @@
   CFX_SystemHandler* GetSystemHandler() const override;  // Covariant return.
 
   // CPWL_Wnd::ProviderIface:
-  CFX_Matrix GetWindowMatrix(const CPWL_Wnd::PrivateData* pAttached) override;
+  CFX_Matrix GetWindowMatrix(
+      const IPWL_SystemHandler::PerWindowData* pAttached) override;
 
   virtual void GetActionData(CPDFSDK_PageView* pPageView,
                              CPDF_AAction::AActionType type,
@@ -104,7 +105,7 @@
   virtual CPWL_Wnd::CreateParams GetCreateParam();
   virtual std::unique_ptr<CPWL_Wnd> NewPWLWindow(
       const CPWL_Wnd::CreateParams& cp,
-      std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) = 0;
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData) = 0;
   virtual CPWL_Wnd* ResetPDFWindow(CPDFSDK_PageView* pPageView,
                                    bool bRestoreValue);
   virtual void SaveState(CPDFSDK_PageView* pPageView);
diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
index c98afcc..8550116 100644
--- a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp
@@ -583,13 +583,13 @@
 }
 
 void CFFL_InteractiveFormFiller::QueryWherePopup(
-    const CPWL_Wnd::PrivateData* pAttached,
+    const IPWL_SystemHandler::PerWindowData* pAttached,
     float fPopupMin,
     float fPopupMax,
     bool* bBottom,
     float* fPopupRet) {
   auto* pData = static_cast<const CFFL_PrivateData*>(pAttached);
-  CPDFSDK_Widget* pWidget = pData->GetWidget();
+  CPDFSDK_Widget* pWidget = pData->pWidget.Get();
   CPDF_Page* pPage = pWidget->GetPDFPage();
 
   CFX_FloatRect rcPageView(0, pPage->GetPageHeight(), pPage->GetPageWidth(), 0);
@@ -808,7 +808,7 @@
 }
 
 bool CFFL_InteractiveFormFiller::OnPopupPreOpen(
-    const CPWL_Wnd::PrivateData* pAttached,
+    const IPWL_SystemHandler::PerWindowData* pAttached,
     uint32_t nFlag) {
   auto* pData = static_cast<const CFFL_PrivateData*>(pAttached);
   ASSERT(pData->pWidget);
@@ -818,7 +818,7 @@
 }
 
 bool CFFL_InteractiveFormFiller::OnPopupPostOpen(
-    const CPWL_Wnd::PrivateData* pAttached,
+    const IPWL_SystemHandler::PerWindowData* pAttached,
     uint32_t nFlag) {
   auto* pData = static_cast<const CFFL_PrivateData*>(pAttached);
   ASSERT(pData->pWidget);
@@ -896,7 +896,7 @@
 }
 
 std::pair<bool, bool> CFFL_InteractiveFormFiller::OnBeforeKeyStroke(
-    const CPWL_Wnd::PrivateData* pAttached,
+    const IPWL_SystemHandler::PerWindowData* pAttached,
     WideString& strChange,
     const WideString& strChangeEx,
     int nSelStart,
@@ -985,10 +985,7 @@
 
 CFFL_PrivateData::~CFFL_PrivateData() = default;
 
-std::unique_ptr<CPWL_Wnd::PrivateData> CFFL_PrivateData::Clone() const {
+std::unique_ptr<IPWL_SystemHandler::PerWindowData> CFFL_PrivateData::Clone()
+    const {
   return pdfium::MakeUnique<CFFL_PrivateData>(*this);
 }
-
-CPDFSDK_Widget* CFFL_PrivateData::GetWidget() const {
-  return pWidget.Get();
-}
diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.h b/fpdfsdk/formfiller/cffl_interactiveformfiller.h
index fb546ab..9a2233d 100644
--- a/fpdfsdk/formfiller/cffl_interactiveformfiller.h
+++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.h
@@ -16,6 +16,7 @@
 #include "fpdfsdk/cpdfsdk_annot.h"
 #include "fpdfsdk/pwl/cpwl_edit.h"
 #include "fpdfsdk/pwl/cpwl_wnd.h"
+#include "fpdfsdk/pwl/ipwl_systemhandler.h"
 
 class CFFL_FormFiller;
 class CPDFSDK_FormFillEnvironment;
@@ -140,14 +141,14 @@
       std::map<CPDFSDK_Annot*, std::unique_ptr<CFFL_FormFiller>>;
 
   // IPWL_Filler_Notify:
-  void QueryWherePopup(const CPWL_Wnd::PrivateData* pAttached,
+  void QueryWherePopup(const IPWL_SystemHandler::PerWindowData* pAttached,
                        float fPopupMin,
                        float fPopupMax,
                        bool* bBottom,
                        float* fPopupRet) override;
   // Returns {bRC, bExit}.
   std::pair<bool, bool> OnBeforeKeyStroke(
-      const CPWL_Wnd::PrivateData* pAttached,
+      const IPWL_SystemHandler::PerWindowData* pAttached,
       WideString& strChange,
       const WideString& strChangeEx,
       int nSelStart,
@@ -155,9 +156,9 @@
       bool bKeyDown,
       uint32_t nFlag) override;
 #ifdef PDF_ENABLE_XFA
-  bool OnPopupPreOpen(const CPWL_Wnd::PrivateData* pAttached,
+  bool OnPopupPreOpen(const IPWL_SystemHandler::PerWindowData* pAttached,
                       uint32_t nFlag) override;
-  bool OnPopupPostOpen(const CPWL_Wnd::PrivateData* pAttached,
+  bool OnPopupPostOpen(const IPWL_SystemHandler::PerWindowData* pAttached,
                        uint32_t nFlag) override;
   void SetFocusAnnotTab(CPDFSDK_Annot* pWidget, bool bSameField, bool bNext);
 #endif  // PDF_ENABLE_XFA
@@ -171,15 +172,16 @@
   bool m_bNotifying = false;
 };
 
-class CFFL_PrivateData final : public CPWL_Wnd::PrivateData {
+class CFFL_PrivateData final : public IPWL_SystemHandler::PerWindowData {
  public:
   CFFL_PrivateData();
   CFFL_PrivateData(const CFFL_PrivateData& that);
   ~CFFL_PrivateData() override;
 
   // CPWL_Wnd::PrivateData:
-  std::unique_ptr<CPWL_Wnd::PrivateData> Clone() const override;
-  CPDFSDK_Widget* GetWidget() const override;
+  std::unique_ptr<IPWL_SystemHandler::PerWindowData> Clone() const override;
+
+  CPDFSDK_Widget* GetWidget() const { return pWidget.Get(); }
 
   ObservedPtr<CPDFSDK_Widget> pWidget;
   CPDFSDK_PageView* pPageView = nullptr;
diff --git a/fpdfsdk/formfiller/cffl_listbox.cpp b/fpdfsdk/formfiller/cffl_listbox.cpp
index 37e2046..735791b 100644
--- a/fpdfsdk/formfiller/cffl_listbox.cpp
+++ b/fpdfsdk/formfiller/cffl_listbox.cpp
@@ -41,7 +41,7 @@
 
 std::unique_ptr<CPWL_Wnd> CFFL_ListBox::NewPWLWindow(
     const CPWL_Wnd::CreateParams& cp,
-    std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) {
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData) {
   auto pWnd = pdfium::MakeUnique<CPWL_ListBox>(cp, std::move(pAttachedData));
   pWnd->AttachFFLData(this);
   pWnd->Realize();
diff --git a/fpdfsdk/formfiller/cffl_listbox.h b/fpdfsdk/formfiller/cffl_listbox.h
index 3d71e7c..b3fe034 100644
--- a/fpdfsdk/formfiller/cffl_listbox.h
+++ b/fpdfsdk/formfiller/cffl_listbox.h
@@ -24,7 +24,8 @@
   CPWL_Wnd::CreateParams GetCreateParam() override;
   std::unique_ptr<CPWL_Wnd> NewPWLWindow(
       const CPWL_Wnd::CreateParams& cp,
-      std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) override;
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
+      override;
   bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
   bool IsDataChanged(CPDFSDK_PageView* pPageView) override;
   void SaveData(CPDFSDK_PageView* pPageView) override;
diff --git a/fpdfsdk/formfiller/cffl_pushbutton.cpp b/fpdfsdk/formfiller/cffl_pushbutton.cpp
index 9843d54..e9872f6 100644
--- a/fpdfsdk/formfiller/cffl_pushbutton.cpp
+++ b/fpdfsdk/formfiller/cffl_pushbutton.cpp
@@ -20,7 +20,7 @@
 
 std::unique_ptr<CPWL_Wnd> CFFL_PushButton::NewPWLWindow(
     const CPWL_Wnd::CreateParams& cp,
-    std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) {
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData) {
   auto pWnd = pdfium::MakeUnique<CPWL_PushButton>(cp, std::move(pAttachedData));
   pWnd->Realize();
   return std::move(pWnd);
diff --git a/fpdfsdk/formfiller/cffl_pushbutton.h b/fpdfsdk/formfiller/cffl_pushbutton.h
index fe48034..9ebaf60 100644
--- a/fpdfsdk/formfiller/cffl_pushbutton.h
+++ b/fpdfsdk/formfiller/cffl_pushbutton.h
@@ -19,7 +19,8 @@
   // CFFL_Button:
   std::unique_ptr<CPWL_Wnd> NewPWLWindow(
       const CPWL_Wnd::CreateParams& cp,
-      std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) override;
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
+      override;
 };
 
 #endif  // FPDFSDK_FORMFILLER_CFFL_PUSHBUTTON_H_
diff --git a/fpdfsdk/formfiller/cffl_radiobutton.cpp b/fpdfsdk/formfiller/cffl_radiobutton.cpp
index 788db49..e9a6f23 100644
--- a/fpdfsdk/formfiller/cffl_radiobutton.cpp
+++ b/fpdfsdk/formfiller/cffl_radiobutton.cpp
@@ -22,7 +22,7 @@
 
 std::unique_ptr<CPWL_Wnd> CFFL_RadioButton::NewPWLWindow(
     const CPWL_Wnd::CreateParams& cp,
-    std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) {
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData) {
   auto pWnd =
       pdfium::MakeUnique<CPWL_RadioButton>(cp, std::move(pAttachedData));
   pWnd->Realize();
diff --git a/fpdfsdk/formfiller/cffl_radiobutton.h b/fpdfsdk/formfiller/cffl_radiobutton.h
index ccbbd3a..8ba2f28 100644
--- a/fpdfsdk/formfiller/cffl_radiobutton.h
+++ b/fpdfsdk/formfiller/cffl_radiobutton.h
@@ -21,7 +21,8 @@
   // CFFL_Button:
   std::unique_ptr<CPWL_Wnd> NewPWLWindow(
       const CPWL_Wnd::CreateParams& cp,
-      std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) override;
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
+      override;
   bool OnKeyDown(uint32_t nKeyCode, uint32_t nFlags) override;
   bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
   bool OnLButtonUp(CPDFSDK_PageView* pPageView,
diff --git a/fpdfsdk/formfiller/cffl_textfield.cpp b/fpdfsdk/formfiller/cffl_textfield.cpp
index bdde87e..c7689e5 100644
--- a/fpdfsdk/formfiller/cffl_textfield.cpp
+++ b/fpdfsdk/formfiller/cffl_textfield.cpp
@@ -72,7 +72,7 @@
 
 std::unique_ptr<CPWL_Wnd> CFFL_TextField::NewPWLWindow(
     const CPWL_Wnd::CreateParams& cp,
-    std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) {
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData) {
   auto pWnd = pdfium::MakeUnique<CPWL_Edit>(cp, std::move(pAttachedData));
   pWnd->AttachFFLData(this);
   pWnd->Realize();
diff --git a/fpdfsdk/formfiller/cffl_textfield.h b/fpdfsdk/formfiller/cffl_textfield.h
index e45755f..43917fc 100644
--- a/fpdfsdk/formfiller/cffl_textfield.h
+++ b/fpdfsdk/formfiller/cffl_textfield.h
@@ -36,7 +36,8 @@
   CPWL_Wnd::CreateParams GetCreateParam() override;
   std::unique_ptr<CPWL_Wnd> NewPWLWindow(
       const CPWL_Wnd::CreateParams& cp,
-      std::unique_ptr<CPWL_Wnd::PrivateData> pAttachedData) override;
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
+      override;
   bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override;
   bool IsDataChanged(CPDFSDK_PageView* pPageView) override;
   void SaveData(CPDFSDK_PageView* pPageView) override;
diff --git a/fpdfsdk/pwl/cpwl_button.cpp b/fpdfsdk/pwl/cpwl_button.cpp
index cf0f348..7554254 100644
--- a/fpdfsdk/pwl/cpwl_button.cpp
+++ b/fpdfsdk/pwl/cpwl_button.cpp
@@ -10,8 +10,9 @@
 
 #include "fpdfsdk/pwl/cpwl_wnd.h"
 
-CPWL_Button::CPWL_Button(const CreateParams& cp,
-                         std::unique_ptr<PrivateData> pAttachedData)
+CPWL_Button::CPWL_Button(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_Wnd(cp, std::move(pAttachedData)) {
   GetCreationParams()->eCursorType = FXCT_HAND;
 }
diff --git a/fpdfsdk/pwl/cpwl_button.h b/fpdfsdk/pwl/cpwl_button.h
index 6d4aec6..e7760dd 100644
--- a/fpdfsdk/pwl/cpwl_button.h
+++ b/fpdfsdk/pwl/cpwl_button.h
@@ -10,11 +10,12 @@
 #include <memory>
 
 #include "fpdfsdk/pwl/cpwl_wnd.h"
+#include "fpdfsdk/pwl/ipwl_systemhandler.h"
 
 class CPWL_Button : public CPWL_Wnd {
  public:
   CPWL_Button(const CreateParams& cp,
-              std::unique_ptr<PrivateData> pAttachedData);
+              std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_Button() override;
 
   // CPWL_Wnd
diff --git a/fpdfsdk/pwl/cpwl_caret.cpp b/fpdfsdk/pwl/cpwl_caret.cpp
index 7447955..581ddb6 100644
--- a/fpdfsdk/pwl/cpwl_caret.cpp
+++ b/fpdfsdk/pwl/cpwl_caret.cpp
@@ -14,8 +14,9 @@
 #include "core/fxge/cfx_renderdevice.h"
 #include "fpdfsdk/pwl/cpwl_wnd.h"
 
-CPWL_Caret::CPWL_Caret(const CreateParams& cp,
-                       std::unique_ptr<PrivateData> pAttachedData)
+CPWL_Caret::CPWL_Caret(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_Wnd(cp, std::move(pAttachedData)) {}
 
 CPWL_Caret::~CPWL_Caret() = default;
diff --git a/fpdfsdk/pwl/cpwl_caret.h b/fpdfsdk/pwl/cpwl_caret.h
index 44c20f3..482ea5b 100644
--- a/fpdfsdk/pwl/cpwl_caret.h
+++ b/fpdfsdk/pwl/cpwl_caret.h
@@ -14,7 +14,7 @@
 class CPWL_Caret final : public CPWL_Wnd {
  public:
   CPWL_Caret(const CreateParams& cp,
-             std::unique_ptr<PrivateData> pAttachedData);
+             std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_Caret() override;
 
   // CPWL_Wnd
diff --git a/fpdfsdk/pwl/cpwl_combo_box.cpp b/fpdfsdk/pwl/cpwl_combo_box.cpp
index 1a9e248..b3da885 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.cpp
+++ b/fpdfsdk/pwl/cpwl_combo_box.cpp
@@ -28,8 +28,9 @@
 
 }  // namespace
 
-CPWL_CBListBox::CPWL_CBListBox(const CreateParams& cp,
-                               std::unique_ptr<PrivateData> pAttachedData)
+CPWL_CBListBox::CPWL_CBListBox(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_ListBox(cp, std::move(pAttachedData)) {}
 
 CPWL_CBListBox::~CPWL_CBListBox() = default;
@@ -102,8 +103,9 @@
   return OnNotifySelectionChanged(true, nFlag);
 }
 
-CPWL_CBButton::CPWL_CBButton(const CreateParams& cp,
-                             std::unique_ptr<PrivateData> pAttachedData)
+CPWL_CBButton::CPWL_CBButton(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_Wnd(cp, std::move(pAttachedData)) {}
 
 CPWL_CBButton::~CPWL_CBButton() = default;
@@ -159,8 +161,9 @@
   return true;
 }
 
-CPWL_ComboBox::CPWL_ComboBox(const CreateParams& cp,
-                             std::unique_ptr<PrivateData> pAttachedData)
+CPWL_ComboBox::CPWL_ComboBox(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_Wnd(cp, std::move(pAttachedData)) {
   GetCreationParams()->dwFlags &= ~PWS_HSCROLL;
   GetCreationParams()->dwFlags &= ~PWS_VSCROLL;
diff --git a/fpdfsdk/pwl/cpwl_combo_box.h b/fpdfsdk/pwl/cpwl_combo_box.h
index c059b5c..8b9bf12 100644
--- a/fpdfsdk/pwl/cpwl_combo_box.h
+++ b/fpdfsdk/pwl/cpwl_combo_box.h
@@ -16,8 +16,9 @@
 
 class CPWL_CBListBox final : public CPWL_ListBox {
  public:
-  CPWL_CBListBox(const CreateParams& cp,
-                 std::unique_ptr<PrivateData> pAttachedData);
+  CPWL_CBListBox(
+      const CreateParams& cp,
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_CBListBox() override;
 
   // CPWL_ListBox
@@ -31,8 +32,9 @@
 
 class CPWL_CBButton final : public CPWL_Wnd {
  public:
-  CPWL_CBButton(const CreateParams& cp,
-                std::unique_ptr<PrivateData> pAttachedData);
+  CPWL_CBButton(
+      const CreateParams& cp,
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_CBButton() override;
 
   // CPWL_Wnd
@@ -44,8 +46,9 @@
 
 class CPWL_ComboBox final : public CPWL_Wnd {
  public:
-  CPWL_ComboBox(const CreateParams& cp,
-                std::unique_ptr<PrivateData> pAttachedData);
+  CPWL_ComboBox(
+      const CreateParams& cp,
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_ComboBox() override;
 
   CPWL_Edit* GetEdit() const { return m_pEdit.Get(); }
diff --git a/fpdfsdk/pwl/cpwl_edit.cpp b/fpdfsdk/pwl/cpwl_edit.cpp
index 99fe2c2..77491da 100644
--- a/fpdfsdk/pwl/cpwl_edit.cpp
+++ b/fpdfsdk/pwl/cpwl_edit.cpp
@@ -27,8 +27,9 @@
 #include "fpdfsdk/pwl/cpwl_wnd.h"
 #include "public/fpdf_fwlevent.h"
 
-CPWL_Edit::CPWL_Edit(const CreateParams& cp,
-                     std::unique_ptr<PrivateData> pAttachedData)
+CPWL_Edit::CPWL_Edit(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_EditCtrl(cp, std::move(pAttachedData)) {}
 
 CPWL_Edit::~CPWL_Edit() {
diff --git a/fpdfsdk/pwl/cpwl_edit.h b/fpdfsdk/pwl/cpwl_edit.h
index 0e16a7f..02de67c 100644
--- a/fpdfsdk/pwl/cpwl_edit.h
+++ b/fpdfsdk/pwl/cpwl_edit.h
@@ -13,19 +13,21 @@
 #include "core/fpdfdoc/cpvt_wordrange.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "fpdfsdk/pwl/cpwl_edit_ctrl.h"
+#include "fpdfsdk/pwl/ipwl_systemhandler.h"
 
 class IPWL_Filler_Notify {
  public:
   virtual ~IPWL_Filler_Notify() = default;
 
   // Must write to |bBottom| and |fPopupRet|.
-  virtual void QueryWherePopup(const CPWL_Wnd::PrivateData* pAttached,
-                               float fPopupMin,
-                               float fPopupMax,
-                               bool* bBottom,
-                               float* fPopupRet) = 0;
+  virtual void QueryWherePopup(
+      const IPWL_SystemHandler::PerWindowData* pAttached,
+      float fPopupMin,
+      float fPopupMax,
+      bool* bBottom,
+      float* fPopupRet) = 0;
   virtual std::pair<bool, bool> OnBeforeKeyStroke(
-      const CPWL_Wnd::PrivateData* pAttached,
+      const IPWL_SystemHandler::PerWindowData* pAttached,
       WideString& strChange,
       const WideString& strChangeEx,
       int nSelStart,
@@ -34,16 +36,19 @@
       uint32_t nFlag) = 0;
 
 #ifdef PDF_ENABLE_XFA
-  virtual bool OnPopupPreOpen(const CPWL_Wnd::PrivateData* pAttached,
-                              uint32_t nFlag) = 0;
-  virtual bool OnPopupPostOpen(const CPWL_Wnd::PrivateData* pAttached,
-                               uint32_t nFlag) = 0;
+  virtual bool OnPopupPreOpen(
+      const IPWL_SystemHandler::PerWindowData* pAttached,
+      uint32_t nFlag) = 0;
+  virtual bool OnPopupPostOpen(
+      const IPWL_SystemHandler::PerWindowData* pAttached,
+      uint32_t nFlag) = 0;
 #endif  // PDF_ENABLE_XFA
 };
 
 class CPWL_Edit final : public CPWL_EditCtrl {
  public:
-  CPWL_Edit(const CreateParams& cp, std::unique_ptr<PrivateData> pAttachedData);
+  CPWL_Edit(const CreateParams& cp,
+            std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_Edit() override;
 
   // CPWL_EditCtrl
diff --git a/fpdfsdk/pwl/cpwl_edit_ctrl.cpp b/fpdfsdk/pwl/cpwl_edit_ctrl.cpp
index 28d9168..efdafce 100644
--- a/fpdfsdk/pwl/cpwl_edit_ctrl.cpp
+++ b/fpdfsdk/pwl/cpwl_edit_ctrl.cpp
@@ -17,8 +17,9 @@
 #include "public/fpdf_fwlevent.h"
 #include "third_party/base/ptr_util.h"
 
-CPWL_EditCtrl::CPWL_EditCtrl(const CreateParams& cp,
-                             std::unique_ptr<PrivateData> pAttachedData)
+CPWL_EditCtrl::CPWL_EditCtrl(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_Wnd(cp, std::move(pAttachedData)),
       m_pEdit(pdfium::MakeUnique<CPWL_EditImpl>()) {
   GetCreationParams()->eCursorType = FXCT_VBEAM;
diff --git a/fpdfsdk/pwl/cpwl_edit_ctrl.h b/fpdfsdk/pwl/cpwl_edit_ctrl.h
index df504d8..9cd92bf 100644
--- a/fpdfsdk/pwl/cpwl_edit_ctrl.h
+++ b/fpdfsdk/pwl/cpwl_edit_ctrl.h
@@ -23,8 +23,9 @@
 
 class CPWL_EditCtrl : public CPWL_Wnd {
  public:
-  CPWL_EditCtrl(const CreateParams& cp,
-                std::unique_ptr<PrivateData> pAttachedData);
+  CPWL_EditCtrl(
+      const CreateParams& cp,
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_EditCtrl() override;
 
   void SetSelection(int32_t nStartChar, int32_t nEndChar);
diff --git a/fpdfsdk/pwl/cpwl_icon.cpp b/fpdfsdk/pwl/cpwl_icon.cpp
index 946c76f..9d47067 100644
--- a/fpdfsdk/pwl/cpwl_icon.cpp
+++ b/fpdfsdk/pwl/cpwl_icon.cpp
@@ -15,8 +15,9 @@
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "fpdfsdk/pwl/cpwl_wnd.h"
 
-CPWL_Icon::CPWL_Icon(const CreateParams& cp,
-                     std::unique_ptr<PrivateData> pAttachedData)
+CPWL_Icon::CPWL_Icon(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_Wnd(cp, std::move(pAttachedData)) {}
 
 CPWL_Icon::~CPWL_Icon() = default;
diff --git a/fpdfsdk/pwl/cpwl_icon.h b/fpdfsdk/pwl/cpwl_icon.h
index c1cc195..859f686 100644
--- a/fpdfsdk/pwl/cpwl_icon.h
+++ b/fpdfsdk/pwl/cpwl_icon.h
@@ -16,7 +16,8 @@
 
 class CPWL_Icon final : public CPWL_Wnd {
  public:
-  CPWL_Icon(const CreateParams& cp, std::unique_ptr<PrivateData> pAttachedData);
+  CPWL_Icon(const CreateParams& cp,
+            std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_Icon() override;
 
   void SetIconFit(CPDF_IconFit* pIconFit) { m_pIconFit = pIconFit; }
diff --git a/fpdfsdk/pwl/cpwl_list_box.cpp b/fpdfsdk/pwl/cpwl_list_box.cpp
index f6f7201..56712a8 100644
--- a/fpdfsdk/pwl/cpwl_list_box.cpp
+++ b/fpdfsdk/pwl/cpwl_list_box.cpp
@@ -65,8 +65,9 @@
   m_pList->InvalidateRect(pRect);
 }
 
-CPWL_ListBox::CPWL_ListBox(const CreateParams& cp,
-                           std::unique_ptr<PrivateData> pAttachedData)
+CPWL_ListBox::CPWL_ListBox(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_Wnd(cp, std::move(pAttachedData)),
       m_pList(pdfium::MakeUnique<CPWL_ListCtrl>()) {}
 
diff --git a/fpdfsdk/pwl/cpwl_list_box.h b/fpdfsdk/pwl/cpwl_list_box.h
index ab53b70..ba3a653 100644
--- a/fpdfsdk/pwl/cpwl_list_box.h
+++ b/fpdfsdk/pwl/cpwl_list_box.h
@@ -38,8 +38,9 @@
 
 class CPWL_ListBox : public CPWL_Wnd {
  public:
-  CPWL_ListBox(const CreateParams& cp,
-               std::unique_ptr<PrivateData> pAttachedData);
+  CPWL_ListBox(
+      const CreateParams& cp,
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_ListBox() override;
 
   // CPWL_Wnd
diff --git a/fpdfsdk/pwl/cpwl_scroll_bar.cpp b/fpdfsdk/pwl/cpwl_scroll_bar.cpp
index f5cdc01..f272a89 100644
--- a/fpdfsdk/pwl/cpwl_scroll_bar.cpp
+++ b/fpdfsdk/pwl/cpwl_scroll_bar.cpp
@@ -106,10 +106,11 @@
     SetPos(ScrollRange.fMin);
 }
 
-CPWL_SBButton::CPWL_SBButton(const CreateParams& cp,
-                             std::unique_ptr<PrivateData> pAttachedData,
-                             PWL_SCROLLBAR_TYPE eScrollBarType,
-                             PWL_SBBUTTON_TYPE eButtonType)
+CPWL_SBButton::CPWL_SBButton(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData,
+    PWL_SCROLLBAR_TYPE eScrollBarType,
+    PWL_SBBUTTON_TYPE eButtonType)
     : CPWL_Wnd(cp, std::move(pAttachedData)),
       m_eScrollBarType(eScrollBarType),
       m_eSBButtonType(eButtonType) {
@@ -298,9 +299,10 @@
   return true;
 }
 
-CPWL_ScrollBar::CPWL_ScrollBar(const CreateParams& cp,
-                               std::unique_ptr<PrivateData> pAttachedData,
-                               PWL_SCROLLBAR_TYPE sbType)
+CPWL_ScrollBar::CPWL_ScrollBar(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData,
+    PWL_SCROLLBAR_TYPE sbType)
     : CPWL_Wnd(cp, std::move(pAttachedData)), m_sbType(sbType) {
   GetCreationParams()->eCursorType = FXCT_ARROW;
 }
diff --git a/fpdfsdk/pwl/cpwl_scroll_bar.h b/fpdfsdk/pwl/cpwl_scroll_bar.h
index 414f718..00fdece 100644
--- a/fpdfsdk/pwl/cpwl_scroll_bar.h
+++ b/fpdfsdk/pwl/cpwl_scroll_bar.h
@@ -43,10 +43,11 @@
 
 class CPWL_SBButton final : public CPWL_Wnd {
  public:
-  CPWL_SBButton(const CreateParams& cp,
-                std::unique_ptr<PrivateData> pAttachedData,
-                PWL_SCROLLBAR_TYPE eScrollBarType,
-                PWL_SBBUTTON_TYPE eButtonType);
+  CPWL_SBButton(
+      const CreateParams& cp,
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData,
+      PWL_SCROLLBAR_TYPE eScrollBarType,
+      PWL_SBBUTTON_TYPE eButtonType);
   ~CPWL_SBButton() override;
 
   // CPWL_Wnd
@@ -114,9 +115,10 @@
 
 class CPWL_ScrollBar final : public CPWL_Wnd {
  public:
-  CPWL_ScrollBar(const CreateParams& cp,
-                 std::unique_ptr<PrivateData> pAttachedData,
-                 PWL_SCROLLBAR_TYPE sbType);
+  CPWL_ScrollBar(
+      const CreateParams& cp,
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData,
+      PWL_SCROLLBAR_TYPE sbType);
   ~CPWL_ScrollBar() override;
 
   // CPWL_Wnd:
diff --git a/fpdfsdk/pwl/cpwl_special_button.cpp b/fpdfsdk/pwl/cpwl_special_button.cpp
index 16f8c89..3fbf919 100644
--- a/fpdfsdk/pwl/cpwl_special_button.cpp
+++ b/fpdfsdk/pwl/cpwl_special_button.cpp
@@ -11,8 +11,9 @@
 #include "fpdfsdk/pwl/cpwl_button.h"
 #include "fpdfsdk/pwl/cpwl_wnd.h"
 
-CPWL_PushButton::CPWL_PushButton(const CreateParams& cp,
-                                 std::unique_ptr<PrivateData> pAttachedData)
+CPWL_PushButton::CPWL_PushButton(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_Button(cp, std::move(pAttachedData)) {}
 
 CPWL_PushButton::~CPWL_PushButton() = default;
@@ -22,8 +23,9 @@
                                      static_cast<float>(GetBorderWidth()));
 }
 
-CPWL_CheckBox::CPWL_CheckBox(const CreateParams& cp,
-                             std::unique_ptr<PrivateData> pAttachedData)
+CPWL_CheckBox::CPWL_CheckBox(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_Button(cp, std::move(pAttachedData)) {}
 
 CPWL_CheckBox::~CPWL_CheckBox() = default;
@@ -41,8 +43,9 @@
   return true;
 }
 
-CPWL_RadioButton::CPWL_RadioButton(const CreateParams& cp,
-                                   std::unique_ptr<PrivateData> pAttachedData)
+CPWL_RadioButton::CPWL_RadioButton(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : CPWL_Button(cp, std::move(pAttachedData)) {}
 
 CPWL_RadioButton::~CPWL_RadioButton() = default;
diff --git a/fpdfsdk/pwl/cpwl_special_button.h b/fpdfsdk/pwl/cpwl_special_button.h
index 68bb965..3d9fa25 100644
--- a/fpdfsdk/pwl/cpwl_special_button.h
+++ b/fpdfsdk/pwl/cpwl_special_button.h
@@ -13,8 +13,9 @@
 
 class CPWL_PushButton final : public CPWL_Button {
  public:
-  CPWL_PushButton(const CreateParams& cp,
-                  std::unique_ptr<PrivateData> pAttachedData);
+  CPWL_PushButton(
+      const CreateParams& cp,
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_PushButton() override;
 
   // CPWL_Button:
@@ -23,8 +24,9 @@
 
 class CPWL_CheckBox final : public CPWL_Button {
  public:
-  CPWL_CheckBox(const CreateParams& cp,
-                std::unique_ptr<PrivateData> pAttachedData);
+  CPWL_CheckBox(
+      const CreateParams& cp,
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_CheckBox() override;
 
   // CPWL_Button:
@@ -40,8 +42,9 @@
 
 class CPWL_RadioButton final : public CPWL_Button {
  public:
-  CPWL_RadioButton(const CreateParams& cp,
-                   std::unique_ptr<PrivateData> pAttachedData);
+  CPWL_RadioButton(
+      const CreateParams& cp,
+      std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_RadioButton() override;
 
   // CPWL_Button
diff --git a/fpdfsdk/pwl/cpwl_wnd.cpp b/fpdfsdk/pwl/cpwl_wnd.cpp
index 0b77ee4..15e4d45 100644
--- a/fpdfsdk/pwl/cpwl_wnd.cpp
+++ b/fpdfsdk/pwl/cpwl_wnd.cpp
@@ -12,7 +12,6 @@
 #include <vector>
 
 #include "core/fxge/cfx_renderdevice.h"
-#include "fpdfsdk/cpdfsdk_widget.h"
 #include "fpdfsdk/pwl/cpwl_scroll_bar.h"
 #include "public/fpdf_fwlevent.h"
 #include "third_party/base/ptr_util.h"
@@ -118,8 +117,9 @@
   return !!(nFlag & FWL_EVENTFLAG_AltKey);
 }
 
-CPWL_Wnd::CPWL_Wnd(const CreateParams& cp,
-                   std::unique_ptr<PrivateData> pAttachedData)
+CPWL_Wnd::CPWL_Wnd(
+    const CreateParams& cp,
+    std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData)
     : m_CreationParams(cp), m_pAttachedData(std::move(pAttachedData)) {}
 
 CPWL_Wnd::~CPWL_Wnd() {
@@ -254,26 +254,21 @@
 }
 
 bool CPWL_Wnd::InvalidateRect(CFX_FloatRect* pRect) {
-    if (!IsValid())
+  if (!IsValid())
     return true;
 
-    ObservedPtr<CPWL_Wnd> thisObserved(this);
-    CFX_FloatRect rcRefresh = pRect ? *pRect : GetWindowRect();
-    if (!HasFlag(PWS_NOREFRESHCLIP)) {
-      CFX_FloatRect rcClip = GetClipRect();
-      if (!rcClip.IsEmpty())
-        rcRefresh.Intersect(rcClip);
-    }
+  ObservedPtr<CPWL_Wnd> thisObserved(this);
+  CFX_FloatRect rcRefresh = pRect ? *pRect : GetWindowRect();
+  if (!HasFlag(PWS_NOREFRESHCLIP)) {
+    CFX_FloatRect rcClip = GetClipRect();
+    if (!rcClip.IsEmpty())
+      rcRefresh.Intersect(rcClip);
+  }
 
   CFX_FloatRect rcWin = PWLtoWnd(rcRefresh);
   rcWin.Inflate(1, 1);
   rcWin.Normalize();
-
-  CPDFSDK_Widget* widget = m_pAttachedData->GetWidget();
-  if (!widget)
-    return true;
-
-  GetSystemHandler()->InvalidateRect(widget, rcWin);
+  GetSystemHandler()->InvalidateRect(m_pAttachedData.get(), rcWin);
   return !!thisObserved;
 }
 
@@ -528,7 +523,8 @@
 
 void CPWL_Wnd::OnKillFocus() {}
 
-std::unique_ptr<CPWL_Wnd::PrivateData> CPWL_Wnd::CloneAttachedData() const {
+std::unique_ptr<IPWL_SystemHandler::PerWindowData> CPWL_Wnd::CloneAttachedData()
+    const {
   return m_pAttachedData ? m_pAttachedData->Clone() : nullptr;
 }
 
diff --git a/fpdfsdk/pwl/cpwl_wnd.h b/fpdfsdk/pwl/cpwl_wnd.h
index d0fe7b7..75a271b 100644
--- a/fpdfsdk/pwl/cpwl_wnd.h
+++ b/fpdfsdk/pwl/cpwl_wnd.h
@@ -17,13 +17,12 @@
 #include "core/fxge/cfx_renderdevice.h"
 #include "fpdfsdk/pwl/cpwl_timer.h"
 #include "fpdfsdk/pwl/cpwl_timer_handler.h"
+#include "fpdfsdk/pwl/ipwl_systemhandler.h"
 
-class CPDFSDK_Widget;
 class CPWL_Edit;
 class CPWL_MsgControl;
 class CPWL_ScrollBar;
 class IPVT_FontMap;
-class IPWL_SystemHandler;
 struct PWL_SCROLL_INFO;
 
 // window styles
@@ -94,19 +93,13 @@
 
 class CPWL_Wnd : public CPWL_TimerHandler, public Observable {
  public:
-  class PrivateData {
-   public:
-    virtual ~PrivateData() = default;
-    virtual std::unique_ptr<PrivateData> Clone() const = 0;
-    virtual CPDFSDK_Widget* GetWidget() const = 0;
-  };
-
   class ProviderIface : public Observable {
    public:
     virtual ~ProviderIface() = default;
 
     // get a matrix which map user space to CWnd client space
-    virtual CFX_Matrix GetWindowMatrix(const PrivateData* pAttached) = 0;
+    virtual CFX_Matrix GetWindowMatrix(
+        const IPWL_SystemHandler::PerWindowData* pAttached) = 0;
   };
 
   class FocusHandlerIface {
@@ -144,7 +137,8 @@
   static bool IsCTRLKeyDown(uint32_t nFlag);
   static bool IsALTKeyDown(uint32_t nFlag);
 
-  CPWL_Wnd(const CreateParams& cp, std::unique_ptr<PrivateData> pAttachedData);
+  CPWL_Wnd(const CreateParams& cp,
+           std::unique_ptr<IPWL_SystemHandler::PerWindowData> pAttachedData);
   ~CPWL_Wnd() override;
 
   // Returns |true| iff this instance is still allocated.
@@ -227,8 +221,10 @@
   const CFX_FloatRect& GetClipRect() const;
 
   CPWL_Wnd* GetParentWindow() const { return m_pParent.Get(); }
-  const PrivateData* GetAttachedData() const { return m_pAttachedData.get(); }
-  std::unique_ptr<PrivateData> CloneAttachedData() const;
+  const IPWL_SystemHandler::PerWindowData* GetAttachedData() const {
+    return m_pAttachedData.get();
+  }
+  std::unique_ptr<IPWL_SystemHandler::PerWindowData> CloneAttachedData() const;
 
   bool WndHitTest(const CFX_PointF& point) const;
   bool ClientHitTest(const CFX_PointF& point) const;
@@ -315,7 +311,7 @@
   CPWL_MsgControl* GetMsgControl() const;
 
   CreateParams m_CreationParams;
-  std::unique_ptr<PrivateData> m_pAttachedData;
+  std::unique_ptr<IPWL_SystemHandler::PerWindowData> m_pAttachedData;
   UnownedPtr<CPWL_Wnd> m_pParent;
   std::vector<std::unique_ptr<CPWL_Wnd>> m_Children;
   UnownedPtr<CPWL_ScrollBar> m_pVScrollBar;
diff --git a/fpdfsdk/pwl/ipwl_systemhandler.h b/fpdfsdk/pwl/ipwl_systemhandler.h
index 3607e73..017bffe 100644
--- a/fpdfsdk/pwl/ipwl_systemhandler.h
+++ b/fpdfsdk/pwl/ipwl_systemhandler.h
@@ -7,18 +7,25 @@
 #ifndef FPDFSDK_PWL_IPWL_SYSTEMHANDLER_H_
 #define FPDFSDK_PWL_IPWL_SYSTEMHANDLER_H_
 
+#include <memory>
+
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/timerhandler_iface.h"
 
-class CPDFSDK_Widget;
 class CFFL_FormFiller;
 
 class IPWL_SystemHandler : public TimerHandlerIface {
  public:
+  class PerWindowData {
+   public:
+    virtual ~PerWindowData() = default;
+    virtual std::unique_ptr<PerWindowData> Clone() const = 0;
+  };
+
   ~IPWL_SystemHandler() override = default;
 
-  virtual void InvalidateRect(CPDFSDK_Widget* widget,
+  virtual void InvalidateRect(PerWindowData* pWidgetData,
                               const CFX_FloatRect& rect) = 0;
   virtual void OutputSelectedRect(CFFL_FormFiller* pFormFiller,
                                   const CFX_FloatRect& rect) = 0;