Bug 1498973: Don't show a popup that should be hidden. r=jmathies
authorAdam Gashlin <agashlin@mozilla.com>
Wed, 06 Mar 2019 18:48:50 +0000
changeset 520568 067c36284e776e3e03d33d3ad99d110be04230af
parent 520567 6927cfe9f9caa0052b0be1fb8387254c5efac6d1
child 520569 dc078ca4d52733fa0905d28d3736dc3a3850d2a1
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmathies
bugs1498973
milestone67.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 1498973: Don't show a popup that should be hidden. r=jmathies Differential Revision: https://phabricator.services.mozilla.com/D21801
view/nsView.cpp
view/nsView.h
widget/nsIWidgetListener.cpp
widget/nsIWidgetListener.h
widget/windows/nsWindow.cpp
--- a/view/nsView.cpp
+++ b/view/nsView.cpp
@@ -1038,16 +1038,25 @@ void nsView::DidCompositeWindow(mozilla:
 
 void nsView::RequestRepaint() {
   nsIPresShell* presShell = mViewManager->GetPresShell();
   if (presShell) {
     presShell->ScheduleViewManagerFlush();
   }
 }
 
+bool nsView::ShouldNotBeVisible() {
+  if (mFrame && mFrame->IsMenuPopupFrame()) {
+    nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
+    return !pm || !pm->IsPopupOpen(mFrame->GetContent());
+  }
+
+  return false;
+}
+
 nsEventStatus nsView::HandleEvent(WidgetGUIEvent* aEvent,
                                   bool aUseAttachedEvents) {
   MOZ_ASSERT(nullptr != aEvent->mWidget, "null widget ptr");
 
   nsEventStatus result = nsEventStatus_eIgnore;
   nsView* view;
   if (aUseAttachedEvents) {
     nsIWidgetListener* listener = aEvent->mWidget->GetAttachedWidgetListener();
--- a/view/nsView.h
+++ b/view/nsView.h
@@ -388,16 +388,17 @@ class nsView final : public nsIWidgetLis
   virtual bool PaintWindow(nsIWidget* aWidget,
                            LayoutDeviceIntRegion aRegion) override;
   virtual void DidPaintWindow() override;
   virtual void DidCompositeWindow(
       mozilla::layers::TransactionId aTransactionId,
       const mozilla::TimeStamp& aCompositeStart,
       const mozilla::TimeStamp& aCompositeEnd) override;
   virtual void RequestRepaint() override;
+  virtual bool ShouldNotBeVisible() override;
   virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent,
                                     bool aUseAttachedEvents) override;
 
   virtual ~nsView();
 
   nsPoint GetOffsetTo(const nsView* aOther, const int32_t aAPD) const;
   nsIWidget* GetNearestWidget(nsPoint* aOffset, const int32_t aAPD) const;
 
--- a/widget/nsIWidgetListener.cpp
+++ b/widget/nsIWidgetListener.cpp
@@ -65,12 +65,17 @@ bool nsIWidgetListener::PaintWindow(nsIW
 void nsIWidgetListener::DidPaintWindow() {}
 
 void nsIWidgetListener::DidCompositeWindow(
     mozilla::layers::TransactionId aTransactionId,
     const TimeStamp& aCompositeStart, const TimeStamp& aCompositeEnd) {}
 
 void nsIWidgetListener::RequestRepaint() {}
 
+bool nsIWidgetListener::ShouldNotBeVisible() {
+  // Returns false to assume that nothing should happen in most cases.
+  return true;
+}
+
 nsEventStatus nsIWidgetListener::HandleEvent(WidgetGUIEvent* aEvent,
                                              bool aUseAttachedEvents) {
   return nsEventStatus_eIgnore;
 }
--- a/widget/nsIWidgetListener.h
+++ b/widget/nsIWidgetListener.h
@@ -158,15 +158,22 @@ class nsIWidgetListener {
                                   const mozilla::TimeStamp& aCompositeEnd);
 
   /**
    * Request that layout schedules a repaint on the next refresh driver tick.
    */
   virtual void RequestRepaint();
 
   /**
+   * Returns true if this is a popup that should not be visible. If this
+   * is a popup that is visible, not a popup or this state is unknown,
+   * returns false.
+   */
+  virtual bool ShouldNotBeVisible();
+
+  /**
    * Handle an event.
    */
   virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent,
                                     bool aUseAttachedEvents);
 };
 
 #endif
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -6533,16 +6533,26 @@ void nsWindow::OnWindowPosChanging(LPWIN
           info->hwndInsertAfter =
               (HWND)actualBelow->GetNativeData(NS_NATIVE_WINDOW);
         }
       }
     }
   }
   // prevent rude external programs from making hidden window visible
   if (mWindowType == eWindowType_invisible) info->flags &= ~SWP_SHOWWINDOW;
+
+  // When waking from sleep or switching out of tablet mode, Windows 10
+  // Version 1809 will reopen popup windows that should be hidden. Detect
+  // this case and refuse to show the window.
+  static bool sDWMUnhidesPopups = IsWin10Sep2018UpdateOrLater();
+  if (sDWMUnhidesPopups && (info->flags & SWP_SHOWWINDOW) &&
+      mWindowType == eWindowType_popup && mWidgetListener &&
+      mWidgetListener->ShouldNotBeVisible()) {
+    info->flags &= ~SWP_SHOWWINDOW;
+  }
 }
 
 void nsWindow::UserActivity() {
   // Check if we have the idle service, if not we try to get it.
   if (!mIdleService) {
     mIdleService = do_GetService("@mozilla.org/widget/idleservice;1");
   }