commit 1b93711736289471493ad12d73e48ee1440641cd
parent 896dd20402885d5bbd6e09fa203f859cb8c62513
Author: Emilio Cobos Álvarez <emilio@crisal.io>
Date: Tue, 28 Oct 2025 07:02:51 +0000
Bug 1994879 - Hide native popup off a script runner. r=tnikkel,layout-reviewers
Rather than off a runnable, so that we don't process native events in
between the enqueueing and the runnable running that could e.g. paint
the popup while it's supposed to be hidden.
Another alternative, maybe nicer, could be to reuse PaintPopups and
queue these there, but this is more similar to what SetViewVisibility used to
do.
Differential Revision: https://phabricator.services.mozilla.com/D270230
Diffstat:
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/layout/xul/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp
@@ -1088,18 +1088,12 @@ void nsMenuPopupFrame::HidePopup(bool aDeselectMenu, nsPopupState aNewState,
mHFlip = mVFlip = false;
mConstrainedByLayout = false;
- if (auto* widget = GetWidget()) {
+ RefPtr widget = GetWidget();
+ if (widget) {
widget->ClearCachedWebrenderResources();
if (!aFromFrameDestruction && !ShouldHaveWidgetWhenHidden()) {
PopupExpirationTracker::GetOrCreate().AddObject(this);
}
- NS_DispatchToMainThread(
- NS_NewRunnableFunction("HideWidget", [widget = RefPtr{widget}] {
- auto* frame = widget->GetPopupFrame();
- if (!frame || !frame->IsVisibleOrShowing()) {
- widget->Show(false);
- }
- }));
}
ClearPendingWidgetMoveResize();
@@ -1114,6 +1108,16 @@ void nsMenuPopupFrame::HidePopup(bool aDeselectMenu, nsPopupState aNewState,
esm->SetContentState(nullptr, dom::ElementState::HOVER);
}
popup->PopupClosed(aDeselectMenu);
+
+ if (widget) {
+ nsContentUtils::AddScriptRunner(
+ NS_NewRunnableFunction("HideWidget", [widget = std::move(widget)] {
+ auto* frame = widget->GetPopupFrame();
+ if (!frame || !frame->IsVisibleOrShowing()) {
+ widget->Show(false);
+ }
+ }));
+ }
}
void nsMenuPopupFrame::SchedulePendingWidgetMoveResize() {