Bug 1849793 - Use non-native rendering for menuarrows on Linux. r=dholbert,stransky

Differential Revision: https://phabricator.services.mozilla.com/D186712
This commit is contained in:
Emilio Cobos Álvarez 2023-08-29 11:16:36 +00:00
Родитель 9ebf038bbe
Коммит 4b3775e6ac
7 изменённых файлов: 42 добавлений и 52 удалений

Просмотреть файл

@ -111,8 +111,8 @@ menulist > menupopup > :is(menuitem, menucaption, menu) {
margin-bottom: 0;
margin-inline-start: 6px;
margin-inline-end: 0;
width: 1ex;
height: 1ex;
width: 2ex;
height: 2ex;
/* These next two rules are needed to prevent inheritance and thus ugliness */
list-style-image: none;
appearance: auto;

Просмотреть файл

@ -755,39 +755,65 @@ void Theme::PaintMenulist(PaintBackendData& aDrawTarget,
}
}
void Theme::PaintMenulistArrowButton(nsIFrame* aFrame, DrawTarget& aDrawTarget,
const LayoutDeviceRect& aRect,
const ElementState& aState) {
enum class PhysicalArrowDirection {
Right,
Left,
Bottom,
};
void Theme::PaintMenuArrow(StyleAppearance aAppearance, nsIFrame* aFrame,
DrawTarget& aDrawTarget,
const LayoutDeviceRect& aRect) {
// not const: these may be negated in-place below
float polygonX[] = {-4.0f, -0.5f, 0.5f, 4.0f, 4.0f,
3.0f, 0.0f, 0.0f, -3.0f, -4.0f};
float polygonY[] = {-1, 3.0f, 3.0f, -1.0f, -2.0f,
-2.0f, 1.5f, 1.5f, -2.0f, -2.0f};
const bool isMenuList =
aAppearance == StyleAppearance::MozMenulistArrowButton;
const float kPolygonSize = kMinimumDropdownArrowButtonWidth;
const auto direction = [&] {
const auto wm = aFrame->GetWritingMode();
if (!isMenuList) {
return wm.IsPhysicalRTL() ? PhysicalArrowDirection::Left
: PhysicalArrowDirection::Right;
}
switch (wm.GetBlockDir()) {
case WritingMode::BlockDir::eBlockLR:
return PhysicalArrowDirection::Right;
case WritingMode::BlockDir::eBlockRL:
return PhysicalArrowDirection::Left;
case WritingMode::BlockDir::eBlockTB:
return PhysicalArrowDirection::Bottom;
}
MOZ_ASSERT_UNREACHABLE("Unknown direction?");
return PhysicalArrowDirection::Bottom;
}();
auto const [xs, ys] = [&] {
using Pair = std::pair<const float*, const float*>;
switch (aFrame->GetWritingMode().GetBlockDir()) {
case WritingMode::BlockDir::eBlockRL:
switch (direction) {
case PhysicalArrowDirection::Left:
// rotate 90°: [[0,1],[-1,0]]
for (float& f : polygonY) {
f = -f;
}
return Pair(polygonY, polygonX);
case WritingMode::BlockDir::eBlockLR:
case PhysicalArrowDirection::Right:
// rotate 270°: [[0,-1],[1,0]]
for (float& f : polygonX) {
f = -f;
}
return Pair(polygonY, polygonX);
case WritingMode::BlockDir::eBlockTB:
case PhysicalArrowDirection::Bottom:
// rotate 0°: [[1,0],[0,1]]
return Pair(polygonX, polygonY);
}
MOZ_ASSERT_UNREACHABLE("unhandled BlockDir");
MOZ_ASSERT_UNREACHABLE("Unknown direction?");
return Pair(polygonX, polygonY);
}();
@ -1148,14 +1174,6 @@ bool Theme::DoDrawWidgetBackground(PaintBackendData& aPaintData,
const DocumentState docState = pc->Document()->GetDocumentState();
ElementState elementState = GetContentState(aFrame, aAppearance);
if (aAppearance == StyleAppearance::MozMenulistArrowButton) {
// HTML select and XUL menulist dropdown buttons get state from the
// parent.
nsIFrame* parentFrame = aFrame->GetParent();
aFrame = parentFrame;
elementState = GetContentState(parentFrame, aAppearance);
}
// Paint the outline iff we're asked to draw overflow and we have
// outline-style: auto.
if (aDrawOverflow == DrawOverflow::Yes &&
@ -1207,12 +1225,13 @@ bool Theme::DoDrawWidgetBackground(PaintBackendData& aPaintData,
case StyleAppearance::Menulist:
PaintMenulist(aPaintData, devPxRect, elementState, colors, dpiRatio);
break;
case StyleAppearance::Menuarrow:
case StyleAppearance::MozMenulistArrowButton:
if constexpr (std::is_same_v<PaintBackendData, WebRenderBackendData>) {
// TODO: Need to figure out how to best draw this using WR.
return false;
} else {
PaintMenulistArrowButton(aFrame, aPaintData, devPxRect, elementState);
PaintMenuArrow(aAppearance, aFrame, aPaintData, devPxRect);
}
break;
case StyleAppearance::Tooltip: {
@ -1671,6 +1690,7 @@ bool Theme::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame,
case StyleAppearance::MenulistButton:
case StyleAppearance::NumberInput:
case StyleAppearance::MozMenulistArrowButton:
case StyleAppearance::Menuarrow:
case StyleAppearance::SpinnerUpbutton:
case StyleAppearance::SpinnerDownbutton:
case StyleAppearance::Menuitem:

Просмотреть файл

@ -171,8 +171,8 @@ class Theme : protected nsNativeTheme, public nsITheme {
template <typename PaintBackendData>
void PaintMenulist(PaintBackendData&, const LayoutDeviceRect&,
const ElementState&, const Colors&, DPIRatio);
void PaintMenulistArrowButton(nsIFrame*, DrawTarget&, const LayoutDeviceRect&,
const ElementState&);
void PaintMenuArrow(StyleAppearance, nsIFrame*, DrawTarget&,
const LayoutDeviceRect&);
void PaintSpinnerButton(nsIFrame*, DrawTarget&, const LayoutDeviceRect&,
const ElementState&, StyleAppearance, const Colors&,
DPIRatio);

Просмотреть файл

@ -1668,18 +1668,6 @@ static gint moz_gtk_tab_scroll_arrow_paint(cairo_t* cr, GdkRectangle* rect,
return MOZ_GTK_SUCCESS;
}
static gint moz_gtk_menu_arrow_paint(cairo_t* cr, GdkRectangle* rect,
GtkWidgetState* state,
GtkTextDirection direction) {
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
GtkStyleContext* style = GetStyleContext(MOZ_GTK_MENUITEM, state->image_scale,
direction, state_flags);
gtk_render_arrow(style, cr,
(direction == GTK_TEXT_DIR_LTR) ? ARROW_RIGHT : ARROW_LEFT,
rect->x, rect->y, rect->width);
return MOZ_GTK_SUCCESS;
}
static gint moz_gtk_header_bar_paint(WidgetNodeType widgetType, cairo_t* cr,
GdkRectangle* rect,
GtkWidgetState* state) {
@ -1912,7 +1900,6 @@ gint moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
case MOZ_GTK_SPINBUTTON:
case MOZ_GTK_WINDOW:
case MOZ_GTK_RESIZER:
case MOZ_GTK_MENUARROW:
case MOZ_GTK_TOOLBARBUTTON_ARROW:
case MOZ_GTK_TOOLBAR:
case MOZ_GTK_TAB_SCROLLARROW:
@ -2373,8 +2360,6 @@ gint moz_gtk_widget_paint(WidgetNodeType widget, cairo_t* cr,
case MOZ_GTK_TAB_SCROLLARROW:
return moz_gtk_tab_scroll_arrow_paint(cr, rect, state,
(GtkArrowType)flags, direction);
case MOZ_GTK_MENUARROW:
return moz_gtk_menu_arrow_paint(cr, rect, state, direction);
case MOZ_GTK_TOOLBARBUTTON_ARROW:
return moz_gtk_arrow_paint(cr, rect, state, (GtkArrowType)flags,
direction);

Просмотреть файл

@ -229,8 +229,6 @@ enum WidgetNodeType : int {
MOZ_GTK_TREEVIEW_EXPANDER,
/* Paints the background of menus, context menus. */
MOZ_GTK_MENUPOPUP,
/* Paints the arrow of menuitems that contain submenus */
MOZ_GTK_MENUARROW,
/* Menubar for -moz-headerbar colors */
MOZ_GTK_MENUBAR,
/* Paints an arrow in a toolbar button. flags is a GtkArrowType. */

Просмотреть файл

@ -217,16 +217,6 @@ bool nsNativeThemeGTK::GetGtkWidgetAndState(StyleAppearance aAppearance,
aState->focused = FALSE;
}
// menu item state is determined by the attribute "_moz-menuactive",
// and not by the mouse hovering (accessibility). as a special case,
// menus which are children of a menu bar are only marked as prelight
// if they are open, not on normal hover.
if (aAppearance == StyleAppearance::Menuarrow) {
aState->inHover = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
aState->active = FALSE;
}
// A button with drop down menu open or an activated toggle button
// should always appear depressed.
if (aAppearance == StyleAppearance::Button ||
@ -446,9 +436,6 @@ bool nsNativeThemeGTK::GetGtkWidgetAndState(StyleAppearance aAppearance,
else
aGtkWidgetType = MOZ_GTK_SPLITTER_HORIZONTAL;
break;
case StyleAppearance::Menuarrow:
aGtkWidgetType = MOZ_GTK_MENUARROW;
break;
case StyleAppearance::MozWindowTitlebar:
aGtkWidgetType = MOZ_GTK_HEADER_BAR;
break;
@ -1359,7 +1346,6 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
case StyleAppearance::Textarea:
case StyleAppearance::Range:
case StyleAppearance::RangeThumb:
case StyleAppearance::Menuarrow:
case StyleAppearance::Splitter:
case StyleAppearance::MozWindowButtonBox:
case StyleAppearance::MozWindowButtonClose:

Просмотреть файл

@ -573,5 +573,6 @@ bool nsNativeTheme::IsWidgetAlwaysNonNative(nsIFrame* aFrame,
StyleAppearance aAppearance) {
return IsWidgetScrollbarPart(aAppearance) ||
aAppearance == StyleAppearance::FocusOutline ||
aAppearance == StyleAppearance::Menuarrow ||
(aFrame && aFrame->StyleUI()->mMozTheme == StyleMozTheme::NonNative);
}