зеркало из https://github.com/mozilla/pjs.git
Fixes for a number of native theme button problems on gtk2 (bug 255911). In order to more easily accomodate CSS fallbacks for when native theme rendering is not available, this adds GetWidgetPadding() to nsITheme, which allows the native theme impl to supply padding values which will override the css padding. This way, padding for the css fallback can be given without having it be added to the padding that's part of the native theme-rendered border. r=caillon, sr=roc.
This commit is contained in:
Родитель
2b8c557704
Коммит
ca84c668d4
|
@ -228,7 +228,7 @@ moz_gtk_checkbox_get_metrics(gint* indicator_size, gint* indicator_spacing);
|
|||
gint
|
||||
moz_gtk_radio_get_metrics(gint* indicator_size, gint* indicator_spacing);
|
||||
|
||||
/** Get the focus metrics for a checkbox or radio button
|
||||
/** Get the focus metrics for a button, checkbox, or radio button.
|
||||
* interior_focus: [OUT] whether the focus is drawn around the
|
||||
* label (TRUE) or around the whole container (FALSE)
|
||||
* focus_width: [OUT] the width of the focus line
|
||||
|
@ -237,6 +237,9 @@ moz_gtk_radio_get_metrics(gint* indicator_size, gint* indicator_spacing);
|
|||
* returns: MOZ_GTK_SUCCESS if there was no error, an error code otherwise
|
||||
*/
|
||||
gint
|
||||
moz_gtk_button_get_focus(gboolean* interior_focus,
|
||||
gint* focus_width, gint* focus_pad);
|
||||
gint
|
||||
moz_gtk_checkbox_get_focus(gboolean* interior_focus,
|
||||
gint* focus_width, gint* focus_pad);
|
||||
gint
|
||||
|
|
|
@ -123,14 +123,8 @@ GetPrimaryPresShell(nsIFrame* aFrame)
|
|||
if (!aFrame)
|
||||
return nsnull;
|
||||
|
||||
nsIPresShell *shell = nsnull;
|
||||
|
||||
nsIDocument* doc = aFrame->GetContent()->GetDocument();
|
||||
if (doc) {
|
||||
shell = doc->GetShellAt(0);
|
||||
}
|
||||
|
||||
return shell;
|
||||
nsPresContext *context = aFrame->GetPresContext();
|
||||
return context ? context->GetPresShell() : nsnull;
|
||||
}
|
||||
|
||||
static void RefreshWidgetWindow(nsIFrame* aFrame)
|
||||
|
@ -337,6 +331,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(PRUint8 aWidgetType, nsIFrame* aFrame,
|
|||
switch (aWidgetType) {
|
||||
case NS_THEME_BUTTON:
|
||||
case NS_THEME_TOOLBAR_BUTTON:
|
||||
case NS_THEME_TOOLBAR_DUAL_BUTTON:
|
||||
if (aWidgetFlags)
|
||||
*aWidgetFlags = (aWidgetType == NS_THEME_BUTTON) ? GTK_RELIEF_NORMAL : GTK_RELIEF_NONE;
|
||||
aGtkWidgetType = MOZ_GTK_BUTTON;
|
||||
|
@ -543,6 +538,14 @@ nsNativeThemeGTK::GetWidgetBorder(nsIDeviceContext* aContext, nsIFrame* aFrame,
|
|||
// gtk's 'toolbar' for purposes of painting the widget background,
|
||||
// we don't use the toolbar border for toolbox.
|
||||
break;
|
||||
case NS_THEME_TOOLBAR_DUAL_BUTTON:
|
||||
// TOOLBAR_DUAL_BUTTON is an interesting case. We want a border to draw
|
||||
// around the entire button + dropdown, and also an inner border if you're
|
||||
// over the button part. But, we want the inner button to be right up
|
||||
// against the edge of the outer button so that the borders overlap.
|
||||
// To make this happen, we draw a button border for the outer button,
|
||||
// but don't reserve any space for it.
|
||||
break;
|
||||
default:
|
||||
{
|
||||
GtkThemeWidgetType gtkWidgetType;
|
||||
|
@ -559,6 +562,21 @@ nsNativeThemeGTK::GetWidgetBorder(nsIDeviceContext* aContext, nsIFrame* aFrame,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsNativeThemeGTK::GetWidgetPadding(nsIDeviceContext* aContext,
|
||||
nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
nsMargin* aResult)
|
||||
{
|
||||
if (aWidgetType == NS_THEME_BUTTON_FOCUS ||
|
||||
aWidgetType == NS_THEME_TOOLBAR_BUTTON ||
|
||||
aWidgetType == NS_THEME_TOOLBAR_DUAL_BUTTON) {
|
||||
aResult->SizeTo(0, 0, 0, 0);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeThemeGTK::GetMinimumWidgetSize(nsIRenderingContext* aContext,
|
||||
nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
|
@ -626,6 +644,8 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsIRenderingContext* aContext,
|
|||
case NS_THEME_RADIO_CONTAINER:
|
||||
case NS_THEME_CHECKBOX_LABEL:
|
||||
case NS_THEME_RADIO_LABEL:
|
||||
case NS_THEME_BUTTON:
|
||||
case NS_THEME_TOOLBAR_BUTTON:
|
||||
{
|
||||
// Just include our border, and let the box code augment the size.
|
||||
|
||||
|
@ -710,6 +730,7 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
|
|||
|
||||
switch (aWidgetType) {
|
||||
case NS_THEME_BUTTON:
|
||||
case NS_THEME_BUTTON_FOCUS:
|
||||
case NS_THEME_RADIO:
|
||||
case NS_THEME_CHECKBOX:
|
||||
case NS_THEME_TOOLBOX: // N/A
|
||||
|
|
|
@ -59,6 +59,11 @@ public:
|
|||
NS_IMETHOD GetWidgetBorder(nsIDeviceContext* aContext, nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType, nsMargin* aResult);
|
||||
|
||||
virtual NS_HIDDEN_(PRBool) GetWidgetPadding(nsIDeviceContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType,
|
||||
nsMargin* aResult);
|
||||
|
||||
NS_IMETHOD GetMinimumWidgetSize(nsIRenderingContext* aContext,
|
||||
nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
nsSize* aResult, PRBool* aIsOverridable);
|
||||
|
|
|
@ -346,10 +346,14 @@ moz_gtk_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
|||
{
|
||||
GtkShadowType shadow_type;
|
||||
GtkStyle* style = widget->style;
|
||||
gint default_spacing = 7; /* xxx fix me */
|
||||
GtkStateType button_state = ConvertGtkState(state);
|
||||
gint x = rect->x, y=rect->y, width=rect->width, height=rect->height;
|
||||
|
||||
gboolean interior_focus;
|
||||
gint focus_width, focus_pad;
|
||||
|
||||
moz_gtk_button_get_focus(&interior_focus, &focus_width, &focus_pad);
|
||||
|
||||
if (WINDOW_IS_MAPPED(drawable)) {
|
||||
gdk_window_set_back_pixmap(drawable, NULL, TRUE);
|
||||
gdk_window_clear_area(drawable, cliprect->x, cliprect->y,
|
||||
|
@ -358,6 +362,8 @@ moz_gtk_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
|||
|
||||
gtk_widget_set_state(widget, button_state);
|
||||
|
||||
/*
|
||||
* XXX fix this code when we have default state working.
|
||||
if (state->isDefault) {
|
||||
TSOffsetStyleGCs(style, x, y);
|
||||
gtk_paint_box(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
|
||||
|
@ -374,12 +380,13 @@ moz_gtk_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
|||
x += (1 + default_spacing) / 2;
|
||||
y += (1 + default_spacing) / 2;
|
||||
}
|
||||
|
||||
if (state->focused) {
|
||||
x += 1;
|
||||
y += 1;
|
||||
width -= 2;
|
||||
height -= 2;
|
||||
*/
|
||||
|
||||
if (!interior_focus && state->focused) {
|
||||
x += focus_width + focus_pad;
|
||||
y += focus_width + focus_pad;
|
||||
width -= 2 * (focus_width + focus_pad);
|
||||
height -= 2 * (focus_width + focus_pad);
|
||||
}
|
||||
|
||||
shadow_type = button_state == GTK_STATE_ACTIVE ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
|
||||
|
@ -395,11 +402,18 @@ moz_gtk_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
|||
}
|
||||
|
||||
if (state->focused) {
|
||||
x -= 1;
|
||||
y -= 1;
|
||||
width += 2;
|
||||
height += 2;
|
||||
|
||||
if (interior_focus) {
|
||||
x += widget->style->xthickness + focus_pad;
|
||||
y += widget->style->ythickness + focus_pad;
|
||||
width -= 2 * (widget->style->xthickness + focus_pad);
|
||||
height -= 2 * (widget->style->ythickness + focus_pad);
|
||||
} else {
|
||||
x -= focus_width + focus_pad;
|
||||
y -= focus_width + focus_pad;
|
||||
width += 2 * (focus_width + focus_pad);
|
||||
height += 2 * (focus_width + focus_pad);
|
||||
}
|
||||
|
||||
TSOffsetStyleGCs(style, x, y);
|
||||
gtk_paint_focus(style, drawable, button_state, cliprect,
|
||||
widget, "button", x, y, width, height);
|
||||
|
@ -470,6 +484,21 @@ moz_gtk_radio_get_focus(gboolean* interior_focus,
|
|||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
||||
gint
|
||||
moz_gtk_button_get_focus(gboolean* interior_focus,
|
||||
gint* focus_width, gint* focus_pad)
|
||||
{
|
||||
ensure_button_widget();
|
||||
|
||||
gtk_widget_style_get (gButtonWidget,
|
||||
"interior-focus", interior_focus,
|
||||
"focus-line-width", focus_width,
|
||||
"focus-padding", focus_pad,
|
||||
NULL);
|
||||
|
||||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
||||
static gint
|
||||
moz_gtk_option_menu_get_metrics(gboolean* interior_focus,
|
||||
GtkRequisition* indicator_size,
|
||||
|
@ -1270,9 +1299,26 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* xthickness,
|
|||
|
||||
switch (widget) {
|
||||
case MOZ_GTK_BUTTON:
|
||||
ensure_button_widget();
|
||||
w = gButtonWidget;
|
||||
break;
|
||||
{
|
||||
/* Constant in gtkbutton.c */
|
||||
static const gint child_spacing = 1;
|
||||
gboolean interior_focus;
|
||||
gint focus_width, focus_pad;
|
||||
|
||||
ensure_button_widget();
|
||||
|
||||
moz_gtk_button_get_focus(&interior_focus,
|
||||
&focus_width, &focus_pad);
|
||||
|
||||
*xthickness = *ythickness =
|
||||
GTK_CONTAINER(gButtonWidget)->border_width + child_spacing
|
||||
+ focus_width + focus_pad;
|
||||
|
||||
*xthickness += gButtonWidget->style->xthickness;
|
||||
*ythickness += gButtonWidget->style->ythickness;
|
||||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
||||
case MOZ_GTK_TOOLBAR:
|
||||
ensure_toolbar_widget();
|
||||
w = gToolbarWidget;
|
||||
|
|
|
@ -228,7 +228,7 @@ moz_gtk_checkbox_get_metrics(gint* indicator_size, gint* indicator_spacing);
|
|||
gint
|
||||
moz_gtk_radio_get_metrics(gint* indicator_size, gint* indicator_spacing);
|
||||
|
||||
/** Get the focus metrics for a checkbox or radio button
|
||||
/** Get the focus metrics for a button, checkbox, or radio button.
|
||||
* interior_focus: [OUT] whether the focus is drawn around the
|
||||
* label (TRUE) or around the whole container (FALSE)
|
||||
* focus_width: [OUT] the width of the focus line
|
||||
|
@ -237,6 +237,9 @@ moz_gtk_radio_get_metrics(gint* indicator_size, gint* indicator_spacing);
|
|||
* returns: MOZ_GTK_SUCCESS if there was no error, an error code otherwise
|
||||
*/
|
||||
gint
|
||||
moz_gtk_button_get_focus(gboolean* interior_focus,
|
||||
gint* focus_width, gint* focus_pad);
|
||||
gint
|
||||
moz_gtk_checkbox_get_focus(gboolean* interior_focus,
|
||||
gint* focus_width, gint* focus_pad);
|
||||
gint
|
||||
|
|
|
@ -123,14 +123,8 @@ GetPrimaryPresShell(nsIFrame* aFrame)
|
|||
if (!aFrame)
|
||||
return nsnull;
|
||||
|
||||
nsIPresShell *shell = nsnull;
|
||||
|
||||
nsIDocument* doc = aFrame->GetContent()->GetDocument();
|
||||
if (doc) {
|
||||
shell = doc->GetShellAt(0);
|
||||
}
|
||||
|
||||
return shell;
|
||||
nsPresContext *context = aFrame->GetPresContext();
|
||||
return context ? context->GetPresShell() : nsnull;
|
||||
}
|
||||
|
||||
static void RefreshWidgetWindow(nsIFrame* aFrame)
|
||||
|
@ -337,6 +331,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(PRUint8 aWidgetType, nsIFrame* aFrame,
|
|||
switch (aWidgetType) {
|
||||
case NS_THEME_BUTTON:
|
||||
case NS_THEME_TOOLBAR_BUTTON:
|
||||
case NS_THEME_TOOLBAR_DUAL_BUTTON:
|
||||
if (aWidgetFlags)
|
||||
*aWidgetFlags = (aWidgetType == NS_THEME_BUTTON) ? GTK_RELIEF_NORMAL : GTK_RELIEF_NONE;
|
||||
aGtkWidgetType = MOZ_GTK_BUTTON;
|
||||
|
@ -543,6 +538,14 @@ nsNativeThemeGTK::GetWidgetBorder(nsIDeviceContext* aContext, nsIFrame* aFrame,
|
|||
// gtk's 'toolbar' for purposes of painting the widget background,
|
||||
// we don't use the toolbar border for toolbox.
|
||||
break;
|
||||
case NS_THEME_TOOLBAR_DUAL_BUTTON:
|
||||
// TOOLBAR_DUAL_BUTTON is an interesting case. We want a border to draw
|
||||
// around the entire button + dropdown, and also an inner border if you're
|
||||
// over the button part. But, we want the inner button to be right up
|
||||
// against the edge of the outer button so that the borders overlap.
|
||||
// To make this happen, we draw a button border for the outer button,
|
||||
// but don't reserve any space for it.
|
||||
break;
|
||||
default:
|
||||
{
|
||||
GtkThemeWidgetType gtkWidgetType;
|
||||
|
@ -559,6 +562,21 @@ nsNativeThemeGTK::GetWidgetBorder(nsIDeviceContext* aContext, nsIFrame* aFrame,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsNativeThemeGTK::GetWidgetPadding(nsIDeviceContext* aContext,
|
||||
nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
nsMargin* aResult)
|
||||
{
|
||||
if (aWidgetType == NS_THEME_BUTTON_FOCUS ||
|
||||
aWidgetType == NS_THEME_TOOLBAR_BUTTON ||
|
||||
aWidgetType == NS_THEME_TOOLBAR_DUAL_BUTTON) {
|
||||
aResult->SizeTo(0, 0, 0, 0);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeThemeGTK::GetMinimumWidgetSize(nsIRenderingContext* aContext,
|
||||
nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
|
@ -626,6 +644,8 @@ nsNativeThemeGTK::GetMinimumWidgetSize(nsIRenderingContext* aContext,
|
|||
case NS_THEME_RADIO_CONTAINER:
|
||||
case NS_THEME_CHECKBOX_LABEL:
|
||||
case NS_THEME_RADIO_LABEL:
|
||||
case NS_THEME_BUTTON:
|
||||
case NS_THEME_TOOLBAR_BUTTON:
|
||||
{
|
||||
// Just include our border, and let the box code augment the size.
|
||||
|
||||
|
@ -710,6 +730,7 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext,
|
|||
|
||||
switch (aWidgetType) {
|
||||
case NS_THEME_BUTTON:
|
||||
case NS_THEME_BUTTON_FOCUS:
|
||||
case NS_THEME_RADIO:
|
||||
case NS_THEME_CHECKBOX:
|
||||
case NS_THEME_TOOLBOX: // N/A
|
||||
|
|
|
@ -59,6 +59,11 @@ public:
|
|||
NS_IMETHOD GetWidgetBorder(nsIDeviceContext* aContext, nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType, nsMargin* aResult);
|
||||
|
||||
virtual NS_HIDDEN_(PRBool) GetWidgetPadding(nsIDeviceContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType,
|
||||
nsMargin* aResult);
|
||||
|
||||
NS_IMETHOD GetMinimumWidgetSize(nsIRenderingContext* aContext,
|
||||
nsIFrame* aFrame, PRUint8 aWidgetType,
|
||||
nsSize* aResult, PRBool* aIsOverridable);
|
||||
|
|
|
@ -535,6 +535,14 @@ nsNativeThemeMac::GetWidgetBorder(nsIDeviceContext* aContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsNativeThemeMac::GetWidgetPadding(nsIDeviceContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType,
|
||||
nsMargin* aResult)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeThemeMac::GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
|
||||
|
|
|
@ -63,6 +63,12 @@ public:
|
|||
nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType,
|
||||
nsMargin* aResult);
|
||||
|
||||
virtual PRBool GetWidgetPadding(nsIDeviceContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType,
|
||||
nsMargin* aResult);
|
||||
|
||||
NS_IMETHOD GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType,
|
||||
nsSize* aResult, PRBool* aIsOverridable);
|
||||
|
|
|
@ -777,6 +777,15 @@ nsNativeThemeWin::GetWidgetBorder(nsIDeviceContext* aContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsNativeThemeWin::GetWidgetPadding(nsIDeviceContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType,
|
||||
nsMargin* aResult)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeThemeWin::GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType,
|
||||
|
|
|
@ -60,6 +60,11 @@ public:
|
|||
PRUint8 aWidgetType,
|
||||
nsMargin* aResult);
|
||||
|
||||
virtual PRBool GetWidgetPadding(nsIDeviceContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType,
|
||||
nsMargin* aResult);
|
||||
|
||||
NS_IMETHOD GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame,
|
||||
PRUint8 aWidgetType,
|
||||
nsSize* aResult,
|
||||
|
|
Загрузка…
Ссылка в новой задаче