Chromium Code Reviews| Index: chrome/browser/ui/libgtkui/gtk_util.h |
| diff --git a/chrome/browser/ui/libgtkui/gtk_util.h b/chrome/browser/ui/libgtkui/gtk_util.h |
| index d71e09a7fd66001eea1a7523632d9b351628dded..9716b8e8ffa808512fecdf18d55612582e4891b4 100644 |
| --- a/chrome/browser/ui/libgtkui/gtk_util.h |
| +++ b/chrome/browser/ui/libgtkui/gtk_util.h |
| @@ -98,10 +98,10 @@ class CairoSurface { |
| // Get the drawing context for GTK to use. |
| cairo_t* cairo() { return cairo_; } |
| - // If |only_frame_pixels| is false, returns the average of all |
| - // pixels in the surface, otherwise returns the average of only the |
| - // edge pixels. |
| - SkColor GetAveragePixelValue(bool only_frame_pixels); |
| + // Returns the average of all pixels in the surface. If |frame| is |
| + // true, the resulting alpha will be the average alpha, otherwise it |
| + // will be the max alpha across all pixels. |
| + SkColor GetAveragePixelValue(bool frame); |
| private: |
| cairo_surface_t* surface_; |
| @@ -112,18 +112,18 @@ class CairoSurface { |
| // |major|.|minor|.|micro|. |
| bool GtkVersionCheck(int major, int minor = 0, int micro = 0); |
| +// Similar in spirit to a std::unique_ptr. |
| template <typename T> |
| class ScopedGObject { |
| public: |
| explicit ScopedGObject(T* obj) : obj_(obj) { |
| - // Increase the reference count of |obj_|, removing the floating |
| - // reference if it has one. |
| - g_object_ref_sink(obj_); |
| + // Remove the floating reference from |obj_| if it has one. |
| + if (g_object_is_floating(obj_)) |
| + g_object_ref_sink(obj_); |
| + DCHECK(G_OBJECT(obj_)->ref_count == 1); |
| } |
| - ScopedGObject(const ScopedGObject<T>& other) : obj_(other.obj_) { |
| - g_object_ref(obj_); |
| - } |
| + ScopedGObject(const ScopedGObject<T>& other) = delete; |
| ScopedGObject(ScopedGObject<T>&& other) : obj_(other.obj_) { |
| other.obj_ = nullptr; |
| @@ -131,15 +131,10 @@ class ScopedGObject { |
| ~ScopedGObject() { |
| if (obj_) |
| - g_object_unref(obj_); |
| + Unref(); |
| } |
| - ScopedGObject<T>& operator=(const ScopedGObject<T>& other) { |
| - g_object_ref(other.obj_); |
| - g_object_unref(obj_); |
| - obj_ = other.obj_; |
| - return *this; |
| - } |
| + ScopedGObject<T>& operator=(const ScopedGObject<T>& other) = delete; |
| ScopedGObject<T>& operator=(ScopedGObject<T>&& other) { |
| g_object_unref(obj_); |
| @@ -151,10 +146,35 @@ class ScopedGObject { |
| operator T*() { return obj_; } |
| private: |
| + void Unref() { g_object_unref(obj_); } |
| + |
| T* obj_; |
| }; |
| +template <> |
| +inline void ScopedGObject<GtkStyleContext>::Unref() { |
| + // Versions of GTK earlier than 3.15.4 had a bug where a g_assert |
| + // would be triggered when trying to free a GtkStyleContext that had |
| + // a parent whose only reference was the child context in question. |
| + // This is a hack to work around that case. See GTK commit |
| + // "gtkstylecontext: Don't try to emit a signal when finalizing". |
| + std::function<void(GtkStyleContext*)> unref_style_context = |
|
Elliot Glaysher
2017/02/10 18:13:41
I don't understand why you're declaring an anonymo
Tom (Use chromium acct)
2017/02/10 18:54:40
oh, it's actually recursive
However, I don't thin
|
| + [&](GtkStyleContext* context) { |
| + GtkStyleContext* parent = gtk_style_context_get_parent(context); |
| + if (parent && G_OBJECT(context)->ref_count == 1 && |
| + !GtkVersionCheck(3, 15, 4)) { |
| + g_object_ref(parent); |
| + gtk_style_context_set_parent(context, nullptr); |
| + unref_style_context(parent); |
| + } else { |
| + g_object_unref(context); |
| + } |
| + }; |
| + unref_style_context(obj_); |
| +} |
| + |
| typedef ScopedGObject<GtkStyleContext> ScopedStyleContext; |
| +typedef ScopedGObject<GtkCssProvider> ScopedCssProvider; |
| // If |context| is NULL, creates a new top-level style context |
| // specified by parsing |css_node|. Otherwise, creates the child |
| @@ -170,10 +190,11 @@ ScopedStyleContext AppendCssNodeToStyleContext(GtkStyleContext* context, |
| // must g_object_unref() the returned context. |
| ScopedStyleContext GetStyleContextFromCss(const char* css_selector); |
| -SkColor SkColorFromStyleContext(GtkStyleContext* context); |
| +SkColor GetFgColorFromStyleContext(GtkStyleContext* context); |
| -// Removes all border-type properties on |context| and all of its parents. |
| -void RemoveBorders(GtkStyleContext* context); |
| +// Overrides properties on |context| and all its parents with those |
| +// provided by |css|. |
| +void ApplyCssToContext(GtkStyleContext* context, const char* css); |
| // Get the 'color' property from the style context created by |
| // GetStyleContextFromCss(|css_selector|). |
| @@ -186,15 +207,18 @@ void RenderBackground(const gfx::Size& size, |
| GtkStyleContext* context); |
| // Renders a background from the style context created by |
| -// GetStyleContextFromCss(|css_selector|) into a single pixel and |
| -// returns the color. |
| +// GetStyleContextFromCss(|css_selector|) into a 24x24 bitmap and |
| +// returns the average color. |
| SkColor GetBgColor(const char* css_selector); |
| -// If there is a border, renders the border from the style context |
| -// created by GetStyleContextFromCss(|css_selector|) into a single |
| -// pixel and returns the color. Otherwise returns kInvalidColor. |
| +// Renders the border from the style context created by |
| +// GetStyleContextFromCss(|css_selector|) into a 24x24 bitmap and |
| +// returns the average color. |
| SkColor GetBorderColor(const char* css_selector); |
| +SkColor GetSelectedTextColor(const char* css_selector); |
| +SkColor GetSelectedBgColor(const char* css_selector); |
| + |
| // Get the color of the GtkSeparator specified by |css_selector|. |
| SkColor GetSeparatorColor(const char* css_selector); |
| #endif |