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:
committed by
ealvarez@mozilla.com
parent
5cf47a8af2
commit
cb24a82ae3
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user