Bug 1328899 - Don't use GTK prelight and active state flags when drawing textfield-multiline background. r=stransky, a=jcristau
authorKarl Tomlinson <karlt+@karlt.net>
Tue, 17 Jan 2017 14:48:55 +1300
changeset 353716 ccec56819e76733f28ae7f046e4602824ddbed10
parent 353715 8cb1602aea5873368486d3fedd861fa8fcbdf10b
child 353717 84c4cc76070fa0a5e6b4abebb07dd666df0a6157
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstransky, jcristau
Bug 1328899 - Don't use GTK prelight and active state flags when drawing textfield-multiline background. r=stransky, a=jcristau This is consistent with GTK not setting these flags with GtkTextView and GtkScrolledWindow. The active flag was triggering @selected_bg_color with Ambiance. This patch almost reverts the state flags to the logic prior to cd7544affe40 but keeps the focused flag in the scrolled window. MozReview-Commit-ID: IVY1sI2Hllw
--- a/widget/gtk/gtk3drawing.cpp
+++ b/widget/gtk/gtk3drawing.cpp
@@ -31,16 +31,27 @@ static gboolean is_initialized;
 #if !GTK_CHECK_VERSION(3,14,0)
 #define GTK_STATE_FLAG_CHECKED (1 << 11)
 static gint
 moz_gtk_get_tab_thickness(GtkStyleContext *style);
+// 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
+// adjusted to match GTK behavior.  Although GTK sets insensitive and focus
+// flags in the generic GtkWidget base class, GTK adds prelight and active
+// flags only to widgets that are expected to demonstrate prelight or active
+// states.  This contrasts with HTML where any element may have :active and
+// :hover states, and so Gecko's GtkStateFlags do not necessarily map to GTK
+// flags.  Failure to restrict the flags in the same way as GTK can cause
+// generic CSS selectors from some themes to unintentionally match elements
+// that are not expected to change appearance on hover or mouse-down.
 static GtkStateFlags
 GetStateFlagsFromGtkWidgetState(GtkWidgetState* state)
     GtkStateFlags stateFlags = GTK_STATE_FLAG_NORMAL;
     if (state->disabled)
         stateFlags = GTK_STATE_FLAG_INSENSITIVE;
     else {    
@@ -853,17 +864,26 @@ 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);
+    // GtkTextView and GtkScrolledWindow do not set active and prelight flags.
+    // The use of focus with MOZ_GTK_SCROLLED_WINDOW here is questionable
+    // because a parent widget will not have focus when its child GtkTextView
+    // has focus, but perhaps this may help identify a focused textarea with
+    // some themes as GtkTextView backgrounds do not typically render
+    // differently with focus.
+    GtkStateFlags state_flags =
+        state->disabled ? GTK_STATE_FLAG_INSENSITIVE :
+        state->focused ? GTK_STATE_FLAG_FOCUSED :
     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);