firefox/widget-rebase.patch

863 lines
31 KiB
Diff
Raw Normal View History

2017-04-18 08:36:12 +00:00
diff -up firefox-53.0/widget/gtk/gtk3drawing.cpp.widget-rebase firefox-53.0/widget/gtk/gtk3drawing.cpp
--- firefox-53.0/widget/gtk/gtk3drawing.cpp.widget-rebase 2017-04-11 06:15:20.000000000 +0200
+++ firefox-53.0/widget/gtk/gtk3drawing.cpp 2017-04-18 10:22:45.332920938 +0200
@@ -18,11 +18,10 @@
#include <math.h>
-static style_prop_t style_prop_func;
-static gboolean have_arrow_scaling;
static gboolean checkbox_check_state;
static gboolean notebook_has_tab_gap;
-static gboolean is_initialized;
+
+static ScrollbarGTKMetrics sScrollbarMetrics[2];
#define ARROW_UP 0
#define ARROW_DOWN G_PI
@@ -40,6 +39,9 @@ static gint
moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
GtkWidgetState* state, GtkTextDirection direction);
2017-04-18 08:36:12 +00:00
+static GtkBorder
+GetMarginBorderPadding(GtkStyleContext* aStyle);
+
2017-03-03 13:35:44 +00:00
// GetStateFlagsFromGtkWidgetState() can be safely used for the specific
// GtkWidgets that set both prelight and active flags. For other widgets,
// either the GtkStateFlags or Gecko's GtkWidgetState need to be carefully
2017-04-18 08:36:12 +00:00
@@ -78,27 +80,22 @@ GetStateFlagsFromGtkTabFlags(GtkTabFlags
}
2017-04-18 08:36:12 +00:00
gint
-moz_gtk_enable_style_props(style_prop_t styleGetProp)
-{
- style_prop_func = styleGetProp;
- return MOZ_GTK_SUCCESS;
-}
-
-gint
moz_gtk_init()
2017-03-03 13:35:44 +00:00
{
2017-04-18 08:36:12 +00:00
- if (is_initialized)
- return MOZ_GTK_SUCCESS;
-
- is_initialized = TRUE;
- have_arrow_scaling = (gtk_major_version > 2 ||
- (gtk_major_version == 2 && gtk_minor_version >= 12));
if (gtk_major_version > 3 ||
(gtk_major_version == 3 && gtk_minor_version >= 14))
checkbox_check_state = GTK_STATE_FLAG_CHECKED;
else
checkbox_check_state = GTK_STATE_FLAG_ACTIVE;
+ moz_gtk_refresh();
+
+ return MOZ_GTK_SUCCESS;
+}
+
2017-04-18 08:36:12 +00:00
+void
+moz_gtk_refresh()
+{
2017-04-18 08:36:12 +00:00
if (gtk_check_version(3, 12, 0) == nullptr &&
gtk_check_version(3, 20, 0) != nullptr)
{
@@ -112,7 +109,8 @@ moz_gtk_init()
notebook_has_tab_gap = true;
}
2017-04-18 08:36:12 +00:00
- return MOZ_GTK_SUCCESS;
+ sScrollbarMetrics[GTK_ORIENTATION_HORIZONTAL].initialized = false;
+ sScrollbarMetrics[GTK_ORIENTATION_VERTICAL].initialized = false;
}
2017-04-18 08:36:12 +00:00
gint
@@ -420,9 +418,8 @@ calculate_arrow_rect(GtkWidget* arrow, G
gfloat mxalign, myalign;
GtkMisc* misc = GTK_MISC(arrow);
- if (have_arrow_scaling)
- gtk_style_context_get_style(gtk_widget_get_style_context(arrow),
- "arrow_scaling", &arrow_scaling, NULL);
+ gtk_style_context_get_style(gtk_widget_get_style_context(arrow),
+ "arrow_scaling", &arrow_scaling, NULL);
gtk_misc_get_padding(misc, &mxpad, &mypad);
extent = MIN((rect->width - mxpad * 2),
@@ -443,7 +440,23 @@ calculate_arrow_rect(GtkWidget* arrow, G
return MOZ_GTK_SUCCESS;
}
2017-04-18 08:36:12 +00:00
-void
+static MozGtkSize
+GetMinContentBox(GtkStyleContext* style)
+{
+ GtkStateFlags state_flags = gtk_style_context_get_state(style);
+ gint width, height;
+ gtk_style_context_get(style, state_flags,
+ "min-width", &width,
+ "min-height", &height,
+ nullptr);
+ return {width, height};
+}
+
2017-04-18 08:36:12 +00:00
+/**
+ * Get minimum widget size as sum of margin, padding, border and
+ * min-width/min-height.
+ */
+static void
moz_gtk_get_widget_min_size(WidgetNodeType aGtkWidgetType, int* width,
int* height)
{
2017-04-18 08:36:12 +00:00
@@ -466,6 +479,14 @@ moz_gtk_get_widget_min_size(WidgetNodeTy
padding.top + padding.bottom;
}
2017-04-18 08:36:12 +00:00
+static MozGtkSize
+GetMinMarginBox(WidgetNodeType aNodeType)
+{
+ gint width, height;
+ moz_gtk_get_widget_min_size(aNodeType, &width, &height);
+ return {width, height};
+}
+
2017-04-18 08:36:12 +00:00
static void
Inset(GdkRectangle* rect, GtkBorder& aBorder)
{
@@ -546,18 +567,22 @@ moz_gtk_scrollbar_button_paint(cairo_t *
// box occupies the full width of the "contents" gadget content box.
InsetByMargin(&rect, style);
} else {
- // 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;
- }
+ // 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).
+ GtkOrientation orientation = flags & MOZ_GTK_STEPPER_VERTICAL ?
+ GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL;
+ const auto& metrics = sScrollbarMetrics[orientation];
+ if (!metrics.initialized) {
+ NS_WARNING("Didn't measure before drawing?");
+ }
+ if (flags & MOZ_GTK_STEPPER_VERTICAL) {
+ rect.x += metrics.border.track.left;
+ rect.width = metrics.size.thumb.width;
+ } else {
+ rect.y += metrics.border.track.top;
+ rect.height = metrics.size.thumb.height;
+ }
}
2017-04-18 08:36:12 +00:00
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
@@ -629,12 +654,37 @@ moz_gtk_draw_styled_frame(GtkStyleContex
static gint
2017-04-18 08:36:12 +00:00
moz_gtk_scrollbar_trough_paint(WidgetNodeType widget,
- cairo_t *cr, const GdkRectangle* rect,
+ cairo_t *cr, const GdkRectangle* aRect,
GtkWidgetState* state,
GtkTextDirection direction)
{
2017-04-18 08:36:12 +00:00
- GtkStyleContext* style = ClaimStyleContext(widget, direction);
- moz_gtk_draw_styled_frame(style, cr, rect, state->focused);
+ GdkRectangle rect = *aRect;
+ GtkStyleContext* style;
+
+ if (gtk_get_minor_version() >= 20) {
+ WidgetNodeType thumb = widget == MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL ?
+ MOZ_GTK_SCROLLBAR_THUMB_VERTICAL :
+ MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
+ MozGtkSize thumbSize = GetMinMarginBox(thumb);
+ style = ClaimStyleContext(widget, direction);
+ MozGtkSize trackSize = GetMinContentBox(style);
+ trackSize.Include(thumbSize);
+ trackSize += GetMarginBorderPadding(style);
+ // Gecko's trough |aRect| fills available breadth, but GTK's trough is
+ // centered in the contents_gadget. The centering here round left
+ // and up, like gtk_box_gadget_allocate_child().
+ if (widget == MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL) {
+ rect.x += (rect.width - trackSize.width)/2;
+ rect.width = trackSize.width;
+ } else {
+ rect.y += (rect.height - trackSize.height)/2;
+ rect.height = trackSize.height;
+ }
+ } else {
2017-04-18 08:36:12 +00:00
+ style = ClaimStyleContext(widget, direction);
+ }
2017-04-18 08:36:12 +00:00
+
+ moz_gtk_draw_styled_frame(style, cr, &rect, state->focused);
ReleaseStyleContext(style);
2017-04-18 08:36:12 +00:00
return MOZ_GTK_SUCCESS;
@@ -2009,6 +2059,20 @@ static void moz_gtk_add_margin_border_pa
moz_gtk_add_style_padding(style, left, top, right, bottom);
}
2017-04-18 08:36:12 +00:00
+static GtkBorder
+GetMarginBorderPadding(GtkStyleContext* aStyle)
+{
+ gint left = 0, top = 0, right = 0, bottom = 0;
+ moz_gtk_add_margin_border_padding(aStyle, &left, &top, &right, &bottom);
+ // narrowing conversions to gint16:
+ GtkBorder result;
+ result.left = left;
+ result.right = right;
+ result.top = top;
+ result.bottom = bottom;
+ return result;
+}
+
gint
moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
gint* right, gint* bottom, GtkTextDirection direction,
@@ -2212,61 +2276,7 @@ moz_gtk_get_widget_border(WidgetNodeType
return MOZ_GTK_SUCCESS;
}
2017-04-18 08:36:12 +00:00
- 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;
2017-03-03 13:35:44 +00:00
-
2017-04-18 08:36:12 +00:00
- 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);
2017-03-03 13:35:44 +00:00
- ReleaseStyleContext(style);
2017-04-18 08:36:12 +00:00
- }
- 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:
@@ -2275,6 +2285,8 @@ moz_gtk_get_widget_border(WidgetNodeType
case MOZ_GTK_CHECKBUTTON:
case MOZ_GTK_RADIOBUTTON:
case MOZ_GTK_SCROLLBAR_BUTTON:
+ 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:
@@ -2498,11 +2510,11 @@ void
2017-03-03 13:35:44 +00:00
moz_gtk_get_scale_metrics(GtkOrientation orient, gint* scale_width,
gint* scale_height)
{
2017-03-03 13:35:44 +00:00
- WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
- MOZ_GTK_SCALE_HORIZONTAL :
- MOZ_GTK_SCALE_VERTICAL;
-
if (gtk_check_version(3, 20, 0) != nullptr) {
+ WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
+ MOZ_GTK_SCALE_HORIZONTAL :
+ MOZ_GTK_SCALE_VERTICAL;
+
2017-03-03 13:35:44 +00:00
gint thumb_length, thumb_height, trough_border;
moz_gtk_get_scalethumb_metrics(orient, &thumb_length, &thumb_height);
2017-04-18 08:36:12 +00:00
@@ -2518,12 +2530,10 @@ moz_gtk_get_scale_metrics(GtkOrientation
2017-03-03 13:35:44 +00:00
}
ReleaseStyleContext(style);
} else {
- GtkStyleContext* style = ClaimStyleContext(widget);
- gtk_style_context_get(style, gtk_style_context_get_state(style),
- "min-width", scale_width,
- "min-height", scale_height,
- nullptr);
- ReleaseStyleContext(style);
+ WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
+ MOZ_GTK_SCALE_TROUGH_HORIZONTAL :
+ MOZ_GTK_SCALE_TROUGH_VERTICAL;
+ moz_gtk_get_widget_min_size(widget, scale_width, scale_height);
}
}
2017-04-18 08:36:12 +00:00
@@ -2546,33 +2556,176 @@ moz_gtk_get_scalethumb_metrics(GtkOrient
2017-03-03 13:35:44 +00:00
MOZ_GTK_SCALE_THUMB_HORIZONTAL:
MOZ_GTK_SCALE_THUMB_VERTICAL;
GtkStyleContext* style = ClaimStyleContext(widget);
- gtk_style_context_get(style, gtk_style_context_get_state(style),
- "min-width", thumb_length,
- "min-height", thumb_height,
+
+ gint min_width, min_height;
+ GtkStateFlags state = gtk_style_context_get_state(style);
+ gtk_style_context_get(style, state,
+ "min-width", &min_width,
+ "min-height", &min_height,
nullptr);
+ GtkBorder margin;
+ gtk_style_context_get_margin(style, state, &margin);
+ gint margin_width = margin.left + margin.right;
+ gint margin_height = margin.top + margin.bottom;
+
+ // Negative margin of slider element also determines its minimal size
+ // so use bigger of those two values.
+ if (min_width < -margin_width)
+ min_width = -margin_width;
+ if (min_height < -margin_height)
+ min_height = -margin_height;
+
+ *thumb_length = min_width;
+ *thumb_height = min_height;
+
ReleaseStyleContext(style);
}
2017-04-18 08:36:12 +00:00
return MOZ_GTK_SUCCESS;
}
2017-04-18 08:36:12 +00:00
-gint
-moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics)
+static MozGtkSize
+SizeFromLengthAndBreadth(GtkOrientation aOrientation,
+ gint aLength, gint aBreadth)
{
- // For Gtk >= 3.20 scrollbar metrics are ignored
- MOZ_ASSERT(gtk_check_version(3, 20, 0) != nullptr);
+ return aOrientation == GTK_ORIENTATION_HORIZONTAL ?
+ MozGtkSize({aLength, aBreadth}) : MozGtkSize({aBreadth, aLength});
+}
+
2017-04-18 08:36:12 +00:00
+const ScrollbarGTKMetrics*
+GetScrollbarMetrics(GtkOrientation aOrientation)
+{
+ auto metrics = &sScrollbarMetrics[aOrientation];
+ if (metrics->initialized)
+ return metrics;
+
+ metrics->initialized = true;
- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_VERTICAL);
+ WidgetNodeType scrollbar = aOrientation == GTK_ORIENTATION_HORIZONTAL ?
+ MOZ_GTK_SCROLLBAR_HORIZONTAL : MOZ_GTK_SCROLLBAR_VERTICAL;
+
+ gboolean backward, forward, secondary_backward, secondary_forward;
+ GtkStyleContext* style = ClaimStyleContext(scrollbar);
gtk_style_context_get_style(style,
- "slider_width", &metrics->slider_width,
- "trough_border", &metrics->trough_border,
- "stepper_size", &metrics->stepper_size,
- "stepper_spacing", &metrics->stepper_spacing,
- "min-slider-length", &metrics->min_slider_size,
- nullptr);
+ "has-backward-stepper", &backward,
+ "has-forward-stepper", &forward,
+ "has-secondary-backward-stepper",
+ &secondary_backward,
+ "has-secondary-forward-stepper",
+ &secondary_forward, nullptr);
+ bool hasButtons =
+ backward || forward || secondary_backward || secondary_forward;
+
+ if (gtk_get_minor_version() < 20) {
+ gint slider_width, trough_border, stepper_size, min_slider_size;
+
+ gtk_style_context_get_style(style,
+ "slider-width", &slider_width,
+ "trough-border", &trough_border,
+ "stepper-size", &stepper_size,
+ "min-slider-length", &min_slider_size,
+ nullptr);
+ ReleaseStyleContext(style);
2017-04-18 08:36:12 +00:00
+
+ metrics->size.thumb =
+ SizeFromLengthAndBreadth(aOrientation, min_slider_size, slider_width);
+ metrics->size.button =
+ SizeFromLengthAndBreadth(aOrientation, stepper_size, slider_width);
+ // overall scrollbar
+ gint breadth = slider_width + 2 * trough_border;
+ // Require room for the slider in the track if we don't have buttons.
+ gint length = hasButtons ? 0 : min_slider_size + 2 * trough_border;
+ metrics->size.scrollbar =
+ SizeFromLengthAndBreadth(aOrientation, length, breadth);
+
+ // Borders on the major axis are set on the outermost scrollbar
+ // element to correctly position the buttons when
+ // trough-under-steppers is true.
+ // Borders on the minor axis are set on the track element so that it
+ // receives mouse events, as in GTK.
+ // Other borders have been zero-initialized.
+ if (aOrientation == GTK_ORIENTATION_HORIZONTAL) {
+ metrics->border.scrollbar.left =
+ metrics->border.scrollbar.right =
+ metrics->border.track.top =
+ metrics->border.track.bottom = trough_border;
+ } else {
+ metrics->border.scrollbar.top =
+ metrics->border.scrollbar.bottom =
+ metrics->border.track.left =
+ metrics->border.track.right = trough_border;
+ }
+
+ return metrics;
+ }
2017-04-18 08:36:12 +00:00
+
+ // GTK version > 3.20
+ // scrollbar
+ metrics->border.scrollbar = GetMarginBorderPadding(style);
ReleaseStyleContext(style);
- return MOZ_GTK_SUCCESS;
+ WidgetNodeType contents, track, thumb;
+ if (aOrientation == GTK_ORIENTATION_HORIZONTAL) {
+ contents = MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL;
+ track = MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL;
+ thumb = MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
+ } else {
+ contents = MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL;
+ track = MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL;
+ thumb = MOZ_GTK_SCROLLBAR_THUMB_VERTICAL;
+ }
2017-04-18 08:36:12 +00:00
+ // thumb
+ metrics->size.thumb = GetMinMarginBox(thumb);
+ // track
+ style = ClaimStyleContext(track);
+ metrics->border.track = GetMarginBorderPadding(style);
+ MozGtkSize trackMinSize = GetMinContentBox(style) + metrics->border.track;
+ ReleaseStyleContext(style);
+ MozGtkSize trackSizeForThumb = metrics->size.thumb + metrics->border.track;
+ // button
+ if (hasButtons) {
+ metrics->size.button = GetMinMarginBox(MOZ_GTK_SCROLLBAR_BUTTON);
+ } else {
+ metrics->size.button = {0, 0};
+ }
2017-04-18 08:36:12 +00:00
+ if (aOrientation == GTK_ORIENTATION_HORIZONTAL) {
+ metrics->size.button.Rotate();
+ // If the track is wider than necessary for the thumb, including when
+ // the buttons will cause Gecko to expand the track to fill
+ // available breadth, then add to the track border to prevent Gecko
+ // from expanding the thumb to fill available breadth.
+ gint extra =
+ std::max(trackMinSize.height,
+ metrics->size.button.height) - trackSizeForThumb.height;
+ if (extra > 0) {
+ // If extra is odd, then the thumb is 0.5 pixels above
+ // center as in gtk_range_compute_slider_position().
+ metrics->border.track.top += extra / 2;
+ metrics->border.track.bottom += extra - extra / 2;
+ // Update size for change in border.
+ trackSizeForThumb.height += extra;
+ }
+ } else {
+ gint extra =
+ std::max(trackMinSize.width,
+ metrics->size.button.width) - trackSizeForThumb.width;
+ if (extra > 0) {
+ // If extra is odd, then the thumb is 0.5 pixels to the left
+ // of center as in gtk_range_compute_slider_position().
+ metrics->border.track.left += extra / 2;
+ metrics->border.track.right += extra - extra / 2;
+ trackSizeForThumb.width += extra;
+ }
+ }
2017-04-18 08:36:12 +00:00
+
+ style = ClaimStyleContext(contents);
+ GtkBorder contentsBorder = GetMarginBorderPadding(style);
+ ReleaseStyleContext(style);
+
+ metrics->size.scrollbar =
+ trackSizeForThumb + contentsBorder + metrics->border.scrollbar;
+
+ return metrics;
}
/* cairo_t *cr argument has to be a system-cairo. */
@@ -2814,34 +2967,11 @@ moz_gtk_widget_paint(WidgetNodeType widg
return MOZ_GTK_UNKNOWN_WIDGET;
}
2017-04-18 08:36:12 +00:00
-GtkWidget* moz_gtk_get_scrollbar_widget(void)
-{
2017-04-18 08:36:12 +00:00
- return GetWidget(MOZ_GTK_SCROLLBAR_HORIZONTAL);
-}
-
2017-04-18 08:36:12 +00:00
-gboolean moz_gtk_has_scrollbar_buttons(void)
-{
- gboolean backward, forward, secondary_backward, secondary_forward;
- MOZ_ASSERT(is_initialized, "Forgot to call moz_gtk_init()");
- GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_VERTICAL);
- gtk_style_context_get_style(style,
- "has-backward-stepper", &backward,
- "has-forward-stepper", &forward,
- "has-secondary-backward-stepper", &secondary_backward,
- "has-secondary-forward-stepper", &secondary_forward,
- NULL);
- ReleaseStyleContext(style);
-
- return backward | forward | secondary_forward | secondary_forward;
-}
-
gint
moz_gtk_shutdown()
{
2017-04-18 08:36:12 +00:00
/* This will destroy all of our widgets */
ResetWidgetCache();
2017-04-18 08:36:12 +00:00
- is_initialized = FALSE;
-
2017-04-18 08:36:12 +00:00
return MOZ_GTK_SUCCESS;
}
diff -up firefox-53.0/widget/gtk/gtkdrawing.h.widget-rebase firefox-53.0/widget/gtk/gtkdrawing.h
--- firefox-53.0/widget/gtk/gtkdrawing.h.widget-rebase 2017-04-18 10:24:37.950508591 +0200
+++ firefox-53.0/widget/gtk/gtkdrawing.h 2017-04-18 10:22:45.412920645 +0200
@@ -39,13 +39,49 @@ typedef struct {
gint32 maxpos;
} GtkWidgetState;
+/**
+ * A size in the same GTK pixel units as GtkBorder and GdkRectangle.
+ */
+struct MozGtkSize {
+ gint width;
+ gint height;
+
+ MozGtkSize& operator+=(const GtkBorder& aBorder)
+ {
+ width += aBorder.left + aBorder.right;
+ height += aBorder.top + aBorder.bottom;
+ return *this;
+ }
+ MozGtkSize operator+(const GtkBorder& aBorder) const
+ {
+ MozGtkSize result = *this;
+ return result += aBorder;
+ }
+ void Include(MozGtkSize aOther)
+ {
+ width = std::max(width, aOther.width);
+ height = std::max(height, aOther.height);
+ }
+ void Rotate()
+ {
+ gint tmp = width;
+ width = height;
+ height = tmp;
+ }
+};
+
typedef struct {
- gint slider_width;
- gint trough_border;
- gint stepper_size;
- gint stepper_spacing;
- gint min_slider_size;
-} MozGtkScrollbarMetrics;
+ bool initialized;
+ struct {
+ MozGtkSize scrollbar;
+ MozGtkSize thumb;
+ MozGtkSize button;
+ } size;
+ struct {
+ GtkBorder scrollbar;
+ GtkBorder track;
+ } border;
+} ScrollbarGTKMetrics;
typedef enum {
MOZ_GTK_STEPPER_DOWN = 1 << 0,
@@ -67,9 +103,6 @@ typedef enum {
MOZ_GTK_TAB_SELECTED = 1 << 10
} GtkTabFlags;
-/* function type for moz_gtk_enable_style_props */
-typedef gint (*style_prop_t)(GtkStyle*, const gchar*, gint);
-
2017-04-18 08:36:12 +00:00
/*** result/error codes ***/
#define MOZ_GTK_SUCCESS 0
#define MOZ_GTK_UNKNOWN_WIDGET -1
@@ -272,13 +305,9 @@ typedef enum {
gint moz_gtk_init();
/**
- * Enable GTK+ 1.2.9+ theme enhancements. You must provide a pointer
- * to the GTK+ 1.2.9+ function "gtk_style_get_prop_experimental".
- * styleGetProp: pointer to gtk_style_get_prop_experimental
- *
- * returns: MOZ_GTK_SUCCESS if there was no error, an error code otherwise
+ * Updates the drawing library when the theme changes.
*/
-gint moz_gtk_enable_style_props(style_prop_t styleGetProp);
+void moz_gtk_refresh();
/**
* Perform cleanup of the drawing library. You should call this function
@@ -432,13 +461,10 @@ gint
moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length, gint* thumb_height);
/**
- * Get the desired metrics for a GtkScrollbar
- * metrics: [IN] struct which will contain the metrics
- *
- * returns: MOZ_GTK_SUCCESS if there was no error, an error code otherwise
+ * Get the metrics in GTK pixels for a scrollbar.
*/
-gint
-moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics* metrics);
+const ScrollbarGTKMetrics*
+GetScrollbarMetrics(GtkOrientation aOrientation);
/**
* Get the desired size of a dropdown arrow button
@@ -518,30 +544,11 @@ gint moz_gtk_get_menu_separator_height(g
gint moz_gtk_splitter_get_metrics(gint orientation, gint* size);
/**
- * Retrieve an actual GTK scrollbar widget for style analysis. It will not
- * be modified.
- */
-GtkWidget* moz_gtk_get_scrollbar_widget(void);
2017-03-10 12:57:35 +00:00
-
2017-04-18 08:36:12 +00:00
-/**
* Get the YTHICKNESS of a tab (notebook extension).
*/
gint
moz_gtk_get_tab_thickness(WidgetNodeType aNodeType);
2017-04-18 08:36:12 +00:00
-/**
- * Get a boolean which indicates whether the theme draws scrollbar buttons.
- * If TRUE, draw scrollbar buttons.
- */
-gboolean moz_gtk_has_scrollbar_buttons(void);
-
2017-04-18 08:36:12 +00:00
-/**
- * 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);
-
2017-04-18 08:36:12 +00:00
#if (MOZ_WIDGET_GTK == 2)
#ifdef __cplusplus
}
diff -up firefox-53.0/widget/gtk/mozgtk/mozgtk.c.widget-rebase firefox-53.0/widget/gtk/mozgtk/mozgtk.c
diff -up firefox-53.0/widget/gtk/nsLookAndFeel.cpp.widget-rebase firefox-53.0/widget/gtk/nsLookAndFeel.cpp
--- firefox-53.0/widget/gtk/nsLookAndFeel.cpp.widget-rebase 2017-04-11 06:15:20.000000000 +0200
+++ firefox-53.0/widget/gtk/nsLookAndFeel.cpp 2017-04-18 10:22:45.333920935 +0200
@@ -18,7 +18,7 @@
#include <fontconfig/fontconfig.h>
#include "gfxPlatformGtk.h"
-#include "nsScreenGtk.h"
+#include "ScreenHelperGTK.h"
#include "gtkdrawing.h"
#include "nsStyleConsts.h"
@@ -49,9 +49,9 @@ nsLookAndFeel::nsLookAndFeel()
mStyle(nullptr),
#endif
mDefaultFontCached(false), mButtonFontCached(false),
- mFieldFontCached(false), mMenuFontCached(false)
+ mFieldFontCached(false), mMenuFontCached(false),
+ mInitialized(false)
{
- Init();
}
2017-04-18 08:36:12 +00:00
nsLookAndFeel::~nsLookAndFeel()
@@ -223,6 +223,8 @@ GetBorderColors(GtkStyleContext* aContex
nsresult
nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
{
+ EnsureInit();
+
2017-04-18 08:36:12 +00:00
#if (MOZ_WIDGET_GTK == 3)
GdkRGBA gdk_color;
#endif
2017-04-18 08:36:12 +00:00
@@ -674,6 +676,11 @@ nsLookAndFeel::GetIntImpl(IntID aID, int
return res;
res = NS_OK;
+ // We use delayed initialization by EnsureInit() here
+ // to make sure mozilla::Preferences is available (Bug 115807).
+ // eIntID_UseAccessibilityTheme is requested before user preferences
+ // are read, and so EnsureInit(), which depends on preference values,
+ // is deliberately delayed until required.
switch (aID) {
case eIntID_CaretBlinkTime:
{
@@ -777,11 +784,11 @@ nsLookAndFeel::GetIntImpl(IntID aID, int
aResult = threshold;
}
break;
- case eIntID_ScrollArrowStyle:
- moz_gtk_init();
- aResult =
- ConvertGTKStepperStyleToMozillaScrollArrowStyle(moz_gtk_get_scrollbar_widget());
+ case eIntID_ScrollArrowStyle: {
+ GtkWidget* scrollbar = GetWidget(MOZ_GTK_SCROLLBAR_HORIZONTAL);
+ aResult = ConvertGTKStepperStyleToMozillaScrollArrowStyle(scrollbar);
break;
+ }
case eIntID_ScrollSliderStyle:
aResult = eScrollThumbStyle_Proportional;
break;
@@ -836,6 +843,7 @@ nsLookAndFeel::GetIntImpl(IntID aID, int
aResult = NS_STYLE_TEXT_DECORATION_STYLE_WAVY;
break;
case eIntID_MenuBarDrag:
+ EnsureInit();
aResult = sMenuSupportsDrag;
break;
case eIntID_ScrollbarButtonAutoRepeatBehavior:
@@ -876,6 +884,7 @@ nsLookAndFeel::GetFloatImpl(FloatID aID,
aResult = 1.0f;
break;
case eFloatID_CaretAspectRatio:
+ EnsureInit();
aResult = sCaretRatio;
break;
default:
@@ -925,7 +934,7 @@ GetSystemFontInfo(GtkWidget *aWidget,
// Scale fonts up on HiDPI displays.
// This would be done automatically with cairo, but we manually manage
// the display scale for platform consistency.
- size *= nsScreenGtk::GetGtkMonitorScaleFactor();
+ size *= ScreenHelperGTK::GetGTKMonitorScaleFactor();
2017-04-18 08:36:12 +00:00
// |size| is now pixels
2017-04-18 08:36:12 +00:00
@@ -1056,11 +1065,15 @@ nsLookAndFeel::GetFontImpl(FontID aID, n
}
2017-04-18 08:36:12 +00:00
void
-nsLookAndFeel::Init()
+nsLookAndFeel::EnsureInit()
{
GdkColor colorValue;
GdkColor *colorValuePtr;
2017-04-18 08:36:12 +00:00
+ if (mInitialized)
+ return;
+ mInitialized = true;
+
#if (MOZ_WIDGET_GTK == 2)
NS_ASSERTION(!mStyle, "already initialized");
// GtkInvisibles come with a refcount that is not floating
@@ -1133,16 +1146,39 @@ nsLookAndFeel::Init()
// with wrong color theme, see Bug 972382
GtkSettings *settings = gtk_settings_get_for_screen(gdk_screen_get_default());
- // Disable dark theme because it interacts poorly with widget styling in
- // web content (see bug 1216658).
+ // Dark themes interacts poorly with widget styling (see bug 1216658).
+ // We disable dark themes by default for all processes (chrome, web content)
+ // but allow user to overide it by prefs.
+ const gchar* dark_setting = "gtk-application-prefer-dark-theme";
+ gboolean darkThemeDefault;
+ g_object_get(settings, dark_setting, &darkThemeDefault, nullptr);
+
// To avoid triggering reload of theme settings unnecessarily, only set the
// setting when necessary.
- const gchar* dark_setting = "gtk-application-prefer-dark-theme";
- gboolean dark;
- g_object_get(settings, dark_setting, &dark, nullptr);
+ if (darkThemeDefault) {
+ bool allowDarkTheme;
+ if (XRE_IsContentProcess()) {
+ allowDarkTheme =
+ mozilla::Preferences::GetBool("widget.content.allow-gtk-dark-theme",
+ false);
+ } else {
+ allowDarkTheme = (PR_GetEnv("MOZ_ALLOW_GTK_DARK_THEME") != nullptr) ||
+ mozilla::Preferences::GetBool("widget.chrome.allow-gtk-dark-theme",
+ false);
+ }
+ if (!allowDarkTheme) {
+ g_object_set(settings, dark_setting, FALSE, nullptr);
+ }
+ }
2017-04-18 08:36:12 +00:00
- if (dark && !PR_GetEnv("MOZ_ALLOW_GTK_DARK_THEME")) {
- g_object_set(settings, dark_setting, FALSE, nullptr);
+ // Allow content Gtk theme override by pref, it's useful when styled Gtk+
+ // widgets break web content.
+ if (XRE_IsContentProcess()) {
+ auto contentThemeName =
+ mozilla::Preferences::GetCString("widget.content.gtk-theme-override");
+ if (!contentThemeName.IsEmpty()) {
+ g_object_set(settings, "gtk-theme-name", contentThemeName.get(), nullptr);
+ }
}
2017-04-18 08:36:12 +00:00
// Scrollbar colors
@@ -1438,6 +1474,7 @@ nsLookAndFeel::Init()
char16_t
nsLookAndFeel::GetPasswordCharacterImpl()
{
+ EnsureInit();
return sInvisibleCharacter;
}
2017-04-18 08:36:12 +00:00
@@ -1445,6 +1482,7 @@ void
nsLookAndFeel::RefreshImpl()
{
nsXPLookAndFeel::RefreshImpl();
+ moz_gtk_refresh();
2017-04-18 08:36:12 +00:00
mDefaultFontCached = false;
mButtonFontCached = false;
@@ -1456,7 +1494,7 @@ nsLookAndFeel::RefreshImpl()
mStyle = nullptr;
#endif
2017-04-18 08:36:12 +00:00
- Init();
+ mInitialized = false;
}
2017-04-18 08:36:12 +00:00
bool