diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-08 15:11:26 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-08 15:11:26 +0000 |
commit | fcea19dfd2c426bac0456da850e7c12258e4b9eb (patch) | |
tree | a31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /layout/xul | |
parent | Adding upstream version 115.7.0esr. (diff) | |
download | firefox-esr-upstream/115.8.0esr.tar.xz firefox-esr-upstream/115.8.0esr.zip |
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'layout/xul')
-rw-r--r-- | layout/xul/nsXULPopupManager.cpp | 70 | ||||
-rw-r--r-- | layout/xul/nsXULPopupManager.h | 11 |
2 files changed, 64 insertions, 17 deletions
diff --git a/layout/xul/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp index fb881b86eb..79ea7d0470 100644 --- a/layout/xul/nsXULPopupManager.cpp +++ b/layout/xul/nsXULPopupManager.cpp @@ -55,6 +55,7 @@ #include "mozilla/MouseEvents.h" #include "mozilla/PresShell.h" #include "mozilla/Services.h" +#include "mozilla/StaticPrefs_layout.h" #include "mozilla/StaticPrefs_ui.h" #include "mozilla/widget/nsAutoRollup.h" #include "mozilla/widget/NativeMenuSupport.h" @@ -209,7 +210,43 @@ UniquePtr<nsMenuChainItem> nsMenuChainItem::Detach() { return std::move(mParent); } +void nsXULPopupManager::AddMenuChainItem(UniquePtr<nsMenuChainItem> aItem) { + PopupType popupType = aItem->Frame()->GetPopupType(); + if (StaticPrefs::layout_cursor_disable_for_popups() && + popupType != PopupType::Tooltip) { + if (nsPresContext* rootPC = + aItem->Frame()->PresContext()->GetRootPresContext()) { + if (nsCOMPtr<nsIWidget> rootWidget = rootPC->GetRootWidget()) { + rootWidget->SetCustomCursorAllowed(false); + } + } + } + + // popups normally hide when an outside click occurs. Panels may use + // the noautohide attribute to disable this behaviour. It is expected + // that the application will hide these popups manually. The tooltip + // listener will handle closing the tooltip also. + nsIContent* oldmenu = nullptr; + if (mPopups) { + oldmenu = mPopups->Element(); + } + aItem->SetParent(std::move(mPopups)); + mPopups = std::move(aItem); + SetCaptureState(oldmenu); +} + void nsXULPopupManager::RemoveMenuChainItem(nsMenuChainItem* aItem) { + nsPresContext* rootPC = aItem->Frame()->PresContext()->GetRootPresContext(); + auto matcher = [&](nsMenuChainItem* aChainItem) -> bool { + return aChainItem != aItem && + rootPC == aChainItem->Frame()->PresContext()->GetRootPresContext(); + }; + if (rootPC && !FirstMatchingPopup(matcher)) { + if (nsCOMPtr<nsIWidget> rootWidget = rootPC->GetRootWidget()) { + rootWidget->SetCustomCursorAllowed(true); + } + } + auto parent = aItem->Detach(); if (auto* child = aItem->GetChild()) { MOZ_ASSERT(aItem != mPopups, @@ -225,6 +262,17 @@ void nsXULPopupManager::RemoveMenuChainItem(nsMenuChainItem* aItem) { } } +nsMenuChainItem* nsXULPopupManager::FirstMatchingPopup( + mozilla::FunctionRef<bool(nsMenuChainItem*)> aMatcher) const { + for (nsMenuChainItem* popup = mPopups.get(); popup; + popup = popup->GetParent()) { + if (aMatcher(popup)) { + return popup; + } + } + return nullptr; +} + void nsMenuChainItem::UpdateFollowAnchor() { mFollowAnchor = mFrame->ShouldFollowAnchor(mCurrentRect); } @@ -1140,17 +1188,7 @@ void nsXULPopupManager::ShowPopupCallback(Element* aPopup, item->UpdateFollowAnchor(); - // popups normally hide when an outside click occurs. Panels may use - // the noautohide attribute to disable this behaviour. It is expected - // that the application will hide these popups manually. The tooltip - // listener will handle closing the tooltip also. - nsIContent* oldmenu = nullptr; - if (mPopups) { - oldmenu = mPopups->Element(); - } - item->SetParent(std::move(mPopups)); - mPopups = std::move(item); - SetCaptureState(oldmenu); + AddMenuChainItem(std::move(item)); NS_ENSURE_TRUE_VOID(weakFrame.IsAlive()); RefPtr popup = &aPopupFrame->PopupElement(); @@ -1166,12 +1204,10 @@ void nsXULPopupManager::ShowPopupCallback(Element* aPopup, } nsMenuChainItem* nsXULPopupManager::FindPopup(Element* aPopup) const { - for (nsMenuChainItem* item = mPopups.get(); item; item = item->GetParent()) { - if (item->Frame()->GetContent() == aPopup) { - return item; - } - } - return nullptr; + auto matcher = [&](nsMenuChainItem* aItem) -> bool { + return aItem->Frame()->GetContent() == aPopup; + }; + return FirstMatchingPopup(matcher); } void nsXULPopupManager::HidePopup(Element* aPopup, HidePopupOptions aOptions, diff --git a/layout/xul/nsXULPopupManager.h b/layout/xul/nsXULPopupManager.h index d056322deb..78d2b2648c 100644 --- a/layout/xul/nsXULPopupManager.h +++ b/layout/xul/nsXULPopupManager.h @@ -23,6 +23,7 @@ #include "nsIObserver.h" #include "nsThreadUtils.h" #include "mozilla/Attributes.h" +#include "mozilla/FunctionRef.h" #include "mozilla/widget/InitData.h" #include "mozilla/widget/NativeMenu.h" @@ -551,6 +552,13 @@ class nsXULPopupManager final : public nsIDOMEventListener, void UpdatePopupPositions(nsRefreshDriver* aRefreshDriver); /** + * Get the first nsMenuChainItem that is matched by the matching callback + * function provided. + */ + nsMenuChainItem* FirstMatchingPopup( + mozilla::FunctionRef<bool(nsMenuChainItem*)> aMatcher) const; + + /** * Enable or disable anchor following on the popup if needed. */ void UpdateFollowAnchor(nsMenuPopupFrame* aPopup); @@ -733,6 +741,9 @@ class nsXULPopupManager final : public nsIDOMEventListener, return GetRollupItem(RollupKind::Menu); } + // Add the chain item to the chain and update mPopups to point to it. + void AddMenuChainItem(mozilla::UniquePtr<nsMenuChainItem>); + // Removes the chain item from the chain and deletes it. void RemoveMenuChainItem(nsMenuChainItem*); |