summaryrefslogtreecommitdiffstats
path: root/layout
diff options
context:
space:
mode:
Diffstat (limited to 'layout')
-rw-r--r--layout/generic/ReflowInput.cpp3
-rw-r--r--layout/generic/ReflowInput.h5
-rw-r--r--layout/generic/nsColumnSetFrame.cpp2
-rw-r--r--layout/generic/nsImageMap.cpp4
-rw-r--r--layout/xul/nsXULPopupManager.cpp70
-rw-r--r--layout/xul/nsXULPopupManager.h11
6 files changed, 75 insertions, 20 deletions
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
index 2f91f5f65c..c8b01fff19 100644
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -304,7 +304,8 @@ bool ReflowInput::ShouldReflowAllKids() const {
// frames NS_FRAME_CONTAINS_RELATIVE_BSIZE is marked on.
return mFrame->HasAnyStateBits(NS_FRAME_IS_DIRTY) || IsIResize() ||
(IsBResize() &&
- mFrame->HasAnyStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE));
+ mFrame->HasAnyStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE)) ||
+ mFlags.mIsInLastColumnBalancingReflow;
}
void ReflowInput::SetComputedISize(nscoord aComputedISize,
diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h
index 0b7f64b543..370ccc1af2 100644
--- a/layout/generic/ReflowInput.h
+++ b/layout/generic/ReflowInput.h
@@ -503,6 +503,11 @@ struct ReflowInput : public SizeComputationInput {
// nsColumnSetFrame is balancing columns
bool mIsColumnBalancing : 1;
+ // We have an ancestor nsColumnSetFrame performing the last column balancing
+ // reflow. The available block-size of the last column might become
+ // unconstrained.
+ bool mIsInLastColumnBalancingReflow : 1;
+
// True if ColumnSetWrapperFrame has a constrained block-size, and is going
// to consume all of its block-size in this fragment. This bit is passed to
// nsColumnSetFrame to determine whether to give up balancing and create
diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp
index 699afaece7..ec349e9ab4 100644
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -662,6 +662,8 @@ nsColumnSetFrame::ColumnBalanceData nsColumnSetFrame::ReflowColumns(
}();
kidReflowInput.mFlags.mTableIsSplittable = false;
kidReflowInput.mFlags.mIsColumnBalancing = aConfig.mIsBalancing;
+ kidReflowInput.mFlags.mIsInLastColumnBalancingReflow =
+ aConfig.mIsLastBalancingReflow;
kidReflowInput.mBreakType = ReflowInput::BreakType::Column;
// We need to reflow any float placeholders, even if our column block-size
diff --git a/layout/generic/nsImageMap.cpp b/layout/generic/nsImageMap.cpp
index 8ddd9338f2..ce621fb6be 100644
--- a/layout/generic/nsImageMap.cpp
+++ b/layout/generic/nsImageMap.cpp
@@ -467,7 +467,7 @@ void PolyArea::Draw(nsIFrame* aFrame, DrawTarget& aDrawTarget,
Point p1(pc->CSSPixelsToDevPixels(mCoords[0]),
pc->CSSPixelsToDevPixels(mCoords[1]));
Point p2, p1snapped, p2snapped;
- for (int32_t i = 2; i < mNumCoords; i += 2) {
+ for (int32_t i = 2; i < mNumCoords - 1; i += 2) {
p2.x = pc->CSSPixelsToDevPixels(mCoords[i]);
p2.y = pc->CSSPixelsToDevPixels(mCoords[i + 1]);
p1snapped = p1;
@@ -493,7 +493,7 @@ void PolyArea::GetRect(nsIFrame* aFrame, nsRect& aRect) {
nscoord x1, x2, y1, y2, xtmp, ytmp;
x1 = x2 = nsPresContext::CSSPixelsToAppUnits(mCoords[0]);
y1 = y2 = nsPresContext::CSSPixelsToAppUnits(mCoords[1]);
- for (int32_t i = 2; i < mNumCoords; i += 2) {
+ for (int32_t i = 2; i < mNumCoords - 1; i += 2) {
xtmp = nsPresContext::CSSPixelsToAppUnits(mCoords[i]);
ytmp = nsPresContext::CSSPixelsToAppUnits(mCoords[i + 1]);
x1 = x1 < xtmp ? x1 : xtmp;
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*);