firefox/widget-rebase.patch
2017-01-18 17:30:40 +01:00

2807 lines
111 KiB
Diff

diff -up firefox-51.0/widget/gtk/gtk3drawing.cpp.old firefox-51.0/widget/gtk/gtk3drawing.cpp
--- firefox-51.0/widget/gtk/gtk3drawing.cpp.old 2017-01-18 16:24:56.375732107 +0100
+++ firefox-51.0/widget/gtk/gtk3drawing.cpp 2017-01-10 11:28:15.000000000 +0100
@@ -18,16 +18,6 @@
#include <math.h>
-static GtkWidget* gProtoLayout;
-static GtkWidget* gComboBoxWidget;
-static GtkWidget* gComboBoxButtonWidget;
-static GtkWidget* gComboBoxArrowWidget;
-static GtkWidget* gComboBoxSeparatorWidget;
-static GtkWidget* gComboBoxEntryWidget;
-static GtkWidget* gComboBoxEntryTextareaWidget;
-static GtkWidget* gComboBoxEntryButtonWidget;
-static GtkWidget* gComboBoxEntryArrowWidget;
-
static style_prop_t style_prop_func;
static gboolean have_arrow_scaling;
static gboolean checkbox_check_state;
@@ -46,6 +36,10 @@ static gboolean is_initialized;
static gint
moz_gtk_get_tab_thickness(GtkStyleContext *style);
+static gint
+moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
+ GtkWidgetState* state, GtkTextDirection direction);
+
static GtkStateFlags
GetStateFlagsFromGtkWidgetState(GtkWidgetState* state)
{
@@ -79,212 +73,6 @@ moz_gtk_enable_style_props(style_prop_t
return MOZ_GTK_SUCCESS;
}
-static gint
-setup_widget_prototype(GtkWidget* widget)
-{
- if (!gProtoLayout) {
- gProtoLayout = GetWidget(MOZ_GTK_WINDOW_CONTAINER);
- }
- gtk_container_add(GTK_CONTAINER(gProtoLayout), widget);
- return MOZ_GTK_SUCCESS;
-}
-
-/* We need to have pointers to the inner widgets (button, separator, arrow)
- * of the ComboBox to get the correct rendering from theme engines which
- * special cases their look. Since the inner layout can change, we ask GTK
- * to NULL our pointers when they are about to become invalid because the
- * corresponding widgets don't exist anymore. It's the role of
- * g_object_add_weak_pointer().
- * Note that if we don't find the inner widgets (which shouldn't happen), we
- * fallback to use generic "non-inner" widgets, and they don't need that kind
- * of weak pointer since they are explicit children of gProtoLayout and as
- * such GTK holds a strong reference to them. */
-static void
-moz_gtk_get_combo_box_inner_button(GtkWidget *widget, gpointer client_data)
-{
- if (GTK_IS_TOGGLE_BUTTON(widget)) {
- gComboBoxButtonWidget = widget;
- g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer *) &gComboBoxButtonWidget);
- gtk_widget_realize(widget);
- }
-}
-
-static void
-moz_gtk_get_combo_box_button_inner_widgets(GtkWidget *widget,
- gpointer client_data)
-{
- if (GTK_IS_SEPARATOR(widget)) {
- gComboBoxSeparatorWidget = widget;
- g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer *) &gComboBoxSeparatorWidget);
- } else if (GTK_IS_ARROW(widget)) {
- gComboBoxArrowWidget = widget;
- g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer *) &gComboBoxArrowWidget);
- } else
- return;
- gtk_widget_realize(widget);
-}
-
-static gint
-ensure_combo_box_widgets()
-{
- GtkWidget* buttonChild;
-
- if (gComboBoxButtonWidget && gComboBoxArrowWidget)
- return MOZ_GTK_SUCCESS;
-
- /* Create a ComboBox if needed */
- if (!gComboBoxWidget) {
- gComboBoxWidget = gtk_combo_box_new();
- setup_widget_prototype(gComboBoxWidget);
- }
-
- /* Get its inner Button */
- gtk_container_forall(GTK_CONTAINER(gComboBoxWidget),
- moz_gtk_get_combo_box_inner_button,
- NULL);
-
- if (gComboBoxButtonWidget) {
- /* Get the widgets inside the Button */
- buttonChild = gtk_bin_get_child(GTK_BIN(gComboBoxButtonWidget));
- if (GTK_IS_BOX(buttonChild)) {
- /* appears-as-list = FALSE, cell-view = TRUE; the button
- * contains an hbox. This hbox is there because the ComboBox
- * needs to place a cell renderer, a separator, and an arrow in
- * the button when appears-as-list is FALSE. */
- gtk_container_forall(GTK_CONTAINER(buttonChild),
- moz_gtk_get_combo_box_button_inner_widgets,
- NULL);
- } else if(GTK_IS_ARROW(buttonChild)) {
- /* appears-as-list = TRUE, or cell-view = FALSE;
- * the button only contains an arrow */
- gComboBoxArrowWidget = buttonChild;
- g_object_add_weak_pointer(G_OBJECT(buttonChild), (gpointer *)
- &gComboBoxArrowWidget);
- gtk_widget_realize(gComboBoxArrowWidget);
- }
- } else {
- /* Shouldn't be reached with current internal gtk implementation; we
- * use a generic toggle button as last resort fallback to avoid
- * crashing. */
- gComboBoxButtonWidget = GetWidget(MOZ_GTK_TOGGLE_BUTTON);
- }
-
- if (!gComboBoxArrowWidget) {
- /* Shouldn't be reached with current internal gtk implementation;
- * we gButtonArrowWidget as last resort fallback to avoid
- * crashing. */
- gComboBoxArrowWidget = GetWidget(MOZ_GTK_BUTTON_ARROW);
- }
-
- /* We don't test the validity of gComboBoxSeparatorWidget since there
- * is none when "appears-as-list" = TRUE or "cell-view" = FALSE; if it
- * is invalid we just won't paint it. */
-
- return MOZ_GTK_SUCCESS;
-}
-
-/* We need to have pointers to the inner widgets (entry, button, arrow) of
- * the ComboBoxEntry to get the correct rendering from theme engines which
- * special cases their look. Since the inner layout can change, we ask GTK
- * to NULL our pointers when they are about to become invalid because the
- * corresponding widgets don't exist anymore. It's the role of
- * g_object_add_weak_pointer().
- * Note that if we don't find the inner widgets (which shouldn't happen), we
- * fallback to use generic "non-inner" widgets, and they don't need that kind
- * of weak pointer since they are explicit children of gProtoLayout and as
- * such GTK holds a strong reference to them. */
-static void
-moz_gtk_get_combo_box_entry_inner_widgets(GtkWidget *widget,
- gpointer client_data)
-{
- if (GTK_IS_TOGGLE_BUTTON(widget)) {
- gComboBoxEntryButtonWidget = widget;
- g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer *) &gComboBoxEntryButtonWidget);
- } else if (GTK_IS_ENTRY(widget)) {
- gComboBoxEntryTextareaWidget = widget;
- g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer *) &gComboBoxEntryTextareaWidget);
- } else
- return;
- gtk_widget_realize(widget);
-}
-
-static void
-moz_gtk_get_combo_box_entry_arrow(GtkWidget *widget, gpointer client_data)
-{
- if (GTK_IS_ARROW(widget)) {
- gComboBoxEntryArrowWidget = widget;
- g_object_add_weak_pointer(G_OBJECT(widget),
- (gpointer *) &gComboBoxEntryArrowWidget);
- gtk_widget_realize(widget);
- }
-}
-
-static gint
-ensure_combo_box_entry_widgets()
-{
- GtkWidget* buttonChild;
-
- if (gComboBoxEntryTextareaWidget &&
- gComboBoxEntryButtonWidget &&
- gComboBoxEntryArrowWidget)
- return MOZ_GTK_SUCCESS;
-
- /* Create a ComboBoxEntry if needed */
- if (!gComboBoxEntryWidget) {
- gComboBoxEntryWidget = gtk_combo_box_new_with_entry();
- setup_widget_prototype(gComboBoxEntryWidget);
- }
-
- /* Get its inner Entry and Button */
- gtk_container_forall(GTK_CONTAINER(gComboBoxEntryWidget),
- moz_gtk_get_combo_box_entry_inner_widgets,
- NULL);
-
- if (!gComboBoxEntryTextareaWidget) {
- gComboBoxEntryTextareaWidget = GetWidget(MOZ_GTK_ENTRY);
- }
-
- if (gComboBoxEntryButtonWidget) {
- /* Get the Arrow inside the Button */
- buttonChild = gtk_bin_get_child(GTK_BIN(gComboBoxEntryButtonWidget));
- if (GTK_IS_BOX(buttonChild)) {
- /* appears-as-list = FALSE, cell-view = TRUE; the button
- * contains an hbox. This hbox is there because the ComboBox
- * needs to place a cell renderer, a separator, and an arrow in
- * the button when appears-as-list is FALSE. */
- gtk_container_forall(GTK_CONTAINER(buttonChild),
- moz_gtk_get_combo_box_entry_arrow,
- NULL);
- } else if(GTK_IS_ARROW(buttonChild)) {
- /* appears-as-list = TRUE, or cell-view = FALSE;
- * the button only contains an arrow */
- gComboBoxEntryArrowWidget = buttonChild;
- g_object_add_weak_pointer(G_OBJECT(buttonChild), (gpointer *)
- &gComboBoxEntryArrowWidget);
- gtk_widget_realize(gComboBoxEntryArrowWidget);
- }
- } else {
- /* Shouldn't be reached with current internal gtk implementation;
- * we use a generic toggle button as last resort fallback to avoid
- * crashing. */
- gComboBoxEntryButtonWidget = GetWidget(MOZ_GTK_TOGGLE_BUTTON);
- }
-
- if (!gComboBoxEntryArrowWidget) {
- /* Shouldn't be reached with current internal gtk implementation;
- * we gButtonArrowWidget as last resort fallback to avoid
- * crashing. */
- gComboBoxEntryArrowWidget = GetWidget(MOZ_GTK_BUTTON_ARROW);
- }
-
- return MOZ_GTK_SUCCESS;
-}
-
gint
moz_gtk_init()
{
@@ -336,16 +124,24 @@ moz_gtk_radio_get_metrics(gint* indicato
return MOZ_GTK_SUCCESS;
}
-gint
-moz_gtk_get_focus_outline_size(gint* focus_h_width, gint* focus_v_width)
+static gint
+moz_gtk_get_focus_outline_size(GtkStyleContext* style,
+ gint* focus_h_width, gint* focus_v_width)
{
GtkBorder border;
GtkBorder padding;
- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_ENTRY);
gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
*focus_h_width = border.left + padding.left;
*focus_v_width = border.top + padding.top;
+ return MOZ_GTK_SUCCESS;
+}
+
+gint
+moz_gtk_get_focus_outline_size(gint* focus_h_width, gint* focus_v_width)
+{
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_ENTRY);
+ moz_gtk_get_focus_outline_size(style, focus_h_width, focus_v_width);
ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -364,7 +160,7 @@ moz_gtk_menuitem_get_horizontal_padding(
gint
moz_gtk_checkmenuitem_get_horizontal_padding(gint* horizontal_padding)
{
- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_CHECKMENUITEM_CONTAINER);
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_CHECKMENUITEM);
gtk_style_context_get_style(style,
"horizontal-padding", horizontal_padding,
nullptr);
@@ -636,8 +432,66 @@ calculate_arrow_rect(GtkWidget* arrow, G
return MOZ_GTK_SUCCESS;
}
+void
+moz_gtk_get_widget_min_size(WidgetNodeType aGtkWidgetType, int* width,
+ int* height)
+{
+ GtkStyleContext* style = ClaimStyleContext(aGtkWidgetType);
+ GtkStateFlags state_flags = gtk_style_context_get_state(style);
+ gtk_style_context_get(style, state_flags,
+ "min-height", height,
+ "min-width", width,
+ nullptr);
+
+ GtkBorder border, padding, margin;
+ gtk_style_context_get_border(style, state_flags, &border);
+ gtk_style_context_get_padding(style, state_flags, &padding);
+ gtk_style_context_get_margin(style, state_flags, &margin);
+ ReleaseStyleContext(style);
+
+ *width += border.left + border.right + margin.left + margin.right +
+ padding.left + padding.right;
+ *height += border.top + border.bottom + margin.top + margin.bottom +
+ padding.top + padding.bottom;
+}
+
+static void
+Inset(GdkRectangle* rect, GtkBorder& aBorder)
+{
+ MOZ_ASSERT(rect);
+ rect->x += aBorder.left;
+ rect->y += aBorder.top;
+ rect->width -= aBorder.left + aBorder.right;
+ rect->height -= aBorder.top + aBorder.bottom;
+}
+
+// Inset a rectangle by the margins specified in a style context.
+static void
+InsetByMargin(GdkRectangle* rect, GtkStyleContext* style)
+{
+ MOZ_ASSERT(rect);
+ GtkBorder margin;
+
+ gtk_style_context_get_margin(style, gtk_style_context_get_state(style),
+ &margin);
+ Inset(rect, margin);
+}
+
+// Inset a rectangle by the border and padding specified in a style context.
+static void
+InsetByBorderPadding(GdkRectangle* rect, GtkStyleContext* style)
+{
+ GtkStateFlags state = gtk_style_context_get_state(style);
+ GtkBorder padding, border;
+
+ gtk_style_context_get_padding(style, state, &padding);
+ Inset(rect, padding);
+ gtk_style_context_get_border(style, state, &border);
+ Inset(rect, border);
+}
+
static gint
-moz_gtk_scrollbar_button_paint(cairo_t *cr, GdkRectangle* rect,
+moz_gtk_scrollbar_button_paint(cairo_t *cr, const GdkRectangle* aRect,
GtkWidgetState* state,
GtkScrollbarButtonFlags flags,
GtkTextDirection direction)
@@ -675,32 +529,38 @@ moz_gtk_scrollbar_button_paint(cairo_t *
gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOP);
}
- /* Scrollbar button has to be inset by trough_border because its DOM element
- * is filling width of vertical scrollbar's track (or height in case
- * of horizontal scrollbars). */
-
- MozGtkScrollbarMetrics metrics;
- moz_gtk_get_scrollbar_metrics(&metrics);
- if (flags & MOZ_GTK_STEPPER_VERTICAL) {
- rect->x += metrics.trough_border;
- rect->width = metrics.slider_width;
+ GdkRectangle rect = *aRect;
+ if (gtk_check_version(3,20,0) == nullptr) {
+ // The "trough-border" is not used since GTK 3.20. The stepper margin
+ // box occupies the full width of the "contents" gadget content box.
+ InsetByMargin(&rect, style);
} else {
- rect->y += metrics.trough_border;
- rect->height = metrics.slider_width;
+ // Scrollbar button has to be inset by trough_border because its DOM
+ // element is filling width of vertical scrollbar's track (or height
+ // in case of horizontal scrollbars).
+ MozGtkScrollbarMetrics metrics;
+ moz_gtk_get_scrollbar_metrics(&metrics);
+ if (flags & MOZ_GTK_STEPPER_VERTICAL) {
+ rect.x += metrics.trough_border;
+ rect.width = metrics.slider_width;
+ } else {
+ rect.y += metrics.trough_border;
+ rect.height = metrics.slider_width;
+ }
}
- gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
- gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
+ gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height);
- arrow_rect.width = rect->width / 2;
- arrow_rect.height = rect->height / 2;
+ arrow_rect.width = rect.width / 2;
+ arrow_rect.height = rect.height / 2;
gfloat arrow_scaling;
gtk_style_context_get_style(style, "arrow-scaling", &arrow_scaling, NULL);
- gdouble arrow_size = MIN(rect->width, rect->height) * arrow_scaling;
- arrow_rect.x = rect->x + (rect->width - arrow_size) / 2;
- arrow_rect.y = rect->y + (rect->height - arrow_size) / 2;
+ gdouble arrow_size = MIN(rect.width, rect.height) * arrow_scaling;
+ arrow_rect.x = rect.x + (rect.width - arrow_size) / 2;
+ arrow_rect.y = rect.y + (rect.height - arrow_size) / 2;
if (state_flags & GTK_STATE_FLAG_ACTIVE) {
gtk_style_context_get_style(style,
@@ -742,19 +602,23 @@ moz_gtk_update_scrollbar_style(GtkStyleC
static void
moz_gtk_draw_styled_frame(GtkStyleContext* style, cairo_t *cr,
- GdkRectangle* rect, bool drawFocus)
+ const GdkRectangle* aRect, bool drawFocus)
{
- gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
- gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
+ GdkRectangle rect = *aRect;
+ if (gtk_check_version(3, 6, 0) == nullptr) {
+ InsetByMargin(&rect, style);
+ }
+ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
+ gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height);
if (drawFocus) {
gtk_render_focus(style, cr,
- rect->x, rect->y, rect->width, rect->height);
+ rect.x, rect.y, rect.width, rect.height);
}
}
static gint
moz_gtk_scrollbar_trough_paint(WidgetNodeType widget,
- cairo_t *cr, GdkRectangle* rect,
+ cairo_t *cr, const GdkRectangle* rect,
GtkWidgetState* state,
GtkScrollbarTrackFlags flags,
GtkTextDirection direction)
@@ -766,26 +630,28 @@ moz_gtk_scrollbar_trough_paint(WidgetNod
ReleaseStyleContext(style);
}
- bool isHorizontal = (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL);
- GtkStyleContext* style;
+ GtkStyleContext* style = ClaimStyleContext(widget, direction);
+ moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
+ ReleaseStyleContext(style);
- // Draw all child CSS Nodes for Gtk >= 3.20
- if (gtk_check_version(3, 20, 0) == nullptr) {
- style = ClaimStyleContext(widget, direction);
- moz_gtk_update_scrollbar_style(style, widget, direction);
- moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
- ReleaseStyleContext(style);
+ return MOZ_GTK_SUCCESS;
+}
- style = ClaimStyleContext(isHorizontal ?
- MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL :
- MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL,
- direction);
- moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
- ReleaseStyleContext(style);
- }
- style = ClaimStyleContext(isHorizontal ?
- MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL :
- MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL,
+static gint
+moz_gtk_scrollbar_paint(WidgetNodeType widget,
+ cairo_t *cr, const GdkRectangle* rect,
+ GtkWidgetState* state,
+ GtkTextDirection direction)
+{
+ GtkStyleContext* style = ClaimStyleContext(widget, direction);
+ moz_gtk_update_scrollbar_style(style, widget, direction);
+
+ moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
+
+ ReleaseStyleContext(style);
+ style = ClaimStyleContext((widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) ?
+ MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL :
+ MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL,
direction);
moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
ReleaseStyleContext(style);
@@ -795,21 +661,21 @@ moz_gtk_scrollbar_trough_paint(WidgetNod
static gint
moz_gtk_scrollbar_thumb_paint(WidgetNodeType widget,
- cairo_t *cr, GdkRectangle* rect,
+ cairo_t *cr, const GdkRectangle* aRect,
GtkWidgetState* state,
GtkTextDirection direction)
{
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
- GtkBorder margin;
+ GdkRectangle rect = *aRect;
GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags);
- gtk_style_context_get_margin (style, state_flags, &margin);
+ InsetByMargin(&rect, style);
gtk_render_slider(style, cr,
- rect->x + margin.left,
- rect->y + margin.top,
- rect->width - margin.left - margin.right,
- rect->height - margin.top - margin.bottom,
+ rect.x,
+ rect.y,
+ rect.width,
+ rect.height,
(widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) ?
GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL);
@@ -980,65 +846,31 @@ moz_gtk_vpaned_paint(cairo_t *cr, GdkRec
static gint
moz_gtk_entry_paint(cairo_t *cr, GdkRectangle* rect,
GtkWidgetState* state,
- GtkWidget* widget, GtkTextDirection direction)
+ GtkStyleContext* style)
{
gint x = rect->x, y = rect->y, width = rect->width, height = rect->height;
- GtkStyleContext* style;
int draw_focus_outline_only = state->depressed; // NS_THEME_FOCUS_OUTLINE
- gtk_widget_set_direction(widget, direction);
-
- style = gtk_widget_get_style_context(widget);
-
if (draw_focus_outline_only) {
// Inflate the given 'rect' with the focus outline size.
gint h, v;
- moz_gtk_get_focus_outline_size(&h, &v);
+ moz_gtk_get_focus_outline_size(style, &h, &v);
rect->x -= h;
rect->width += 2 * h;
rect->y -= v;
rect->height += 2 * v;
width = rect->width;
height = rect->height;
- }
-
- /* gtkentry.c uses two windows, one for the entire widget and one for the
- * text area inside it. The background of both windows is set to the "base"
- * color of the new state in gtk_entry_state_changed, but only the inner
- * textarea window uses gtk_paint_flat_box when exposed */
-
- /* This gets us a lovely greyish disabledish look */
- gtk_widget_set_sensitive(widget, !state->disabled);
-
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_ENTRY);
-
- /* Now paint the shadow and focus border.
- * We do like in gtk_entry_draw_frame, we first draw the shadow, a tad
- * smaller when focused if the focus is not interior, then the focus. */
-
- if (state->focused && !state->disabled) {
- /* This will get us the lit borders that focused textboxes enjoy on
- * some themes. */
- gtk_style_context_set_state(style, GTK_STATE_FLAG_FOCUSED);
- }
-
- if (state->disabled) {
- gtk_style_context_set_state(style, GTK_STATE_FLAG_INSENSITIVE);
- }
-
- if (!draw_focus_outline_only) {
+ } else {
gtk_render_background(style, cr, x, y, width, height);
}
gtk_render_frame(style, cr, x, y, width, height);
- gtk_style_context_restore(style);
-
return MOZ_GTK_SUCCESS;
}
static gint
-moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect,
+moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* aRect,
GtkWidgetState* state,
GtkTextDirection direction)
{
@@ -1046,24 +878,29 @@ moz_gtk_text_view_paint(cairo_t *cr, Gdk
GtkStyleContext* style_frame =
ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction, state_flags);
- gtk_render_frame(style_frame, cr, rect->x, rect->y, rect->width, rect->height);
+ gtk_render_frame(style_frame, cr,
+ aRect->x, aRect->y, aRect->width, aRect->height);
+
+ GdkRectangle rect = *aRect;
+ InsetByBorderPadding(&rect, style_frame);
- GtkBorder border, padding;
- gtk_style_context_get_border(style_frame, state_flags, &border);
- gtk_style_context_get_padding(style_frame, state_flags, &padding);
ReleaseStyleContext(style_frame);
GtkStyleContext* style =
ClaimStyleContext(MOZ_GTK_TEXT_VIEW, direction, state_flags);
-
- gint xthickness = border.left + padding.left;
- gint ythickness = border.top + padding.top;
-
- gtk_render_background(style, cr,
- rect->x + xthickness, rect->y + ythickness,
- rect->width - 2 * xthickness,
- rect->height - 2 * ythickness);
-
+ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
+ ReleaseStyleContext(style);
+ // There is a separate "text" window, which usually provides the
+ // background behind the text. However, this is transparent in Ambiance
+ // for GTK 3.20, in which case the MOZ_GTK_TEXT_VIEW background is
+ // visible.
+ // Workaround for Bug 1328899 - We don't want "selected" background color
+ // for active view class here which is set by Ambiance theme.
+ if (state->focused && !state->disabled) {
+ state_flags = static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED);
+ }
+ style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT, direction, state_flags);
+ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
@@ -1198,34 +1035,37 @@ moz_gtk_combo_box_paint(cairo_t *cr, Gdk
GtkStyleContext* style;
GtkRequisition arrow_req;
- ensure_combo_box_widgets();
+ GtkWidget* comboBoxButton = GetWidget(MOZ_GTK_COMBOBOX_BUTTON);
+ GtkWidget* comboBoxArrow = GetWidget(MOZ_GTK_COMBOBOX_ARROW);
/* Also sets the direction on gComboBoxButtonWidget, which is then
* inherited by the separator and arrow */
moz_gtk_button_paint(cr, rect, state, GTK_RELIEF_NORMAL,
- gComboBoxButtonWidget, direction);
+ comboBoxButton, direction);
- calculate_button_inner_rect(gComboBoxButtonWidget,
- rect, &arrow_rect, direction);
+ calculate_button_inner_rect(comboBoxButton, rect, &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(gComboBoxArrowWidget, NULL, &arrow_req);
+ gtk_widget_get_preferred_size(comboBoxArrow, NULL, &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(gComboBoxArrowWidget,
+ calculate_arrow_rect(comboBoxArrow,
&arrow_rect, &real_arrow_rect, direction);
- style = gtk_widget_get_style_context(gComboBoxArrowWidget);
+ style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ARROW);
gtk_render_arrow(style, cr, ARROW_DOWN,
real_arrow_rect.x, real_arrow_rect.y,
real_arrow_rect.width);
+ ReleaseStyleContext(style);
/* If there is no separator in the theme, there's nothing left to do. */
- if (!gComboBoxSeparatorWidget)
+ GtkWidget* widget = GetWidget(MOZ_GTK_COMBOBOX_SEPARATOR);
+ if (!widget)
return MOZ_GTK_SUCCESS;
- style = gtk_widget_get_style_context(gComboBoxSeparatorWidget);
+ style = gtk_widget_get_style_context(widget);
gtk_style_context_get_style(style,
"wide-separators", &wide_separators,
"separator-width", &separator_width,
@@ -1309,15 +1149,14 @@ moz_gtk_combo_box_entry_button_paint(cai
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
GtkStyleContext* style;
- ensure_combo_box_entry_widgets();
-
+ GtkWidget* comboBoxEntry = GetWidget(MOZ_GTK_COMBOBOX_ENTRY_BUTTON);
moz_gtk_button_paint(cr, rect, state, GTK_RELIEF_NORMAL,
- gComboBoxEntryButtonWidget, direction);
+ comboBoxEntry, direction);
+ calculate_button_inner_rect(comboBoxEntry, rect, &arrow_rect, direction);
- calculate_button_inner_rect(gComboBoxEntryButtonWidget,
- rect, &arrow_rect, direction);
if (state_flags & GTK_STATE_FLAG_ACTIVE) {
- gtk_style_context_get_style(gtk_widget_get_style_context(gComboBoxEntryButtonWidget),
+ style = gtk_widget_get_style_context(comboBoxEntry);
+ gtk_style_context_get_style(style,
"child-displacement-x", &x_displacement,
"child-displacement-y", &y_displacement,
NULL);
@@ -1325,15 +1164,14 @@ moz_gtk_combo_box_entry_button_paint(cai
arrow_rect.y += y_displacement;
}
- calculate_arrow_rect(gComboBoxEntryArrowWidget,
+ calculate_arrow_rect(GetWidget(MOZ_GTK_COMBOBOX_ENTRY_ARROW),
&arrow_rect, &real_arrow_rect, direction);
- style = gtk_widget_get_style_context(gComboBoxEntryArrowWidget);
-
+ style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ENTRY_ARROW);
gtk_render_arrow(style, cr, ARROW_DOWN,
real_arrow_rect.x, real_arrow_rect.y,
real_arrow_rect.width);
-
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1353,7 +1191,6 @@ moz_gtk_container_paint(cairo_t *cr, Gdk
}
ReleaseStyleContext(style);
-
return MOZ_GTK_SUCCESS;
}
@@ -1439,13 +1276,52 @@ moz_gtk_toolbar_separator_paint(cairo_t
}
static gint
-moz_gtk_tooltip_paint(cairo_t *cr, GdkRectangle* rect,
+moz_gtk_tooltip_paint(cairo_t *cr, const GdkRectangle* aRect,
GtkTextDirection direction)
{
+ // Tooltip widget is made in GTK3 as following tree:
+ // Tooltip window
+ // Horizontal Box
+ // Icon (not supported by Firefox)
+ // Label
+ // Each element can be fully styled by CSS of GTK theme.
+ // We have to draw all elements with appropriate offset and right dimensions.
+
+ // Tooltip drawing
GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLTIP, direction);
- gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
- gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
- ReleaseStyleContext(style);
+ GdkRectangle rect = *aRect;
+ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
+ gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height);
+ ReleaseStyleContext(style);
+
+ // Horizontal Box drawing
+ //
+ // The box element has hard-coded 6px margin-* GtkWidget properties, which
+ // are added between the window dimensions and the CSS margin box of the
+ // horizontal box. The frame of the tooltip window is drawn in the
+ // 6px margin.
+ // For drawing Horizontal Box we have to inset drawing area by that 6px
+ // plus its CSS margin.
+ GtkStyleContext* boxStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX, direction);
+
+ rect.x += 6;
+ rect.y += 6;
+ rect.width -= 12;
+ rect.height -= 12;
+
+ InsetByMargin(&rect, boxStyle);
+ gtk_render_background(boxStyle, cr, rect.x, rect.y, rect.width, rect.height);
+ gtk_render_frame(boxStyle, cr, rect.x, rect.y, rect.width, rect.height);
+
+ // Label drawing
+ InsetByBorderPadding(&rect, boxStyle);
+ ReleaseStyleContext(boxStyle);
+
+ GtkStyleContext* labelStyle =
+ ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL, direction);
+ moz_gtk_draw_styled_frame(labelStyle, cr, &rect, false);
+ ReleaseStyleContext(labelStyle);
+
return MOZ_GTK_SUCCESS;
}
@@ -1454,17 +1330,9 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRe
GtkWidgetState* state,
GtkTextDirection direction)
{
- GtkStyleContext* style;
-
- // gtk_render_handle() draws a background, so use GtkTextView and its
- // GTK_STYLE_CLASS_VIEW to match the background with textarea elements.
- // The resizer is drawn with shaded variants of the background color, and
- // so a transparent background would lead to a transparent resizer.
- style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW, GTK_TEXT_DIR_LTR,
- GetStateFlagsFromGtkWidgetState(state));
- // TODO - we need to save/restore style when gtk 3.20 CSS node path
- // is used
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
+ GtkStyleContext* style =
+ ClaimStyleContext(MOZ_GTK_RESIZER, GTK_TEXT_DIR_LTR,
+ GetStateFlagsFromGtkWidgetState(state));
// Workaround unico not respecting the text direction for resizers.
// See bug 1174248.
@@ -1511,17 +1379,8 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
GtkTextDirection direction,
WidgetNodeType widget)
{
- GtkStyleContext* style;
-
- if (gtk_check_version(3, 20, 0) != nullptr) {
- /* Ask for MOZ_GTK_PROGRESS_TROUGH instead of MOZ_GTK_PROGRESSBAR
- * because ClaimStyleContext() saves/restores that style */
- style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH, direction);
- gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR);
- } else {
- style = ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction);
- }
+ GtkStyleContext* style =
+ ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction);
if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
@@ -1905,6 +1764,13 @@ static gint
moz_gtk_menu_separator_paint(cairo_t *cr, GdkRectangle* rect,
GtkTextDirection direction)
{
+ GtkWidgetState defaultState = { 0 };
+ moz_gtk_menu_item_paint(MOZ_GTK_MENUSEPARATOR, cr, rect,
+ &defaultState, direction);
+
+ if (gtk_get_minor_version() >= 20)
+ return MOZ_GTK_SUCCESS;
+
GtkStyleContext* style;
gboolean wide_separators;
gint separator_height;
@@ -1952,36 +1818,39 @@ moz_gtk_menu_item_paint(WidgetNodeType w
GtkWidgetState* state, GtkTextDirection direction)
{
gint x, y, w, h;
+ guint minorVersion = gtk_get_minor_version();
+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
- if (state->inHover && !state->disabled) {
- GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
- GtkStyleContext* style =
- ClaimStyleContext(widget, direction, state_flags);
-
- bool pre_3_6 = gtk_check_version(3, 6, 0) != nullptr;
- if (pre_3_6) {
- // GTK+ 3.4 saves the style context and adds the menubar class to
- // menubar children, but does each of these only when drawing, not
- // during layout.
- gtk_style_context_save(style);
- if (widget == MOZ_GTK_MENUBARITEM) {
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
- }
+ // GTK versions prior to 3.8 render the background and frame only when not
+ // a separator and in hover prelight.
+ if (minorVersion < 8 && (widget == MOZ_GTK_MENUSEPARATOR ||
+ !(state_flags & GTK_STATE_FLAG_PRELIGHT)))
+ return MOZ_GTK_SUCCESS;
+
+ GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags);
+
+ if (minorVersion < 6) {
+ // GTK+ 3.4 saves the style context and adds the menubar class to
+ // menubar children, but does each of these only when drawing, not
+ // during layout.
+ gtk_style_context_save(style);
+ if (widget == MOZ_GTK_MENUBARITEM) {
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
}
+ }
- x = rect->x;
- y = rect->y;
- w = rect->width;
- h = rect->height;
+ x = rect->x;
+ y = rect->y;
+ w = rect->width;
+ h = rect->height;
- gtk_render_background(style, cr, x, y, w, h);
- gtk_render_frame(style, cr, x, y, w, h);
+ gtk_render_background(style, cr, x, y, w, h);
+ gtk_render_frame(style, cr, x, y, w, h);
- if (pre_3_6) {
- gtk_style_context_restore(style);
- }
- ReleaseStyleContext(style);
+ if (minorVersion < 6) {
+ gtk_style_context_restore(style);
}
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -2001,16 +1870,16 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd
return MOZ_GTK_SUCCESS;
}
-// See gtk_real_check_menu_item_draw_indicator() for reference.
+// For reference, see gtk_check_menu_item_size_allocate() in GTK versions after
+// 3.20 and gtk_real_check_menu_item_draw_indicator() in earlier versions.
static gint
-moz_gtk_check_menu_item_paint(cairo_t *cr, GdkRectangle* rect,
+moz_gtk_check_menu_item_paint(WidgetNodeType widgetType,
+ cairo_t *cr, GdkRectangle* rect,
GtkWidgetState* state,
- gboolean checked, gboolean isradio,
- GtkTextDirection direction)
+ gboolean checked, GtkTextDirection direction)
{
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
GtkStyleContext* style;
- GtkBorder padding;
gint indicator_size, horizontal_padding;
gint x, y;
@@ -2020,35 +1889,44 @@ moz_gtk_check_menu_item_paint(cairo_t *c
state_flags = static_cast<GtkStateFlags>(state_flags|checkbox_check_state);
}
- style = ClaimStyleContext(isradio ? MOZ_GTK_RADIOMENUITEM_CONTAINER :
- MOZ_GTK_CHECKMENUITEM_CONTAINER,
- direction);
+ bool pre_3_20 = gtk_get_minor_version() < 20;
+ gint offset;
+ style = ClaimStyleContext(widgetType, direction);
gtk_style_context_get_style(style,
"indicator-size", &indicator_size,
"horizontal-padding", &horizontal_padding,
NULL);
+ if (pre_3_20) {
+ GtkBorder padding;
+ gtk_style_context_get_padding(style, state_flags, &padding);
+ offset = horizontal_padding + padding.left + 2;
+ } else {
+ GdkRectangle r = { 0 };
+ InsetByMargin(&r, style);
+ InsetByBorderPadding(&r, style);
+ offset = r.x;
+ }
ReleaseStyleContext(style);
- style = ClaimStyleContext(isradio ? MOZ_GTK_RADIOMENUITEM :
- MOZ_GTK_CHECKMENUITEM,
- direction, state_flags);
- gtk_style_context_get_padding(style, state_flags, &padding);
- gint offset = padding.left + 2;
+ bool isRadio = (widgetType == MOZ_GTK_RADIOMENUITEM);
+ WidgetNodeType indicatorType = isRadio ? MOZ_GTK_RADIOMENUITEM_INDICATOR
+ : MOZ_GTK_CHECKMENUITEM_INDICATOR;
+ style = ClaimStyleContext(indicatorType, direction, state_flags);
if (direction == GTK_TEXT_DIR_RTL) {
- x = rect->width - indicator_size - offset - horizontal_padding;
+ x = rect->width - indicator_size - offset;
}
else {
- x = rect->x + offset + horizontal_padding;
+ x = rect->x + offset;
}
y = rect->y + (rect->height - indicator_size) / 2;
- if (gtk_check_version(3, 20, 0) == nullptr) {
+ 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);
}
- if (isradio) {
+ if (isRadio) {
gtk_render_option(style, cr, x, y, indicator_size, indicator_size);
} else {
gtk_render_check(style, cr, x, y, indicator_size, indicator_size);
@@ -2074,6 +1952,20 @@ moz_gtk_info_bar_paint(cairo_t *cr, GdkR
}
static void
+moz_gtk_add_style_margin(GtkStyleContext* style,
+ gint* left, gint* top, gint* right, gint* bottom)
+{
+ GtkBorder margin;
+
+ gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &margin);
+
+ *left += margin.left;
+ *right += margin.right;
+ *top += margin.top;
+ *bottom += margin.bottom;
+}
+
+static void
moz_gtk_add_style_border(GtkStyleContext* style,
gint* left, gint* top, gint* right, gint* bottom)
{
@@ -2101,6 +1993,15 @@ moz_gtk_add_style_padding(GtkStyleContex
*bottom += padding.bottom;
}
+static void moz_gtk_add_margin_border_padding(GtkStyleContext *style,
+ gint* left, gint* top,
+ gint* right, gint* bottom)
+{
+ moz_gtk_add_style_margin(style, left, top, right, bottom);
+ moz_gtk_add_style_border(style, left, top, right, bottom);
+ moz_gtk_add_style_padding(style, left, top, right, bottom);
+}
+
gint
moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
gint* right, gint* bottom, GtkTextDirection direction,
@@ -2129,9 +2030,6 @@ moz_gtk_get_widget_border(WidgetNodeType
if (widget == MOZ_GTK_TOOLBAR_BUTTON)
gtk_style_context_restore(style);
- // XXX: Subtract 1 pixel from the border to account for the added
- // -moz-focus-inner border (Bug 1228281).
- *left -= 1; *top -= 1; *right -= 1; *bottom -= 1;
moz_gtk_add_style_border(style, left, top, right, bottom);
ReleaseStyleContext(style);
@@ -2179,12 +2077,10 @@ moz_gtk_get_widget_border(WidgetNodeType
w = GetWidget(MOZ_GTK_TREE_HEADER_SORTARROW);
break;
case MOZ_GTK_DROPDOWN_ENTRY:
- ensure_combo_box_entry_widgets();
- w = gComboBoxEntryTextareaWidget;
+ w = GetWidget(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA);
break;
case MOZ_GTK_DROPDOWN_ARROW:
- ensure_combo_box_entry_widgets();
- w = gComboBoxEntryButtonWidget;
+ w = GetWidget(MOZ_GTK_COMBOBOX_ENTRY_BUTTON);
break;
case MOZ_GTK_DROPDOWN:
{
@@ -2196,32 +2092,33 @@ moz_gtk_get_widget_border(WidgetNodeType
GtkRequisition arrow_req;
GtkBorder border;
- ensure_combo_box_widgets();
-
- *left = *top = *right = *bottom =
- gtk_container_get_border_width(GTK_CONTAINER(gComboBoxButtonWidget));
-
- style = gtk_widget_get_style_context(gComboBoxButtonWidget);
-
+ *left = *top = *right = *bottom =
+ gtk_container_get_border_width(GTK_CONTAINER(
+ GetWidget(MOZ_GTK_COMBOBOX_BUTTON)));
+ style = ClaimStyleContext(MOZ_GTK_COMBOBOX_BUTTON);
moz_gtk_add_style_padding(style, left, top, right, bottom);
moz_gtk_add_style_border(style, left, top, right, bottom);
+ ReleaseStyleContext(style);
/* If there is no separator, don't try to count its width. */
separator_width = 0;
- if (gComboBoxSeparatorWidget) {
- style = gtk_widget_get_style_context(gComboBoxSeparatorWidget);
+ 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_STATE_FLAG_NORMAL, &border);
+ gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL,
+ &border);
separator_width = border.left;
}
}
- gtk_widget_get_preferred_size(gComboBoxArrowWidget, NULL, &arrow_req);
+ gtk_widget_get_preferred_size(GetWidget(MOZ_GTK_COMBOBOX_ARROW),
+ NULL, &arrow_req);
if (direction == GTK_TEXT_DIR_RTL)
*left += separator_width + arrow_req.width;
@@ -2271,12 +2168,15 @@ moz_gtk_get_widget_border(WidgetNodeType
{
// Bug 1274143 for MOZ_GTK_MENUBARITEM
WidgetNodeType type =
- widget == MOZ_GTK_MENUBARITEM || widget == MOZ_GTK_MENUITEM ?
- MOZ_GTK_MENUITEM : MOZ_GTK_CHECKMENUITEM_CONTAINER;
+ widget == MOZ_GTK_MENUBARITEM ? MOZ_GTK_MENUITEM : widget;
style = ClaimStyleContext(type);
- moz_gtk_add_style_padding(style, left, top, right, bottom);
-
+ if (gtk_get_minor_version() < 20) {
+ moz_gtk_add_style_padding(style, left, top, right, bottom);
+ } else {
+ moz_gtk_add_margin_border_padding(style,
+ left, top, right, bottom);
+ }
ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -2285,12 +2185,81 @@ moz_gtk_get_widget_border(WidgetNodeType
break;
case MOZ_GTK_TOOLTIP:
{
- style = ClaimStyleContext(MOZ_GTK_TOOLTIP);
- moz_gtk_add_style_border(style, left, top, right, bottom);
- moz_gtk_add_style_padding(style, left, top, right, bottom);
- ReleaseStyleContext(style);
+ // In GTK 3 there are 6 pixels of additional margin around the box.
+ // See details there:
+ // https://github.com/GNOME/gtk/blob/5ea69a136bd7e4970b3a800390e20314665aaed2/gtk/ui/gtktooltipwindow.ui#L11
+ *left = *right = *top = *bottom = 6;
+
+ // We also need to add margin/padding/borders from Tooltip content.
+ // Tooltip contains horizontal box, where icon and label is put.
+ // We ignore icon as long as we don't have support for it.
+ GtkStyleContext* boxStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX);
+ moz_gtk_add_margin_border_padding(boxStyle,
+ left, top, right, bottom);
+ ReleaseStyleContext(boxStyle);
+
+ GtkStyleContext* labelStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL);
+ moz_gtk_add_margin_border_padding(labelStyle,
+ left, top, right, bottom);
+ ReleaseStyleContext(labelStyle);
+
return MOZ_GTK_SUCCESS;
}
+ case MOZ_GTK_SCROLLBAR_VERTICAL:
+ case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL:
+ {
+ if (gtk_check_version(3,20,0) == nullptr) {
+ style = ClaimStyleContext(widget);
+ moz_gtk_add_margin_border_padding(style, left, top, right, bottom);
+ ReleaseStyleContext(style);
+ if (widget == MOZ_GTK_SCROLLBAR_VERTICAL) {
+ style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL);
+ moz_gtk_add_margin_border_padding(style, left, top, right, bottom);
+ ReleaseStyleContext(style);
+ }
+ } else {
+ MozGtkScrollbarMetrics metrics;
+ moz_gtk_get_scrollbar_metrics(&metrics);
+ /* Top and bottom border for whole vertical scrollbar, top and bottom
+ * border for horizontal track - to correctly position thumb element */
+ *top = *bottom = metrics.trough_border;
+ }
+ return MOZ_GTK_SUCCESS;
+ }
+ break;
+
+ case MOZ_GTK_SCROLLBAR_HORIZONTAL:
+ case MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL:
+ {
+ if (gtk_check_version(3,20,0) == nullptr) {
+ style = ClaimStyleContext(widget);
+ moz_gtk_add_margin_border_padding(style, left, top, right, bottom);
+ ReleaseStyleContext(style);
+ if (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) {
+ style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL);
+ moz_gtk_add_margin_border_padding(style, left, top, right, bottom);
+ ReleaseStyleContext(style);
+ }
+ } else {
+ MozGtkScrollbarMetrics metrics;
+ moz_gtk_get_scrollbar_metrics(&metrics);
+ *left = *right = metrics.trough_border;
+ }
+ return MOZ_GTK_SUCCESS;
+ }
+ break;
+
+ case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
+ case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL:
+ {
+ if (gtk_check_version(3,20,0) == nullptr) {
+ style = ClaimStyleContext(widget);
+ moz_gtk_add_margin_border_padding(style, left, top, right, bottom);
+ ReleaseStyleContext(style);
+ }
+ return MOZ_GTK_SUCCESS;
+ }
+ break;
/* These widgets have no borders, since they are not containers. */
case MOZ_GTK_CHECKBUTTON_LABEL:
case MOZ_GTK_RADIOBUTTON_LABEL:
@@ -2299,10 +2268,6 @@ moz_gtk_get_widget_border(WidgetNodeType
case MOZ_GTK_CHECKBUTTON:
case MOZ_GTK_RADIOBUTTON:
case MOZ_GTK_SCROLLBAR_BUTTON:
- case MOZ_GTK_SCROLLBAR_HORIZONTAL:
- case MOZ_GTK_SCROLLBAR_VERTICAL:
- case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
- case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL:
case MOZ_GTK_SCALE_THUMB_HORIZONTAL:
case MOZ_GTK_SCALE_THUMB_VERTICAL:
case MOZ_GTK_GRIPPER:
@@ -2390,9 +2355,9 @@ moz_gtk_get_combo_box_entry_button_size(
* as well as the minimum arrow size and its padding
* */
GtkRequisition requisition;
- ensure_combo_box_entry_widgets();
- gtk_widget_get_preferred_size(gComboBoxEntryButtonWidget, NULL, &requisition);
+ gtk_widget_get_preferred_size(GetWidget(MOZ_GTK_COMBOBOX_ENTRY_BUTTON),
+ NULL, &requisition);
*width = requisition.width;
*height = requisition.height;
@@ -2421,8 +2386,7 @@ moz_gtk_get_arrow_size(WidgetNodeType wi
GtkWidget* widget;
switch (widgetType) {
case MOZ_GTK_DROPDOWN:
- ensure_combo_box_widgets();
- widget = gComboBoxArrowWidget;
+ widget = GetWidget(MOZ_GTK_COMBOBOX_ARROW);
break;
default:
widget = GetWidget(MOZ_GTK_BUTTON_ARROW);
@@ -2588,6 +2552,9 @@ moz_gtk_get_scalethumb_metrics(GtkOrient
gint
moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics)
{
+ // For Gtk >= 3.20 scrollbar metrics are ignored
+ MOZ_ASSERT(gtk_check_version(3, 20, 0) != nullptr);
+
GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_VERTICAL);
gtk_style_context_get_style(style,
"slider_width", &metrics->slider_width,
@@ -2598,40 +2565,9 @@ moz_gtk_get_scrollbar_metrics(MozGtkScro
nullptr);
ReleaseStyleContext(style);
- if(!gtk_check_version(3, 20, 0)) {
- style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_THUMB_VERTICAL);
- gtk_style_context_get(style, gtk_style_context_get_state(style),
- "min-height", &metrics->min_slider_size, nullptr);
- ReleaseStyleContext(style);
- }
-
return MOZ_GTK_SUCCESS;
}
-gboolean
-moz_gtk_images_in_menus()
-{
- gboolean result;
- GtkSettings* settings;
-
- settings = gtk_widget_get_settings(GetWidget(MOZ_GTK_IMAGEMENUITEM));
-
- g_object_get(settings, "gtk-menu-images", &result, NULL);
- return result;
-}
-
-gboolean
-moz_gtk_images_in_buttons()
-{
- gboolean result;
- GtkSettings* settings;
-
- settings = gtk_widget_get_settings(GetWidget(MOZ_GTK_BUTTON));
-
- g_object_get(settings, "gtk-button-images", &result, NULL);
- return result;
-}
-
/* cairo_t *cr argument has to be a system-cairo. */
gint
moz_gtk_widget_paint(WidgetNodeType widget, cairo_t *cr,
@@ -2672,10 +2608,25 @@ moz_gtk_widget_paint(WidgetNodeType widg
break;
case MOZ_GTK_SCROLLBAR_HORIZONTAL:
case MOZ_GTK_SCROLLBAR_VERTICAL:
- return moz_gtk_scrollbar_trough_paint(widget, cr, rect,
- state,
- (GtkScrollbarTrackFlags) flags,
- direction);
+ if (gtk_check_version(3,20,0) == nullptr) {
+ return moz_gtk_scrollbar_paint(widget, cr, rect, state, direction);
+ } else {
+ WidgetNodeType trough_widget = (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) ?
+ MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL : MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL;
+ return moz_gtk_scrollbar_trough_paint(trough_widget, cr, rect,
+ state,
+ (GtkScrollbarTrackFlags) flags,
+ direction);
+ }
+ break;
+ case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL:
+ case MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL:
+ if (gtk_check_version(3,20,0) == nullptr) {
+ return moz_gtk_scrollbar_trough_paint(widget, cr, rect,
+ state,
+ (GtkScrollbarTrackFlags) flags,
+ direction);
+ }
break;
case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL:
@@ -2702,9 +2653,13 @@ moz_gtk_widget_paint(WidgetNodeType widg
state, direction);
break;
case MOZ_GTK_SPINBUTTON_ENTRY:
- // TODO - use MOZ_GTK_SPINBUTTON_ENTRY style directly
- return moz_gtk_entry_paint(cr, rect, state,
- GetWidget(MOZ_GTK_SPINBUTTON), direction);
+ {
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON_ENTRY,
+ direction, GetStateFlagsFromGtkWidgetState(state));
+ gint ret = moz_gtk_entry_paint(cr, rect, state, style);
+ ReleaseStyleContext(style);
+ return ret;
+ }
break;
case MOZ_GTK_GRIPPER:
return moz_gtk_gripper_paint(cr, rect, state,
@@ -2729,9 +2684,13 @@ moz_gtk_widget_paint(WidgetNodeType widg
(GtkExpanderStyle) flags, direction);
break;
case MOZ_GTK_ENTRY:
- return moz_gtk_entry_paint(cr, rect, state, GetWidget(MOZ_GTK_ENTRY),
- direction);
- break;
+ {
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_ENTRY,
+ direction, GetStateFlagsFromGtkWidgetState(state));
+ gint ret = moz_gtk_entry_paint(cr, rect, state, style);
+ ReleaseStyleContext(style);
+ return ret;
+ }
case MOZ_GTK_TEXT_VIEW:
return moz_gtk_text_view_paint(cr, rect, state, direction);
break;
@@ -2743,9 +2702,13 @@ moz_gtk_widget_paint(WidgetNodeType widg
state, flags, direction);
break;
case MOZ_GTK_DROPDOWN_ENTRY:
- ensure_combo_box_entry_widgets();
- return moz_gtk_entry_paint(cr, rect, state,
- gComboBoxEntryTextareaWidget, direction);
+ {
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA,
+ direction, GetStateFlagsFromGtkWidgetState(state));
+ gint ret = moz_gtk_entry_paint(cr, rect, state, style);
+ ReleaseStyleContext(style);
+ return ret;
+ }
break;
case MOZ_GTK_CHECKBUTTON_CONTAINER:
case MOZ_GTK_RADIOBUTTON_CONTAINER:
@@ -2819,10 +2782,8 @@ moz_gtk_widget_paint(WidgetNodeType widg
break;
case MOZ_GTK_CHECKMENUITEM:
case MOZ_GTK_RADIOMENUITEM:
- return moz_gtk_check_menu_item_paint(cr, rect, state,
- (gboolean) flags,
- (widget == MOZ_GTK_RADIOMENUITEM),
- direction);
+ return moz_gtk_check_menu_item_paint(widget, cr, rect, state,
+ (gboolean) flags, direction);
break;
case MOZ_GTK_SPLITTER_HORIZONTAL:
return moz_gtk_vpaned_paint(cr, rect, state);
@@ -2870,16 +2831,6 @@ moz_gtk_shutdown()
/* This will destroy all of our widgets */
ResetWidgetCache();
- gProtoLayout = NULL;
- gComboBoxWidget = NULL;
- gComboBoxButtonWidget = NULL;
- gComboBoxSeparatorWidget = NULL;
- gComboBoxArrowWidget = NULL;
- gComboBoxEntryWidget = NULL;
- gComboBoxEntryButtonWidget = NULL;
- gComboBoxEntryArrowWidget = NULL;
- gComboBoxEntryTextareaWidget = NULL;
-
is_initialized = FALSE;
return MOZ_GTK_SUCCESS;
diff -up firefox-51.0/widget/gtk/gtkdrawing.h.old firefox-51.0/widget/gtk/gtkdrawing.h
--- firefox-51.0/widget/gtk/gtkdrawing.h.old 2017-01-16 17:16:53.000000000 +0100
+++ firefox-51.0/widget/gtk/gtkdrawing.h 2017-01-06 10:20:43.000000000 +0100
@@ -145,8 +145,11 @@ typedef enum {
MOZ_GTK_ENTRY,
/* Paints a GtkExpander. */
MOZ_GTK_EXPANDER,
- /* Paints a GtkTextView. */
+ /* Paints a GtkTextView or gets the style context corresponding to the
+ root node of a GtkTextView. */
MOZ_GTK_TEXT_VIEW,
+ /* The "text" window or node of a GtkTextView */
+ MOZ_GTK_TEXT_VIEW_TEXT,
/* Paints a GtkOptionMenu. */
MOZ_GTK_DROPDOWN,
/* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */
@@ -160,11 +163,15 @@ typedef enum {
MOZ_GTK_TOOLBAR_SEPARATOR,
/* Paints a GtkToolTip */
MOZ_GTK_TOOLTIP,
+ /* Paints a GtkBox from GtkToolTip */
+ MOZ_GTK_TOOLTIP_BOX,
+ /* Paints a GtkLabel of GtkToolTip */
+ MOZ_GTK_TOOLTIP_BOX_LABEL,
/* Paints a GtkFrame (e.g. a status bar panel). */
MOZ_GTK_FRAME,
/* Paints the border of a GtkFrame */
MOZ_GTK_FRAME_BORDER,
- /* Paints a resize grip for a GtkWindow */
+ /* Paints a resize grip for a GtkTextView */
MOZ_GTK_RESIZER,
/* Paints a GtkProgressBar. */
MOZ_GTK_PROGRESSBAR,
@@ -210,11 +217,13 @@ typedef enum {
MOZ_GTK_MENUBARITEM,
/* Paints items of popup menus. */
MOZ_GTK_MENUITEM,
- MOZ_GTK_IMAGEMENUITEM,
- MOZ_GTK_CHECKMENUITEM_CONTAINER,
- MOZ_GTK_RADIOMENUITEM_CONTAINER,
+ /* Paints a menuitem with check indicator, or the gets the style context for
+ a menuitem that contains a checkbox. */
MOZ_GTK_CHECKMENUITEM,
+ /* Gets the style context for a checkbox in a check menuitem. */
+ MOZ_GTK_CHECKMENUITEM_INDICATOR,
MOZ_GTK_RADIOMENUITEM,
+ MOZ_GTK_RADIOMENUITEM_INDICATOR,
MOZ_GTK_MENUSEPARATOR,
/* GtkVPaned base class */
MOZ_GTK_SPLITTER_HORIZONTAL,
@@ -230,6 +239,22 @@ typedef enum {
MOZ_GTK_WINDOW_CONTAINER,
/* Paints a GtkInfoBar, for notifications. */
MOZ_GTK_INFO_BAR,
+ /* 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,
@@ -505,23 +530,18 @@ gint
moz_gtk_get_tab_thickness(WidgetNodeType aNodeType);
/**
- * Get a boolean which indicates whether or not to use images in menus.
- * If TRUE, use images in menus.
- */
-gboolean moz_gtk_images_in_menus(void);
-
-/**
- * Get a boolean which indicates whether or not to use images in buttons.
- * If TRUE, use images in buttons.
- */
-gboolean moz_gtk_images_in_buttons(void);
-
-/**
* Get a boolean which indicates whether the theme draws scrollbar buttons.
* If TRUE, draw scrollbar buttons.
*/
gboolean moz_gtk_has_scrollbar_buttons(void);
+/**
+ * Get minimum widget size as sum of margin, padding, border and min-width,
+ * min-height.
+ */
+void moz_gtk_get_widget_min_size(WidgetNodeType aGtkWidgetType, int* width,
+ int* height);
+
#if (MOZ_WIDGET_GTK == 2)
#ifdef __cplusplus
}
diff -up firefox-51.0/widget/gtk/mozgtk/mozgtk.c.old firefox-51.0/widget/gtk/mozgtk/mozgtk.c
--- firefox-51.0/widget/gtk/mozgtk/mozgtk.c.old 2017-01-18 16:26:11.416376760 +0100
+++ firefox-51.0/widget/gtk/mozgtk/mozgtk.c 2016-12-21 13:10:28.000000000 +0100
@@ -9,6 +9,7 @@ STUB(gdk_atom_name)
STUB(gdk_beep)
STUB(gdk_cairo_create)
STUB(gdk_color_free)
+STUB(gdk_color_parse)
STUB(gdk_cursor_new_for_display)
STUB(gdk_cursor_new_from_name)
STUB(gdk_cursor_new_from_pixbuf)
@@ -244,7 +245,6 @@ STUB(gtk_icon_theme_get_icon_sizes)
STUB(gtk_icon_theme_lookup_by_gicon)
STUB(gtk_icon_theme_lookup_icon)
STUB(gtk_image_get_type)
-STUB(gtk_image_menu_item_new)
STUB(gtk_image_new)
STUB(gtk_image_new_from_stock)
STUB(gtk_image_set_from_pixbuf)
@@ -577,10 +577,10 @@ STUB(gtk_tree_view_column_get_button)
STUB(gtk_widget_get_preferred_size)
STUB(gtk_widget_get_state_flags)
STUB(gtk_widget_get_style_context)
-STUB(gtk_widget_path_append_for_widget)
STUB(gtk_widget_path_append_type)
STUB(gtk_widget_path_copy)
STUB(gtk_widget_path_free)
+STUB(gtk_widget_path_iter_add_class)
STUB(gtk_widget_path_new)
STUB(gtk_widget_path_unref)
STUB(gtk_widget_set_visual)
@@ -612,6 +612,9 @@ STUB(gdkx_visual_get)
STUB(gtk_object_get_type)
#endif
+#ifndef GTK3_SYMBOLS
+// Only define the following workaround when using GTK3, which we detect
+// by checking if GTK3 stubs are not provided.
#include <X11/Xlib.h>
// Bug 1271100
// We need to trick system Cairo into not using the XShm extension due to
@@ -625,4 +628,5 @@ XShmQueryExtension(Display* aDisplay)
{
return False;
}
+#endif
diff -up firefox-51.0/widget/gtk/nsLookAndFeel.cpp.old firefox-51.0/widget/gtk/nsLookAndFeel.cpp
--- firefox-51.0/widget/gtk/nsLookAndFeel.cpp.old 2017-01-18 16:25:23.072605687 +0100
+++ firefox-51.0/widget/gtk/nsLookAndFeel.cpp 2017-01-06 10:20:43.000000000 +0100
@@ -47,9 +47,6 @@ nsLookAndFeel::nsLookAndFeel()
: nsXPLookAndFeel(),
#if (MOZ_WIDGET_GTK == 2)
mStyle(nullptr),
-#else
- mBackgroundStyle(nullptr),
- mButtonStyle(nullptr),
#endif
mDefaultFontCached(false), mButtonFontCached(false),
mFieldFontCached(false), mMenuFontCached(false)
@@ -61,13 +58,27 @@ nsLookAndFeel::~nsLookAndFeel()
{
#if (MOZ_WIDGET_GTK == 2)
g_object_unref(mStyle);
-#else
- g_object_unref(mBackgroundStyle);
- g_object_unref(mButtonStyle);
#endif
}
#if MOZ_WIDGET_GTK != 2
+// Modifies color |*aDest| as if a pattern of color |aSource| was painted with
+// CAIRO_OPERATOR_OVER to a surface with color |*aDest|.
+static void
+ApplyColorOver(const GdkRGBA& aSource, GdkRGBA* aDest) {
+ gdouble sourceCoef = aSource.alpha;
+ gdouble destCoef = aDest->alpha * (1.0 - sourceCoef);
+ gdouble resultAlpha = sourceCoef + destCoef;
+ if (resultAlpha != 0.0) { // don't divide by zero
+ destCoef /= resultAlpha;
+ sourceCoef /= resultAlpha;
+ aDest->red = sourceCoef * aSource.red + destCoef * aDest->red;
+ aDest->green = sourceCoef * aSource.green + destCoef * aDest->green;
+ aDest->blue = sourceCoef * aSource.blue + destCoef * aDest->blue;
+ aDest->alpha = resultAlpha;
+ }
+}
+
static void
GetLightAndDarkness(const GdkRGBA& aColor,
double* aLightness, double* aDarkness)
@@ -157,30 +168,55 @@ GetUnicoBorderGradientColors(GtkStyleCon
return result;
}
-
-static void
+// Sets |aLightColor| and |aDarkColor| to colors from |aContext|. Returns
+// true if |aContext| uses these colors to render a visible border.
+// If returning false, then the colors returned are a fallback from the
+// border-color value even though |aContext| does not use these colors to
+// render a border.
+static bool
GetBorderColors(GtkStyleContext* aContext,
GdkRGBA* aLightColor, GdkRGBA* aDarkColor)
{
- if (GetUnicoBorderGradientColors(aContext, aLightColor, aDarkColor))
- return;
-
+ // Determine whether the border on this style context is visible.
GtkStateFlags state = gtk_style_context_get_state(aContext);
+ GtkBorderStyle borderStyle;
+ gtk_style_context_get(aContext, state, GTK_STYLE_PROPERTY_BORDER_STYLE,
+ &borderStyle, nullptr);
+ bool visible = borderStyle != GTK_BORDER_STYLE_NONE &&
+ borderStyle != GTK_BORDER_STYLE_HIDDEN;
+ if (visible) {
+ // GTK has an initial value of zero for border-widths, and so themes
+ // need to explicitly set border-widths to make borders visible.
+ GtkBorder border;
+ gtk_style_context_get_border(aContext, GTK_STATE_FLAG_NORMAL, &border);
+ visible = border.top != 0 || border.right != 0 ||
+ border.bottom != 0 || border.left != 0;
+ }
+
+ if (visible &&
+ GetUnicoBorderGradientColors(aContext, aLightColor, aDarkColor))
+ return true;
+
+ // The initial value for the border-color is the foreground color, and so
+ // this will usually return a color distinct from the background even if
+ // there is no visible border detected.
gtk_style_context_get_border_color(aContext, state, aDarkColor);
// TODO GTK3 - update aLightColor
// for GTK_BORDER_STYLE_INSET/OUTSET/GROVE/RIDGE border styles.
// https://bugzilla.mozilla.org/show_bug.cgi?id=978172#c25
*aLightColor = *aDarkColor;
+ return visible;
}
-static void
+static bool
GetBorderColors(GtkStyleContext* aContext,
nscolor* aLightColor, nscolor* aDarkColor)
{
GdkRGBA lightColor, darkColor;
- GetBorderColors(aContext, &lightColor, &darkColor);
+ bool ret = GetBorderColors(aContext, &lightColor, &darkColor);
*aLightColor = GDK_RGBA_TO_NS_RGBA(lightColor);
*aDarkColor = GDK_RGBA_TO_NS_RGBA(darkColor);
+ return ret;
}
#endif
@@ -352,30 +388,39 @@ nsLookAndFeel::NativeGetColor(ColorID aI
break;
#else
// css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
- case eColorID_activeborder:
+ case eColorID_activeborder: {
// active window border
- gtk_style_context_get_border_color(mBackgroundStyle,
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
+ gtk_style_context_get_border_color(style,
GTK_STATE_FLAG_NORMAL, &gdk_color);
aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+ ReleaseStyleContext(style);
break;
- case eColorID_inactiveborder:
+ }
+ case eColorID_inactiveborder: {
// inactive window border
- gtk_style_context_get_border_color(mBackgroundStyle,
- GTK_STATE_FLAG_INSENSITIVE,
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
+ gtk_style_context_get_border_color(style,
+ GTK_STATE_FLAG_INSENSITIVE,
&gdk_color);
aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+ ReleaseStyleContext(style);
break;
+ }
case eColorID_graytext: // disabled text in windows, menus, etc.
case eColorID_inactivecaptiontext: // text in inactive window caption
aColor = sMenuTextInactive;
break;
- case eColorID_inactivecaption:
+ case eColorID_inactivecaption: {
// inactive window caption
- gtk_style_context_get_background_color(mBackgroundStyle,
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
+ gtk_style_context_get_background_color(style,
GTK_STATE_FLAG_INSENSITIVE,
&gdk_color);
aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+ ReleaseStyleContext(style);
break;
+ }
#endif
case eColorID_infobackground:
// tooltip background color
@@ -496,18 +541,24 @@ nsLookAndFeel::NativeGetColor(ColorID aI
case eColorID__moz_fieldtext:
aColor = sMozFieldText;
break;
- case eColorID__moz_buttondefault:
- // default button border color
- gtk_style_context_get_border_color(mButtonStyle,
+ case eColorID__moz_buttondefault: {
+ // default button border color
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
+ gtk_style_context_get_border_color(style,
GTK_STATE_FLAG_NORMAL, &gdk_color);
aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+ ReleaseStyleContext(style);
break;
- case eColorID__moz_buttonhoverface:
- gtk_style_context_get_background_color(mButtonStyle,
+ }
+ case eColorID__moz_buttonhoverface: {
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
+ gtk_style_context_get_background_color(style,
GTK_STATE_FLAG_PRELIGHT,
&gdk_color);
aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+ ReleaseStyleContext(style);
break;
+ }
case eColorID__moz_buttonhovertext:
aColor = sButtonHoverText;
break;
@@ -784,12 +835,6 @@ nsLookAndFeel::GetIntImpl(IntID aID, int
case eIntID_SpellCheckerUnderlineStyle:
aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY;
break;
- case eIntID_ImagesInMenus:
- aResult = moz_gtk_images_in_menus();
- break;
- case eIntID_ImagesInButtons:
- aResult = moz_gtk_images_in_buttons();
- break;
case eIntID_MenuBarDrag:
aResult = sMenuSupportsDrag;
break;
@@ -1010,16 +1055,6 @@ nsLookAndFeel::GetFontImpl(FontID aID, n
return true;
}
-#if (MOZ_WIDGET_GTK == 3)
-static GtkStyleContext*
-create_context(GtkWidgetPath *path)
-{
- GtkStyleContext *style = gtk_style_context_new();
- gtk_style_context_set_path(style, path);
- return(style);
-}
-#endif
-
void
nsLookAndFeel::Init()
{
@@ -1110,78 +1145,54 @@ nsLookAndFeel::Init()
g_object_set(settings, dark_setting, FALSE, nullptr);
}
- GtkWidgetPath *path = gtk_widget_path_new();
- gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);
-
- mBackgroundStyle = create_context(path);
- gtk_style_context_add_class(mBackgroundStyle, GTK_STYLE_CLASS_BACKGROUND);
-
- mButtonStyle = create_context(path);
- gtk_style_context_add_class(mButtonStyle, GTK_STYLE_CLASS_BUTTON);
-
// Scrollbar colors
- style = create_context(path);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCROLLBAR);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
+ style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color);
- g_object_unref(style);
+ ReleaseStyleContext(style);
// Window colors
- style = create_context(path);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
+ style = ClaimStyleContext(MOZ_GTK_WINDOW);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
- gtk_style_context_restore(style);
- g_object_unref(style);
+ ReleaseStyleContext(style);
// tooltip foreground and background
style = ClaimStyleContext(MOZ_GTK_TOOLTIP);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
sInfoBackground = GDK_RGBA_TO_NS_RGBA(color);
- {
- GtkStyleContext* boxStyle =
- CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0),
- style);
- GtkStyleContext* labelStyle =
- CreateStyleForWidget(gtk_label_new(nullptr), boxStyle);
- gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color);
- g_object_unref(labelStyle);
- g_object_unref(boxStyle);
- }
- sInfoText = GDK_RGBA_TO_NS_RGBA(color);
ReleaseStyleContext(style);
- // menu foreground & menu background
- GtkWidget *accel_label = gtk_accel_label_new("M");
- GtkWidget *menuitem = gtk_menu_item_new();
- GtkWidget *menu = gtk_menu_new();
-
- g_object_ref_sink(menu);
-
- gtk_container_add(GTK_CONTAINER(menuitem), accel_label);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-
- style = gtk_widget_get_style_context(accel_label);
+ style = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
- sMenuText = GDK_RGBA_TO_NS_RGBA(color);
- gtk_style_context_get_color(style, GTK_STATE_FLAG_INSENSITIVE, &color);
- sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color);
+ sInfoText = GDK_RGBA_TO_NS_RGBA(color);
+ ReleaseStyleContext(style);
- style = gtk_widget_get_style_context(menu);
+ style = ClaimStyleContext(MOZ_GTK_MENUITEM);
+ {
+ GtkStyleContext* accelStyle =
+ CreateStyleForWidget(gtk_accel_label_new("M"), style);
+ gtk_style_context_get_color(accelStyle, GTK_STATE_FLAG_NORMAL, &color);
+ sMenuText = GDK_RGBA_TO_NS_RGBA(color);
+ gtk_style_context_get_color(accelStyle, GTK_STATE_FLAG_INSENSITIVE, &color);
+ sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color);
+ g_object_unref(accelStyle);
+ }
+ ReleaseStyleContext(style);
+
+ style = ClaimStyleContext(MOZ_GTK_MENUPOPUP);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMenuBackground = GDK_RGBA_TO_NS_RGBA(color);
+ ReleaseStyleContext(style);
- style = gtk_widget_get_style_context(menuitem);
+ style = ClaimStyleContext(MOZ_GTK_MENUITEM);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
sMenuHover = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color);
-
- g_object_unref(menu);
+ ReleaseStyleContext(style);
#endif
// button styles
@@ -1192,9 +1203,6 @@ nsLookAndFeel::Init()
GtkWidget *combobox = gtk_combo_box_new();
GtkWidget *comboboxLabel = gtk_label_new("M");
gtk_container_add(GTK_CONTAINER(combobox), comboboxLabel);
-#else
- GtkWidget *combobox = gtk_combo_box_new_with_entry();
- GtkWidget *comboboxLabel = gtk_bin_get_child(GTK_BIN(combobox));
#endif
GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
GtkWidget *treeView = gtk_tree_view_new();
@@ -1208,7 +1216,9 @@ nsLookAndFeel::Init()
gtk_container_add(GTK_CONTAINER(parent), button);
gtk_container_add(GTK_CONTAINER(parent), treeView);
gtk_container_add(GTK_CONTAINER(parent), linkButton);
+#if (MOZ_WIDGET_GTK == 2)
gtk_container_add(GTK_CONTAINER(parent), combobox);
+#endif
gtk_container_add(GTK_CONTAINER(parent), menuBar);
gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), menuBarItem);
gtk_container_add(GTK_CONTAINER(window), parent);
@@ -1291,11 +1301,19 @@ nsLookAndFeel::Init()
}
#else
// Text colors
- style = gtk_widget_get_style_context(textView);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_VIEW);
- gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
- sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(color);
+ GdkRGBA bgColor;
+ // If the text window background is translucent, then the background of
+ // the textview root node is visible.
+ style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW);
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
+ &bgColor);
+ ReleaseStyleContext(style);
+
+ style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT);
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
+ &color);
+ ApplyColorOver(color, &bgColor);
+ sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(bgColor);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMozFieldText = GDK_RGBA_TO_NS_RGBA(color);
@@ -1308,26 +1326,34 @@ nsLookAndFeel::Init()
static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED),
&color);
sTextSelectedText = GDK_RGBA_TO_NS_RGBA(color);
- gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
- // Button text, background, border
- style = gtk_widget_get_style_context(label);
- gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
- sButtonText = GDK_RGBA_TO_NS_RGBA(color);
- gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
- sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color);
+ // Button text color
+ style = ClaimStyleContext(MOZ_GTK_BUTTON);
+ {
+ GtkStyleContext* labelStyle =
+ CreateStyleForWidget(gtk_label_new("M"), style);
+ gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color);
+ sButtonText = GDK_RGBA_TO_NS_RGBA(color);
+ gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_PRELIGHT, &color);
+ sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color);
+ g_object_unref(labelStyle);
+ }
+ ReleaseStyleContext(style);
// Combobox text color
- style = gtk_widget_get_style_context(comboboxLabel);
+ style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
sComboBoxText = GDK_RGBA_TO_NS_RGBA(color);
+ ReleaseStyleContext(style);
// Menubar text and hover text colors
- style = gtk_widget_get_style_context(menuBarItem);
+ style = ClaimStyleContext(MOZ_GTK_MENUBARITEM);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMenuBarText = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color);
+ ReleaseStyleContext(style);
// GTK's guide to fancy odd row background colors:
// 1) Check if a theme explicitly defines an odd row color
@@ -1335,7 +1361,7 @@ nsLookAndFeel::Init()
// slightly by a hardcoded value (gtkstyle.c)
// 3) If neither are defined, take the base background color and
// darken that by a hardcoded value
- style = gtk_widget_get_style_context(treeView);
+ style = ClaimStyleContext(MOZ_GTK_TREEVIEW);
// Get odd row background color
gtk_style_context_save(style);
@@ -1343,12 +1369,21 @@ nsLookAndFeel::Init()
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
- gtk_widget_path_free(path);
-
+ // GtkFrame has a "border" subnode on which Adwaita draws the border.
+ // Some themes do not draw on this node but draw a border on the widget
+ // root node, so check the root node if no border is found on the border
+ // node.
style = ClaimStyleContext(MOZ_GTK_FRAME_BORDER);
- GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder);
+ bool themeUsesColors =
+ GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder);
ReleaseStyleContext(style);
+ if (!themeUsesColors) {
+ style = ClaimStyleContext(MOZ_GTK_FRAME);
+ GetBorderColors(style, &sFrameOuterLightBorder, &sFrameInnerDarkBorder);
+ ReleaseStyleContext(style);
+ }
// GtkInfoBar
// TODO - Use WidgetCache for it?
@@ -1419,12 +1454,6 @@ nsLookAndFeel::RefreshImpl()
#if (MOZ_WIDGET_GTK == 2)
g_object_unref(mStyle);
mStyle = nullptr;
-#else
- g_object_unref(mBackgroundStyle);
- g_object_unref(mButtonStyle);
-
- mBackgroundStyle = nullptr;
- mButtonStyle = nullptr;
#endif
Init();
diff -up firefox-51.0/widget/gtk/nsNativeThemeGTK.cpp.old firefox-51.0/widget/gtk/nsNativeThemeGTK.cpp
--- firefox-51.0/widget/gtk/nsNativeThemeGTK.cpp.old 2017-01-16 17:16:53.000000000 +0100
+++ firefox-51.0/widget/gtk/nsNativeThemeGTK.cpp 2016-10-31 11:52:13.000000000 +0100
@@ -149,19 +149,15 @@ static void SetWidgetStateSafe(uint8_t *
aSafeVector[key >> 3] |= (1 << (key & 7));
}
-static GtkTextDirection GetTextDirection(nsIFrame* aFrame)
+/* static */ GtkTextDirection
+nsNativeThemeGTK::GetTextDirection(nsIFrame* aFrame)
{
- if (!aFrame)
- return GTK_TEXT_DIR_NONE;
-
- switch (aFrame->StyleVisibility()->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;
+ // IsFrameRTL() treats vertical-rl modes as right-to-left (in addition to
+ // horizontal text with direction=RTL), rather than just considering the
+ // text direction. GtkTextDirection does not have distinct values for
+ // vertical writing modes, but considering the block flow direction is
+ // important for resizers and scrollbar elements, at least.
+ return IsFrameRTL(aFrame) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
}
// Returns positive for negative margins (otherwise 0).
@@ -429,6 +425,20 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
else
*aWidgetFlags = 0;
break;
+ case NS_THEME_SCROLLBARTRACK_HORIZONTAL:
+ if (gtk_check_version(3,20,0) == nullptr) {
+ aGtkWidgetType = MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL;
+ } else {
+ return false;
+ }
+ break;
+ case NS_THEME_SCROLLBARTRACK_VERTICAL:
+ if (gtk_check_version(3,20,0) == nullptr) {
+ aGtkWidgetType = MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL;
+ } else {
+ return false;
+ }
+ break;
case NS_THEME_SCROLLBARTHUMB_VERTICAL:
aGtkWidgetType = MOZ_GTK_SCROLLBAR_THUMB_VERTICAL;
break;
@@ -1105,14 +1115,7 @@ nsNativeThemeGTK::DrawWidgetBackground(n
{
GtkWidgetState state;
WidgetNodeType gtkWidgetType;
- // For resizer drawing, we want IsFrameRTL, which treats vertical-rl modes
- // as right-to-left (in addition to horizontal text with direction=RTL),
- // rather than just considering the text direction.
- // This will make resizers on vertically-oriented elements render properly.
- GtkTextDirection direction =
- aWidgetType == NS_THEME_RESIZER
- ? (IsFrameRTL(aFrame) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR)
- : GetTextDirection(aFrame);
+ GtkTextDirection direction = GetTextDirection(aFrame);
gint flags;
if (!GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, &state,
&flags))
@@ -1248,6 +1251,21 @@ nsNativeThemeGTK::DrawWidgetBackground(n
return NS_OK;
}
+WidgetNodeType
+nsNativeThemeGTK::NativeThemeToGtkTheme(uint8_t aWidgetType, nsIFrame* aFrame)
+{
+ WidgetNodeType gtkWidgetType;
+ gint unusedFlags;
+
+ if (!GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, nullptr,
+ &unusedFlags))
+ {
+ MOZ_ASSERT_UNREACHABLE("Unknown native widget to gtk widget mapping");
+ return MOZ_GTK_WINDOW;
+ }
+ return gtkWidgetType;
+}
+
NS_IMETHODIMP
nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame,
uint8_t aWidgetType, nsIntMargin* aResult)
@@ -1255,24 +1273,6 @@ nsNativeThemeGTK::GetWidgetBorder(nsDevi
GtkTextDirection direction = GetTextDirection(aFrame);
aResult->top = aResult->left = aResult->right = aResult->bottom = 0;
switch (aWidgetType) {
- case NS_THEME_SCROLLBAR_VERTICAL:
- case NS_THEME_SCROLLBARTRACK_HORIZONTAL:
- {
- MozGtkScrollbarMetrics metrics;
- moz_gtk_get_scrollbar_metrics(&metrics);
- /* Top and bottom border for whole vertical scrollbar, top and bottom
- * border for horizontal track - to correctly position thumb element */
- aResult->top = aResult->bottom = metrics.trough_border;
- }
- break;
- case NS_THEME_SCROLLBAR_HORIZONTAL:
- case NS_THEME_SCROLLBARTRACK_VERTICAL:
- {
- MozGtkScrollbarMetrics metrics;
- moz_gtk_get_scrollbar_metrics(&metrics);
- aResult->left = aResult->right = metrics.trough_border;
- }
- break;
case NS_THEME_TOOLBOX:
// gtk has no toolbox equivalent. So, although we map toolbox to
// gtk's 'toolbar' for purposes of painting the widget background,
@@ -1312,8 +1312,9 @@ nsNativeThemeGTK::GetWidgetBorder(nsDevi
default:
{
WidgetNodeType gtkWidgetType;
+ gint unusedFlags;
if (GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, nullptr,
- nullptr)) {
+ &unusedFlags)) {
moz_gtk_get_widget_border(gtkWidgetType, &aResult->left, &aResult->top,
&aResult->right, &aResult->bottom, direction,
IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XHTML));
@@ -1426,22 +1427,33 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n
case NS_THEME_SCROLLBARBUTTON_UP:
case NS_THEME_SCROLLBARBUTTON_DOWN:
{
- MozGtkScrollbarMetrics metrics;
- moz_gtk_get_scrollbar_metrics(&metrics);
+ if (gtk_check_version(3,20,0) == nullptr) {
+ moz_gtk_get_widget_min_size(MOZ_GTK_SCROLLBAR_BUTTON,
+ &(aResult->width), &(aResult->height));
+ } else {
+ MozGtkScrollbarMetrics metrics;
+ moz_gtk_get_scrollbar_metrics(&metrics);
+
+ aResult->width = metrics.slider_width;
+ aResult->height = metrics.stepper_size;
+ }
- aResult->width = metrics.slider_width;
- aResult->height = metrics.stepper_size;
*aIsOverridable = false;
}
break;
case NS_THEME_SCROLLBARBUTTON_LEFT:
case NS_THEME_SCROLLBARBUTTON_RIGHT:
{
- MozGtkScrollbarMetrics metrics;
- moz_gtk_get_scrollbar_metrics(&metrics);
+ if (gtk_check_version(3,20,0) == nullptr) {
+ moz_gtk_get_widget_min_size(MOZ_GTK_SCROLLBAR_BUTTON,
+ &(aResult->width), &(aResult->height));
+ } else {
+ MozGtkScrollbarMetrics metrics;
+ moz_gtk_get_scrollbar_metrics(&metrics);
- aResult->width = metrics.stepper_size;
- aResult->height = metrics.slider_width;
+ aResult->width = metrics.stepper_size;
+ aResult->height = metrics.slider_width;
+ }
*aIsOverridable = false;
}
break;
@@ -1468,39 +1480,65 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n
* the thumb isn't a direct child of the scrollbar, unlike the buttons
* or track. So add a minimum size to the track as well to prevent a
* 0-width scrollbar. */
- MozGtkScrollbarMetrics metrics;
- moz_gtk_get_scrollbar_metrics(&metrics);
+ if (gtk_check_version(3,20,0) == nullptr) {
+ // Thumb min dimensions to start with
+ WidgetNodeType thumbType = aWidgetType == NS_THEME_SCROLLBAR_VERTICAL ?
+ MOZ_GTK_SCROLLBAR_THUMB_VERTICAL : MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
+ moz_gtk_get_widget_min_size(thumbType, &(aResult->width), &(aResult->height));
+
+ // Add scrollbar's borders
+ nsIntMargin border;
+ nsNativeThemeGTK::GetWidgetBorder(aFrame->PresContext()->DeviceContext(),
+ aFrame, aWidgetType, &border);
+ aResult->width += border.left + border.right;
+ aResult->height += border.top + border.bottom;
+
+ // Add track's borders
+ uint8_t trackType = aWidgetType == NS_THEME_SCROLLBAR_VERTICAL ?
+ NS_THEME_SCROLLBARTRACK_VERTICAL : NS_THEME_SCROLLBARTRACK_HORIZONTAL;
+ nsNativeThemeGTK::GetWidgetBorder(aFrame->PresContext()->DeviceContext(),
+ aFrame, trackType, &border);
+ aResult->width += border.left + border.right;
+ aResult->height += border.top + border.bottom;
+ } else {
+ MozGtkScrollbarMetrics metrics;
+ moz_gtk_get_scrollbar_metrics(&metrics);
- // Require room for the slider in the track if we don't have buttons.
- bool hasScrollbarButtons = moz_gtk_has_scrollbar_buttons();
+ // Require room for the slider in the track if we don't have buttons.
+ bool hasScrollbarButtons = moz_gtk_has_scrollbar_buttons();
- if (aWidgetType == NS_THEME_SCROLLBAR_VERTICAL) {
- aResult->width = metrics.slider_width + 2 * metrics.trough_border;
- if (!hasScrollbarButtons)
- aResult->height = metrics.min_slider_size + 2 * metrics.trough_border;
- } else {
- aResult->height = metrics.slider_width + 2 * metrics.trough_border;
- if (!hasScrollbarButtons)
- aResult->width = metrics.min_slider_size + 2 * metrics.trough_border;
+ if (aWidgetType == NS_THEME_SCROLLBAR_VERTICAL) {
+ aResult->width = metrics.slider_width + 2 * metrics.trough_border;
+ if (!hasScrollbarButtons)
+ aResult->height = metrics.min_slider_size + 2 * metrics.trough_border;
+ } else {
+ aResult->height = metrics.slider_width + 2 * metrics.trough_border;
+ if (!hasScrollbarButtons)
+ aResult->width = metrics.min_slider_size + 2 * metrics.trough_border;
+ }
+ *aIsOverridable = false;
}
- *aIsOverridable = false;
}
break;
case NS_THEME_SCROLLBARTHUMB_VERTICAL:
case NS_THEME_SCROLLBARTHUMB_HORIZONTAL:
{
- MozGtkScrollbarMetrics metrics;
- moz_gtk_get_scrollbar_metrics(&metrics);
-
- if (aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL) {
- aResult->width = metrics.slider_width;
- aResult->height = metrics.min_slider_size;
+ if (gtk_check_version(3,20,0) == nullptr) {
+ moz_gtk_get_widget_min_size(NativeThemeToGtkTheme(aWidgetType, aFrame),
+ &(aResult->width), &(aResult->height));
} else {
- aResult->height = metrics.slider_width;
- aResult->width = metrics.min_slider_size;
- }
+ MozGtkScrollbarMetrics metrics;
+ moz_gtk_get_scrollbar_metrics(&metrics);
+ if (aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL) {
+ aResult->width = metrics.slider_width;
+ aResult->height = metrics.min_slider_size;
+ } else {
+ aResult->height = metrics.slider_width;
+ aResult->width = metrics.min_slider_size;
+ }
+ }
*aIsOverridable = false;
}
break;
diff -up firefox-51.0/widget/gtk/nsNativeThemeGTK.h.old firefox-51.0/widget/gtk/nsNativeThemeGTK.h
--- firefox-51.0/widget/gtk/nsNativeThemeGTK.h.old 2016-07-25 22:22:07.000000000 +0200
+++ firefox-51.0/widget/gtk/nsNativeThemeGTK.h 2016-10-27 16:22:27.000000000 +0200
@@ -74,6 +74,7 @@ protected:
virtual ~nsNativeThemeGTK();
private:
+ GtkTextDirection GetTextDirection(nsIFrame* aFrame);
gint GetTabMarginPixels(nsIFrame* aFrame);
bool GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame,
WidgetNodeType& aGtkWidgetType,
@@ -82,6 +83,7 @@ private:
nsIntMargin* aExtra);
void RefreshWidgetWindow(nsIFrame* aFrame);
+ WidgetNodeType NativeThemeToGtkTheme(uint8_t aWidgetType, nsIFrame* aFrame);
uint8_t mDisabledWidgetTypes[32];
uint8_t mSafeWidgetStates[1024]; // 256 widgets * 32 bits per widget
diff -up firefox-51.0/widget/gtk/WidgetStyleCache.cpp.old firefox-51.0/widget/gtk/WidgetStyleCache.cpp
--- firefox-51.0/widget/gtk/WidgetStyleCache.cpp.old 2017-01-16 17:16:53.000000000 +0100
+++ firefox-51.0/widget/gtk/WidgetStyleCache.cpp 2017-01-06 10:20:43.000000000 +0100
@@ -33,7 +33,6 @@ static GtkWidget*
CreateWindowWidget()
{
GtkWidget *widget = gtk_window_new(GTK_WINDOW_POPUP);
- gtk_widget_realize(widget);
gtk_widget_set_name(widget, "MozillaGtkWidget");
return widget;
}
@@ -50,7 +49,6 @@ static void
AddToWindowContainer(GtkWidget* widget)
{
gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_WINDOW_CONTAINER)), widget);
- gtk_widget_realize(widget);
}
static GtkWidget*
@@ -142,7 +140,6 @@ CreateToolbarWidget()
{
GtkWidget* widget = gtk_toolbar_new();
gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_GRIPPER)), widget);
- gtk_widget_realize(widget);
return widget;
}
@@ -183,7 +180,6 @@ 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_realize(widget);
gtk_widget_show(widget);
return widget;
}
@@ -205,19 +201,235 @@ CreateEntryWidget()
}
static GtkWidget*
-CreateScrolledWindowWidget()
+CreateComboBoxWidget()
{
- GtkWidget* widget = gtk_scrolled_window_new(nullptr, nullptr);
+ 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*
+CreateComboBoxButtonWidget()
+{
+ GtkWidget* comboBox = GetWidget(MOZ_GTK_COMBOBOX);
+ GtkWidget* comboBoxButton = nullptr;
+
+ /* Get its inner Button */
+ GtkInnerWidgetInfo info = { GTK_TYPE_TOGGLE_BUTTON,
+ &comboBoxButton };
+ gtk_container_forall(GTK_CONTAINER(comboBox),
+ GetInnerWidget, &info);
+
+ if (!comboBoxButton) {
+ /* Shouldn't be reached with current internal gtk implementation; we
+ * use a generic toggle button as last resort fallback to avoid
+ * crashing. */
+ comboBoxButton = GetWidget(MOZ_GTK_TOGGLE_BUTTON);
+ } else {
+ /* We need to have pointers to the inner widgets (button, separator, arrow)
+ * of the ComboBox to get the correct rendering from theme engines which
+ * special cases their look. Since the inner layout can change, we ask GTK
+ * to NULL our pointers when they are about to become invalid because the
+ * corresponding widgets don't exist anymore. It's the role of
+ * g_object_add_weak_pointer().
+ * Note that if we don't find the inner widgets (which shouldn't happen), we
+ * fallback to use generic "non-inner" widgets, and they don't need that kind
+ * of weak pointer since they are explicit children of gProtoLayout and as
+ * such GTK holds a strong reference to them. */
+ g_object_add_weak_pointer(G_OBJECT(comboBoxButton),
+ reinterpret_cast<gpointer *>(sWidgetStorage) +
+ MOZ_GTK_COMBOBOX_BUTTON);
+ }
+
+ return comboBoxButton;
+}
+
+static GtkWidget*
+CreateComboBoxArrowWidget()
+{
+ GtkWidget* comboBoxButton = GetWidget(MOZ_GTK_COMBOBOX_BUTTON);
+ GtkWidget* comboBoxArrow = nullptr;
+
+ /* Get the widgets inside the Button */
+ GtkWidget* buttonChild = gtk_bin_get_child(GTK_BIN(comboBoxButton));
+ if (GTK_IS_BOX(buttonChild)) {
+ /* appears-as-list = FALSE, cell-view = TRUE; the button
+ * contains an hbox. This hbox is there because the ComboBox
+ * needs to place a cell renderer, a separator, and an arrow in
+ * the button when appears-as-list is FALSE. */
+ GtkInnerWidgetInfo info = { GTK_TYPE_ARROW,
+ &comboBoxArrow };
+ gtk_container_forall(GTK_CONTAINER(buttonChild),
+ GetInnerWidget, &info);
+ } else if (GTK_IS_ARROW(buttonChild)) {
+ /* appears-as-list = TRUE, or cell-view = FALSE;
+ * the button only contains an arrow */
+ comboBoxArrow = buttonChild;
+ }
+
+ if (!comboBoxArrow) {
+ /* Shouldn't be reached with current internal gtk implementation;
+ * we gButtonArrowWidget as last resort fallback to avoid
+ * crashing. */
+ comboBoxArrow = GetWidget(MOZ_GTK_BUTTON_ARROW);
+ } else {
+ g_object_add_weak_pointer(G_OBJECT(comboBoxArrow),
+ reinterpret_cast<gpointer *>(sWidgetStorage) +
+ MOZ_GTK_COMBOBOX_ARROW);
+ }
+
+ return comboBoxArrow;
+}
+
+static GtkWidget*
+CreateComboBoxSeparatorWidget()
+{
+ // Ensure to search for separator only once as it can fail
+ // TODO - it won't initialize after ResetWidgetCache() call
+ static bool isMissingSeparator = false;
+ if (isMissingSeparator)
+ return nullptr;
+
+ /* Get the widgets inside the Button */
+ GtkWidget* comboBoxSeparator = nullptr;
+ GtkWidget* buttonChild =
+ gtk_bin_get_child(GTK_BIN(GetWidget(MOZ_GTK_COMBOBOX_BUTTON)));
+ if (GTK_IS_BOX(buttonChild)) {
+ /* appears-as-list = FALSE, cell-view = TRUE; the button
+ * contains an hbox. This hbox is there because the ComboBox
+ * needs to place a cell renderer, a separator, and an arrow in
+ * the button when appears-as-list is FALSE. */
+ GtkInnerWidgetInfo info = { GTK_TYPE_SEPARATOR,
+ &comboBoxSeparator };
+ gtk_container_forall(GTK_CONTAINER(buttonChild),
+ GetInnerWidget, &info);
+ }
+
+ if (comboBoxSeparator) {
+ g_object_add_weak_pointer(G_OBJECT(comboBoxSeparator),
+ reinterpret_cast<gpointer *>(sWidgetStorage) +
+ MOZ_GTK_COMBOBOX_SEPARATOR);
+ } else {
+ /* comboBoxSeparator may be NULL
+ * when "appears-as-list" = TRUE or "cell-view" = FALSE;
+ * if there is no separator, then we just won't paint it. */
+ isMissingSeparator = true;
+ }
+
+ return comboBoxSeparator;
+}
+
+static GtkWidget*
+CreateComboBoxEntryWidget()
+{
+ GtkWidget* widget = gtk_combo_box_new_with_entry();
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateComboBoxEntryTextareaWidget()
+{
+ GtkWidget* comboBoxTextarea = nullptr;
+
+ /* Get its inner Entry and Button */
+ GtkInnerWidgetInfo info = { GTK_TYPE_ENTRY,
+ &comboBoxTextarea };
+ gtk_container_forall(GTK_CONTAINER(GetWidget(MOZ_GTK_COMBOBOX_ENTRY)),
+ GetInnerWidget, &info);
+
+ if (!comboBoxTextarea) {
+ comboBoxTextarea = GetWidget(MOZ_GTK_ENTRY);
+ } else {
+ g_object_add_weak_pointer(G_OBJECT(comboBoxTextarea),
+ reinterpret_cast<gpointer *>(sWidgetStorage) +
+ MOZ_GTK_COMBOBOX_ENTRY);
+ }
+
+ return comboBoxTextarea;
+}
+
+static GtkWidget*
+CreateComboBoxEntryButtonWidget()
+{
+ GtkWidget* comboBoxButton = nullptr;
+
+ /* Get its inner Entry and Button */
+ GtkInnerWidgetInfo info = { GTK_TYPE_TOGGLE_BUTTON,
+ &comboBoxButton };
+ gtk_container_forall(GTK_CONTAINER(GetWidget(MOZ_GTK_COMBOBOX_ENTRY)),
+ GetInnerWidget, &info);
+
+ if (!comboBoxButton) {
+ comboBoxButton = GetWidget(MOZ_GTK_TOGGLE_BUTTON);
+ } else {
+ g_object_add_weak_pointer(G_OBJECT(comboBoxButton),
+ reinterpret_cast<gpointer *>(sWidgetStorage) +
+ MOZ_GTK_COMBOBOX_ENTRY_BUTTON);
+ }
+
+ return comboBoxButton;
+}
+
static GtkWidget*
-CreateTextViewWidget()
+CreateComboBoxEntryArrowWidget()
{
- GtkWidget* widget = gtk_text_view_new();
- gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_SCROLLED_WINDOW)),
- widget);
+ GtkWidget* comboBoxArrow = nullptr;
+
+ /* Get the Arrow inside the Button */
+ GtkWidget* buttonChild =
+ gtk_bin_get_child(GTK_BIN(GetWidget(MOZ_GTK_COMBOBOX_ENTRY_BUTTON)));
+
+ if (GTK_IS_BOX(buttonChild)) {
+ /* appears-as-list = FALSE, cell-view = TRUE; the button
+ * contains an hbox. This hbox is there because the ComboBox
+ * needs to place a cell renderer, a separator, and an arrow in
+ * the button when appears-as-list is FALSE. */
+ GtkInnerWidgetInfo info = { GTK_TYPE_ARROW,
+ &comboBoxArrow };
+ gtk_container_forall(GTK_CONTAINER(buttonChild),
+ GetInnerWidget, &info);
+ } else if (GTK_IS_ARROW(buttonChild)) {
+ /* appears-as-list = TRUE, or cell-view = FALSE;
+ * the button only contains an arrow */
+ comboBoxArrow = buttonChild;
+ }
+
+ if (!comboBoxArrow) {
+ /* Shouldn't be reached with current internal gtk implementation;
+ * we gButtonArrowWidget as last resort fallback to avoid
+ * crashing. */
+ comboBoxArrow = GetWidget(MOZ_GTK_BUTTON_ARROW);
+ } else {
+ g_object_add_weak_pointer(G_OBJECT(comboBoxArrow),
+ reinterpret_cast<gpointer *>(sWidgetStorage) +
+ MOZ_GTK_COMBOBOX_ENTRY_ARROW);
+ }
+
+ return comboBoxArrow;
+}
+
+static GtkWidget*
+CreateScrolledWindowWidget()
+{
+ GtkWidget* widget = gtk_scrolled_window_new(nullptr, nullptr);
+ AddToWindowContainer(widget);
return widget;
}
@@ -227,7 +439,6 @@ CreateMenuSeparatorWidget()
GtkWidget* widget = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)),
widget);
- gtk_widget_realize(widget);
return widget;
}
@@ -306,15 +517,6 @@ CreateVPanedWidget()
}
static GtkWidget*
-CreateImageMenuItemWidget()
-{
- GtkWidget* widget = gtk_image_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)), widget);
- gtk_widget_realize(widget);
- return widget;
-}
-
-static GtkWidget*
CreateScaleWidget(GtkOrientation aOrientation)
{
GtkWidget* widget = gtk_scale_new(aOrientation, nullptr);
@@ -380,8 +582,6 @@ CreateWidget(WidgetNodeType aWidgetType)
return CreateEntryWidget();
case MOZ_GTK_SCROLLED_WINDOW:
return CreateScrolledWindowWidget();
- case MOZ_GTK_TEXT_VIEW:
- return CreateTextViewWidget();
case MOZ_GTK_TREEVIEW:
return CreateTreeViewWidget();
case MOZ_GTK_TREE_HEADER_CELL:
@@ -392,14 +592,28 @@ CreateWidget(WidgetNodeType aWidgetType)
return CreateHPanedWidget();
case MOZ_GTK_SPLITTER_VERTICAL:
return CreateVPanedWidget();
- case MOZ_GTK_IMAGEMENUITEM:
- return CreateImageMenuItemWidget();
case MOZ_GTK_SCALE_HORIZONTAL:
return CreateScaleWidget(GTK_ORIENTATION_HORIZONTAL);
case MOZ_GTK_SCALE_VERTICAL:
return CreateScaleWidget(GTK_ORIENTATION_VERTICAL);
case MOZ_GTK_NOTEBOOK:
return CreateNotebookWidget();
+ case MOZ_GTK_COMBOBOX:
+ return CreateComboBoxWidget();
+ case MOZ_GTK_COMBOBOX_BUTTON:
+ return CreateComboBoxButtonWidget();
+ case MOZ_GTK_COMBOBOX_ARROW:
+ return CreateComboBoxArrowWidget();
+ case MOZ_GTK_COMBOBOX_SEPARATOR:
+ return CreateComboBoxSeparatorWidget();
+ case MOZ_GTK_COMBOBOX_ENTRY:
+ return CreateComboBoxEntryWidget();
+ case MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA:
+ return CreateComboBoxEntryTextareaWidget();
+ case MOZ_GTK_COMBOBOX_ENTRY_BUTTON:
+ return CreateComboBoxEntryButtonWidget();
+ case MOZ_GTK_COMBOBOX_ENTRY_ARROW:
+ return CreateComboBoxEntryArrowWidget();
default:
/* Not implemented */
return nullptr;
@@ -474,9 +688,20 @@ CreateCSSNode(const char* aName, GtkStyl
reinterpret_cast<void (*)(GtkWidgetPath *, gint, const char *)>
(dlsym(RTLD_DEFAULT, "gtk_widget_path_iter_set_object_name"));
- GtkWidgetPath* path = aParentStyle ?
- gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle)) :
- gtk_widget_path_new();
+ GtkWidgetPath* path;
+ if (aParentStyle) {
+ path = gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle));
+ // Copy classes from the parent style context to its corresponding node in
+ // the path, because GTK will only match against ancestor classes if they
+ // are on the path.
+ GList* classes = gtk_style_context_list_classes(aParentStyle);
+ for (GList* link = classes; link; link = link->next) {
+ gtk_widget_path_iter_add_class(path, -1, static_cast<gchar*>(link->data));
+ }
+ g_list_free(classes);
+ } else {
+ path = gtk_widget_path_new();
+ }
gtk_widget_path_append_type(path, aType);
@@ -508,13 +733,38 @@ GetWidgetRootStyle(WidgetNodeType aNodeT
case MOZ_GTK_MENUITEM:
style = CreateStyleForWidget(gtk_menu_item_new(), MOZ_GTK_MENUPOPUP);
break;
- case MOZ_GTK_CHECKMENUITEM_CONTAINER:
+ case MOZ_GTK_CHECKMENUITEM:
style = CreateStyleForWidget(gtk_check_menu_item_new(), MOZ_GTK_MENUPOPUP);
break;
- case MOZ_GTK_RADIOMENUITEM_CONTAINER:
+ case MOZ_GTK_RADIOMENUITEM:
style = CreateStyleForWidget(gtk_radio_menu_item_new(nullptr),
MOZ_GTK_MENUPOPUP);
break;
+ case MOZ_GTK_TEXT_VIEW:
+ style = CreateStyleForWidget(gtk_text_view_new(),
+ MOZ_GTK_SCROLLED_WINDOW);
+ break;
+ case MOZ_GTK_TOOLTIP:
+ if (gtk_check_version(3, 20, 0) != nullptr) {
+ // The tooltip style class is added first in CreateTooltipWidget()
+ // and transfered to style in CreateStyleForWidget().
+ GtkWidget* tooltipWindow = CreateTooltipWidget();
+ style = CreateStyleForWidget(tooltipWindow, nullptr);
+ gtk_widget_destroy(tooltipWindow); // Release GtkWindow self-reference.
+ } else {
+ // We create this from the path because GtkTooltipWindow is not public.
+ style = CreateCSSNode("tooltip", nullptr, GTK_TYPE_TOOLTIP);
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
+ }
+ break;
+ case MOZ_GTK_TOOLTIP_BOX:
+ style = CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0),
+ MOZ_GTK_TOOLTIP);
+ break;
+ case MOZ_GTK_TOOLTIP_BOX_LABEL:
+ style = CreateStyleForWidget(gtk_label_new(nullptr),
+ MOZ_GTK_TOOLTIP_BOX);
+ break;
default:
GtkWidget* widget = GetWidget(aNodeType);
MOZ_ASSERT(widget);
@@ -576,6 +826,10 @@ GetCssNodeStyleInternal(WidgetNodeType a
style = CreateChildCSSNode(GTK_STYLE_CLASS_SLIDER,
MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
break;
+ case MOZ_GTK_SCROLLBAR_BUTTON:
+ style = CreateChildCSSNode(GTK_STYLE_CLASS_BUTTON,
+ MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL);
+ break;
case MOZ_GTK_RADIOBUTTON:
style = CreateChildCSSNode(GTK_STYLE_CLASS_RADIO,
MOZ_GTK_RADIOBUTTON_CONTAINER);
@@ -584,13 +838,13 @@ GetCssNodeStyleInternal(WidgetNodeType a
style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK,
MOZ_GTK_CHECKBUTTON_CONTAINER);
break;
- case MOZ_GTK_RADIOMENUITEM:
+ case MOZ_GTK_RADIOMENUITEM_INDICATOR:
style = CreateChildCSSNode(GTK_STYLE_CLASS_RADIO,
- MOZ_GTK_RADIOMENUITEM_CONTAINER);
+ MOZ_GTK_RADIOMENUITEM);
break;
- case MOZ_GTK_CHECKMENUITEM:
+ case MOZ_GTK_CHECKMENUITEM_INDICATOR:
style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK,
- MOZ_GTK_CHECKMENUITEM_CONTAINER);
+ MOZ_GTK_CHECKMENUITEM);
break;
case MOZ_GTK_PROGRESS_TROUGH:
/* Progress bar background (trough) */
@@ -601,11 +855,6 @@ GetCssNodeStyleInternal(WidgetNodeType a
style = CreateChildCSSNode("progress",
MOZ_GTK_PROGRESS_TROUGH);
break;
- case MOZ_GTK_TOOLTIP:
- // We create this from the path because GtkTooltipWindow is not public.
- style = CreateCSSNode("tooltip", nullptr, GTK_TYPE_TOOLTIP);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
- break;
case MOZ_GTK_GRIPPER:
// TODO - create from CSS node
return GetWidgetStyleWithClass(MOZ_GTK_GRIPPER,
@@ -622,10 +871,28 @@ GetCssNodeStyleInternal(WidgetNodeType a
// TODO - create from CSS node
return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
GTK_STYLE_CLASS_FRAME);
- case MOZ_GTK_TEXT_VIEW:
- // TODO - create from CSS node
- return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW,
- GTK_STYLE_CLASS_VIEW);
+ case MOZ_GTK_TEXT_VIEW_TEXT:
+ case MOZ_GTK_RESIZER:
+ style = CreateChildCSSNode("text", MOZ_GTK_TEXT_VIEW);
+ if (aNodeType == MOZ_GTK_RESIZER) {
+ // The "grip" class provides the correct builtin icon from
+ // gtk_render_handle(). The icon is drawn with shaded variants of
+ // the background color, and so a transparent background would lead to
+ // a transparent resizer. gtk_render_handle() also uses the
+ // background color to draw a background, and so this style otherwise
+ // matches what is used in GtkTextView to match the background with
+ // textarea elements.
+ GdkRGBA color;
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
+ &color);
+ if (color.alpha == 0.0) {
+ g_object_unref(style);
+ style = CreateStyleForWidget(gtk_text_view_new(),
+ MOZ_GTK_SCROLLED_WINDOW);
+ }
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
+ }
+ break;
case MOZ_GTK_FRAME_BORDER:
style = CreateChildCSSNode("border", MOZ_GTK_FRAME);
break;
@@ -728,27 +995,20 @@ GetWidgetStyleInternal(WidgetNodeType aN
case MOZ_GTK_CHECKBUTTON:
return GetWidgetStyleWithClass(MOZ_GTK_CHECKBUTTON_CONTAINER,
GTK_STYLE_CLASS_CHECK);
- case MOZ_GTK_RADIOMENUITEM:
- return GetWidgetStyleWithClass(MOZ_GTK_RADIOMENUITEM_CONTAINER,
+ case MOZ_GTK_RADIOMENUITEM_INDICATOR:
+ return GetWidgetStyleWithClass(MOZ_GTK_RADIOMENUITEM,
GTK_STYLE_CLASS_RADIO);
- case MOZ_GTK_CHECKMENUITEM:
- return GetWidgetStyleWithClass(MOZ_GTK_CHECKMENUITEM_CONTAINER,
+ case MOZ_GTK_CHECKMENUITEM_INDICATOR:
+ return GetWidgetStyleWithClass(MOZ_GTK_CHECKMENUITEM,
GTK_STYLE_CLASS_CHECK);
case MOZ_GTK_PROGRESS_TROUGH:
return GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR,
GTK_STYLE_CLASS_TROUGH);
- case MOZ_GTK_TOOLTIP: {
- GtkStyleContext* style = sStyleStorage[aNodeType];
- if (style)
- return style;
-
- // The tooltip style class is added first in CreateTooltipWidget() so
- // that gtk_widget_path_append_for_widget() in CreateStyleForWidget()
- // will find it.
- GtkWidget* tooltipWindow = CreateTooltipWidget();
- style = CreateStyleForWidget(tooltipWindow, nullptr);
- gtk_widget_destroy(tooltipWindow); // Release GtkWindow self-reference.
- sStyleStorage[aNodeType] = style;
+ case MOZ_GTK_PROGRESS_CHUNK: {
+ GtkStyleContext* style =
+ GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR,
+ GTK_STYLE_CLASS_PROGRESSBAR);
+ gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH);
return style;
}
case MOZ_GTK_GRIPPER:
@@ -763,9 +1023,25 @@ GetWidgetStyleInternal(WidgetNodeType aN
case MOZ_GTK_SCROLLED_WINDOW:
return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
GTK_STYLE_CLASS_FRAME);
- case MOZ_GTK_TEXT_VIEW:
- return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW,
- GTK_STYLE_CLASS_VIEW);
+ case MOZ_GTK_TEXT_VIEW_TEXT:
+ case MOZ_GTK_RESIZER: {
+ // GTK versions prior to 3.20 do not have the view class on the root
+ // node, but add this to determine the background for the text window.
+ GtkStyleContext* style =
+ GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, GTK_STYLE_CLASS_VIEW);
+ if (aNodeType == MOZ_GTK_RESIZER) {
+ // The "grip" class provides the correct builtin icon from
+ // gtk_render_handle(). The icon is drawn with shaded variants of
+ // the background color, and so a transparent background would lead to
+ // a transparent resizer. gtk_render_handle() also uses the
+ // background color to draw a background, and so this style otherwise
+ // matches MOZ_GTK_TEXT_VIEW_TEXT to match the background with
+ // textarea elements. GtkTextView creates a separate text window and
+ // so the background should not be transparent.
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
+ }
+ return style;
+ }
case MOZ_GTK_FRAME_BORDER:
return GetWidgetRootStyle(MOZ_GTK_FRAME);
case MOZ_GTK_TREEVIEW_VIEW: