mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 316748 - "[RTL] [GTK] dropdown arrow is on the wrong side" [p=twanno@lycos.nl (Teune van Steeg) r+sr=roc a1.9=schrep]
This commit is contained in:
parent
71fe589716
commit
08d82cdca1
@ -1173,7 +1173,8 @@ moz_gtk_expander_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
|
||||
static gint
|
||||
moz_gtk_option_menu_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
GdkRectangle* cliprect, GtkWidgetState* state)
|
||||
GdkRectangle* cliprect, GtkWidgetState* state,
|
||||
GtkTextDirection direction)
|
||||
{
|
||||
GtkStyle* style;
|
||||
GtkStateType state_type = ConvertGtkState(state);
|
||||
@ -1186,6 +1187,7 @@ moz_gtk_option_menu_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
gint focus_pad;
|
||||
|
||||
ensure_option_menu_widget();
|
||||
gtk_widget_set_direction(gOptionMenuWidget, direction);
|
||||
moz_gtk_option_menu_get_metrics(&interior_focus, &indicator_size,
|
||||
&indicator_spacing, &focus_width,
|
||||
&focus_pad);
|
||||
@ -1204,7 +1206,7 @@ moz_gtk_option_menu_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
cliprect, gOptionMenuWidget, "optionmenu",
|
||||
x, y, width, height);
|
||||
|
||||
if (gtk_widget_get_direction(gOptionMenuWidget) == GTK_TEXT_DIR_RTL) {
|
||||
if (direction == GTK_TEXT_DIR_RTL) {
|
||||
tab_x = x + indicator_spacing.right + XTHICKNESS(style);
|
||||
} else {
|
||||
tab_x = x + width - indicator_size.width - indicator_spacing.right -
|
||||
@ -1585,14 +1587,14 @@ moz_gtk_tab_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
gboolean before_selected = ((flags & MOZ_GTK_TAB_BEFORE_SELECTED)!=0);
|
||||
cliprect->y -= 2;
|
||||
cliprect->height += 2;
|
||||
rect->y -= 2 * before_selected;
|
||||
rect->x += rect->width - 2;
|
||||
|
||||
TSOffsetStyleGCs(style, rect->x + rect->width - 2,
|
||||
rect->y - (2 * before_selected));
|
||||
TSOffsetStyleGCs(style, rect->x, rect->y);
|
||||
|
||||
gtk_paint_extension(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
|
||||
cliprect, gTabWidget, "tab",
|
||||
rect->x + rect->width - 2,
|
||||
rect->y - (2 * before_selected), rect->width,
|
||||
rect->x, rect->y, rect->width,
|
||||
rect->height + (2 * before_selected),
|
||||
GTK_POS_BOTTOM);
|
||||
}
|
||||
@ -1741,21 +1743,20 @@ moz_gtk_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
|
||||
static gint
|
||||
moz_gtk_menu_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
GdkRectangle* cliprect, GtkWidgetState* state)
|
||||
GdkRectangle* cliprect, GtkWidgetState* state,
|
||||
GtkTextDirection direction)
|
||||
{
|
||||
GtkStyle* style;
|
||||
GtkTextDirection chromedir;
|
||||
GtkStateType state_type = ConvertGtkState(state);
|
||||
|
||||
ensure_menu_item_widget();
|
||||
style = gMenuItemWidget->style;
|
||||
chromedir = gtk_widget_get_direction(gMenuItemWidget);
|
||||
|
||||
TSOffsetStyleGCs(style, rect->x, rect->y);
|
||||
gtk_paint_arrow(style, drawable, state_type,
|
||||
(state_type == GTK_STATE_PRELIGHT) ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
|
||||
cliprect, gMenuItemWidget, "menuitem",
|
||||
(chromedir == GTK_TEXT_DIR_LTR) ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT,
|
||||
(direction == GTK_TEXT_DIR_LTR) ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT,
|
||||
TRUE, rect->x, rect->y, rect->width, rect->height);
|
||||
|
||||
return MOZ_GTK_SUCCESS;
|
||||
@ -1764,7 +1765,8 @@ moz_gtk_menu_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
static gint
|
||||
moz_gtk_check_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
GdkRectangle* cliprect, GtkWidgetState* state,
|
||||
gboolean checked, gboolean isradio)
|
||||
gboolean checked, GtkTextDirection direction,
|
||||
gboolean isradio)
|
||||
{
|
||||
GtkStateType state_type = ConvertGtkState(state);
|
||||
GtkStyle* style;
|
||||
@ -1772,9 +1774,9 @@ moz_gtk_check_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
gint offset;
|
||||
gint indicator_size;
|
||||
gint x, y;
|
||||
|
||||
|
||||
moz_gtk_menu_item_paint(drawable, rect, cliprect, state, FALSE);
|
||||
|
||||
|
||||
ensure_check_menu_item_widget();
|
||||
|
||||
gtk_widget_style_get (gCheckMenuItemWidget,
|
||||
@ -1783,20 +1785,21 @@ moz_gtk_check_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
|
||||
if (checked || GTK_CHECK_MENU_ITEM(gCheckMenuItemWidget)->always_show_toggle) {
|
||||
style = gCheckMenuItemWidget->style;
|
||||
|
||||
offset = GTK_CONTAINER(gCheckMenuItemWidget)->border_width +
|
||||
|
||||
offset = GTK_CONTAINER(gCheckMenuItemWidget)->border_width +
|
||||
gCheckMenuItemWidget->style->xthickness + 2;
|
||||
|
||||
/* while normally this "3" would be the horizontal-padding style value, passing it to Gecko
|
||||
as the value of menuitem padding causes problems with dropdowns (bug 406129), so in the menu.css
|
||||
file this is hardcoded as 3px. Yes it sucks, but we don't really have a choice. */
|
||||
x = rect->x + offset + 3;
|
||||
x = (direction == GTK_TEXT_DIR_RTL) ?
|
||||
rect->width - indicator_size - offset - 3: rect->x + offset + 3;
|
||||
y = rect->y + (rect->height - indicator_size) / 2;
|
||||
|
||||
|
||||
TSOffsetStyleGCs(style, x, y);
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gCheckMenuItemWidget),
|
||||
checked);
|
||||
|
||||
|
||||
if (isradio) {
|
||||
gtk_paint_option(style, drawable, state_type, shadow_type, cliprect,
|
||||
gCheckMenuItemWidget, "option",
|
||||
@ -1807,7 +1810,7 @@ moz_gtk_check_menu_item_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
x, y, indicator_size, indicator_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return MOZ_GTK_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1830,7 +1833,8 @@ moz_gtk_window_paint(GdkDrawable* drawable, GdkRectangle* rect,
|
||||
|
||||
gint
|
||||
moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
|
||||
gint* right, gint* bottom, gboolean inhtml)
|
||||
gint* right, gint* bottom, GtkTextDirection direction,
|
||||
gboolean inhtml)
|
||||
{
|
||||
GtkWidget* w;
|
||||
|
||||
@ -1925,7 +1929,7 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
|
||||
moz_gtk_option_menu_get_metrics(&interior_focus, &indicator_size,
|
||||
&indicator_spacing, &focus_width, &focus_pad);
|
||||
|
||||
if (gtk_widget_get_direction(gOptionMenuWidget) == GTK_TEXT_DIR_RTL)
|
||||
if (direction == GTK_TEXT_DIR_RTL)
|
||||
*left += indicator_spacing.left + indicator_size.width + indicator_spacing.right;
|
||||
else
|
||||
*right += indicator_spacing.left + indicator_size.width + indicator_spacing.right;
|
||||
@ -2189,7 +2193,7 @@ moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics)
|
||||
gint
|
||||
moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
|
||||
GdkRectangle* rect, GdkRectangle* cliprect,
|
||||
GtkWidgetState* state, gint flags)
|
||||
GtkWidgetState* state, gint flags, GtkTextDirection direction)
|
||||
{
|
||||
switch (widget) {
|
||||
case MOZ_GTK_BUTTON:
|
||||
@ -2255,7 +2259,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
|
||||
return moz_gtk_entry_paint(drawable, rect, cliprect, state);
|
||||
break;
|
||||
case MOZ_GTK_DROPDOWN:
|
||||
return moz_gtk_option_menu_paint(drawable, rect, cliprect, state);
|
||||
return moz_gtk_option_menu_paint(drawable, rect, cliprect, state, direction);
|
||||
break;
|
||||
case MOZ_GTK_DROPDOWN_ARROW:
|
||||
return moz_gtk_dropdown_arrow_paint(drawable, rect, cliprect, state);
|
||||
@ -2310,12 +2314,12 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
|
||||
return moz_gtk_menu_item_paint(drawable, rect, cliprect, state, flags);
|
||||
break;
|
||||
case MOZ_GTK_MENUARROW:
|
||||
return moz_gtk_menu_arrow_paint(drawable, rect, cliprect, state);
|
||||
return moz_gtk_menu_arrow_paint(drawable, rect, cliprect, state, direction);
|
||||
break;
|
||||
case MOZ_GTK_CHECKMENUITEM:
|
||||
case MOZ_GTK_RADIOMENUITEM:
|
||||
return moz_gtk_check_menu_item_paint(drawable, rect, cliprect, state,
|
||||
(gboolean) flags,
|
||||
(gboolean) flags, direction,
|
||||
(widget == MOZ_GTK_RADIOMENUITEM));
|
||||
break;
|
||||
case MOZ_GTK_WINDOW:
|
||||
|
@ -218,16 +218,18 @@ gint moz_gtk_shutdown();
|
||||
/*** Widget drawing ***/
|
||||
/**
|
||||
* Paint a widget in the current theme.
|
||||
* widget: a constant giving the widget to paint
|
||||
* rect: the bounding rectangle for the widget
|
||||
* cliprect: a clipprect rectangle for this painting operation
|
||||
* state: the state of the widget. ignored for some widgets.
|
||||
* flags: widget-dependant flags; see the GtkThemeWidgetType definition.
|
||||
* widget: a constant giving the widget to paint
|
||||
* rect: the bounding rectangle for the widget
|
||||
* cliprect: a clipprect rectangle for this painting operation
|
||||
* state: the state of the widget. ignored for some widgets.
|
||||
* flags: widget-dependant flags; see the GtkThemeWidgetType definition.
|
||||
* direction: the text direction, to draw the widget correctly LTR and RTL.
|
||||
*/
|
||||
gint
|
||||
moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
|
||||
GdkRectangle* rect, GdkRectangle* cliprect,
|
||||
GtkWidgetState* state, gint flags);
|
||||
GtkWidgetState* state, gint flags,
|
||||
GtkTextDirection direction);
|
||||
|
||||
|
||||
/*** Widget metrics ***/
|
||||
@ -235,13 +237,15 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
|
||||
* Get the border size of a widget
|
||||
* left/right: [OUT] the widget's left/right border
|
||||
* top/bottom: [OUT] the widget's top/bottom border
|
||||
* direction: the text direction for the widget
|
||||
* inhtml: boolean indicating whether this widget will be drawn as a HTML form control,
|
||||
* in order to workaround a size issue (MOZ_GTK_BUTTON only, ignored otherwise)
|
||||
*
|
||||
* returns: MOZ_GTK_SUCCESS if there was no error, an error code otherwise
|
||||
*/
|
||||
gint moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
|
||||
gint* right, gint* bottom, gboolean inhtml);
|
||||
gint* right, gint* bottom, GtkTextDirection direction,
|
||||
gboolean inhtml);
|
||||
|
||||
/**
|
||||
* Get the desired size of a GtkCheckButton
|
||||
|
@ -164,6 +164,21 @@ static void SetWidgetStateSafe(PRUint8 *aSafeVector,
|
||||
aSafeVector[key >> 3] |= (1 << (key & 7));
|
||||
}
|
||||
|
||||
static GtkTextDirection GetTextDirection(nsIFrame* aFrame)
|
||||
{
|
||||
if (!aFrame)
|
||||
return GTK_TEXT_DIR_NONE;
|
||||
|
||||
switch (aFrame->GetStyleVisibility()->mDirection) {
|
||||
case NS_STYLE_DIRECTION_RTL:
|
||||
return GTK_TEXT_DIR_RTL;
|
||||
case NS_STYLE_DIRECTION_LTR:
|
||||
return GTK_TEXT_DIR_LTR;
|
||||
}
|
||||
|
||||
return GTK_TEXT_DIR_NONE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsNativeThemeGTK::GetGtkWidgetAndState(PRUint8 aWidgetType, nsIFrame* aFrame,
|
||||
GtkThemeWidgetType& aGtkWidgetType,
|
||||
@ -536,10 +551,10 @@ NativeThemeErrorHandler(Display* dpy, XErrorEvent* error) {
|
||||
class ThemeRenderer : public gfxXlibNativeRenderer {
|
||||
public:
|
||||
ThemeRenderer(GtkWidgetState aState, GtkThemeWidgetType aGTKWidgetType,
|
||||
gint aFlags, const GdkRectangle& aGDKRect,
|
||||
const GdkRectangle& aGDKClip)
|
||||
gint aFlags, GtkTextDirection aDirection,
|
||||
const GdkRectangle& aGDKRect, const GdkRectangle& aGDKClip)
|
||||
: mState(aState), mGTKWidgetType(aGTKWidgetType), mFlags(aFlags),
|
||||
mGDKRect(aGDKRect), mGDKClip(aGDKClip) {}
|
||||
mDirection(aDirection), mGDKRect(aGDKRect), mGDKClip(aGDKClip) {}
|
||||
nsresult NativeDraw(Display* dpy, Drawable drawable, Visual* visual,
|
||||
short offsetX, short offsetY,
|
||||
XRectangle* clipRects, PRUint32 numClipRects);
|
||||
@ -547,6 +562,7 @@ private:
|
||||
GtkWidgetState mState;
|
||||
GtkThemeWidgetType mGTKWidgetType;
|
||||
gint mFlags;
|
||||
GtkTextDirection mDirection;
|
||||
GdkWindow* mWindow;
|
||||
const GdkRectangle& mGDKRect;
|
||||
const GdkRectangle& mGDKClip;
|
||||
@ -589,7 +605,7 @@ ThemeRenderer::NativeDraw(Display* dpy, Drawable drawable, Visual* visual,
|
||||
|
||||
NS_ASSERTION(numClipRects == 0, "We don't support clipping!!!");
|
||||
moz_gtk_widget_paint(mGTKWidgetType, gdkPixmap, &gdk_rect, &gdk_clip, &mState,
|
||||
mFlags);
|
||||
mFlags, mDirection);
|
||||
|
||||
g_object_unref(G_OBJECT(gdkPixmap));
|
||||
return NS_OK;
|
||||
@ -655,6 +671,7 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext,
|
||||
{
|
||||
GtkWidgetState state;
|
||||
GtkThemeWidgetType gtkWidgetType;
|
||||
GtkTextDirection direction = GetTextDirection(aFrame);
|
||||
gint flags;
|
||||
if (!GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, &state,
|
||||
&flags))
|
||||
@ -712,7 +729,7 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext,
|
||||
gdk_rect = ConvertToGdkRect(aRect - drawingRect.TopLeft(), p2a);
|
||||
gdk_clip = ConvertToGdkRect(aClipRect - drawingRect.TopLeft(), p2a);
|
||||
}
|
||||
ThemeRenderer renderer(state, gtkWidgetType, flags, gdk_rect, gdk_clip);
|
||||
ThemeRenderer renderer(state, gtkWidgetType, flags, direction, gdk_rect, gdk_clip);
|
||||
|
||||
// XXXbz do we really want to round here, then snap, then round again?
|
||||
gfxRect rect(0, 0, NSAppUnitsToIntPixels(drawingRect.width, p2a),
|
||||
@ -792,10 +809,11 @@ nsNativeThemeGTK::GetWidgetBorder(nsIDeviceContext* aContext, nsIFrame* aFrame,
|
||||
default:
|
||||
{
|
||||
GtkThemeWidgetType gtkWidgetType;
|
||||
GtkTextDirection direction = GetTextDirection(aFrame);
|
||||
if (GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, nsnull,
|
||||
nsnull))
|
||||
moz_gtk_get_widget_border(gtkWidgetType, &aResult->left, &aResult->top,
|
||||
&aResult->right, &aResult->bottom,
|
||||
&aResult->right, &aResult->bottom, direction,
|
||||
(aFrame ? aFrame->GetContent()->IsNodeOfType(nsINode::eHTML) : FALSE));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user