bug 1328899 don't use GTK prelight and active state flags when drawing textfield-multiline background r=stransky draft
authorKarl Tomlinson <karlt+@karlt.net>
Tue, 17 Jan 2017 14:48:55 +1300
changeset 462316 24f0ad503eadc08060a4f108d06e1dd53a9632e0
parent 460419 b1c31c4a0a678194931779e0f13fba7b508eb109
child 542341 66abbe364a8a8abcbcce3a35095b67a81ff48d0e
push id41696
push userktomlinson@mozilla.com
push dateTue, 17 Jan 2017 01:57:31 +0000
bug 1328899 don't use GTK prelight and active state flags when drawing textfield-multiline background r=stransky 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
@@ -35,16 +35,27 @@ static gboolean is_initialized;
 static gint
 moz_gtk_get_tab_thickness(GtkStyleContext *style);
 static gint
 moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
                         GtkWidgetState* state, GtkTextDirection direction);
+// 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 {    
@@ -869,17 +880,26 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect
     return MOZ_GTK_SUCCESS;
 static gint
 moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* aRect,
                         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,
                      aRect->x, aRect->y, aRect->width, aRect->height);
     GdkRectangle rect = *aRect;
     InsetByBorderPadding(&rect, style_frame);