Bug 1553825 - Fix blurry radio and checkbox indicators in menus; r=stransky

This fix wrong rendering of radio and checkbox indicators in menus by
correcting the dimensions acording to used theme.

Differential Revision: https://phabricator.services.mozilla.com/D32316

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan Horak 2019-05-28 06:54:44 +00:00
parent 3a5fb86b01
commit 1e8f702108
3 changed files with 44 additions and 34 deletions

View File

@ -27,6 +27,8 @@ static ScrollbarGTKMetrics sScrollbarMetrics[2];
static ScrollbarGTKMetrics sActiveScrollbarMetrics[2];
static ToggleGTKMetrics sCheckboxMetrics;
static ToggleGTKMetrics sRadioMetrics;
static ToggleGTKMetrics sMenuRadioMetrics;
static ToggleGTKMetrics sMenuCheckboxMetrics;
static ToolbarGTKMetrics sToolbarMetrics;
#define ARROW_UP 0
@ -212,27 +214,14 @@ void moz_gtk_refresh() {
sActiveScrollbarMetrics[GTK_ORIENTATION_VERTICAL].initialized = false;
sCheckboxMetrics.initialized = false;
sRadioMetrics.initialized = false;
sMenuCheckboxMetrics.initialized = false;
sMenuRadioMetrics.initialized = false;
sToolbarMetrics.initialized = false;
/* This will destroy all of our widgets */
ResetWidgetCache();
}
gint moz_gtk_checkbox_get_metrics(gint* indicator_size,
gint* indicator_spacing) {
gtk_widget_style_get(GetWidget(MOZ_GTK_CHECKBUTTON_CONTAINER),
"indicator_size", indicator_size, "indicator_spacing",
indicator_spacing, NULL);
return MOZ_GTK_SUCCESS;
}
gint moz_gtk_radio_get_metrics(gint* indicator_size, gint* indicator_spacing) {
gtk_widget_style_get(GetWidget(MOZ_GTK_RADIOBUTTON_CONTAINER),
"indicator_size", indicator_size, "indicator_spacing",
indicator_spacing, NULL);
return MOZ_GTK_SUCCESS;
}
static gint moz_gtk_get_focus_outline_size(GtkStyleContext* style,
gint* focus_h_width,
gint* focus_v_width) {
@ -611,8 +600,10 @@ static gint moz_gtk_toggle_paint(cairo_t* cr, GdkRectangle* rect,
gint x, y, width, height;
GtkStyleContext* style;
const ToggleGTKMetrics* metrics = GetToggleMetrics(isradio);
// We need to call this before GetStyleContext, because otherwise we would
// reset state flags
const ToggleGTKMetrics* metrics =
GetToggleMetrics(isradio ? MOZ_GTK_RADIOBUTTON : MOZ_GTK_CHECKBUTTON);
// Clamp the rect and paint it center aligned in the rect.
x = rect->x;
y = rect->y;
@ -2151,6 +2142,7 @@ static gint moz_gtk_check_menu_item_paint(WidgetNodeType widgetType,
bool isRadio = (widgetType == MOZ_GTK_RADIOMENUITEM);
WidgetNodeType indicatorType = isRadio ? MOZ_GTK_RADIOMENUITEM_INDICATOR
: MOZ_GTK_CHECKMENUITEM_INDICATOR;
const ToggleGTKMetrics* metrics = GetToggleMetrics(indicatorType);
style = GetStyleContext(indicatorType, state->scale, direction, state_flags);
if (direction == GTK_TEXT_DIR_RTL) {
@ -2160,15 +2152,25 @@ static gint moz_gtk_check_menu_item_paint(WidgetNodeType widgetType,
}
y = rect->y + (rect->height - indicator_size) / 2;
gint indicator_width, indicator_height;
indicator_width = indicator_height = indicator_size;
if (!pre_3_20) {
gtk_render_background(style, cr, x, y, indicator_size, indicator_size);
gtk_render_frame(style, cr, x, y, indicator_size, indicator_size);
x = x + metrics->borderAndPadding.left;
y = y + metrics->borderAndPadding.top;
indicator_width = metrics->minSizeWithBorder.width -
metrics->borderAndPadding.left -
metrics->borderAndPadding.right;
indicator_height = metrics->minSizeWithBorder.height -
metrics->borderAndPadding.top -
metrics->borderAndPadding.bottom;
}
if (isRadio) {
gtk_render_option(style, cr, x, y, indicator_size, indicator_size);
gtk_render_option(style, cr, x, y, indicator_width, indicator_height);
} else {
gtk_render_check(style, cr, x, y, indicator_size, indicator_size);
gtk_render_check(style, cr, x, y, indicator_width, indicator_height);
}
return MOZ_GTK_SUCCESS;
@ -2702,23 +2704,30 @@ static MozGtkSize SizeFromLengthAndBreadth(GtkOrientation aOrientation,
: MozGtkSize({aBreadth, aLength});
}
const ToggleGTKMetrics* GetToggleMetrics(bool isRadio) {
const ToggleGTKMetrics* GetToggleMetrics(WidgetNodeType aWidgetType) {
ToggleGTKMetrics* metrics;
if (isRadio) {
metrics = &sRadioMetrics;
} else {
metrics = &sCheckboxMetrics;
switch (aWidgetType) {
case MOZ_GTK_RADIOBUTTON:
metrics = &sRadioMetrics;
break;
case MOZ_GTK_CHECKBUTTON:
metrics = &sCheckboxMetrics;
break;
case MOZ_GTK_RADIOMENUITEM_INDICATOR:
metrics = &sMenuRadioMetrics;
break;
case MOZ_GTK_CHECKMENUITEM_INDICATOR:
metrics = &sMenuCheckboxMetrics;
break;
default:
MOZ_CRASH("Unsupported widget type for getting metrics");
return nullptr;
}
if (metrics->initialized) return metrics;
metrics->initialized = true;
if (gtk_check_version(3, 20, 0) == nullptr) {
GtkStyleContext* style;
if (isRadio) {
style = GetStyleContext(MOZ_GTK_RADIOBUTTON);
} else {
style = GetStyleContext(MOZ_GTK_CHECKBUTTON);
}
GtkStyleContext* style = GetStyleContext(aWidgetType);
GtkStateFlags state_flags = gtk_style_context_get_state(style);
gtk_style_context_get(style, state_flags, "min-height",
&(metrics->minSizeWithBorder.height), "min-width",

View File

@ -427,7 +427,7 @@ gint moz_gtk_checkbox_get_metrics(gint* indicator_size,
* isRadio: [IN] true when requesting metrics for the radio button
* returns: pointer to ToggleGTKMetrics struct
*/
const ToggleGTKMetrics* GetToggleMetrics(bool isRadio);
const ToggleGTKMetrics* GetToggleMetrics(WidgetNodeType aWidgetType);
/**
* Get the desired size of a GtkRadioButton

View File

@ -1595,8 +1595,9 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
} break;
case StyleAppearance::Checkbox:
case StyleAppearance::Radio: {
const ToggleGTKMetrics* metrics =
GetToggleMetrics(aAppearance == StyleAppearance::Radio);
const ToggleGTKMetrics* metrics = GetToggleMetrics(
aAppearance == StyleAppearance::Radio ? MOZ_GTK_RADIOBUTTON
: MOZ_GTK_CHECKBUTTON);
aResult->width = metrics->minSizeWithBorder.width;
aResult->height = metrics->minSizeWithBorder.height;
} break;