firefox/firefox-gtk3-20.patch

2280 lines
80 KiB
Diff

diff -up firefox-48.0/media/webrtc/trunk/Makefile.old firefox-48.0/media/webrtc/trunk/Makefile
diff -up firefox-48.0/widget/gtk/gtk3drawing.cpp.old firefox-48.0/widget/gtk/gtk3drawing.cpp
--- firefox-48.0/widget/gtk/gtk3drawing.cpp.old 2016-07-25 22:22:07.000000000 +0200
+++ firefox-48.0/widget/gtk/gtk3drawing.cpp 2016-07-28 09:50:25.000000000 +0200
@@ -18,15 +18,9 @@
#include <math.h>
-static GtkWidget* gProtoWindow;
static GtkWidget* gProtoLayout;
-static GtkWidget* gButtonWidget;
-static GtkWidget* gToggleButtonWidget;
-static GtkWidget* gButtonArrowWidget;
-static GtkWidget* gSpinWidget;
static GtkWidget* gHScaleWidget;
static GtkWidget* gVScaleWidget;
-static GtkWidget* gEntryWidget;
static GtkWidget* gComboBoxWidget;
static GtkWidget* gComboBoxButtonWidget;
static GtkWidget* gComboBoxArrowWidget;
@@ -35,30 +29,15 @@ static GtkWidget* gComboBoxEntryWidget;
static GtkWidget* gComboBoxEntryTextareaWidget;
static GtkWidget* gComboBoxEntryButtonWidget;
static GtkWidget* gComboBoxEntryArrowWidget;
-static GtkWidget* gHandleBoxWidget;
-static GtkWidget* gToolbarWidget;
-static GtkWidget* gFrameWidget;
-static GtkWidget* gProgressWidget;
static GtkWidget* gTabWidget;
-static GtkWidget* gTextViewWidget;
-static GtkWidget* gTooltipWidget;
-static GtkWidget* gMenuBarWidget;
-static GtkWidget* gMenuBarItemWidget;
-static GtkWidget* gMenuPopupWidget;
-static GtkWidget* gMenuItemWidget;
static GtkWidget* gImageMenuItemWidget;
static GtkWidget* gCheckMenuItemWidget;
static GtkWidget* gTreeViewWidget;
static GtkTreeViewColumn* gMiddleTreeViewColumn;
static GtkWidget* gTreeHeaderCellWidget;
static GtkWidget* gTreeHeaderSortArrowWidget;
-static GtkWidget* gExpanderWidget;
-static GtkWidget* gToolbarSeparatorWidget;
-static GtkWidget* gMenuSeparatorWidget;
static GtkWidget* gHPanedWidget;
static GtkWidget* gVPanedWidget;
-static GtkWidget* gScrolledWindowWidget;
-static GtkWidget* gInfoBar;
static style_prop_t style_prop_func;
static gboolean have_arrow_scaling;
@@ -94,15 +73,6 @@ GetStateFlagsFromGtkWidgetState(GtkWidge
return stateFlags;
}
-/* Because we have such an unconventional way of drawing widgets, signal to the GTK theme engine
- that they are drawing for Mozilla instead of a conventional GTK app so they can do any specific
- things they may want to do. */
-static void
-moz_gtk_set_widget_name(GtkWidget* widget)
-{
- gtk_widget_set_name(widget, "MozillaGtkWidget");
-}
-
gint
moz_gtk_enable_style_props(style_prop_t styleGetProp)
{
@@ -111,15 +81,6 @@ moz_gtk_enable_style_props(style_prop_t
}
static gint
-ensure_window_widget()
-{
- if (!gProtoWindow) {
- gProtoWindow = GetWidget(MOZ_GTK_WINDOW);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
setup_widget_prototype(GtkWidget* widget)
{
if (!gProtoLayout) {
@@ -130,16 +91,6 @@ setup_widget_prototype(GtkWidget* widget
}
static gint
-ensure_button_widget()
-{
- if (!gButtonWidget) {
- gButtonWidget = gtk_button_new_with_label("M");
- setup_widget_prototype(gButtonWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
ensure_hpaned_widget()
{
if (!gHPanedWidget) {
@@ -160,40 +111,6 @@ ensure_vpaned_widget()
}
static gint
-ensure_toggle_button_widget()
-{
- if (!gToggleButtonWidget) {
- gToggleButtonWidget = gtk_toggle_button_new();
- setup_widget_prototype(gToggleButtonWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
-ensure_button_arrow_widget()
-{
- if (!gButtonArrowWidget) {
- ensure_toggle_button_widget();
-
- gButtonArrowWidget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
- gtk_container_add(GTK_CONTAINER(gToggleButtonWidget), gButtonArrowWidget);
- gtk_widget_realize(gButtonArrowWidget);
- gtk_widget_show(gButtonArrowWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
-ensure_spin_widget()
-{
- if (!gSpinWidget) {
- gSpinWidget = gtk_spin_button_new(NULL, 1, 0);
- setup_widget_prototype(gSpinWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
ensure_scale_widget()
{
if (!gHScaleWidget) {
@@ -207,16 +124,6 @@ ensure_scale_widget()
return MOZ_GTK_SUCCESS;
}
-static gint
-ensure_entry_widget()
-{
- if (!gEntryWidget) {
- gEntryWidget = gtk_entry_new();
- setup_widget_prototype(gEntryWidget);
- }
- 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
@@ -225,7 +132,7 @@ ensure_entry_widget()
* 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 gProtoWindow and as
+ * 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)
@@ -297,16 +204,14 @@ ensure_combo_box_widgets()
/* Shouldn't be reached with current internal gtk implementation; we
* use a generic toggle button as last resort fallback to avoid
* crashing. */
- ensure_toggle_button_widget();
- gComboBoxButtonWidget = gToggleButtonWidget;
+ 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. */
- ensure_button_arrow_widget();
- gComboBoxArrowWidget = gButtonArrowWidget;
+ gComboBoxArrowWidget = GetWidget(MOZ_GTK_BUTTON_ARROW);
}
/* We don't test the validity of gComboBoxSeparatorWidget since there
@@ -316,15 +221,6 @@ ensure_combo_box_widgets()
return MOZ_GTK_SUCCESS;
}
-static void
-ensure_info_bar()
-{
- if (!gInfoBar) {
- gInfoBar = gtk_info_bar_new();
- setup_widget_prototype(gInfoBar);
- }
-}
-
/* 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
@@ -333,7 +229,7 @@ ensure_info_bar()
* 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 gProtoWindow and as
+ * 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,
@@ -385,8 +281,7 @@ ensure_combo_box_entry_widgets()
NULL);
if (!gComboBoxEntryTextareaWidget) {
- ensure_entry_widget();
- gComboBoxEntryTextareaWidget = gEntryWidget;
+ gComboBoxEntryTextareaWidget = GetWidget(MOZ_GTK_ENTRY);
}
if (gComboBoxEntryButtonWidget) {
@@ -412,68 +307,19 @@ ensure_combo_box_entry_widgets()
/* Shouldn't be reached with current internal gtk implementation;
* we use a generic toggle button as last resort fallback to avoid
* crashing. */
- ensure_toggle_button_widget();
- gComboBoxEntryButtonWidget = gToggleButtonWidget;
+ 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. */
- ensure_button_arrow_widget();
- gComboBoxEntryArrowWidget = gButtonArrowWidget;
+ gComboBoxEntryArrowWidget = GetWidget(MOZ_GTK_BUTTON_ARROW);
}
return MOZ_GTK_SUCCESS;
}
-
-static gint
-ensure_handlebox_widget()
-{
- if (!gHandleBoxWidget) {
- gHandleBoxWidget = gtk_handle_box_new();
- setup_widget_prototype(gHandleBoxWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
-ensure_toolbar_widget()
-{
- if (!gToolbarWidget) {
- ensure_handlebox_widget();
- gToolbarWidget = gtk_toolbar_new();
- gtk_container_add(GTK_CONTAINER(gHandleBoxWidget), gToolbarWidget);
- gtk_widget_realize(gToolbarWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
-ensure_toolbar_separator_widget()
-{
- if (!gToolbarSeparatorWidget) {
- ensure_toolbar_widget();
- gToolbarSeparatorWidget = GTK_WIDGET(gtk_separator_tool_item_new());
- setup_widget_prototype(gToolbarSeparatorWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
-ensure_tooltip_widget()
-{
- if (!gTooltipWidget) {
- gTooltipWidget = gtk_window_new(GTK_WINDOW_POPUP);
- GtkStyleContext* style = gtk_widget_get_style_context(gTooltipWidget);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
- gtk_widget_realize(gTooltipWidget);
- moz_gtk_set_widget_name(gTooltipWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
static gint
ensure_tab_widget()
{
@@ -485,81 +331,11 @@ ensure_tab_widget()
}
static gint
-ensure_progress_widget()
-{
- if (!gProgressWidget) {
- gProgressWidget = gtk_progress_bar_new();
- setup_widget_prototype(gProgressWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
-ensure_frame_widget()
-{
- if (!gFrameWidget) {
- gFrameWidget = gtk_frame_new(NULL);
- setup_widget_prototype(gFrameWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
-ensure_menu_bar_widget()
-{
- if (!gMenuBarWidget) {
- gMenuBarWidget = gtk_menu_bar_new();
- setup_widget_prototype(gMenuBarWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
-ensure_menu_bar_item_widget()
-{
- if (!gMenuBarItemWidget) {
- ensure_menu_bar_widget();
- gMenuBarItemWidget = gtk_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuBarWidget),
- gMenuBarItemWidget);
- gtk_widget_realize(gMenuBarItemWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
-ensure_menu_popup_widget()
-{
- if (!gMenuPopupWidget) {
- ensure_window_widget();
- gMenuPopupWidget = gtk_menu_new();
- gtk_menu_attach_to_widget(GTK_MENU(gMenuPopupWidget), gProtoWindow,
- NULL);
- gtk_widget_realize(gMenuPopupWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
-ensure_menu_item_widget()
-{
- if (!gMenuItemWidget) {
- ensure_menu_popup_widget();
- gMenuItemWidget = gtk_menu_item_new_with_label("M");
- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
- gMenuItemWidget);
- gtk_widget_realize(gMenuItemWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
ensure_image_menu_item_widget()
{
if (!gImageMenuItemWidget) {
- ensure_menu_popup_widget();
gImageMenuItemWidget = gtk_image_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
+ gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)),
gImageMenuItemWidget);
gtk_widget_realize(gImageMenuItemWidget);
}
@@ -567,25 +343,11 @@ ensure_image_menu_item_widget()
}
static gint
-ensure_menu_separator_widget()
-{
- if (!gMenuSeparatorWidget) {
- ensure_menu_popup_widget();
- gMenuSeparatorWidget = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
- gMenuSeparatorWidget);
- gtk_widget_realize(gMenuSeparatorWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
ensure_check_menu_item_widget()
{
if (!gCheckMenuItemWidget) {
- ensure_menu_popup_widget();
- gCheckMenuItemWidget = gtk_check_menu_item_new_with_label("M");
- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget),
+ gCheckMenuItemWidget = gtk_check_menu_item_new();
+ gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)),
gCheckMenuItemWidget);
gtk_widget_realize(gCheckMenuItemWidget);
}
@@ -646,37 +408,6 @@ ensure_tree_header_cell_widget()
return MOZ_GTK_SUCCESS;
}
-static gint
-ensure_expander_widget()
-{
- if (!gExpanderWidget) {
- gExpanderWidget = gtk_expander_new("M");
- setup_widget_prototype(gExpanderWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static gint
-ensure_scrolled_window_widget()
-{
- if (!gScrolledWindowWidget) {
- gScrolledWindowWidget = gtk_scrolled_window_new(NULL, NULL);
- setup_widget_prototype(gScrolledWindowWidget);
- }
- return MOZ_GTK_SUCCESS;
-}
-
-static void
-ensure_text_view_widget()
-{
- if (gTextViewWidget)
- return;
-
- gTextViewWidget = gtk_text_view_new();
- ensure_scrolled_window_widget();
- gtk_container_add(GTK_CONTAINER(gScrolledWindowWidget), gTextViewWidget);
-}
-
gint
moz_gtk_init()
{
@@ -729,26 +460,21 @@ moz_gtk_get_focus_outline_size(gint* foc
{
GtkBorder border;
GtkBorder padding;
- GtkStyleContext *style;
-
- ensure_entry_widget();
- style = gtk_widget_get_style_context(gEntryWidget);
-
+ 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;
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
gint
moz_gtk_menuitem_get_horizontal_padding(gint* horizontal_padding)
{
- ensure_menu_item_widget();
-
- gtk_style_context_get_style(gtk_widget_get_style_context(gMenuItemWidget),
- "horizontal-padding", horizontal_padding,
- NULL);
+ gtk_widget_style_get(GetWidget(MOZ_GTK_MENUITEM),
+ "horizontal-padding", horizontal_padding,
+ nullptr);
return MOZ_GTK_SUCCESS;
}
@@ -771,10 +497,11 @@ moz_gtk_button_get_default_overflow(gint
{
GtkBorder* default_outside_border;
- ensure_button_widget();
- gtk_style_context_get_style(gtk_widget_get_style_context(gButtonWidget),
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
+ gtk_style_context_get_style(style,
"default-outside-border", &default_outside_border,
NULL);
+ ReleaseStyleContext(style);
if (default_outside_border) {
*border_top = default_outside_border->top;
@@ -794,10 +521,11 @@ moz_gtk_button_get_default_border(gint*
{
GtkBorder* default_border;
- ensure_button_widget();
- gtk_style_context_get_style(gtk_widget_get_style_context(gButtonWidget),
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
+ gtk_style_context_get_style(style,
"default-border", &default_border,
NULL);
+ ReleaseStyleContext(style);
if (default_border) {
*border_top = default_border->top;
@@ -831,17 +559,15 @@ static gint
moz_gtk_window_paint(cairo_t *cr, GdkRectangle* rect,
GtkTextDirection direction)
{
- GtkStyleContext* style;
-
- ensure_window_widget();
- gtk_widget_set_direction(gProtoWindow, direction);
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW, direction);
- style = gtk_widget_get_style_context(gProtoWindow);
gtk_style_context_save(style);
gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
+
return MOZ_GTK_SUCCESS;
}
@@ -1118,6 +844,36 @@ moz_gtk_scrollbar_button_paint(cairo_t *
return MOZ_GTK_SUCCESS;
}
+static void
+moz_gtk_update_scrollbar_style(GtkStyleContext* style,
+ WidgetNodeType widget,
+ GtkTextDirection direction)
+{
+ if (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) {
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_BOTTOM);
+ } else {
+ if (direction == GTK_TEXT_DIR_LTR) {
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_RIGHT);
+ gtk_style_context_remove_class(style, GTK_STYLE_CLASS_LEFT);
+ } else {
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_LEFT);
+ gtk_style_context_remove_class(style, GTK_STYLE_CLASS_RIGHT);
+ }
+ }
+}
+
+static void
+moz_gtk_draw_styled_frame(GtkStyleContext* style, cairo_t *cr,
+ GdkRectangle* rect, 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);
+ if (drawFocus) {
+ gtk_render_focus(style, cr,
+ rect->x, rect->y, rect->width, rect->height);
+ }
+}
+
static gint
moz_gtk_scrollbar_trough_paint(WidgetNodeType widget,
cairo_t *cr, GdkRectangle* rect,
@@ -1126,26 +882,34 @@ moz_gtk_scrollbar_trough_paint(WidgetNod
GtkTextDirection direction)
{
if (flags & MOZ_GTK_TRACK_OPAQUE) {
- GtkStyleContext* style =
- gtk_widget_get_style_context(GTK_WIDGET(gProtoWindow));
- gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW, direction);
+ gtk_render_background(style, cr,
+ rect->x, rect->y, rect->width, rect->height);
+ ReleaseStyleContext(style);
}
- GtkStyleContext* style =
- ClaimStyleContext(widget == MOZ_GTK_SCROLLBAR_HORIZONTAL ?
- MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL :
- MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL,
- direction);
- // TODO - integate with ClaimStyleContext()?
- gtk_style_context_set_direction(style, direction);
+ bool isHorizontal = (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL);
+ GtkStyleContext* 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);
+ // 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);
- if (state->focused) {
- gtk_render_focus(style, cr,
- rect->x, rect->y, rect->width, rect->height);
+ 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,
+ direction);
+ moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
@@ -1160,12 +924,7 @@ moz_gtk_scrollbar_thumb_paint(WidgetNode
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
GtkBorder margin;
- GtkStyleContext* style = ClaimStyleContext(widget, direction);
-
- // TODO - integate those with ClaimStyleContext()?
- gtk_style_context_set_state(style, state_flags);
- gtk_style_context_set_direction(style, direction);
-
+ GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags);
gtk_style_context_get_margin (style, state_flags, &margin);
gtk_render_slider(style, cr,
@@ -1185,17 +944,10 @@ static gint
moz_gtk_spin_paint(cairo_t *cr, GdkRectangle* rect,
GtkTextDirection direction)
{
- GtkStyleContext* style;
-
- ensure_spin_widget();
- gtk_widget_set_direction(gSpinWidget, direction);
- style = gtk_widget_get_style_context(gSpinWidget);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON, 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);
- gtk_style_context_restore(style);
-
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1204,21 +956,14 @@ moz_gtk_spin_updown_paint(cairo_t *cr, G
gboolean isDown, GtkWidgetState* state,
GtkTextDirection direction)
{
- GdkRectangle arrow_rect;
- GtkStyleContext* style;
-
- ensure_spin_widget();
- style = gtk_widget_get_style_context(gSpinWidget);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON);
- gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
- gtk_widget_set_direction(gSpinWidget, direction);
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON, direction,
+ GetStateFlagsFromGtkWidgetState(state));
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);
-
/* hard code these values */
+ GdkRectangle arrow_rect;
arrow_rect.width = 6;
arrow_rect.height = 6;
arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2;
@@ -1229,7 +974,8 @@ moz_gtk_spin_updown_paint(cairo_t *cr, G
isDown ? ARROW_DOWN : ARROW_UP,
arrow_rect.x, arrow_rect.y,
arrow_rect.width);
- gtk_style_context_restore(style);
+
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1295,8 +1041,8 @@ moz_gtk_scale_thumb_paint(cairo_t *cr, G
gtk_widget_set_direction(widget, direction);
style = gtk_widget_get_style_context(widget);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER);
gtk_style_context_save(style);
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER);
gtk_style_context_set_state(style, state_flags);
/* determine the thumb size, and position the thumb in the center in the opposite axis
*/
@@ -1321,20 +1067,12 @@ moz_gtk_gripper_paint(cairo_t *cr, GdkRe
GtkWidgetState* state,
GtkTextDirection direction)
{
- GtkStyleContext* style;
-
- ensure_handlebox_widget();
- gtk_widget_set_direction(gHandleBoxWidget, direction);
-
- style = gtk_widget_get_style_context(gHandleBoxWidget);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
- gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
-
+ GtkStyleContext* style =
+ ClaimStyleContext(MOZ_GTK_GRIPPER, direction,
+ GetStateFlagsFromGtkWidgetState(state));
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_style_context_restore(style);
-
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1435,6 +1173,38 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect
return MOZ_GTK_SUCCESS;
}
+static gint
+moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect,
+ GtkWidgetState* state,
+ GtkTextDirection direction)
+{
+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+
+ 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);
+
+ 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);
+
+ ReleaseStyleContext(style);
+
+ return MOZ_GTK_SUCCESS;
+}
+
static gint
moz_gtk_treeview_paint(cairo_t *cr, GdkRectangle* rect,
GtkWidgetState* state,
@@ -1447,18 +1217,13 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR
GtkBorder border;
ensure_tree_view_widget();
- ensure_scrolled_window_widget();
-
gtk_widget_set_direction(gTreeViewWidget, direction);
- gtk_widget_set_direction(gScrolledWindowWidget, direction);
/* only handle disabled and normal states, otherwise the whole background
* area will be painted differently with other states */
state_flags = state->disabled ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL;
- style = gtk_widget_get_style_context(gScrolledWindowWidget);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);
+ style = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction);
gtk_style_context_get_border(style, state_flags, &border);
xthickness = border.left;
ythickness = border.top;
@@ -1473,7 +1238,7 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR
rect->height - 2 * ythickness);
gtk_render_frame(style, cr,
rect->x, rect->y, rect->width, rect->height);
- gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
gtk_style_context_restore(style_tree);
return MOZ_GTK_SUCCESS;
}
@@ -1648,20 +1413,9 @@ moz_gtk_arrow_paint(cairo_t *cr, GdkRect
GtkWidgetState* state,
GtkArrowType arrow_type, GtkTextDirection direction)
{
- GtkStyleContext* style;
- GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
GdkRectangle arrow_rect;
gdouble arrow_angle;
- ensure_button_arrow_widget();
- style = gtk_widget_get_style_context(gButtonArrowWidget);
- gtk_style_context_save(style);
- gtk_style_context_set_state(style, state_flags);
- gtk_widget_set_direction(gButtonArrowWidget, direction);
-
- calculate_arrow_rect(gButtonArrowWidget, rect, &arrow_rect,
- direction);
-
if (direction == GTK_TEXT_DIR_RTL) {
arrow_type = (arrow_type == GTK_ARROW_LEFT) ?
GTK_ARROW_RIGHT : GTK_ARROW_LEFT;
@@ -1680,10 +1434,17 @@ moz_gtk_arrow_paint(cairo_t *cr, GdkRect
arrow_angle = ARROW_UP;
break;
}
- if (arrow_type != GTK_ARROW_NONE)
- gtk_render_arrow(style, cr, arrow_angle,
- arrow_rect.x, arrow_rect.y, arrow_rect.width);
- gtk_style_context_restore(style);
+ if (arrow_type == GTK_ARROW_NONE)
+ return MOZ_GTK_SUCCESS;
+
+ calculate_arrow_rect(GetWidget(MOZ_GTK_BUTTON_ARROW), rect, &arrow_rect,
+ direction);
+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_BUTTON_ARROW,
+ direction, state_flags);
+ gtk_render_arrow(style, cr, arrow_angle,
+ arrow_rect.x, arrow_rect.y, arrow_rect.width);
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1776,19 +1537,10 @@ static gint
moz_gtk_toolbar_paint(cairo_t *cr, GdkRectangle* rect,
GtkTextDirection direction)
{
- GtkStyleContext* style;
-
- ensure_toolbar_widget();
- gtk_widget_set_direction(gToolbarWidget, direction);
-
- style = gtk_widget_get_style_context(gToolbarWidget);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLBAR);
-
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR, 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);
- gtk_style_context_restore(style);
-
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1798,7 +1550,6 @@ static gint
moz_gtk_toolbar_separator_paint(cairo_t *cr, GdkRectangle* rect,
GtkTextDirection direction)
{
- GtkStyleContext* style;
gint separator_width;
gint paint_width;
gboolean wide_separators;
@@ -1807,16 +1558,14 @@ moz_gtk_toolbar_separator_paint(cairo_t
const double start_fraction = 0.2;
const double end_fraction = 0.8;
- ensure_toolbar_separator_widget();
- gtk_widget_set_direction(gToolbarSeparatorWidget, direction);
-
- style = gtk_widget_get_style_context(gToolbarSeparatorWidget);
-
- gtk_style_context_get_style(gtk_widget_get_style_context(gToolbarWidget),
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR);
+ gtk_style_context_get_style(style,
"wide-separators", &wide_separators,
"separator-width", &separator_width,
NULL);
+ ReleaseStyleContext(style);
+ style = ClaimStyleContext(MOZ_GTK_TOOLBAR_SEPARATOR, direction);
if (wide_separators) {
if (separator_width > rect->width)
separator_width = rect->width;
@@ -1840,7 +1589,7 @@ moz_gtk_toolbar_separator_paint(cairo_t
rect->x + (rect->width - paint_width) / 2,
rect->y + rect->height * end_fraction);
}
-
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1848,14 +1597,10 @@ static gint
moz_gtk_tooltip_paint(cairo_t *cr, GdkRectangle* rect,
GtkTextDirection direction)
{
- GtkStyleContext* style;
-
- ensure_tooltip_widget();
- gtk_widget_set_direction(gTooltipWidget, direction);
-
- style = gtk_widget_get_style_context(gTooltipWidget);
+ 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);
return MOZ_GTK_SUCCESS;
}
@@ -1870,14 +1615,11 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRe
// 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.
- ensure_text_view_widget();
- gtk_widget_set_direction(gTextViewWidget, GTK_TEXT_DIR_LTR);
-
- style = gtk_widget_get_style_context(gTextViewWidget);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_VIEW);
+ 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);
- gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
// Workaround unico not respecting the text direction for resizers.
// See bug 1174248.
@@ -1891,7 +1633,7 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRe
gtk_render_handle(style, cr, rect->x, rect->y, rect->width, rect->height);
cairo_restore(cr);
- gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1900,16 +1642,9 @@ static gint
moz_gtk_frame_paint(cairo_t *cr, GdkRectangle* rect,
GtkTextDirection direction)
{
- GtkStyleContext* style;
-
- ensure_frame_widget();
- gtk_widget_set_direction(gFrameWidget, direction);
- style = gtk_widget_get_style_context(gFrameWidget);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);
-
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_FRAME, direction);
gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
- gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1917,18 +1652,11 @@ static gint
moz_gtk_progressbar_paint(cairo_t *cr, GdkRectangle* rect,
GtkTextDirection direction)
{
- GtkStyleContext* style;
-
- ensure_progress_widget();
- gtk_widget_set_direction(gProgressWidget, direction);
-
- style = gtk_widget_get_style_context(gProgressWidget);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
-
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH,
+ 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);
- gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1940,13 +1668,15 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
{
GtkStyleContext* style;
- ensure_progress_widget();
- gtk_widget_set_direction(gProgressWidget, direction);
-
- style = gtk_widget_get_style_context(gProgressWidget);
- gtk_style_context_save(style);
- gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR);
+ 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);
+ }
if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
@@ -1990,7 +1720,7 @@ moz_gtk_progress_chunk_paint(cairo_t *cr
} else {
gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height);
}
- gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -2324,10 +2054,10 @@ moz_gtk_menu_bar_paint(cairo_t *cr, GdkR
{
GtkStyleContext* style;
- ensure_menu_bar_widget();
- gtk_widget_set_direction(gMenuBarWidget, direction);
+ GtkWidget* widget = GetWidget(MOZ_GTK_MENUBAR);
+ gtk_widget_set_direction(widget, direction);
- style = gtk_widget_get_style_context(gMenuBarWidget);
+ style = gtk_widget_get_style_context(widget);
gtk_style_context_save(style);
gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
@@ -2343,14 +2073,14 @@ moz_gtk_menu_popup_paint(cairo_t *cr, Gd
{
GtkStyleContext* style;
- ensure_menu_popup_widget();
- gtk_widget_set_direction(gMenuPopupWidget, direction);
+ GtkWidget* widget = GetWidget(MOZ_GTK_MENUPOPUP);
+ gtk_widget_set_direction(widget, direction);
// Draw a backing toplevel. This fixes themes that don't provide a menu
// background, and depend on the GtkMenu's implementation window to provide it.
moz_gtk_window_paint(cr, rect, direction);
- style = gtk_widget_get_style_context(gMenuPopupWidget);
+ style = gtk_widget_get_style_context(widget);
gtk_style_context_save(style);
gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENU);
@@ -2373,12 +2103,10 @@ moz_gtk_menu_separator_paint(cairo_t *cr
gint x, y, w;
GtkBorder padding;
- ensure_menu_separator_widget();
- gtk_widget_set_direction(gMenuSeparatorWidget, direction);
-
- border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget));
-
- style = gtk_widget_get_style_context(gMenuSeparatorWidget);
+ border_width =
+ gtk_container_get_border_width(GTK_CONTAINER(
+ GetWidget(MOZ_GTK_MENUSEPARATOR)));
+ style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR, direction);
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
x = rect->x + border_width;
@@ -2408,42 +2136,36 @@ moz_gtk_menu_separator_paint(cairo_t *cr
}
gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
// See gtk_menu_item_draw() for reference.
static gint
-moz_gtk_menu_item_paint(cairo_t *cr, GdkRectangle* rect,
- GtkWidgetState* state,
- gint flags, GtkTextDirection direction)
+moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
+ GtkWidgetState* state, GtkTextDirection direction)
{
- GtkStyleContext* style;
- GtkWidget* item_widget;
- guint border_width;
gint x, y, w, h;
if (state->inHover && !state->disabled) {
- if (flags & MOZ_TOPLEVEL_MENU_ITEM) {
- ensure_menu_bar_item_widget();
- item_widget = gMenuBarItemWidget;
- } else {
- ensure_menu_item_widget();
- item_widget = gMenuItemWidget;
- }
- style = gtk_widget_get_style_context(item_widget);
- gtk_style_context_save(style);
+ guint border_width =
+ gtk_container_get_border_width(GTK_CONTAINER(GetWidget(widget)));
+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
+ GtkStyleContext* style =
+ ClaimStyleContext(widget, direction, state_flags);
- if (flags & MOZ_TOPLEVEL_MENU_ITEM) {
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
+ 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_widget_set_direction(item_widget, direction);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM);
- gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state));
-
- border_width = gtk_container_get_border_width(GTK_CONTAINER(item_widget));
-
x = rect->x + border_width;
y = rect->y + border_width;
w = rect->width - border_width * 2;
@@ -2451,7 +2173,11 @@ moz_gtk_menu_item_paint(cairo_t *cr, Gdk
gtk_render_background(style, cr, x, y, w, h);
gtk_render_frame(style, cr, x, y, w, h);
- gtk_style_context_restore(style);
+
+ if (pre_3_6) {
+ gtk_style_context_restore(style);
+ }
+ ReleaseStyleContext(style);
}
return MOZ_GTK_SUCCESS;
@@ -2462,21 +2188,13 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd
GtkWidgetState* state,
GtkTextDirection direction)
{
- GtkStyleContext* style;
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
-
- ensure_menu_item_widget();
- gtk_widget_set_direction(gMenuItemWidget, direction);
-
- style = gtk_widget_get_style_context(gMenuItemWidget);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM);
- gtk_style_context_set_state(style, state_flags);
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_MENUITEM,
+ direction, state_flags);
gtk_render_arrow(style, cr,
(direction == GTK_TEXT_DIR_LTR) ? ARROW_RIGHT : ARROW_LEFT,
rect->x, rect->y, rect->width);
- gtk_style_context_restore(style);
-
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -2494,7 +2212,7 @@ moz_gtk_check_menu_item_paint(cairo_t *c
gint indicator_size, horizontal_padding;
gint x, y;
- moz_gtk_menu_item_paint(cr, rect, state, FALSE, direction);
+ moz_gtk_menu_item_paint(MOZ_GTK_MENUITEM, cr, rect, state, direction);
ensure_check_menu_item_widget();
gtk_widget_set_direction(gCheckMenuItemWidget, direction);
@@ -2545,21 +2263,13 @@ static gint
moz_gtk_info_bar_paint(cairo_t *cr, GdkRectangle* rect,
GtkWidgetState* state)
{
- GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
- GtkStyleContext *style;
- ensure_info_bar();
-
- style = gtk_widget_get_style_context(gInfoBar);
- gtk_style_context_save(style);
-
- gtk_style_context_set_state(style, state_flags);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_INFO);
-
+ GtkStyleContext *style =
+ ClaimStyleContext(MOZ_GTK_INFO_BAR, GTK_TEXT_DIR_LTR,
+ GetStateFlagsFromGtkWidgetState(state));
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_style_context_restore(style);
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -2605,18 +2315,18 @@ moz_gtk_get_widget_border(WidgetNodeType
case MOZ_GTK_BUTTON:
case MOZ_GTK_TOOLBAR_BUTTON:
{
- ensure_button_widget();
- style = gtk_widget_get_style_context(gButtonWidget);
+ style = ClaimStyleContext(MOZ_GTK_BUTTON);
- *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gButtonWidget));
+ *left = *top = *right = *bottom =
+ gtk_container_get_border_width(GTK_CONTAINER(GetWidget(MOZ_GTK_BUTTON)));
if (widget == MOZ_GTK_TOOLBAR_BUTTON) {
gtk_style_context_save(style);
gtk_style_context_add_class(style, "image-button");
}
-
+
moz_gtk_add_style_padding(style, left, top, right, bottom);
-
+
if (widget == MOZ_GTK_TOOLBAR_BUTTON)
gtk_style_context_restore(style);
@@ -2624,12 +2334,13 @@ moz_gtk_get_widget_border(WidgetNodeType
// -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);
return MOZ_GTK_SUCCESS;
}
case MOZ_GTK_ENTRY:
{
- ensure_entry_widget();
- style = gtk_widget_get_style_context(gEntryWidget);
+ style = ClaimStyleContext(MOZ_GTK_ENTRY);
// XXX: Subtract 1 pixel from the padding to account for the default
// padding in forms.css. See bug 1187385.
@@ -2637,16 +2348,15 @@ moz_gtk_get_widget_border(WidgetNodeType
moz_gtk_add_style_padding(style, left, top, right, bottom);
moz_gtk_add_style_border(style, left, top, right, bottom);
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
+ case MOZ_GTK_TEXT_VIEW:
case MOZ_GTK_TREEVIEW:
{
- ensure_scrolled_window_widget();
- style = gtk_widget_get_style_context(gScrolledWindowWidget);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME);
+ style = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW);
moz_gtk_add_style_border(style, left, top, right, bottom);
- gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
case MOZ_GTK_TREE_HEADER_CELL:
@@ -2726,14 +2436,12 @@ moz_gtk_get_widget_border(WidgetNodeType
w = gTabWidget;
break;
case MOZ_GTK_PROGRESSBAR:
- ensure_progress_widget();
- w = gProgressWidget;
+ w = GetWidget(MOZ_GTK_PROGRESSBAR);
break;
case MOZ_GTK_SPINBUTTON_ENTRY:
case MOZ_GTK_SPINBUTTON_UP:
case MOZ_GTK_SPINBUTTON_DOWN:
- ensure_spin_widget();
- w = gSpinWidget;
+ w = GetWidget(MOZ_GTK_SPINBUTTON);
break;
case MOZ_GTK_SCALE_HORIZONTAL:
ensure_scale_widget();
@@ -2744,8 +2452,7 @@ moz_gtk_get_widget_border(WidgetNodeType
w = gVScaleWidget;
break;
case MOZ_GTK_FRAME:
- ensure_frame_widget();
- w = gFrameWidget;
+ w = GetWidget(MOZ_GTK_FRAME);
break;
case MOZ_GTK_CHECKBUTTON_CONTAINER:
case MOZ_GTK_RADIOBUTTON_CONTAINER:
@@ -2761,19 +2468,17 @@ moz_gtk_get_widget_border(WidgetNodeType
return MOZ_GTK_SUCCESS;
}
case MOZ_GTK_MENUPOPUP:
- ensure_menu_popup_widget();
- w = gMenuPopupWidget;
+ w = GetWidget(MOZ_GTK_MENUPOPUP);
break;
+ case MOZ_GTK_MENUBARITEM:
case MOZ_GTK_MENUITEM:
case MOZ_GTK_CHECKMENUITEM:
case MOZ_GTK_RADIOMENUITEM:
{
- if (widget == MOZ_GTK_MENUITEM) {
- ensure_menu_item_widget();
- ensure_menu_bar_item_widget();
- w = gMenuItemWidget;
- }
- else {
+ if (widget == MOZ_GTK_MENUBARITEM || widget == MOZ_GTK_MENUITEM) {
+ // Bug 1274143 for MOZ_GTK_MENUBARITEM
+ w = GetWidget(MOZ_GTK_MENUITEM);
+ } else {
ensure_check_menu_item_widget();
w = gCheckMenuItemWidget;
}
@@ -2784,9 +2489,16 @@ moz_gtk_get_widget_border(WidgetNodeType
return MOZ_GTK_SUCCESS;
}
case MOZ_GTK_INFO_BAR:
- ensure_info_bar();
- w = gInfoBar;
+ w = GetWidget(MOZ_GTK_INFO_BAR);
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);
+ return MOZ_GTK_SUCCESS;
+ }
/* These widgets have no borders, since they are not containers. */
case MOZ_GTK_CHECKBUTTON_LABEL:
case MOZ_GTK_RADIOBUTTON_LABEL:
@@ -2810,7 +2522,6 @@ moz_gtk_get_widget_border(WidgetNodeType
case MOZ_GTK_MENUSEPARATOR:
/* These widgets have no borders.*/
case MOZ_GTK_SPINBUTTON:
- case MOZ_GTK_TOOLTIP:
case MOZ_GTK_WINDOW:
case MOZ_GTK_RESIZER:
case MOZ_GTK_MENUARROW:
@@ -2908,8 +2619,7 @@ moz_gtk_get_arrow_size(WidgetNodeType wi
widget = gComboBoxArrowWidget;
break;
default:
- ensure_button_arrow_widget();
- widget = gButtonArrowWidget;
+ widget = GetWidget(MOZ_GTK_BUTTON_ARROW);
break;
}
@@ -2924,11 +2634,9 @@ moz_gtk_get_toolbar_separator_width(gint
{
gboolean wide_separators;
gint separator_width;
- GtkStyleContext* style;
GtkBorder border;
- ensure_toolbar_widget();
- style = gtk_widget_get_style_context(gToolbarWidget);
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR);
gtk_style_context_get_style(style,
"space-size", size,
"wide-separators", &wide_separators,
@@ -2937,17 +2645,18 @@ moz_gtk_get_toolbar_separator_width(gint
/* Just in case... */
gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border);
*size = MAX(*size, (wide_separators ? separator_width : border.left));
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
gint
moz_gtk_get_expander_size(gint* size)
{
- ensure_expander_widget();
- gtk_style_context_get_style(gtk_widget_get_style_context(gExpanderWidget),
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_EXPANDER);
+ gtk_style_context_get_style(style,
"expander-size", size,
NULL);
-
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -2972,11 +2681,11 @@ moz_gtk_get_menu_separator_height(gint *
GtkStyleContext* style;
guint border_width;
- ensure_menu_separator_widget();
-
- border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget));
+ border_width =
+ gtk_container_get_border_width(GTK_CONTAINER(
+ GetWidget(MOZ_GTK_MENUSEPARATOR)));
- style = gtk_widget_get_style_context(gMenuSeparatorWidget);
+ style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR);
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
gtk_style_context_save(style);
@@ -2988,6 +2697,7 @@ moz_gtk_get_menu_separator_height(gint *
NULL);
gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
*size = padding.top + padding.bottom + border_width*2;
*size += (wide_separators) ? separator_height : 1;
@@ -2998,8 +2708,7 @@ moz_gtk_get_menu_separator_height(gint *
void
moz_gtk_get_entry_min_height(gint* height)
{
- ensure_entry_widget();
- GtkStyleContext* style = gtk_widget_get_style_context(gEntryWidget);
+ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_ENTRY);
if (!gtk_check_version(3, 20, 0)) {
gtk_style_context_get(style, gtk_style_context_get_state(style),
"min-height", height,
@@ -3014,6 +2723,7 @@ moz_gtk_get_entry_min_height(gint* heigh
gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding);
*height += (border.top + border.bottom + padding.top + padding.bottom);
+ ReleaseStyleContext(style);
}
void
@@ -3094,8 +2804,7 @@ moz_gtk_images_in_buttons()
gboolean result;
GtkSettings* settings;
- ensure_button_widget();
- settings = gtk_widget_get_settings(gButtonWidget);
+ settings = gtk_widget_get_settings(GetWidget(MOZ_GTK_BUTTON));
g_object_get(settings, "gtk-button-images", &result, NULL);
return result;
@@ -3116,14 +2825,14 @@ moz_gtk_widget_paint(WidgetNodeType widg
case MOZ_GTK_BUTTON:
case MOZ_GTK_TOOLBAR_BUTTON:
if (state->depressed) {
- ensure_toggle_button_widget();
return moz_gtk_button_paint(cr, rect, state,
(GtkReliefStyle) flags,
- gToggleButtonWidget, direction);
+ GetWidget(MOZ_GTK_TOGGLE_BUTTON),
+ direction);
}
- ensure_button_widget();
return moz_gtk_button_paint(cr, rect, state,
- (GtkReliefStyle) flags, gButtonWidget,
+ (GtkReliefStyle) flags,
+ GetWidget(MOZ_GTK_BUTTON),
direction);
break;
case MOZ_GTK_CHECKBUTTON:
@@ -3171,9 +2880,9 @@ moz_gtk_widget_paint(WidgetNodeType widg
state, direction);
break;
case MOZ_GTK_SPINBUTTON_ENTRY:
- ensure_spin_widget();
+ // TODO - use MOZ_GTK_SPINBUTTON_ENTRY style directly
return moz_gtk_entry_paint(cr, rect, state,
- gSpinWidget, direction);
+ GetWidget(MOZ_GTK_SPINBUTTON), direction);
break;
case MOZ_GTK_GRIPPER:
return moz_gtk_gripper_paint(cr, rect, state,
@@ -3198,9 +2907,11 @@ moz_gtk_widget_paint(WidgetNodeType widg
(GtkExpanderStyle) flags, direction);
break;
case MOZ_GTK_ENTRY:
- ensure_entry_widget();
- return moz_gtk_entry_paint(cr, rect, state,
- gEntryWidget, direction);
+ return moz_gtk_entry_paint(cr, rect, state, GetWidget(MOZ_GTK_ENTRY),
+ direction);
+ break;
+ case MOZ_GTK_TEXT_VIEW:
+ return moz_gtk_text_view_paint(cr, rect, state, direction);
break;
case MOZ_GTK_DROPDOWN:
return moz_gtk_combo_box_paint(cr, rect, state, direction);
@@ -3271,9 +2982,9 @@ moz_gtk_widget_paint(WidgetNodeType widg
return moz_gtk_menu_separator_paint(cr, rect,
direction);
break;
+ case MOZ_GTK_MENUBARITEM:
case MOZ_GTK_MENUITEM:
- return moz_gtk_menu_item_paint(cr, rect, state, flags,
- direction);
+ return moz_gtk_menu_item_paint(widget, cr, rect, state, direction);
break;
case MOZ_GTK_MENUARROW:
return moz_gtk_menu_arrow_paint(cr, rect, state,
@@ -3333,25 +3044,16 @@ gboolean moz_gtk_has_scrollbar_buttons(v
gint
moz_gtk_shutdown()
{
- if (gTooltipWidget)
- gtk_widget_destroy(gTooltipWidget);
/* This will destroy all of our widgets */
-
ResetWidgetCache();
/* TODO - replace it with appropriate widget */
if (gTreeHeaderSortArrowWidget)
gtk_widget_destroy(gTreeHeaderSortArrowWidget);
- gProtoWindow = NULL;
gProtoLayout = NULL;
- gButtonWidget = NULL;
- gToggleButtonWidget = NULL;
- gButtonArrowWidget = NULL;
- gSpinWidget = NULL;
gHScaleWidget = NULL;
gVScaleWidget = NULL;
- gEntryWidget = NULL;
gComboBoxWidget = NULL;
gComboBoxButtonWidget = NULL;
gComboBoxSeparatorWidget = NULL;
@@ -3360,29 +3062,15 @@ moz_gtk_shutdown()
gComboBoxEntryButtonWidget = NULL;
gComboBoxEntryArrowWidget = NULL;
gComboBoxEntryTextareaWidget = NULL;
- gHandleBoxWidget = NULL;
- gToolbarWidget = NULL;
- gFrameWidget = NULL;
- gProgressWidget = NULL;
gTabWidget = NULL;
- gTextViewWidget = nullptr;
- gTooltipWidget = NULL;
- gMenuBarWidget = NULL;
- gMenuBarItemWidget = NULL;
- gMenuPopupWidget = NULL;
- gMenuItemWidget = NULL;
gImageMenuItemWidget = NULL;
gCheckMenuItemWidget = NULL;
gTreeViewWidget = NULL;
gMiddleTreeViewColumn = NULL;
gTreeHeaderCellWidget = NULL;
gTreeHeaderSortArrowWidget = NULL;
- gExpanderWidget = NULL;
- gToolbarSeparatorWidget = NULL;
- gMenuSeparatorWidget = NULL;
gHPanedWidget = NULL;
gVPanedWidget = NULL;
- gScrolledWindowWidget = NULL;
is_initialized = FALSE;
diff -up firefox-48.0/widget/gtk/gtkdrawing.h.old firefox-48.0/widget/gtk/gtkdrawing.h
--- firefox-48.0/widget/gtk/gtkdrawing.h.old 2016-07-25 22:22:07.000000000 +0200
+++ firefox-48.0/widget/gtk/gtkdrawing.h 2016-07-28 09:50:25.000000000 +0200
@@ -69,12 +69,6 @@ typedef enum {
MOZ_GTK_TAB_SELECTED = 1 << 10
} GtkTabFlags;
-/** flags for menuitems **/
-typedef enum {
- /* menuitem is part of the menubar */
- MOZ_TOPLEVEL_MENU_ITEM = 1 << 0
-} GtkMenuItemFlags;
-
/* function type for moz_gtk_enable_style_props */
typedef gint (*style_prop_t)(GtkStyle*, const gchar*, gint);
@@ -93,6 +87,10 @@ typedef enum {
MOZ_GTK_BUTTON,
/* Paints a button with image and no text */
MOZ_GTK_TOOLBAR_BUTTON,
+ /* Paints a toggle button */
+ MOZ_GTK_TOGGLE_BUTTON,
+ /* Paints a button arrow */
+ MOZ_GTK_BUTTON_ARROW,
/* Paints the container part of a GtkCheckButton. */
MOZ_GTK_CHECKBUTTON_CONTAINER,
@@ -115,6 +113,7 @@ typedef enum {
/* Horizontal GtkScrollbar counterparts */
MOZ_GTK_SCROLLBAR_HORIZONTAL,
+ MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL,
/* Paints the trough (track) of a GtkScrollbar. */
MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL,
/* Paints the slider (thumb) of a GtkScrollbar. */
@@ -122,6 +121,7 @@ typedef enum {
/* Vertical GtkScrollbar counterparts */
MOZ_GTK_SCROLLBAR_VERTICAL,
+ MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL,
MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL,
MOZ_GTK_SCROLLBAR_THUMB_VERTICAL,
@@ -140,6 +140,10 @@ typedef enum {
MOZ_GTK_GRIPPER,
/* Paints a GtkEntry. */
MOZ_GTK_ENTRY,
+ /* Paints a GtkExpander. */
+ MOZ_GTK_EXPANDER,
+ /* Paints a GtkTextView. */
+ MOZ_GTK_TEXT_VIEW,
/* Paints a GtkOptionMenu. */
MOZ_GTK_DROPDOWN,
/* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */
@@ -159,6 +163,8 @@ typedef enum {
MOZ_GTK_RESIZER,
/* Paints a GtkProgressBar. */
MOZ_GTK_PROGRESSBAR,
+ /* Paints a trough (track) of a GtkProgressBar */
+ MOZ_GTK_PROGRESS_TROUGH,
/* Paints a progress chunk of a GtkProgressBar. */
MOZ_GTK_PROGRESS_CHUNK,
/* Paints a progress chunk of an indeterminated GtkProgressBar. */
@@ -187,7 +193,9 @@ typedef enum {
MOZ_GTK_MENUARROW,
/* Paints an arrow in a toolbar button. flags is a GtkArrowType. */
MOZ_GTK_TOOLBARBUTTON_ARROW,
- /* Paints items of menubar and popups. */
+ /* Paints items of menubar. */
+ MOZ_GTK_MENUBARITEM,
+ /* Paints items of popup menus. */
MOZ_GTK_MENUITEM,
MOZ_GTK_CHECKMENUITEM,
MOZ_GTK_RADIOMENUITEM,
@@ -202,6 +210,8 @@ typedef enum {
MOZ_GTK_WINDOW_CONTAINER,
/* Paints a GtkInfoBar, for notifications. */
MOZ_GTK_INFO_BAR,
+ /* Used for scrolled window shell. */
+ MOZ_GTK_SCROLLED_WINDOW,
MOZ_GTK_WIDGET_NODE_COUNT
} WidgetNodeType;
diff -up firefox-48.0/widget/gtk/mozgtk/mozgtk.c.old firefox-48.0/widget/gtk/mozgtk/mozgtk.c
--- firefox-48.0/widget/gtk/mozgtk/mozgtk.c.old 2016-07-28 11:19:55.923461294 +0200
+++ firefox-48.0/widget/gtk/mozgtk/mozgtk.c 2016-07-28 11:25:24.095940924 +0200
@@ -587,6 +587,11 @@ STUB(gtk_color_chooser_get_type)
STUB(gtk_color_chooser_set_rgba)
STUB(gtk_color_chooser_get_rgba)
STUB(gtk_color_chooser_set_use_alpha)
+STUB(gtk_check_menu_item_new)
+STUB(gtk_widget_path_append_for_widget)
+STUB(gtk_style_context_get_direction)
+STUB(gtk_style_context_invalidate)
+STUB(gtk_tooltip_get_type)
#endif
#ifdef GTK2_SYMBOLS
diff -up firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp.old firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp
--- firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp.old 2016-07-25 22:22:07.000000000 +0200
+++ firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp 2016-07-28 11:35:21.804656790 +0200
@@ -354,10 +354,8 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
if (isTopLevel) {
aState->inHover = menuFrame->IsOpen();
- *aWidgetFlags |= MOZ_TOPLEVEL_MENU_ITEM;
} else {
aState->inHover = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive);
- *aWidgetFlags &= ~MOZ_TOPLEVEL_MENU_ITEM;
}
aState->active = FALSE;
@@ -510,8 +508,14 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
break;
case NS_THEME_NUMBER_INPUT:
case NS_THEME_TEXTFIELD:
+ aGtkWidgetType = MOZ_GTK_ENTRY;
+ break;
case NS_THEME_TEXTFIELD_MULTILINE:
+#if (MOZ_WIDGET_GTK == 3)
+ aGtkWidgetType = MOZ_GTK_TEXT_VIEW;
+#else
aGtkWidgetType = MOZ_GTK_ENTRY;
+#endif
break;
case NS_THEME_LISTBOX:
case NS_THEME_TREEVIEW:
@@ -673,6 +677,13 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
aGtkWidgetType = MOZ_GTK_MENUPOPUP;
break;
case NS_THEME_MENUITEM:
+ {
+ nsMenuFrame *menuFrame = do_QueryFrame(aFrame);
+ if (menuFrame && menuFrame->IsOnMenuBar()) {
+ aGtkWidgetType = MOZ_GTK_MENUBARITEM;
+ break;
+ }
+ }
aGtkWidgetType = MOZ_GTK_MENUITEM;
break;
case NS_THEME_MENUSEPARATOR:
diff -up firefox-48.0/widget/gtk/WidgetStyleCache.cpp.old firefox-48.0/widget/gtk/WidgetStyleCache.cpp
--- firefox-48.0/widget/gtk/WidgetStyleCache.cpp.old 2016-07-25 22:22:07.000000000 +0200
+++ firefox-48.0/widget/gtk/WidgetStyleCache.cpp 2016-07-28 09:50:25.000000000 +0200
@@ -22,7 +22,7 @@ static bool sStyleContextNeedsRestore;
static GtkStyleContext* sCurrentStyleContext;
#endif
static GtkStyleContext*
-GetStyleInternal(WidgetNodeType aNodeType);
+GetCssNodeStyleInternal(WidgetNodeType aNodeType);
static GtkWidget*
CreateWindowWidget()
@@ -67,12 +67,175 @@ CreateCheckboxWidget()
static GtkWidget*
CreateRadiobuttonWidget()
{
- GtkWidget* widget = gtk_radio_button_new_with_label(NULL, "M");
+ GtkWidget* widget = gtk_radio_button_new_with_label(nullptr, "M");
AddToWindowContainer(widget);
return widget;
}
static GtkWidget*
+CreateMenuBarWidget()
+{
+ GtkWidget* widget = gtk_menu_bar_new();
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateMenuPopupWidget()
+{
+ GtkWidget* widget = gtk_menu_new();
+ gtk_menu_attach_to_widget(GTK_MENU(widget), GetWidget(MOZ_GTK_WINDOW),
+ nullptr);
+ return widget;
+}
+
+static GtkWidget*
+CreateMenuItemWidget(WidgetNodeType aShellType)
+{
+ GtkWidget* widget = gtk_menu_item_new();
+ gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(aShellType)), widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateProgressWidget()
+{
+ GtkWidget* widget = gtk_progress_bar_new();
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateTooltipWidget()
+{
+ MOZ_ASSERT(gtk_check_version(3, 20, 0) != nullptr,
+ "CreateTooltipWidget should be used for Gtk < 3.20 only.");
+ GtkWidget* widget = CreateWindowWidget();
+ GtkStyleContext* style = gtk_widget_get_style_context(widget);
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP);
+ return widget;
+}
+
+static GtkWidget*
+CreateExpanderWidget()
+{
+ GtkWidget* widget = gtk_expander_new("M");
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateFrameWidget()
+{
+ GtkWidget* widget = gtk_frame_new(nullptr);
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateGripperWidget()
+{
+ GtkWidget* widget = gtk_handle_box_new();
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateToolbarWidget()
+{
+ GtkWidget* widget = gtk_toolbar_new();
+ gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_GRIPPER)), widget);
+ gtk_widget_realize(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateToolbarSeparatorWidget()
+{
+ GtkWidget* widget = GTK_WIDGET(gtk_separator_tool_item_new());
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateInfoBarWidget()
+{
+ GtkWidget* widget = gtk_info_bar_new();
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateButtonWidget()
+{
+ GtkWidget* widget = gtk_button_new_with_label("M");
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateToggleButtonWidget()
+{
+ GtkWidget* widget = gtk_toggle_button_new();
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateButtonArrowWidget()
+{
+ GtkWidget* widget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+ gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_TOGGLE_BUTTON)), widget);
+ gtk_widget_realize(widget);
+ gtk_widget_show(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateSpinWidget()
+{
+ GtkWidget* widget = gtk_spin_button_new(nullptr, 1, 0);
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateEntryWidget()
+{
+ GtkWidget* widget = gtk_entry_new();
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateScrolledWindowWidget()
+{
+ GtkWidget* widget = gtk_scrolled_window_new(nullptr, nullptr);
+ AddToWindowContainer(widget);
+ return widget;
+}
+
+static GtkWidget*
+CreateTextViewWidget()
+{
+ GtkWidget* widget = gtk_text_view_new();
+ gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_SCROLLED_WINDOW)),
+ widget);
+ return widget;
+}
+
+static GtkWidget*
+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;
+}
+
+
+static GtkWidget*
CreateWidget(WidgetNodeType aWidgetType)
{
switch (aWidgetType) {
@@ -80,16 +243,54 @@ CreateWidget(WidgetNodeType aWidgetType)
return CreateWindowWidget();
case MOZ_GTK_WINDOW_CONTAINER:
return CreateWindowContainerWidget();
+ case MOZ_GTK_CHECKBUTTON_CONTAINER:
+ return CreateCheckboxWidget();
+ case MOZ_GTK_PROGRESSBAR:
+ return CreateProgressWidget();
+ case MOZ_GTK_RADIOBUTTON_CONTAINER:
+ return CreateRadiobuttonWidget();
case MOZ_GTK_SCROLLBAR_HORIZONTAL:
return CreateScrollbarWidget(aWidgetType,
GTK_ORIENTATION_HORIZONTAL);
case MOZ_GTK_SCROLLBAR_VERTICAL:
return CreateScrollbarWidget(aWidgetType,
GTK_ORIENTATION_VERTICAL);
- case MOZ_GTK_CHECKBUTTON_CONTAINER:
- return CreateCheckboxWidget();
- case MOZ_GTK_RADIOBUTTON_CONTAINER:
- return CreateRadiobuttonWidget();
+ case MOZ_GTK_MENUBAR:
+ return CreateMenuBarWidget();
+ case MOZ_GTK_MENUPOPUP:
+ return CreateMenuPopupWidget();
+ case MOZ_GTK_MENUBARITEM:
+ return CreateMenuItemWidget(MOZ_GTK_MENUBAR);
+ case MOZ_GTK_MENUITEM:
+ return CreateMenuItemWidget(MOZ_GTK_MENUPOPUP);
+ case MOZ_GTK_MENUSEPARATOR:
+ return CreateMenuSeparatorWidget();
+ case MOZ_GTK_EXPANDER:
+ return CreateExpanderWidget();
+ case MOZ_GTK_FRAME:
+ return CreateFrameWidget();
+ case MOZ_GTK_GRIPPER:
+ return CreateGripperWidget();
+ case MOZ_GTK_TOOLBAR:
+ return CreateToolbarWidget();
+ case MOZ_GTK_TOOLBAR_SEPARATOR:
+ return CreateToolbarSeparatorWidget();
+ case MOZ_GTK_INFO_BAR:
+ return CreateInfoBarWidget();
+ case MOZ_GTK_SPINBUTTON:
+ return CreateSpinWidget();
+ case MOZ_GTK_BUTTON:
+ return CreateButtonWidget();
+ case MOZ_GTK_TOGGLE_BUTTON:
+ return CreateToggleButtonWidget();
+ case MOZ_GTK_BUTTON_ARROW:
+ return CreateButtonArrowWidget();
+ case MOZ_GTK_ENTRY:
+ return CreateEntryWidget();
+ case MOZ_GTK_SCROLLED_WINDOW:
+ return CreateScrolledWindowWidget();
+ case MOZ_GTK_TEXT_VIEW:
+ return CreateTextViewWidget();
default:
/* Not implemented */
return nullptr;
@@ -107,17 +308,42 @@ GetWidget(WidgetNodeType aWidgetType)
return widget;
}
-static GtkStyleContext*
-CreateCSSNode(const char* aName, GtkStyleContext *aParentStyle)
+GtkStyleContext*
+CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle)
+{
+ GtkWidgetPath* path = aParentStyle ?
+ gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle)) :
+ gtk_widget_path_new();
+
+ // Work around https://bugzilla.gnome.org/show_bug.cgi?id=767312
+ // which exists in GTK+ 3.20.
+ gtk_widget_get_style_context(aWidget);
+
+ gtk_widget_path_append_for_widget(path, aWidget);
+ // Release any floating reference on aWidget.
+ g_object_ref_sink(aWidget);
+ g_object_unref(aWidget);
+
+ GtkStyleContext *context = gtk_style_context_new();
+ gtk_style_context_set_path(context, path);
+ gtk_style_context_set_parent(context, aParentStyle);
+ gtk_widget_path_unref(path);
+
+ return context;
+}
+
+GtkStyleContext*
+CreateCSSNode(const char* aName, GtkStyleContext* aParentStyle, GType aType)
{
static auto sGtkWidgetPathIterSetObjectName =
reinterpret_cast<void (*)(GtkWidgetPath *, gint, const char *)>
(dlsym(RTLD_DEFAULT, "gtk_widget_path_iter_set_object_name"));
- GtkWidgetPath* path =
- gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle));
+ GtkWidgetPath* path = aParentStyle ?
+ gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle)) :
+ gtk_widget_path_new();
- gtk_widget_path_append_type(path, G_TYPE_NONE);
+ gtk_widget_path_append_type(path, aType);
(*sGtkWidgetPathIterSetObjectName)(path, -1, aName);
@@ -130,95 +356,168 @@ CreateCSSNode(const char* aName, GtkStyl
}
static GtkStyleContext*
-GetChildNodeStyle(WidgetNodeType aStyleType,
- WidgetNodeType aWidgetType,
- const gchar* aStyleClass,
- WidgetNodeType aParentNodeType)
+CreateChildCSSNode(const char* aName, WidgetNodeType aParentNodeType)
{
- GtkStyleContext* style;
-
- if (gtk_check_version(3, 20, 0) != nullptr) {
- style = gtk_widget_get_style_context(sWidgetStorage[aWidgetType]);
-
- gtk_style_context_save(style);
- MOZ_ASSERT(!sStyleContextNeedsRestore);
- sStyleContextNeedsRestore = true;
-
- gtk_style_context_add_class(style, aStyleClass);
- }
- else {
- style = sStyleStorage[aStyleType];
- if (!style) {
- style = CreateCSSNode(aStyleClass, GetStyleInternal(aParentNodeType));
- MOZ_ASSERT(!sStyleContextNeedsRestore);
- sStyleStorage[aStyleType] = style;
- }
- }
+ return CreateCSSNode(aName, GetCssNodeStyleInternal(aParentNodeType));
+}
+static GtkStyleContext*
+GetWidgetStyleWithClass(WidgetNodeType aWidgetType, const gchar* aStyleClass)
+{
+ GtkStyleContext* style = gtk_widget_get_style_context(GetWidget(aWidgetType));
+ gtk_style_context_save(style);
+ MOZ_ASSERT(!sStyleContextNeedsRestore);
+ sStyleContextNeedsRestore = true;
+ gtk_style_context_add_class(style, aStyleClass);
return style;
}
+/* GetCssNodeStyleInternal is used by Gtk >= 3.20 */
static GtkStyleContext*
-GetStyleInternal(WidgetNodeType aNodeType)
+GetCssNodeStyleInternal(WidgetNodeType aNodeType)
{
+ GtkStyleContext* style = sStyleStorage[aNodeType];
+ if (style)
+ return style;
+
switch (aNodeType) {
- case MOZ_GTK_SCROLLBAR_HORIZONTAL:
- /* Root CSS node / widget for scrollbars */
+ case MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL:
+ style = CreateChildCSSNode("contents",
+ MOZ_GTK_SCROLLBAR_HORIZONTAL);
break;
case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL:
- return GetChildNodeStyle(aNodeType,
- MOZ_GTK_SCROLLBAR_HORIZONTAL,
- GTK_STYLE_CLASS_TROUGH,
- MOZ_GTK_SCROLLBAR_HORIZONTAL);
-
+ style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
+ MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL);
+ break;
case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
- return GetChildNodeStyle(aNodeType,
- MOZ_GTK_SCROLLBAR_HORIZONTAL,
- GTK_STYLE_CLASS_SLIDER,
- MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL);
-
- case MOZ_GTK_SCROLLBAR_VERTICAL:
- /* Root CSS node / widget for scrollbars */
+ style = CreateChildCSSNode(GTK_STYLE_CLASS_SLIDER,
+ MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL);
+ break;
+ case MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL:
+ style = CreateChildCSSNode("contents",
+ MOZ_GTK_SCROLLBAR_VERTICAL);
break;
case MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL:
- return GetChildNodeStyle(aNodeType,
- MOZ_GTK_SCROLLBAR_VERTICAL,
- GTK_STYLE_CLASS_TROUGH,
- MOZ_GTK_SCROLLBAR_VERTICAL);
-
+ style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
+ MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL);
+ break;
case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL:
- return GetChildNodeStyle(aNodeType,
- MOZ_GTK_SCROLLBAR_VERTICAL,
- GTK_STYLE_CLASS_SLIDER,
- MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
-
- case MOZ_GTK_RADIOBUTTON_CONTAINER:
- /* Root CSS node / widget for checkboxes */
+ style = CreateChildCSSNode(GTK_STYLE_CLASS_SLIDER,
+ MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
break;
case MOZ_GTK_RADIOBUTTON:
- return GetChildNodeStyle(aNodeType,
- MOZ_GTK_RADIOBUTTON_CONTAINER,
- GTK_STYLE_CLASS_RADIO,
- MOZ_GTK_RADIOBUTTON_CONTAINER);
- case MOZ_GTK_CHECKBUTTON_CONTAINER:
- /* Root CSS node / widget for radiobuttons */
+ style = CreateChildCSSNode(GTK_STYLE_CLASS_RADIO,
+ MOZ_GTK_RADIOBUTTON_CONTAINER);
break;
case MOZ_GTK_CHECKBUTTON:
- return GetChildNodeStyle(aNodeType,
- MOZ_GTK_CHECKBUTTON_CONTAINER,
- GTK_STYLE_CLASS_CHECK,
- MOZ_GTK_CHECKBUTTON_CONTAINER);
- default:
+ style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK,
+ MOZ_GTK_CHECKBUTTON_CONTAINER);
+ break;
+ case MOZ_GTK_PROGRESS_TROUGH:
+ /* Progress bar background (trough) */
+ style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH,
+ MOZ_GTK_PROGRESSBAR);
+ break;
+ case MOZ_GTK_PROGRESS_CHUNK:
+ 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,
+ GTK_STYLE_CLASS_GRIP);
+ case MOZ_GTK_INFO_BAR:
+ // TODO - create from CSS node
+ return GetWidgetStyleWithClass(MOZ_GTK_INFO_BAR,
+ GTK_STYLE_CLASS_INFO);
+ case MOZ_GTK_SPINBUTTON_ENTRY:
+ // TODO - create from CSS node
+ return GetWidgetStyleWithClass(MOZ_GTK_SPINBUTTON,
+ GTK_STYLE_CLASS_ENTRY);
+ case MOZ_GTK_SCROLLED_WINDOW:
+ // 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);
+ default:
+ // TODO - create style from style path
+ GtkWidget* widget = GetWidget(aNodeType);
+ return gtk_widget_get_style_context(widget);
}
- GtkWidget* widget = GetWidget(aNodeType);
- if (widget) {
- return gtk_widget_get_style_context(widget);
- }
+ MOZ_ASSERT(style, "missing style context for node type");
+ sStyleStorage[aNodeType] = style;
+ return style;
+}
- MOZ_ASSERT_UNREACHABLE("missing style context for node type");
- return nullptr;
+/* GetWidgetStyleInternal is used by Gtk < 3.20 */
+static GtkStyleContext*
+GetWidgetStyleInternal(WidgetNodeType aNodeType)
+{
+ switch (aNodeType) {
+ case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL:
+ return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_HORIZONTAL,
+ GTK_STYLE_CLASS_TROUGH);
+ case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL:
+ return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_HORIZONTAL,
+ GTK_STYLE_CLASS_SLIDER);
+ case MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL:
+ return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_VERTICAL,
+ GTK_STYLE_CLASS_TROUGH);
+ case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL:
+ return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_VERTICAL,
+ GTK_STYLE_CLASS_SLIDER);
+ case MOZ_GTK_RADIOBUTTON:
+ return GetWidgetStyleWithClass(MOZ_GTK_RADIOBUTTON_CONTAINER,
+ GTK_STYLE_CLASS_RADIO);
+ case MOZ_GTK_CHECKBUTTON:
+ return GetWidgetStyleWithClass(MOZ_GTK_CHECKBUTTON_CONTAINER,
+ 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;
+ return style;
+ }
+ case MOZ_GTK_GRIPPER:
+ return GetWidgetStyleWithClass(MOZ_GTK_GRIPPER,
+ GTK_STYLE_CLASS_GRIP);
+ case MOZ_GTK_INFO_BAR:
+ return GetWidgetStyleWithClass(MOZ_GTK_INFO_BAR,
+ GTK_STYLE_CLASS_INFO);
+ case MOZ_GTK_SPINBUTTON_ENTRY:
+ return GetWidgetStyleWithClass(MOZ_GTK_SPINBUTTON,
+ GTK_STYLE_CLASS_ENTRY);
+ 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);
+ default:
+ GtkWidget* widget = GetWidget(aNodeType);
+ MOZ_ASSERT(widget);
+ return gtk_widget_get_style_context(widget);
+ }
}
void
@@ -245,13 +544,39 @@ ResetWidgetCache(void)
GtkStyleContext*
ClaimStyleContext(WidgetNodeType aNodeType, GtkTextDirection aDirection,
- StyleFlags aFlags)
+ GtkStateFlags aStateFlags, StyleFlags aFlags)
{
- GtkStyleContext* style = GetStyleInternal(aNodeType);
+ MOZ_ASSERT(!sStyleContextNeedsRestore);
+ GtkStyleContext* style;
+ if (gtk_check_version(3, 20, 0) != nullptr) {
+ style = GetWidgetStyleInternal(aNodeType);
+ } else {
+ style = GetCssNodeStyleInternal(aNodeType);
+ }
#ifdef DEBUG
MOZ_ASSERT(!sCurrentStyleContext);
sCurrentStyleContext = style;
#endif
+ GtkStateFlags oldState = gtk_style_context_get_state(style);
+ GtkTextDirection oldDirection = gtk_style_context_get_direction(style);
+ if (oldState != aStateFlags || oldDirection != aDirection) {
+ // From GTK 3.8, set_state() will overwrite the direction, so set
+ // direction after state.
+ gtk_style_context_set_state(style, aStateFlags);
+ gtk_style_context_set_direction(style, aDirection);
+
+ // This invalidate is necessary for unsaved style contexts from GtkWidgets
+ // in pre-3.18 GTK, because automatic invalidation of such contexts
+ // was delayed until a resize event runs.
+ //
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1272194#c7
+ //
+ // Avoid calling invalidate on saved contexts to avoid performing
+ // build_properties() (in 3.16 stylecontext.c) unnecessarily early.
+ if (!sStyleContextNeedsRestore) {
+ gtk_style_context_invalidate(style);
+ }
+ }
return style;
}
diff -up firefox-48.0/widget/gtk/WidgetStyleCache.h.old firefox-48.0/widget/gtk/WidgetStyleCache.h
--- firefox-48.0/widget/gtk/WidgetStyleCache.h.old 2016-07-25 22:22:07.000000000 +0200
+++ firefox-48.0/widget/gtk/WidgetStyleCache.h 2016-06-22 10:13:10.000000000 +0200
@@ -21,10 +21,24 @@ enum : StyleFlags {
GtkWidget*
GetWidget(WidgetNodeType aNodeType);
+/*
+ * Return a new style context based on aWidget, as a child of aParentStyle.
+ * If aWidget still has a floating reference, then it is sunk and released.
+ */
+GtkStyleContext*
+CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle);
+
+// CreateCSSNode is implemented for gtk >= 3.20 only.
+GtkStyleContext*
+CreateCSSNode(const char* aName,
+ GtkStyleContext* aParentStyle,
+ GType aType = G_TYPE_NONE);
+
// Callers must call ReleaseStyleContext() on the returned context.
GtkStyleContext*
ClaimStyleContext(WidgetNodeType aNodeType,
GtkTextDirection aDirection = GTK_TEXT_DIR_LTR,
+ GtkStateFlags aStateFlags = GTK_STATE_FLAG_NORMAL,
StyleFlags aFlags = NO_STYLE_FLAGS);
void
ReleaseStyleContext(GtkStyleContext* style);