summaryrefslogtreecommitdiff
path: root/layout/xul
diff options
context:
space:
mode:
Diffstat (limited to 'layout/xul')
-rw-r--r--layout/xul/nsButtonBoxFrame.cpp3
-rw-r--r--layout/xul/nsMenuBarListener.cpp12
-rw-r--r--layout/xul/nsMenuFrame.cpp16
-rw-r--r--layout/xul/nsMenuPopupFrame.cpp11
-rw-r--r--layout/xul/nsRepeatService.h4
-rw-r--r--layout/xul/nsSliderFrame.cpp12
-rw-r--r--layout/xul/nsXULPopupManager.cpp28
-rw-r--r--layout/xul/tree/nsTreeBodyFrame.cpp53
8 files changed, 133 insertions, 6 deletions
diff --git a/layout/xul/nsButtonBoxFrame.cpp b/layout/xul/nsButtonBoxFrame.cpp
index 3e0529e600..ba0b7fb2ab 100644
--- a/layout/xul/nsButtonBoxFrame.cpp
+++ b/layout/xul/nsButtonBoxFrame.cpp
@@ -126,6 +126,8 @@ nsButtonBoxFrame::HandleEvent(nsPresContext* aPresContext,
break;
}
+// On mac, Return fires the default button, not the focused one.
+#ifndef XP_MACOSX
case eKeyPress: {
WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
if (!keyEvent) {
@@ -140,6 +142,7 @@ nsButtonBoxFrame::HandleEvent(nsPresContext* aPresContext,
}
break;
}
+#endif
case eKeyUp: {
WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
diff --git a/layout/xul/nsMenuBarListener.cpp b/layout/xul/nsMenuBarListener.cpp
index 70955c4301..23df81937a 100644
--- a/layout/xul/nsMenuBarListener.cpp
+++ b/layout/xul/nsMenuBarListener.cpp
@@ -76,9 +76,15 @@ void nsMenuBarListener::InitAccessKey()
if (mAccessKey >= 0)
return;
- // Compiled-in defaults, in case we can't get LookAndFeel...
+ // Compiled-in defaults, in case we can't get LookAndFeel --
+ // mac doesn't have menu shortcuts, other platforms use alt.
+#ifdef XP_MACOSX
+ mAccessKey = 0;
+ mAccessKeyMask = 0;
+#else
mAccessKey = nsIDOMKeyEvent::DOM_VK_ALT;
mAccessKeyMask = MODIFIER_ALT;
+#endif
// Get the menu access key value from prefs, overriding the default:
mAccessKey = Preferences::GetInt("ui.key.menuAccessKey", mAccessKey);
@@ -248,7 +254,8 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent)
aKeyEvent->PreventDefault();
}
}
- // Also need to handle F10 specially.
+#ifndef XP_MACOSX
+ // Also need to handle F10 specially on Non-Mac platform.
else if (nativeKeyEvent->mMessage == eKeyPress && keyCode == NS_VK_F10) {
if ((GetModifiersForAccessKey(keyEvent) & ~MODIFIER_CONTROL) == 0) {
// The F10 key just went down by itself or with ctrl pressed.
@@ -266,6 +273,7 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent)
}
}
}
+#endif // !XP_MACOSX
}
return NS_OK;
diff --git a/layout/xul/nsMenuFrame.cpp b/layout/xul/nsMenuFrame.cpp
index 30cab242ea..933cc43cf3 100644
--- a/layout/xul/nsMenuFrame.cpp
+++ b/layout/xul/nsMenuFrame.cpp
@@ -404,12 +404,26 @@ nsMenuFrame::HandleEvent(nsPresContext* aPresContext,
if (aEvent->mMessage == eKeyPress && !IsDisabled()) {
WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
uint32_t keyCode = keyEvent->mKeyCode;
- // Toggle menulist on unmodified F4 or Alt arrow
+#ifdef XP_MACOSX
+ // On mac, open menulist on either up/down arrow or space (w/o Cmd pressed)
+ if (!IsOpen() && ((keyEvent->mCharCode == ' ' && !keyEvent->IsMeta()) ||
+ (keyCode == NS_VK_UP || keyCode == NS_VK_DOWN))) {
+
+ // When pressing space, don't open the menu if performing an incremental search.
+ if (keyEvent->mCharCode != ' ' ||
+ !nsMenuPopupFrame::IsWithinIncrementalTime(keyEvent->mTime)) {
+ *aEventStatus = nsEventStatus_eConsumeNoDefault;
+ OpenMenu(false);
+ }
+ }
+#else
+ // On other platforms, toggle menulist on unmodified F4 or Alt arrow
if ((keyCode == NS_VK_F4 && !keyEvent->IsAlt()) ||
((keyCode == NS_VK_UP || keyCode == NS_VK_DOWN) && keyEvent->IsAlt())) {
*aEventStatus = nsEventStatus_eConsumeNoDefault;
ToggleMenuState();
}
+#endif
}
else if (aEvent->mMessage == eMouseDown &&
aEvent->AsMouseEvent()->button == WidgetMouseEvent::eLeftButton &&
diff --git a/layout/xul/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp
index 1d47652dcb..378d719d44 100644
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -1502,8 +1502,17 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove, bool aS
screenPoint.MoveBy(margin.left + offsetForContextMenu.x,
margin.top + offsetForContextMenu.y);
- // Screen positioned popups can be flipped vertically but never horizontally
+#ifdef XP_MACOSX
+ // OSX tooltips follow standard flip rule but other popups flip horizontally not vertically
+ if (mPopupType == ePopupTypeTooltip) {
+ vFlip = FlipStyle_Outside;
+ } else {
+ hFlip = FlipStyle_Outside;
+ }
+#else
+ // Other OS screen positioned popups can be flipped vertically but never horizontally
vFlip = FlipStyle_Outside;
+#endif // #ifdef XP_MACOSX
}
// If a panel is being moved or has flip="none", don't constrain or flip it. But always do this for
diff --git a/layout/xul/nsRepeatService.h b/layout/xul/nsRepeatService.h
index c731f8cf59..81321a4729 100644
--- a/layout/xul/nsRepeatService.h
+++ b/layout/xul/nsRepeatService.h
@@ -14,7 +14,11 @@
#define INITAL_REPEAT_DELAY 250
+#ifdef XP_MACOSX
+#define REPEAT_DELAY 25
+#else
#define REPEAT_DELAY 50
+#endif
class nsITimer;
diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp
index b98ac4a03f..812c233fc1 100644
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -664,7 +664,11 @@ nsSliderFrame::GetScrollToClick()
return false;
}
+#ifdef XP_MACOSX
+ return true;
+#else
return false;
+#endif
}
nsIFrame*
@@ -1174,8 +1178,8 @@ nsSliderFrame::ShouldScrollToClickForEvent(WidgetGUIEvent* aEvent)
return false;
}
-#if defined(MOZ_WIDGET_GTK)
- // On Linux, clicking the scrollbar thumb should never scroll to click.
+#if defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK)
+ // On Mac and Linux, clicking the scrollbar thumb should never scroll to click.
if (IsEventOverThumb(aEvent)) {
return false;
}
@@ -1183,7 +1187,11 @@ nsSliderFrame::ShouldScrollToClickForEvent(WidgetGUIEvent* aEvent)
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
if (mouseEvent->button == WidgetMouseEvent::eLeftButton) {
+#ifdef XP_MACOSX
+ bool invertPref = mouseEvent->IsAlt();
+#else
bool invertPref = mouseEvent->IsShift();
+#endif
return GetScrollToClick() != invertPref;
}
diff --git a/layout/xul/nsXULPopupManager.cpp b/layout/xul/nsXULPopupManager.cpp
index 5fc533e1b9..6e8cc3dda1 100644
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -712,6 +712,21 @@ nsXULPopupManager::ShowMenu(nsIContent *aMenu,
nsAutoString position;
+#ifdef XP_MACOSX
+ nsCOMPtr<nsIDOMXULMenuListElement> menulist = do_QueryInterface(aMenu);
+ bool isNonEditableMenulist = false;
+ if (menulist) {
+ bool editable;
+ menulist->GetEditable(&editable);
+ isNonEditableMenulist = !editable;
+ }
+
+ if (isNonEditableMenulist) {
+ position.AssignLiteral("selection");
+ }
+ else
+#endif
+
if (onMenuBar || !onmenu)
position.AssignLiteral("after_start");
else
@@ -1799,6 +1814,15 @@ nsXULPopupManager::MayShowPopup(nsMenuPopupFrame* aPopup)
return false;
}
+#ifdef XP_MACOSX
+ if (rootWin) {
+ auto globalWin = nsGlobalWindow::Cast(rootWin.get());
+ if (globalWin->IsInModalState()) {
+ return false;
+ }
+ }
+#endif
+
// cannot open a popup that is a submenu of a menupopup that isn't open.
nsMenuFrame* menuFrame = do_QueryFrame(aPopup->GetParent());
if (menuFrame) {
@@ -2304,6 +2328,7 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode(
switch (keyCode) {
case nsIDOMKeyEvent::DOM_VK_UP:
case nsIDOMKeyEvent::DOM_VK_DOWN:
+#ifndef XP_MACOSX
// roll up the popup when alt+up/down are pressed within a menulist.
bool alt;
aKeyEvent->GetAltKey(&alt);
@@ -2312,6 +2337,7 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode(
break;
}
MOZ_FALLTHROUGH;
+#endif
case nsIDOMKeyEvent::DOM_VK_LEFT:
case nsIDOMKeyEvent::DOM_VK_RIGHT:
@@ -2340,7 +2366,9 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode(
break;
case nsIDOMKeyEvent::DOM_VK_TAB:
+#ifndef XP_MACOSX
case nsIDOMKeyEvent::DOM_VK_F10:
+#endif
if (aTopVisibleMenuItem &&
!aTopVisibleMenuItem->Frame()->GetContent()->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::activateontab, nsGkAtoms::_true, eCaseMatters)) {
diff --git a/layout/xul/tree/nsTreeBodyFrame.cpp b/layout/xul/tree/nsTreeBodyFrame.cpp
index 262884c9a8..ec054a234e 100644
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -2613,7 +2613,9 @@ nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext,
// Save last values, we will need them.
int32_t lastDropRow = mSlots->mDropRow;
int16_t lastDropOrient = mSlots->mDropOrient;
+#ifndef XP_MACOSX
int16_t lastScrollLines = mSlots->mScrollLines;
+#endif
// Find out the current drag action
uint32_t lastDragAction = mSlots->mDragAction;
@@ -2631,6 +2633,9 @@ nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext,
mSlots->mDropAllowed = false;
InvalidateDropFeedback(lastDropRow, lastDropOrient);
}
+#ifdef XP_MACOSX
+ ScrollByLines(mSlots->mScrollLines);
+#else
if (!lastScrollLines) {
// Cancel any previously initialized timer.
if (mSlots->mTimer) {
@@ -2643,6 +2648,7 @@ nsTreeBodyFrame::HandleEvent(nsPresContext* aPresContext,
LazyScrollCallback, nsITimer::TYPE_ONE_SHOT,
getter_AddRefs(mSlots->mTimer));
}
+#endif
// Bail out to prevent spring loaded timer and feedback line settings.
return NS_OK;
}
@@ -2836,6 +2842,53 @@ nsTreeBodyFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (!mView || !GetContent ()->GetComposedDoc()->GetWindow())
return;
+#ifdef XP_MACOSX
+ nsIContent* baseElement = GetBaseElement();
+ nsIFrame* treeFrame =
+ baseElement ? baseElement->GetPrimaryFrame() : nullptr;
+ nsCOMPtr<nsITreeSelection> selection;
+ mView->GetSelection(getter_AddRefs(selection));
+ nsITheme* theme = PresContext()->GetTheme();
+ // On Mac, we support native theming of selected rows. On 10.10 and higher,
+ // this means applying vibrancy which require us to register the theme
+ // geometrics for the row. In order to make the vibrancy effect to work
+ // properly, we also need the tree to be themed as a source list.
+ if (selection && treeFrame && theme &&
+ treeFrame->StyleDisplay()->mAppearance == NS_THEME_MAC_SOURCE_LIST) {
+ // Loop through our onscreen rows. If the row is selected and a
+ // -moz-appearance is provided, RegisterThemeGeometry might be necessary.
+ const auto end = std::min(mRowCount, LastVisibleRow() + 1);
+ for (auto i = FirstVisibleRow(); i < end; i++) {
+ bool isSelected;
+ selection->IsSelected(i, &isSelected);
+ if (isSelected) {
+ PrefillPropertyArray(i, nullptr);
+ nsAutoString properties;
+ mView->GetRowProperties(i, properties);
+ nsTreeUtils::TokenizeProperties(properties, mScratchArray);
+ nsStyleContext* rowContext =
+ GetPseudoStyleContext(nsCSSAnonBoxes::moztreerow);
+ auto appearance = rowContext->StyleDisplay()->mAppearance;
+ if (appearance) {
+ if (theme->ThemeSupportsWidget(PresContext(), this, appearance)) {
+ nsITheme::ThemeGeometryType type =
+ theme->ThemeGeometryTypeForWidget(this, appearance);
+ if (type != nsITheme::eThemeGeometryTypeUnknown) {
+ nsRect rowRect(mInnerBox.x, mInnerBox.y + mRowHeight *
+ (i - FirstVisibleRow()), mInnerBox.width,
+ mRowHeight);
+ aBuilder->RegisterThemeGeometry(type,
+ LayoutDeviceIntRect::FromUnknownRect(
+ (rowRect + aBuilder->ToReferenceFrame(this)).ToNearestPixels(
+ PresContext()->AppUnitsPerDevPixel())));
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+
aLists.Content()->AppendNewToTop(new (aBuilder)
nsDisplayTreeBody(aBuilder, this));
}