diff options
Diffstat (limited to 'layout/xul')
-rw-r--r-- | layout/xul/nsButtonBoxFrame.cpp | 3 | ||||
-rw-r--r-- | layout/xul/nsMenuBarListener.cpp | 12 | ||||
-rw-r--r-- | layout/xul/nsMenuFrame.cpp | 16 | ||||
-rw-r--r-- | layout/xul/nsMenuPopupFrame.cpp | 11 | ||||
-rw-r--r-- | layout/xul/nsRepeatService.h | 4 | ||||
-rw-r--r-- | layout/xul/nsSliderFrame.cpp | 12 | ||||
-rw-r--r-- | layout/xul/nsXULPopupManager.cpp | 28 | ||||
-rw-r--r-- | layout/xul/tree/nsTreeBodyFrame.cpp | 53 |
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)); } |