Bug 1963446 - Use non-native buttons on Linux. r=stransky,desktop-theme-reviewers,dao

Differential Revision: https://phabricator.services.mozilla.com/D247164
This commit is contained in:
Emilio Cobos Álvarez
2025-05-01 17:47:44 +00:00
committed by ealvarez@mozilla.com
parent 00fefccf69
commit d58f9ecbbc
8 changed files with 84 additions and 568 deletions

View File

@@ -76,12 +76,11 @@
.expander-up > .button-box {
appearance: auto;
-moz-default-appearance: button-arrow-up;
-moz-default-appearance: -moz-menulist-arrow-button;
}
.expander-down > .button-box {
appearance: auto;
-moz-default-appearance: button-arrow-down;
transform: scaleY(-1);
}
/* Downloads pane */

View File

@@ -1498,11 +1498,6 @@ pub enum Appearance {
Textfield,
/// The dropdown button(s) that open up a dropdown list.
MenulistButton,
/// Various arrows that go in buttons
#[parse(condition = "ParserContext::chrome_rules_enabled")]
ButtonArrowDown,
#[parse(condition = "ParserContext::chrome_rules_enabled")]
ButtonArrowUp,
/// Menu Popup background.
#[parse(condition = "ParserContext::chrome_rules_enabled")]
Menupopup,
@@ -1577,9 +1572,6 @@ pub enum Appearance {
/// A single toolbar button (with no associated dropdown).
#[parse(condition = "ParserContext::chrome_rules_enabled")]
Toolbarbutton,
/// The dropdown portion of a toolbar button
#[parse(condition = "ParserContext::chrome_rules_enabled")]
ToolbarbuttonDropdown,
/// A tooltip.
#[parse(condition = "ParserContext::chrome_rules_enabled")]
Tooltip,

View File

@@ -14,46 +14,41 @@ button {
margin: 1px 5px 2px;
min-width: 6.3em;
color: ButtonText;
background-color: ButtonFace;
text-shadow: none;
border: 1px solid ThreeDLightShadow;
padding: 2px 3px;
&:where(:hover:not([checked="true"])) {
background-color: -moz-buttonhoverface;
color: -moz-buttonhovertext;
}
&:where(:hover:active, [open="true"]) {
background-color: -moz-buttonactiveface;
color: -moz-buttonactivetext;
}
&:where([disabled="true"]) {
color: GrayText;
background-color: ButtonFace;
}
&:where(:focus-visible) {
outline: auto;
}
&.plain {
margin: 0 !important;
padding: 0 !important;
}
}
.button-text {
margin: 0;
margin-inline-start: 2px;
text-align: center;
}
/* .......... hover state .......... */
button:where(:hover:not([checked="true"])) {
color: -moz-buttonhovertext;
}
/* .......... active state .......... */
button:where(:hover:active, [open="true"]) {
color: -moz-buttonactivetext;
}
/* .......... disabled state .......... */
button:where([disabled="true"]) {
color: GrayText;
}
/* .......... focused state .......... */
button:where(:focus-visible) {
outline: auto;
}
/* ::::: menu buttons ::::: */
.button-menu-dropmarker {
appearance: auto;
-moz-default-appearance: toolbarbutton-dropdown;
}
/* ::::: plain buttons ::::: */
button.plain {

View File

@@ -108,44 +108,6 @@ static GtkWidget* CreateButtonWidget() {
return widget;
}
static GtkWidget* CreateToggleButtonWidget() {
GtkWidget* widget = gtk_toggle_button_new();
AddToWindowContainer(widget);
return widget;
}
static GtkWidget* CreateButtonArrowWidget() {
GtkWidget* widget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_TOGGLE_BUTTON)), widget);
gtk_widget_show(widget);
return widget;
}
static GtkWidget* CreateComboBoxWidget() {
GtkWidget* widget = gtk_combo_box_new();
AddToWindowContainer(widget);
return widget;
}
typedef struct {
GType type;
GtkWidget** widget;
} GtkInnerWidgetInfo;
static void GetInnerWidget(GtkWidget* widget, gpointer client_data) {
auto info = static_cast<GtkInnerWidgetInfo*>(client_data);
if (G_TYPE_CHECK_INSTANCE_TYPE(widget, info->type)) {
*info->widget = widget;
}
}
static GtkWidget* CreateComboBoxEntryWidget() {
GtkWidget* widget = gtk_combo_box_new_with_entry();
AddToWindowContainer(widget);
return widget;
}
static GtkWidget* CreateScrolledWindowWidget() {
GtkWidget* widget = gtk_scrolled_window_new(nullptr, nullptr);
AddToWindowContainer(widget);
@@ -508,10 +470,6 @@ static GtkWidget* CreateWidget(WidgetNodeType aAppearance) {
return CreateFrameWidget();
case MOZ_GTK_BUTTON:
return CreateButtonWidget();
case MOZ_GTK_TOGGLE_BUTTON:
return CreateToggleButtonWidget();
case MOZ_GTK_BUTTON_ARROW:
return CreateButtonArrowWidget();
case MOZ_GTK_SCROLLED_WINDOW:
return CreateScrolledWindowWidget();
case MOZ_GTK_TREEVIEW:

View File

@@ -54,8 +54,6 @@ style_path_print(GtkStyleContext *context)
static gint moz_gtk_get_tab_thickness(GtkStyleContext* style);
static void Inset(GdkRectangle*, const GtkBorder&);
static void moz_gtk_add_style_border(GtkStyleContext* style, gint* left,
gint* top, gint* right, gint* bottom) {
GtkBorder border;
@@ -88,19 +86,6 @@ static void moz_gtk_add_border_padding(GtkStyleContext* style, gint* left,
moz_gtk_add_style_padding(style, left, top, right, bottom);
}
// In case there's an error in Gtk theme and preferred size is zero,
// return some sane values to pass mozilla automation tests.
// It should not happen in real-life.
#define MIN_WIDGET_SIZE 10
static void moz_gtk_sanity_preferred_size(GtkRequisition* requisition) {
if (requisition->width <= 0) {
requisition->width = MIN_WIDGET_SIZE;
}
if (requisition->height <= 0) {
requisition->height = MIN_WIDGET_SIZE;
}
}
// GetStateFlagsFromGtkWidgetState() can be safely used for the specific
// GtkWidgets that set both prelight and active flags. For other widgets,
// either the GtkStateFlags or Gecko's GtkWidgetState need to be carefully
@@ -168,49 +153,6 @@ void moz_gtk_refresh() {
ResetWidgetCache();
}
gint moz_gtk_button_get_default_overflow(gint* border_top, gint* border_left,
gint* border_bottom,
gint* border_right) {
GtkBorder* default_outside_border;
GtkStyleContext* style = GetStyleContext(MOZ_GTK_BUTTON);
gtk_style_context_get_style(style, "default-outside-border",
&default_outside_border, NULL);
if (default_outside_border) {
*border_top = default_outside_border->top;
*border_left = default_outside_border->left;
*border_bottom = default_outside_border->bottom;
*border_right = default_outside_border->right;
gtk_border_free(default_outside_border);
} else {
*border_top = *border_left = *border_bottom = *border_right = 0;
}
return MOZ_GTK_SUCCESS;
}
static gint moz_gtk_button_get_default_border(gint* border_top,
gint* border_left,
gint* border_bottom,
gint* border_right) {
GtkBorder* default_border;
GtkStyleContext* style = GetStyleContext(MOZ_GTK_BUTTON);
gtk_style_context_get_style(style, "default-border", &default_border, NULL);
if (default_border) {
*border_top = default_border->top;
*border_left = default_border->left;
*border_bottom = default_border->bottom;
*border_right = default_border->right;
gtk_border_free(default_border);
} else {
/* see gtkbutton.c */
*border_top = *border_left = *border_bottom = *border_right = 1;
}
return MOZ_GTK_SUCCESS;
}
gint moz_gtk_splitter_get_metrics(gint orientation, gint* size) {
GtkStyleContext* style;
if (orientation == GTK_ORIENTATION_HORIZONTAL) {
@@ -384,6 +326,49 @@ static gint moz_gtk_window_decoration_paint(cairo_t* cr,
return MOZ_GTK_SUCCESS;
}
gint moz_gtk_button_get_default_overflow(gint* border_top, gint* border_left,
gint* border_bottom,
gint* border_right) {
GtkBorder* default_outside_border;
GtkStyleContext* style = GetStyleContext(MOZ_GTK_BUTTON);
gtk_style_context_get_style(style, "default-outside-border",
&default_outside_border, NULL);
if (default_outside_border) {
*border_top = default_outside_border->top;
*border_left = default_outside_border->left;
*border_bottom = default_outside_border->bottom;
*border_right = default_outside_border->right;
gtk_border_free(default_outside_border);
} else {
*border_top = *border_left = *border_bottom = *border_right = 0;
}
return MOZ_GTK_SUCCESS;
}
static gint moz_gtk_button_get_default_border(gint* border_top,
gint* border_left,
gint* border_bottom,
gint* border_right) {
GtkBorder* default_border;
GtkStyleContext* style = GetStyleContext(MOZ_GTK_BUTTON);
gtk_style_context_get_style(style, "default-border", &default_border, NULL);
if (default_border) {
*border_top = default_border->top;
*border_left = default_border->left;
*border_bottom = default_border->bottom;
*border_right = default_border->right;
gtk_border_free(default_border);
} else {
/* see gtkbutton.c */
*border_top = *border_left = *border_bottom = *border_right = 1;
}
return MOZ_GTK_SUCCESS;
}
static gint moz_gtk_button_paint(cairo_t* cr, const GdkRectangle* rect,
GtkWidgetState* state, GtkReliefStyle relief,
GtkWidget* widget,
@@ -490,64 +475,6 @@ static gint moz_gtk_header_bar_button_paint(cairo_t* cr, GdkRectangle* aRect,
return MOZ_GTK_SUCCESS;
}
static gint calculate_button_inner_rect(GtkWidget* button,
const GdkRectangle* rect,
GdkRectangle* inner_rect,
GtkTextDirection direction) {
GtkStyleContext* style;
GtkBorder border;
GtkBorder padding = {0, 0, 0, 0};
style = gtk_widget_get_style_context(button);
/* This mirrors gtkbutton's child positioning */
gtk_style_context_get_border(style, gtk_style_context_get_state(style),
&border);
gtk_style_context_get_padding(style, gtk_style_context_get_state(style),
&padding);
inner_rect->x = rect->x + border.left + padding.left;
inner_rect->y = rect->y + padding.top + border.top;
inner_rect->width =
MAX(1, rect->width - padding.left - padding.right - border.left * 2);
inner_rect->height =
MAX(1, rect->height - padding.top - padding.bottom - border.top * 2);
return MOZ_GTK_SUCCESS;
}
static gint calculate_arrow_rect(GtkWidget* arrow, GdkRectangle* rect,
GdkRectangle* arrow_rect,
GtkTextDirection direction) {
/* defined in gtkarrow.c */
gfloat arrow_scaling = 0.7;
gfloat xalign, xpad;
gint extent;
gint mxpad, mypad;
gfloat mxalign, myalign;
GtkMisc* misc = GTK_MISC(arrow);
gtk_style_context_get_style(gtk_widget_get_style_context(arrow),
"arrow_scaling", &arrow_scaling, NULL);
gtk_misc_get_padding(misc, &mxpad, &mypad);
extent = MIN((rect->width - mxpad * 2), (rect->height - mypad * 2)) *
arrow_scaling;
gtk_misc_get_alignment(misc, &mxalign, &myalign);
xalign = direction == GTK_TEXT_DIR_LTR ? mxalign : 1.0 - mxalign;
xpad = mxpad + (rect->width - extent) * xalign;
arrow_rect->x = direction == GTK_TEXT_DIR_LTR ? floor(rect->x + xpad)
: ceil(rect->x + xpad);
arrow_rect->y = floor(rect->y + mypad + ((rect->height - extent) * myalign));
arrow_rect->width = arrow_rect->height = extent;
return MOZ_GTK_SUCCESS;
}
/**
* Get minimum widget size as sum of margin, padding, border and
* min-width/min-height.
@@ -569,13 +496,6 @@ static void moz_gtk_get_widget_min_size(GtkStyleContext* style, int* width,
padding.top + padding.bottom;
}
static void Inset(GdkRectangle* rect, const GtkBorder& aBorder) {
rect->x += aBorder.left;
rect->y += aBorder.top;
rect->width -= aBorder.left + aBorder.right;
rect->height -= aBorder.top + aBorder.bottom;
}
/* See gtk_range_draw() for reference. */
static gint moz_gtk_scale_paint(cairo_t* cr, GdkRectangle* rect,
GtkWidgetState* state, GtkOrientation flags,
@@ -698,105 +618,6 @@ static gint moz_gtk_treeview_paint(cairo_t* cr, GdkRectangle* rect,
return MOZ_GTK_SUCCESS;
}
/* See gtk_separator_draw() for reference. */
static gint moz_gtk_combo_box_paint(cairo_t* cr, const GdkRectangle* aRect,
GtkWidgetState* state,
GtkTextDirection direction) {
GdkRectangle arrow_rect, real_arrow_rect;
gint separator_width;
gboolean wide_separators;
GtkStyleContext* style;
GtkRequisition arrow_req;
GtkWidget* comboBoxButton = GetWidget(MOZ_GTK_COMBOBOX_BUTTON);
GtkWidget* comboBoxArrow = GetWidget(MOZ_GTK_COMBOBOX_ARROW);
if (!comboBoxButton || !comboBoxArrow) {
return MOZ_GTK_UNKNOWN_WIDGET;
}
/* Also sets the direction on gComboBoxButtonWidget, which is then
* inherited by the separator and arrow */
moz_gtk_button_paint(cr, aRect, state, GTK_RELIEF_NORMAL, comboBoxButton,
direction);
calculate_button_inner_rect(comboBoxButton, aRect, &arrow_rect, direction);
/* Now arrow_rect contains the inner rect ; we want to correct the width
* to what the arrow needs (see gtk_combo_box_size_allocate) */
gtk_widget_get_preferred_size(comboBoxArrow, NULL, &arrow_req);
moz_gtk_sanity_preferred_size(&arrow_req);
if (direction == GTK_TEXT_DIR_LTR)
arrow_rect.x += arrow_rect.width - arrow_req.width;
arrow_rect.width = arrow_req.width;
calculate_arrow_rect(comboBoxArrow, &arrow_rect, &real_arrow_rect, direction);
style = GetStyleContext(MOZ_GTK_COMBOBOX_ARROW, state->image_scale);
gtk_render_arrow(style, cr, ARROW_DOWN, real_arrow_rect.x, real_arrow_rect.y,
real_arrow_rect.width);
/* If there is no separator in the theme, there's nothing left to do. */
GtkWidget* widget = GetWidget(MOZ_GTK_COMBOBOX_SEPARATOR);
if (!widget) {
return MOZ_GTK_SUCCESS;
}
style = gtk_widget_get_style_context(widget);
StyleContextSetScale(style, state->image_scale);
gtk_style_context_get_style(style, "wide-separators", &wide_separators,
"separator-width", &separator_width, NULL);
if (wide_separators) {
if (direction == GTK_TEXT_DIR_LTR)
arrow_rect.x -= separator_width;
else
arrow_rect.x += arrow_rect.width;
gtk_render_frame(style, cr, arrow_rect.x, arrow_rect.y, separator_width,
arrow_rect.height);
} else {
if (direction == GTK_TEXT_DIR_LTR) {
GtkBorder padding;
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
gtk_style_context_get_padding(style, state_flags, &padding);
arrow_rect.x -= padding.left;
} else
arrow_rect.x += arrow_rect.width;
gtk_render_line(style, cr, arrow_rect.x, arrow_rect.y, arrow_rect.x,
arrow_rect.y + arrow_rect.height);
}
return MOZ_GTK_SUCCESS;
}
static gint moz_gtk_arrow_paint(cairo_t* cr, GdkRectangle* rect,
GtkWidgetState* state, GtkArrowType arrow_type,
GtkTextDirection direction) {
GdkRectangle arrow_rect;
gdouble arrow_angle;
switch (arrow_type) {
case GTK_ARROW_DOWN:
arrow_angle = ARROW_DOWN;
break;
default:
arrow_angle = ARROW_UP;
break;
}
if (arrow_type == GTK_ARROW_NONE) return MOZ_GTK_SUCCESS;
GtkWidget* widget = GetWidget(MOZ_GTK_BUTTON_ARROW);
if (!widget) {
return MOZ_GTK_UNKNOWN_WIDGET;
}
calculate_arrow_rect(widget, rect, &arrow_rect, direction);
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
GtkStyleContext* style = GetStyleContext(
MOZ_GTK_BUTTON_ARROW, state->image_scale, direction, state_flags);
gtk_render_arrow(style, cr, arrow_angle, arrow_rect.x, arrow_rect.y,
arrow_rect.width);
return MOZ_GTK_SUCCESS;
}
static gint moz_gtk_resizer_paint(cairo_t* cr, GdkRectangle* rect,
GtkWidgetState* state,
GtkTextDirection direction) {
@@ -1152,71 +973,11 @@ gint moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
*left = *top = *right = *bottom = 0;
switch (widget) {
case MOZ_GTK_BUTTON:
case MOZ_GTK_TOOLBAR_BUTTON: {
style = GetStyleContext(MOZ_GTK_BUTTON);
*left = *top = *right = *bottom = gtk_container_get_border_width(
GTK_CONTAINER(GetWidget(MOZ_GTK_BUTTON)));
if (widget == MOZ_GTK_TOOLBAR_BUTTON) {
gtk_style_context_save(style);
gtk_style_context_add_class(style, "image-button");
}
moz_gtk_add_style_padding(style, left, top, right, bottom);
if (widget == MOZ_GTK_TOOLBAR_BUTTON) gtk_style_context_restore(style);
moz_gtk_add_style_border(style, left, top, right, bottom);
return MOZ_GTK_SUCCESS;
}
case MOZ_GTK_TREEVIEW: {
style = GetStyleContext(MOZ_GTK_SCROLLED_WINDOW);
moz_gtk_add_style_border(style, left, top, right, bottom);
return MOZ_GTK_SUCCESS;
}
case MOZ_GTK_DROPDOWN: {
/* We need to account for the arrow on the dropdown, so text
* doesn't come too close to the arrow, or in some cases spill
* into the arrow. */
gboolean wide_separators;
gint separator_width;
GtkRequisition arrow_req;
GtkBorder border;
*left = *top = *right = *bottom = gtk_container_get_border_width(
GTK_CONTAINER(GetWidget(MOZ_GTK_COMBOBOX_BUTTON)));
style = GetStyleContext(MOZ_GTK_COMBOBOX_BUTTON);
moz_gtk_add_border_padding(style, left, top, right, bottom);
/* If there is no separator, don't try to count its width. */
separator_width = 0;
GtkWidget* comboBoxSeparator = GetWidget(MOZ_GTK_COMBOBOX_SEPARATOR);
if (comboBoxSeparator) {
style = gtk_widget_get_style_context(comboBoxSeparator);
gtk_style_context_get_style(style, "wide-separators", &wide_separators,
"separator-width", &separator_width, NULL);
if (!wide_separators) {
gtk_style_context_get_border(
style, gtk_style_context_get_state(style), &border);
separator_width = border.left;
}
}
gtk_widget_get_preferred_size(GetWidget(MOZ_GTK_COMBOBOX_ARROW), NULL,
&arrow_req);
moz_gtk_sanity_preferred_size(&arrow_req);
if (direction == GTK_TEXT_DIR_RTL)
*left += separator_width + arrow_req.width;
else
*right += separator_width + arrow_req.width;
return MOZ_GTK_SUCCESS;
}
case MOZ_GTK_TABPANELS:
w = GetWidget(MOZ_GTK_TABPANELS);
break;
@@ -1318,30 +1079,6 @@ gint moz_gtk_get_tab_scroll_arrow_size(gint* width, gint* height) {
return MOZ_GTK_SUCCESS;
}
void moz_gtk_get_arrow_size(WidgetNodeType widgetType, gint* width,
gint* height) {
GtkWidget* widget;
switch (widgetType) {
case MOZ_GTK_DROPDOWN:
widget = GetWidget(MOZ_GTK_COMBOBOX_ARROW);
break;
default:
widget = GetWidget(MOZ_GTK_BUTTON_ARROW);
break;
}
if (widget) {
GtkRequisition requisition;
gtk_widget_get_preferred_size(widget, NULL, &requisition);
moz_gtk_sanity_preferred_size(&requisition);
*width = requisition.width;
*height = requisition.height;
} else {
*width = 0;
*height = 0;
}
}
void moz_gtk_get_scale_metrics(GtkOrientation orient, gint* scale_width,
gint* scale_height) {
if (gtk_check_version(3, 20, 0) != nullptr) {
@@ -1416,15 +1153,6 @@ gint moz_gtk_widget_paint(WidgetNodeType widget, cairo_t* cr,
cairo_new_path(cr);
switch (widget) {
case MOZ_GTK_BUTTON:
case MOZ_GTK_TOOLBAR_BUTTON:
if (state->depressed) {
return moz_gtk_button_paint(cr, rect, state, (GtkReliefStyle)flags,
GetWidget(MOZ_GTK_TOGGLE_BUTTON),
direction);
}
return moz_gtk_button_paint(cr, rect, state, (GtkReliefStyle)flags,
GetWidget(MOZ_GTK_BUTTON), direction);
case MOZ_GTK_HEADER_BAR_BUTTON_CLOSE:
case MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE:
case MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE:
@@ -1441,8 +1169,6 @@ gint moz_gtk_widget_paint(WidgetNodeType widget, cairo_t* cr,
direction);
case MOZ_GTK_TREEVIEW:
return moz_gtk_treeview_paint(cr, rect, state, direction);
case MOZ_GTK_DROPDOWN:
return moz_gtk_combo_box_paint(cr, rect, state, direction);
case MOZ_GTK_FRAME:
return moz_gtk_frame_paint(cr, rect, state, direction);
case MOZ_GTK_RESIZER:
@@ -1459,9 +1185,6 @@ gint moz_gtk_widget_paint(WidgetNodeType widget, cairo_t* cr,
widget);
case MOZ_GTK_TABPANELS:
return moz_gtk_tabpanels_paint(cr, rect, state, direction);
case MOZ_GTK_TOOLBARBUTTON_ARROW:
return moz_gtk_arrow_paint(cr, rect, state, (GtkArrowType)flags,
direction);
case MOZ_GTK_SPLITTER_HORIZONTAL:
return moz_gtk_vpaned_paint(cr, rect, state);
case MOZ_GTK_SPLITTER_VERTICAL:

View File

@@ -110,12 +110,6 @@ enum GtkTabFlags {
enum WidgetNodeType : int {
/* Paints a GtkButton. flags is a GtkReliefStyle. */
MOZ_GTK_BUTTON,
/* Paints a button with image and no text */
MOZ_GTK_TOOLBAR_BUTTON,
/* Paints a toggle button */
MOZ_GTK_TOGGLE_BUTTON,
/* Paints a button arrow */
MOZ_GTK_BUTTON_ARROW,
/* Vertical GtkScrollbar counterparts */
MOZ_GTK_SCROLLBAR_VERTICAL,
@@ -143,10 +137,6 @@ enum WidgetNodeType : int {
MOZ_GTK_TEXT_VIEW_TEXT,
/* The "selection" node of a GtkTextView.text */
MOZ_GTK_TEXT_VIEW_TEXT_SELECTION,
/* Paints a GtkOptionMenu. */
MOZ_GTK_DROPDOWN,
/* Paints an entry in an editable option menu */
MOZ_GTK_DROPDOWN_ENTRY,
/* Paints a GtkToolTip */
MOZ_GTK_TOOLTIP,
@@ -217,22 +207,6 @@ enum WidgetNodeType : int {
MOZ_GTK_HEADERBAR_FIXED_MAXIMIZED,
/* Window container for all widgets */
MOZ_GTK_WINDOW_CONTAINER,
/* Used for widget tree construction. */
MOZ_GTK_COMBOBOX,
/* Paints a GtkComboBox button widget. */
MOZ_GTK_COMBOBOX_BUTTON,
/* Paints a GtkComboBox arrow widget. */
MOZ_GTK_COMBOBOX_ARROW,
/* Paints a GtkComboBox separator widget. */
MOZ_GTK_COMBOBOX_SEPARATOR,
/* Used for widget tree construction. */
MOZ_GTK_COMBOBOX_ENTRY,
/* Paints a GtkComboBox entry widget. */
MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA,
/* Paints a GtkComboBox entry button widget. */
MOZ_GTK_COMBOBOX_ENTRY_BUTTON,
/* Paints a GtkComboBox entry arrow widget. */
MOZ_GTK_COMBOBOX_ENTRY_ARROW,
/* Used for scrolled window shell. */
MOZ_GTK_SCROLLED_WINDOW,
/* Paints a GtkHeaderBar */
@@ -377,16 +351,6 @@ gint moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length,
*/
gint moz_gtk_get_tab_scroll_arrow_size(gint* width, gint* height);
/**
* Get the desired size of an arrow in a button
*
* widgetType: [IN] the widget for which to get the arrow size
* width: [OUT] the desired width
* height: [OUT] the desired height
*/
void moz_gtk_get_arrow_size(WidgetNodeType widgetType, gint* width,
gint* height);
/**
* Get the minimum height of a entry widget
* min_content_height: [OUT] the minimum height of the content box.

View File

@@ -184,14 +184,10 @@ bool nsNativeThemeGTK::GetGtkWidgetAndState(StyleAppearance aAppearance,
aState->isDefault = IsDefaultButton(aFrame);
aState->canDefault = FALSE; // XXX fix me
if (aAppearance == StyleAppearance::Button ||
aAppearance == StyleAppearance::Toolbarbutton ||
aAppearance == StyleAppearance::ToolbarbuttonDropdown ||
aAppearance == StyleAppearance::MozWindowButtonMinimize ||
if (aAppearance == StyleAppearance::MozWindowButtonMinimize ||
aAppearance == StyleAppearance::MozWindowButtonRestore ||
aAppearance == StyleAppearance::MozWindowButtonMaximize ||
aAppearance == StyleAppearance::MozWindowButtonClose ||
aAppearance == StyleAppearance::Menulist) {
aAppearance == StyleAppearance::MozWindowButtonClose) {
aState->active &= aState->inHover;
}
@@ -200,18 +196,6 @@ bool nsNativeThemeGTK::GetGtkWidgetAndState(StyleAppearance aAppearance,
// actually has element focus, so we check the focused attribute
// to see whether to draw in the focused state.
aState->focused = elementState.HasState(ElementState::FOCUSRING);
// A button with drop down menu open or an activated toggle button
// should always appear depressed.
if (aAppearance == StyleAppearance::Button ||
aAppearance == StyleAppearance::Toolbarbutton ||
aAppearance == StyleAppearance::ToolbarbuttonDropdown ||
aAppearance == StyleAppearance::Menulist) {
bool menuOpen = IsOpenButton(aFrame);
aState->depressed = IsCheckedButton(aFrame) || menuOpen;
// we must not highlight buttons with open drop down menus on hover.
aState->inHover = aState->inHover && !menuOpen;
}
}
if (aAppearance == StyleAppearance::MozWindowTitlebar ||
@@ -226,14 +210,6 @@ bool nsNativeThemeGTK::GetGtkWidgetAndState(StyleAppearance aAppearance,
}
switch (aAppearance) {
case StyleAppearance::Button:
if (aWidgetFlags) *aWidgetFlags = GTK_RELIEF_NORMAL;
aGtkWidgetType = MOZ_GTK_BUTTON;
break;
case StyleAppearance::Toolbarbutton:
if (aWidgetFlags) *aWidgetFlags = GTK_RELIEF_NONE;
aGtkWidgetType = MOZ_GTK_TOOLBAR_BUTTON;
break;
case StyleAppearance::Range: {
if (IsRangeHorizontal(aFrame)) {
if (aWidgetFlags) *aWidgetFlags = GTK_ORIENTATION_HORIZONTAL;
@@ -257,23 +233,6 @@ bool nsNativeThemeGTK::GetGtkWidgetAndState(StyleAppearance aAppearance,
case StyleAppearance::Listbox:
aGtkWidgetType = MOZ_GTK_TREEVIEW;
break;
case StyleAppearance::Menulist:
aGtkWidgetType = MOZ_GTK_DROPDOWN;
if (aWidgetFlags)
*aWidgetFlags =
IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XHTML);
break;
case StyleAppearance::ToolbarbuttonDropdown:
case StyleAppearance::ButtonArrowDown:
case StyleAppearance::ButtonArrowUp:
aGtkWidgetType = MOZ_GTK_TOOLBARBUTTON_ARROW;
if (aWidgetFlags) {
*aWidgetFlags = GTK_ARROW_DOWN;
if (aAppearance == StyleAppearance::ButtonArrowUp)
*aWidgetFlags = GTK_ARROW_UP;
}
break;
case StyleAppearance::ProgressBar:
aGtkWidgetType = MOZ_GTK_PROGRESSBAR;
break;
@@ -580,30 +539,6 @@ static void DrawThemeWithCairo(gfxContext* aContext, DrawTarget* aDrawTarget,
}
}
CSSIntMargin nsNativeThemeGTK::GetExtraSizeForWidget(
nsIFrame* aFrame, StyleAppearance aAppearance) {
CSSIntMargin extra;
// Allow an extra one pixel above and below the thumb for certain
// GTK2 themes (Ximian Industrial, Bluecurve, Misty, at least);
// We modify the frame's overflow area. See bug 297508.
switch (aAppearance) {
case StyleAppearance::Button: {
if (IsDefaultButton(aFrame)) {
// Some themes draw a default indicator outside the widget,
// include that in overflow
moz_gtk_button_get_default_overflow(&extra.top.value, &extra.left.value,
&extra.bottom.value,
&extra.right.value);
break;
}
return {};
}
default:
return {};
}
return extra;
}
NS_IMETHODIMP
nsNativeThemeGTK::DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
StyleAppearance aAppearance,
@@ -792,12 +727,10 @@ CSSIntMargin nsNativeThemeGTK::GetCachedWidgetBorder(
moz_gtk_get_widget_border(gtkWidgetType, &result.left.value,
&result.top.value, &result.right.value,
&result.bottom.value, aDirection);
if (gtkWidgetType != MOZ_GTK_DROPDOWN) { // depends on aDirection
mBorderCacheValid[cacheIndex] |= cacheBit;
mBorderCache[gtkWidgetType] = result;
}
}
}
FixupForVerticalWritingMode(aFrame->GetWritingMode(), &result);
return result;
}
@@ -844,9 +777,6 @@ bool nsNativeThemeGTK::GetWidgetPadding(nsDeviceContext* aContext,
case StyleAppearance::MozWindowButtonMinimize:
case StyleAppearance::MozWindowButtonMaximize:
case StyleAppearance::MozWindowButtonRestore:
case StyleAppearance::ToolbarbuttonDropdown:
case StyleAppearance::ButtonArrowUp:
case StyleAppearance::ButtonArrowDown:
case StyleAppearance::RangeThumb:
aResult->SizeTo(0, 0, 0, 0);
return true;
@@ -865,13 +795,8 @@ bool nsNativeThemeGTK::GetWidgetOverflow(nsDeviceContext* aContext,
return Theme::GetWidgetOverflow(aContext, aFrame, aAppearance,
aOverflowRect);
}
auto overflow = GetExtraSizeForWidget(aFrame, aAppearance);
if (overflow == CSSIntMargin()) {
return false;
}
aOverflowRect->Inflate(CSSIntMargin::ToAppUnits(overflow));
return true;
}
auto nsNativeThemeGTK::IsWidgetNonNative(nsIFrame* aFrame,
StyleAppearance aAppearance)
@@ -904,7 +829,10 @@ bool nsNativeThemeGTK::IsWidgetAlwaysNonNative(nsIFrame* aFrame,
aAppearance == StyleAppearance::PasswordInput ||
aAppearance == StyleAppearance::Textarea ||
aAppearance == StyleAppearance::Checkbox ||
aAppearance == StyleAppearance::Radio;
aAppearance == StyleAppearance::Radio ||
aAppearance == StyleAppearance::Button ||
aAppearance == StyleAppearance::Toolbarbutton ||
aAppearance == StyleAppearance::Menulist;
}
LayoutDeviceIntSize nsNativeThemeGTK::GetMinimumWidgetSize(
@@ -932,12 +860,6 @@ LayoutDeviceIntSize nsNativeThemeGTK::GetMinimumWidgetSize(
&result.width);
}
} break;
case StyleAppearance::ToolbarbuttonDropdown:
case StyleAppearance::ButtonArrowUp:
case StyleAppearance::ButtonArrowDown: {
moz_gtk_get_arrow_size(MOZ_GTK_TOOLBARBUTTON_ARROW, &result.width,
&result.height);
} break;
case StyleAppearance::MozWindowButtonClose: {
const ToolbarButtonGTKMetrics* metrics =
GetToolbarButtonMetrics(MOZ_GTK_HEADER_BAR_BUTTON_CLOSE);
@@ -960,21 +882,6 @@ LayoutDeviceIntSize nsNativeThemeGTK::GetMinimumWidgetSize(
result.height = metrics->minSizeWithBorder.height;
break;
}
case StyleAppearance::Button:
case StyleAppearance::Menulist: {
if (aAppearance == StyleAppearance::Menulist) {
// Include the arrow size.
moz_gtk_get_arrow_size(MOZ_GTK_DROPDOWN, &result.width, &result.height);
}
// else the minimum size is missing consideration of container
// descendants; the value returned here will not be helpful, but the
// box model may consider border and padding with child minimum sizes.
CSSIntMargin border =
GetCachedWidgetBorder(aFrame, aAppearance, GetTextDirection(aFrame));
result.width += border.LeftRight();
result.height += border.TopBottom();
} break;
default:
break;
}
@@ -1015,18 +922,6 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
}
switch (aAppearance) {
// Combobox dropdowns don't support native theming in vertical mode.
case StyleAppearance::Menulist:
if (aFrame && aFrame->GetWritingMode().IsVertical()) {
return false;
}
[[fallthrough]];
case StyleAppearance::Button:
case StyleAppearance::Toolbarbutton:
case StyleAppearance::ToolbarbuttonDropdown:
case StyleAppearance::ButtonArrowUp:
case StyleAppearance::ButtonArrowDown:
case StyleAppearance::Listbox:
case StyleAppearance::ProgressBar:
case StyleAppearance::Progresschunk:
@@ -1054,9 +949,7 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
NS_IMETHODIMP_(bool)
nsNativeThemeGTK::WidgetIsContainer(StyleAppearance aAppearance) {
// XXXdwh At some point flesh all of this out.
if (aAppearance == StyleAppearance::RangeThumb ||
aAppearance == StyleAppearance::ButtonArrowUp ||
aAppearance == StyleAppearance::ButtonArrowDown) {
if (aAppearance == StyleAppearance::RangeThumb) {
return false;
}
return true;
@@ -1067,14 +960,8 @@ bool nsNativeThemeGTK::ThemeDrawsFocusForWidget(nsIFrame* aFrame,
if (IsWidgetNonNative(aFrame, aAppearance) != NonNative::No) {
return Theme::ThemeDrawsFocusForWidget(aFrame, aAppearance);
}
switch (aAppearance) {
case StyleAppearance::Button:
case StyleAppearance::Menulist:
return true;
default:
return false;
}
}
bool nsNativeThemeGTK::ThemeNeedsComboboxDropmarker() { return false; }

View File

@@ -53,15 +53,13 @@ NS_IMPL_ISUPPORTS(nsNativeTheme, nsITimerCallback, nsINamed)
if (isXULElement) {
if (aAppearance == StyleAppearance::Checkbox ||
aAppearance == StyleAppearance::Radio ||
aAppearance == StyleAppearance::ToolbarbuttonDropdown ||
aAppearance == StyleAppearance::ButtonArrowUp ||
#ifdef MOZ_WIDGET_GTK
aAppearance == StyleAppearance::MozWindowButtonClose ||
aAppearance == StyleAppearance::MozWindowButtonMinimize ||
aAppearance == StyleAppearance::MozWindowButtonRestore ||
aAppearance == StyleAppearance::MozWindowButtonMaximize ||
#endif
aAppearance == StyleAppearance::ButtonArrowDown) {
false) {
aFrame = aFrame->GetParent();
frameContent = aFrame->GetContent();
}