From 50205986b227cdbdcfdae2f03aa44ae5ffb47acb Mon Sep 17 00:00:00 2001 From: Martin Stransky Date: Fri, 21 Aug 2020 11:14:37 +0200 Subject: [PATCH] spec cleanup --- bug1375074-save-restore-x28.patch | 74 ----- firefox.spec | 3 - mozilla-1337988.patch | 496 ----------------------------- mozilla-1580174-webrtc-popup.patch | 51 --- 4 files changed, 624 deletions(-) delete mode 100644 bug1375074-save-restore-x28.patch delete mode 100644 mozilla-1337988.patch delete mode 100644 mozilla-1580174-webrtc-popup.patch diff --git a/bug1375074-save-restore-x28.patch b/bug1375074-save-restore-x28.patch deleted file mode 100644 index 57a83a2..0000000 --- a/bug1375074-save-restore-x28.patch +++ /dev/null @@ -1,74 +0,0 @@ -# HG changeset patch -# User Lars T Hansen -# Date 1519822672 -3600 -# Wed Feb 28 13:57:52 2018 +0100 -# Node ID 672f0415217b202ae59a930769dffd9d6ba6b87c -# Parent 825fd04dacc6297d3a980ec4184079405950b35d -Bug 1375074 - Save and restore non-volatile x28 on ARM64 for generated unboxed object constructor. - -diff --git a/js/src/jit-test/tests/bug1375074.js b/js/src/jit-test/tests/bug1375074.js -new file mode 100644 ---- /dev/null -+++ b/js/src/jit-test/tests/bug1375074.js -@@ -0,0 +1,18 @@ -+// This forces the VM to start creating unboxed objects and thus stresses a -+// particular path into generated code for a specialized unboxed object -+// constructor. -+ -+var K = 2000; // 2000 should be plenty -+var s = "["; -+var i; -+for ( i=0; i < K-1; i++ ) -+ s = s + `{"i":${i}},`; -+s += `{"i":${i}}]`; -+var v = JSON.parse(s); -+ -+assertEq(v.length == K, true); -+ -+for ( i=0; i < K; i++) { -+ assertEq(v[i] instanceof Object, true); -+ assertEq(v[i].i, i); -+} -diff --git a/js/src/vm/UnboxedObject.cpp b/js/src/vm/UnboxedObject.cpp ---- a/js/src/vm/UnboxedObject.cpp -+++ b/js/src/vm/UnboxedObject.cpp -@@ -95,7 +95,15 @@ UnboxedLayout::makeConstructorCode(JSCon - #endif - - #ifdef JS_CODEGEN_ARM64 -- // ARM64 communicates stack address via sp, but uses a pseudo-sp for addressing. -+ // ARM64 communicates stack address via sp, but uses a pseudo-sp (PSP) for -+ // addressing. The register we use for PSP may however also be used by -+ // calling code, and it is nonvolatile, so save it. Do this as a special -+ // case first because the generic save/restore code needs the PSP to be -+ // initialized already. -+ MOZ_ASSERT(PseudoStackPointer64.Is(masm.GetStackPointer64())); -+ masm.Str(PseudoStackPointer64, vixl::MemOperand(sp, -16, vixl::PreIndex)); -+ -+ // Initialize the PSP from the SP. - masm.initStackPtr(); - #endif - -@@ -233,7 +241,22 @@ UnboxedLayout::makeConstructorCode(JSCon - masm.pop(ScratchDoubleReg); - masm.PopRegsInMask(savedNonVolatileRegisters); - -+#ifdef JS_CODEGEN_ARM64 -+ // Now restore the value that was in the PSP register on entry, and return. -+ -+ // Obtain the correct SP from the PSP. -+ masm.Mov(sp, PseudoStackPointer64); -+ -+ // Restore the saved value of the PSP register, this value is whatever the -+ // caller had saved in it, not any actual SP value, and it must not be -+ // overwritten subsequently. -+ masm.Ldr(PseudoStackPointer64, vixl::MemOperand(sp, 16, vixl::PostIndex)); -+ -+ // Perform a plain Ret(), as abiret() will move SP <- PSP and that is wrong. -+ masm.Ret(vixl::lr); -+#else - masm.abiret(); -+#endif - - masm.bind(&failureStoreOther); - diff --git a/firefox.spec b/firefox.spec index d1e86ef..aa2e672 100644 --- a/firefox.spec +++ b/firefox.spec @@ -171,9 +171,6 @@ Patch227: firefox-locale-debug.patch # Upstream patches Patch402: mozilla-1196777.patch -Patch412: mozilla-1337988.patch -Patch417: bug1375074-save-restore-x28.patch -Patch422: mozilla-1580174-webrtc-popup.patch # Wayland specific upstream patches Patch574: firefox-pipewire-0-2.patch diff --git a/mozilla-1337988.patch b/mozilla-1337988.patch deleted file mode 100644 index 8c40445..0000000 --- a/mozilla-1337988.patch +++ /dev/null @@ -1,496 +0,0 @@ -diff -up firefox-56.0/dom/plugins/base/nsJSNPRuntime.cpp.1337988 firefox-56.0/dom/plugins/base/nsJSNPRuntime.cpp ---- firefox-56.0/dom/plugins/base/nsJSNPRuntime.cpp.1337988 2017-09-14 22:15:56.000000000 +0200 -+++ firefox-56.0/dom/plugins/base/nsJSNPRuntime.cpp 2017-09-25 10:34:11.205611698 +0200 -@@ -1719,7 +1719,7 @@ NPObjWrapper_ObjectMoved(JSObject *obj, - auto entry = - static_cast(sNPObjWrappers->Search(npobj)); - MOZ_ASSERT(entry && entry->mJSObj); -- MOZ_ASSERT(entry->mJSObj == old); -+ MOZ_ASSERT(entry->mJSObj.unbarrieredGetPtr() == old); - entry->mJSObj = obj; - } - -diff -up firefox-56.0/js/ipc/JavaScriptShared.cpp.1337988 firefox-56.0/js/ipc/JavaScriptShared.cpp ---- firefox-56.0/js/ipc/JavaScriptShared.cpp.1337988 2017-07-31 18:20:47.000000000 +0200 -+++ firefox-56.0/js/ipc/JavaScriptShared.cpp 2017-09-25 10:34:11.205611698 +0200 -@@ -101,7 +101,7 @@ IdToObjectMap::has(const ObjectId& id, c - auto p = table_.lookup(id); - if (!p) - return false; -- return p->value() == obj; -+ return p->value().unbarrieredGet() == obj; - } - #endif - -diff -up firefox-56.0/js/public/RootingAPI.h.1337988 firefox-56.0/js/public/RootingAPI.h ---- firefox-56.0/js/public/RootingAPI.h.1337988 2017-07-31 18:20:47.000000000 +0200 -+++ firefox-56.0/js/public/RootingAPI.h 2017-09-25 10:34:11.206611695 +0200 -@@ -148,6 +148,10 @@ template - struct PersistentRootedMarker; - } /* namespace gc */ - -+#define DECLARE_POINTER_COMPARISON_OPS(T) \ -+ bool operator==(const T& other) const { return get() == other; } \ -+ bool operator!=(const T& other) const { return get() != other; } -+ - // Important: Return a reference so passing a Rooted, etc. to - // something that takes a |const T&| is not a GC hazard. - #define DECLARE_POINTER_CONSTREF_OPS(T) \ -@@ -237,8 +241,6 @@ class Heap : public js::HeapBase::value, - "Type T must be a public GC pointer type"); - public: -- using ElementType = T; -- - Heap() { - static_assert(sizeof(T) == sizeof(Heap), - "Heap must be binary compatible with T."); -@@ -385,8 +387,6 @@ template - class TenuredHeap : public js::HeapBase> - { - public: -- using ElementType = T; -- - TenuredHeap() : bits(0) { - static_assert(sizeof(T) == sizeof(TenuredHeap), - "TenuredHeap must be binary compatible with T."); -@@ -394,6 +394,9 @@ class TenuredHeap : public js::HeapBase< - explicit TenuredHeap(T p) : bits(0) { setPtr(p); } - explicit TenuredHeap(const TenuredHeap& p) : bits(0) { setPtr(p.getPtr()); } - -+ bool operator==(const TenuredHeap& other) { return bits == other.bits; } -+ bool operator!=(const TenuredHeap& other) { return bits != other.bits; } -+ - void setPtr(T newPtr) { - MOZ_ASSERT((reinterpret_cast(newPtr) & flagsMask) == 0); - if (newPtr) -@@ -470,8 +473,6 @@ class MOZ_NONHEAP_CLASS Handle : public - friend class JS::MutableHandle; - - public: -- using ElementType = T; -- - /* Creates a handle from a handle of a type convertible to T. */ - template - MOZ_IMPLICIT Handle(Handle handle, -@@ -533,6 +534,7 @@ class MOZ_NONHEAP_CLASS Handle : public - MOZ_IMPLICIT Handle(MutableHandle& root, - typename mozilla::EnableIf::value, int>::Type dummy = 0); - -+ DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr); - -@@ -559,8 +561,6 @@ template - class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase> - { - public: -- using ElementType = T; -- - inline MOZ_IMPLICIT MutableHandle(Rooted* root); - inline MOZ_IMPLICIT MutableHandle(PersistentRooted* root); - -@@ -589,6 +589,7 @@ class MOZ_STACK_CLASS MutableHandle : pu - return h; - } - -+ DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr); - DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr); -@@ -805,8 +806,6 @@ class MOZ_RAII Rooted : public js::Roote - } - - public: -- using ElementType = T; -- - template - explicit Rooted(const RootingContext& cx) - : ptr(GCPolicy::initial()) -@@ -839,6 +838,7 @@ class MOZ_RAII Rooted : public js::Roote - ptr = mozilla::Move(value); - } - -+ DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(Rooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); -@@ -903,14 +903,13 @@ template - class MOZ_RAII FakeRooted : public RootedBase> - { - public: -- using ElementType = T; -- - template - explicit FakeRooted(CX* cx) : ptr(JS::GCPolicy::initial()) {} - - template - FakeRooted(CX* cx, T initial) : ptr(initial) {} - -+ DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(FakeRooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); -@@ -931,8 +930,6 @@ template - class FakeMutableHandle : public js::MutableHandleBase> - { - public: -- using ElementType = T; -- - MOZ_IMPLICIT FakeMutableHandle(T* t) { - ptr = t; - } -@@ -1124,8 +1121,6 @@ class PersistentRooted : public js::Root - } - - public: -- using ElementType = T; -- - PersistentRooted() : ptr(GCPolicy::initial()) {} - - explicit PersistentRooted(RootingContext* cx) -@@ -1203,6 +1198,7 @@ class PersistentRooted : public js::Root - } - } - -+ DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - DECLARE_POINTER_ASSIGN_OPS(PersistentRooted, T); - DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr); -@@ -1234,8 +1230,6 @@ class JS_PUBLIC_API(ObjectPtr) - Heap value; - - public: -- using ElementType = JSObject*; -- - ObjectPtr() : value(nullptr) {} - - explicit ObjectPtr(JSObject* obj) : value(obj) {} -@@ -1342,177 +1336,6 @@ Swap(JS::TenuredHeap& aX, JS::Tenured - - } /* namespace mozilla */ - --namespace js { --namespace detail { -- --// DefineComparisonOps is a trait which selects which wrapper classes to define --// operator== and operator!= for. It supplies a getter function to extract the --// value to compare. This is used to avoid triggering the automatic read --// barriers where appropriate. --// --// If DefineComparisonOps is not specialized for a particular wrapper you may --// get errors such as 'invalid operands to binary expression' or 'no match for --// operator==' when trying to compare against instances of the wrapper. -- --template --struct DefineComparisonOps : mozilla::FalseType {}; -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T& get(const JS::Heap& v) { return v.unbarrieredGet(); } --}; -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T get(const JS::TenuredHeap& v) { return v.unbarrieredGetPtr(); } --}; -- --template <> --struct DefineComparisonOps : mozilla::TrueType { -- static const JSObject* get(const JS::ObjectPtr& v) { return v.unbarrieredGet(); } --}; -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T& get(const JS::Rooted& v) { return v.get(); } --}; -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T& get(const JS::Handle& v) { return v.get(); } --}; -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T& get(const JS::MutableHandle& v) { return v.get(); } --}; -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T& get(const JS::PersistentRooted& v) { return v.get(); } --}; -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T& get(const js::FakeRooted& v) { return v.get(); } --}; -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T& get(const js::FakeMutableHandle& v) { return v.get(); } --}; -- --} /* namespace detail */ --} /* namespace js */ -- --// Overload operator== and operator!= for all types with the DefineComparisonOps --// trait using the supplied getter. --// --// There are four cases: -- --// Case 1: comparison between two wrapper objects. -- --template --typename mozilla::EnableIf::value && -- js::detail::DefineComparisonOps::value, bool>::Type --operator==(const T& a, const U& b) { -- return js::detail::DefineComparisonOps::get(a) == js::detail::DefineComparisonOps::get(b); --} -- --template --typename mozilla::EnableIf::value && -- js::detail::DefineComparisonOps::value, bool>::Type --operator!=(const T& a, const U& b) { -- return !(a == b); --} -- --// Case 2: comparison between a wrapper object and its unwrapped element type. -- --template --typename mozilla::EnableIf::value, bool>::Type --operator==(const T& a, const typename T::ElementType& b) { -- return js::detail::DefineComparisonOps::get(a) == b; --} -- --template --typename mozilla::EnableIf::value, bool>::Type --operator!=(const T& a, const typename T::ElementType& b) { -- return !(a == b); --} -- --template --typename mozilla::EnableIf::value, bool>::Type --operator==(const typename T::ElementType& a, const T& b) { -- return a == js::detail::DefineComparisonOps::get(b); --} -- --template --typename mozilla::EnableIf::value, bool>::Type --operator!=(const typename T::ElementType& a, const T& b) { -- return !(a == b); --} -- --// Case 3: For pointer wrappers, comparison between the wrapper and a const --// element pointer. -- --template --typename mozilla::EnableIf::value && -- mozilla::IsPointer::value, bool>::Type --operator==(const typename mozilla::RemovePointer::Type* a, const T& b) { -- return a == js::detail::DefineComparisonOps::get(b); --} -- --template --typename mozilla::EnableIf::value && -- mozilla::IsPointer::value, bool>::Type --operator!=(const typename mozilla::RemovePointer::Type* a, const T& b) { -- return !(a == b); --} -- --template --typename mozilla::EnableIf::value && -- mozilla::IsPointer::value, bool>::Type --operator==(const T& a, const typename mozilla::RemovePointer::Type* b) { -- return js::detail::DefineComparisonOps::get(a) == b; --} -- --template --typename mozilla::EnableIf::value && -- mozilla::IsPointer::value, bool>::Type --operator!=(const T& a, const typename mozilla::RemovePointer::Type* b) { -- return !(a == b); --} -- --// Case 4: For pointer wrappers, comparison between the wrapper and nullptr. -- --template --typename mozilla::EnableIf::value && -- mozilla::IsPointer::value, bool>::Type --operator==(std::nullptr_t a, const T& b) { -- return a == js::detail::DefineComparisonOps::get(b); --} -- --template --typename mozilla::EnableIf::value && -- mozilla::IsPointer::value, bool>::Type --operator!=(std::nullptr_t a, const T& b) { -- return !(a == b); --} -- --template --typename mozilla::EnableIf::value && -- mozilla::IsPointer::value, bool>::Type --operator==(const T& a, std::nullptr_t b) { -- return js::detail::DefineComparisonOps::get(a) == b; --} -- --template --typename mozilla::EnableIf::value && -- mozilla::IsPointer::value, bool>::Type --operator!=(const T& a, std::nullptr_t b) { -- return !(a == b); --} -- - #undef DELETE_ASSIGNMENT_OPS - - #endif /* js_RootingAPI_h */ -diff -up firefox-56.0/js/src/gc/Barrier.h.1337988 firefox-56.0/js/src/gc/Barrier.h ---- firefox-56.0/js/src/gc/Barrier.h.1337988 2017-09-14 22:16:01.000000000 +0200 -+++ firefox-56.0/js/src/gc/Barrier.h 2017-09-25 10:34:11.206611695 +0200 -@@ -353,8 +353,8 @@ class WriteBarrieredBase : public Barrie - explicit WriteBarrieredBase(const T& v) : BarrieredBase(v) {} - - public: -- using ElementType = T; - -+ DECLARE_POINTER_COMPARISON_OPS(T); - DECLARE_POINTER_CONSTREF_OPS(T); - - // Use this if the automatic coercion to T isn't working. -@@ -612,13 +612,14 @@ class ReadBarriered : public ReadBarrier - return *this; - } - -- const T& get() const { -- if (InternalBarrierMethods::isMarkable(this->value)) -- this->read(); -+ const T get() const { -+ if (!InternalBarrierMethods::isMarkable(this->value)) -+ return JS::GCPolicy::initial(); -+ this->read(); - return this->value; - } - -- const T& unbarrieredGet() const { -+ const T unbarrieredGet() const { - return this->value; - } - -@@ -626,9 +627,9 @@ class ReadBarriered : public ReadBarrier - return bool(this->value); - } - -- operator const T&() const { return get(); } -+ operator const T() const { return get(); } - -- const T& operator->() const { return get(); } -+ const T operator->() const { return get(); } - - T* unsafeGet() { return &this->value; } - T const* unsafeGet() const { return &this->value; } -@@ -955,35 +956,6 @@ typedef ReadBarriered - - typedef ReadBarriered ReadBarrieredValue; - --namespace detail { -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T& get(const PreBarriered& v) { return v.get(); } --}; -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T& get(const GCPtr& v) { return v.get(); } --}; -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T& get(const HeapPtr& v) { return v.get(); } --}; -- --template --struct DefineComparisonOps> : mozilla::TrueType { -- static const T& get(const ReadBarriered& v) { return v.unbarrieredGet(); } --}; -- --template <> --struct DefineComparisonOps : mozilla::TrueType { -- static const Value& get(const HeapSlot& v) { return v.get(); } --}; -- --} /* namespace detail */ -- - } /* namespace js */ - - #endif /* gc_Barrier_h */ -diff -up firefox-56.0/js/src/jsapi-tests/testGCHeapPostBarriers.cpp.1337988 firefox-56.0/js/src/jsapi-tests/testGCHeapPostBarriers.cpp ---- firefox-56.0/js/src/jsapi-tests/testGCHeapPostBarriers.cpp.1337988 2017-09-14 22:16:02.000000000 +0200 -+++ firefox-56.0/js/src/jsapi-tests/testGCHeapPostBarriers.cpp 2017-09-25 10:34:11.206611695 +0200 -@@ -5,7 +5,6 @@ - * 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 "mozilla/TypeTraits.h" - #include "mozilla/UniquePtr.h" - - #include "js/RootingAPI.h" -diff -up firefox-56.0/js/src/vm/SharedMem.h.1337988 firefox-56.0/js/src/vm/SharedMem.h ---- firefox-56.0/js/src/vm/SharedMem.h.1337988 2017-06-15 22:52:29.000000000 +0200 -+++ firefox-56.0/js/src/vm/SharedMem.h 2017-09-25 10:34:11.206611695 +0200 -@@ -12,8 +12,8 @@ - template - class SharedMem - { -- // static_assert(mozilla::IsPointer::value, -- // "SharedMem encapsulates pointer types"); -+ static_assert(mozilla::IsPointer::value, -+ "SharedMem encapsulates pointer types"); - - enum Sharedness { - IsUnshared, -diff -up firefox-56.0/js/xpconnect/src/XPCInlines.h.1337988 firefox-56.0/js/xpconnect/src/XPCInlines.h ---- firefox-56.0/js/xpconnect/src/XPCInlines.h.1337988 2017-09-14 22:16:03.000000000 +0200 -+++ firefox-56.0/js/xpconnect/src/XPCInlines.h 2017-09-25 10:34:11.206611695 +0200 -@@ -465,7 +465,7 @@ inline - void XPCWrappedNativeTearOff::JSObjectMoved(JSObject* obj, const JSObject* old) - { - MOZ_ASSERT(!IsMarked()); -- MOZ_ASSERT(mJSObject == old); -+ MOZ_ASSERT(mJSObject.unbarrieredGetPtr() == old); - mJSObject = obj; - } - -diff -up firefox-56.0/js/xpconnect/src/XPCWrappedNative.cpp.1337988 firefox-56.0/js/xpconnect/src/XPCWrappedNative.cpp ---- firefox-56.0/js/xpconnect/src/XPCWrappedNative.cpp.1337988 2017-09-14 22:16:03.000000000 +0200 -+++ firefox-56.0/js/xpconnect/src/XPCWrappedNative.cpp 2017-09-25 10:34:11.207611692 +0200 -@@ -874,7 +874,7 @@ void - XPCWrappedNative::FlatJSObjectMoved(JSObject* obj, const JSObject* old) - { - JS::AutoAssertGCCallback inCallback; -- MOZ_ASSERT(mFlatJSObject == old); -+ MOZ_ASSERT(mFlatJSObject.unbarrieredGetPtr() == old); - - nsWrapperCache* cache = nullptr; - CallQueryInterface(mIdentity, &cache); -diff -up firefox-56.0/js/xpconnect/src/XPCWrappedNativeProto.cpp.1337988 firefox-56.0/js/xpconnect/src/XPCWrappedNativeProto.cpp ---- firefox-56.0/js/xpconnect/src/XPCWrappedNativeProto.cpp.1337988 2017-07-31 18:20:47.000000000 +0200 -+++ firefox-56.0/js/xpconnect/src/XPCWrappedNativeProto.cpp 2017-09-25 10:34:11.207611692 +0200 -@@ -101,7 +101,7 @@ XPCWrappedNativeProto::CallPostCreatePro - void - XPCWrappedNativeProto::JSProtoObjectFinalized(js::FreeOp* fop, JSObject* obj) - { -- MOZ_ASSERT(obj == mJSProtoObject, "huh?"); -+ MOZ_ASSERT(obj == mJSProtoObject.unbarrieredGet(), "huh?"); - - #ifdef DEBUG - // Check that this object has already been swept from the map. -@@ -117,7 +117,7 @@ XPCWrappedNativeProto::JSProtoObjectFina - void - XPCWrappedNativeProto::JSProtoObjectMoved(JSObject* obj, const JSObject* old) - { -- MOZ_ASSERT(mJSProtoObject == old); -+ MOZ_ASSERT(mJSProtoObject.unbarrieredGet() == old); - mJSProtoObject.init(obj); // Update without triggering barriers. - } - diff --git a/mozilla-1580174-webrtc-popup.patch b/mozilla-1580174-webrtc-popup.patch deleted file mode 100644 index f2c45b5..0000000 --- a/mozilla-1580174-webrtc-popup.patch +++ /dev/null @@ -1,51 +0,0 @@ -diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp ---- a/widget/gtk/nsWindow.cpp -+++ b/widget/gtk/nsWindow.cpp -@@ -1155,6 +1155,28 @@ - } - } - -+bool IsPopupWithoutToplevelParent(nsMenuPopupFrame* aMenuPopupFrame) { -+ // Check if the popup is autocomplete (like tags autocomplete -+ // in the bookmark edit popup). -+ nsAtom* popupId = aMenuPopupFrame->GetContent()->GetID(); -+ if (popupId && popupId->Equals(NS_LITERAL_STRING_FROM_CSTRING("PopupAutoComplete"))) { -+ return true; -+ } -+ -+ // Check if the popup is in popupnotificationcontent (like choosing capture -+ // device when starting webrtc session). -+ nsIFrame* parentFrame = aMenuPopupFrame->GetParent(); -+ if (!parentFrame) { -+ return false; -+ } -+ parentFrame = parentFrame->GetParent(); -+ if (parentFrame && parentFrame->GetContent()->NodeName().EqualsLiteral( -+ "popupnotificationcontent")) { -+ return true; -+ } -+ return false; -+} -+ - // Wayland keeps strong popup window hierarchy. We need to track active - // (visible) popup windows and make sure we hide popup on the same level - // before we open another one on that level. It means that every open -@@ -1211,10 +1233,14 @@ - LOG(("...[%p] GetParentMenuWidget() = %p\n", (void*)this, parentWindow)); - - // If the popup is a regular menu but GetParentMenuWidget() returns -- // nullptr which means it's connected non-menu parent -- // (bookmark toolbar for instance). -+ // nullptr which means is not a submenu of any other menu. - // In this case use a parent given at nsWindow::Create(). -- if (!parentWindow && !menuPopupFrame->IsContextMenu()) { -+ // But we have to avoid using mToplevelParentWindow in case the popup -+ // is in 'popupnotificationcontent' element or autocomplete popup, -+ // otherwise the popupnotification would disappear when for -+ // example opening a popup with microphone selection. -+ if (!parentWindow && !menuPopupFrame->IsContextMenu() && -+ !IsPopupWithoutToplevelParent(menuPopupFrame)) { - parentWindow = - get_window_for_gtk_widget(GTK_WIDGET(mToplevelParentWindow)); - } -