Changeset 76182 in webkit


Ignore:
Timestamp:
Jan 19, 2011 5:03:18 PM (13 years ago)
Author:
Martin Robinson
Message:

2011-01-12 Martin Robinson <mrobinson@igalia.com>

Reviewed by Gustavo Noronha Silva.

[GTK] Move text field painting out of gtk2drawing.c
https://bugs.webkit.org/show_bug.cgi?id=52327

No new tests. This should not change behavior.

  • platform/gtk/RenderThemeGtk2.cpp: (WebCore::RenderThemeGtk::paintButton): Use the setWidgetHasFocus helper. (WebCore::RenderThemeGtk::paintTextField): Do this manually now instead of calling into the Mozilla code.
  • platform/gtk/WidgetRenderingContext.cpp: Added a couple more wrappers for GTK+ theme functions. (WebCore::WidgetRenderingContext::gtkPaintFlatBox): (WebCore::WidgetRenderingContext::gtkPaintShadow):
  • platform/gtk/WidgetRenderingContext.h: Added new method declarations.
  • platform/gtk/gtk2drawing.c: Remove unused code. (moz_gtk_get_widget_border): (moz_gtk_widget_paint):
  • platform/gtk/gtkdrawing.h:
Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r76177 r76182  
     12011-01-12  Martin Robinson  <mrobinson@igalia.com>
     2
     3        Reviewed by Gustavo Noronha Silva.
     4
     5        [GTK] Move text field painting out of gtk2drawing.c
     6        https://bugs.webkit.org/show_bug.cgi?id=52327
     7
     8        No new tests. This should not change behavior.
     9
     10        * platform/gtk/RenderThemeGtk2.cpp:
     11        (WebCore::RenderThemeGtk::paintButton): Use the setWidgetHasFocus helper.
     12        (WebCore::RenderThemeGtk::paintTextField): Do this manually now instead
     13        of calling into the Mozilla code.
     14        * platform/gtk/WidgetRenderingContext.cpp: Added a couple more wrappers
     15        for GTK+ theme functions.
     16        (WebCore::WidgetRenderingContext::gtkPaintFlatBox):
     17        (WebCore::WidgetRenderingContext::gtkPaintShadow):
     18        * platform/gtk/WidgetRenderingContext.h: Added new method declarations.
     19        * platform/gtk/gtk2drawing.c: Remove unused code.
     20        (moz_gtk_get_widget_border):
     21        (moz_gtk_widget_paint):
     22        * platform/gtk/gtkdrawing.h:
     23
    1242011-01-19  Antti Koivisto  <antti@apple.com>
    225
  • trunk/Source/WebCore/platform/gtk/RenderThemeGtk2.cpp

    r76175 r76182  
    2828#ifdef GTK_API_VERSION_2
    2929
     30// We need this to allow building while using GTK_WIDGET_SET_FLAGS. It's deprecated
     31// but some theme engines require it to ensure proper rendering of focus indicators.
     32#undef GTK_DISABLE_DEPRECATED
     33
    3034#include "CSSValueKeywords.h"
    3135#include "GraphicsContext.h"
     
    244248}
    245249
     250static void setWidgetHasFocus(GtkWidget* widget, gboolean hasFocus)
     251{
     252    g_object_set(widget, "has-focus", hasFocus, NULL);
     253
     254    // These functions are deprecated in GTK+ 2.22, yet theme engines still look
     255    // at these flags when determining if a widget has focus, so we must use them.
     256    if (hasFocus)
     257        GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
     258    else
     259        GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
     260}
     261
    246262bool RenderThemeGtk::paintButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    247263{
     
    258274
    259275    if (isFocused(object)) {
    260         if (isEnabled(object)) {
    261 #if !GTK_CHECK_VERSION(2, 22, 0)
    262             GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
    263 #endif
    264             g_object_set(widget, "has-focus", TRUE, NULL);
    265         }
     276        setWidgetHasFocus(widget, TRUE);
    266277
    267278        gboolean interiorFocus = 0, focusWidth = 0, focusPadding = 0;
     
    289300        widgetContext.gtkPaintFocus(focusRect, widget, state, "button");
    290301
    291 #if !GTK_CHECK_VERSION(2, 22, 0)
    292     GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
    293 #endif
    294     g_object_set(widget, "has-focus", FALSE, NULL);
     302    setWidgetHasFocus(widget, FALSE);
    295303    return false;
    296304}
     
    339347}
    340348
    341 bool RenderThemeGtk::paintTextField(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    342 {
    343     return paintRenderObject(MOZ_GTK_ENTRY, object, info.context, rect);
     349bool RenderThemeGtk::paintTextField(RenderObject* renderObject, const PaintInfo& info, const IntRect& rect)
     350{
     351    GtkWidget* widget = gtkEntry();
     352
     353    bool enabled = isEnabled(renderObject) && !isReadOnlyControl(renderObject);
     354    GtkStateType backgroundState = enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE;
     355    gtk_widget_set_sensitive(widget, enabled);
     356    gtk_widget_set_direction(widget, gtkTextDirection(renderObject->style()->direction()));
     357    setWidgetHasFocus(widget, isFocused(renderObject));
     358
     359    WidgetRenderingContext widgetContext(info.context, rect);
     360    IntRect textFieldRect(IntPoint(), rect.size());
     361
     362    // The entry background is only painted over the interior part of the GTK+ entry, not
     363    // the entire frame. This happens in the Mozilla theme drawing code as well.
     364    IntRect interiorRect(textFieldRect);
     365    GtkStyle* style = gtk_widget_get_style(widget);
     366    interiorRect.inflateX(-style->xthickness);
     367    interiorRect.inflateY(-style->ythickness);
     368    widgetContext.gtkPaintFlatBox(interiorRect, widget, backgroundState, GTK_SHADOW_NONE, "entry_bg");
     369
     370    // This is responsible for drawing the actual frame.
     371    widgetContext.gtkPaintShadow(textFieldRect, widget, GTK_STATE_NORMAL, GTK_SHADOW_IN, "entry");
     372
     373    gboolean interiorFocus;
     374    gint focusWidth;
     375    gtk_widget_style_get(widget,
     376                         "interior-focus", &interiorFocus,
     377                         "focus-line-width", &focusWidth,  NULL);
     378    if (isFocused(renderObject) && !interiorFocus) {
     379        // When GTK+ paints a text entry with focus, it shrinks the size of the frame area by the
     380        // focus width and paints over the previously unfocused text entry. We need to emulate that
     381        // by drawing both the unfocused frame above and the focused frame here.
     382        IntRect shadowRect(textFieldRect);
     383        shadowRect.inflate(-focusWidth);
     384        widgetContext.gtkPaintShadow(shadowRect, widget, GTK_STATE_NORMAL, GTK_SHADOW_IN, "entry");
     385
     386        widgetContext.gtkPaintFocus(textFieldRect, widget, GTK_STATE_NORMAL, "entry");
     387    }
     388
     389    return false;
    344390}
    345391
  • trunk/Source/WebCore/platform/gtk/WidgetRenderingContext.cpp

    r76175 r76182  
    160160}
    161161
     162void WidgetRenderingContext::gtkPaintFlatBox(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, GtkShadowType shadowType, const gchar* detail)
     163{
     164    GdkRectangle paintRect = { m_paintRect.x + rect.x(), m_paintRect.y + rect.y(), rect.width(), rect.height() };
     165    gtk_paint_flat_box(gtk_widget_get_style(widget), m_target, stateType, shadowType, &paintRect,
     166                       widget, detail, paintRect.x, paintRect.y, paintRect.width, paintRect.height);
     167}
     168
    162169void WidgetRenderingContext::gtkPaintFocus(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, const gchar* detail)
    163170{
     
    188195}
    189196
     197void WidgetRenderingContext::gtkPaintShadow(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, GtkShadowType shadowType, const gchar* detail)
     198{
     199    GdkRectangle paintRect = { m_paintRect.x + rect.x(), m_paintRect.y + rect.y(), rect.width(), rect.height() };
     200    gtk_paint_shadow(gtk_widget_get_style(widget), m_target, stateType, shadowType, &paintRect, widget,
     201                     detail, paintRect.x, paintRect.y, paintRect.width, paintRect.height);
     202}
     203
     204
    190205}
    191206
  • trunk/Source/WebCore/platform/gtk/WidgetRenderingContext.h

    r76175 r76182  
    4040    bool paintMozillaWidget(GtkThemeWidgetType, GtkWidgetState*, int flags, GtkTextDirection = GTK_TEXT_DIR_NONE);
    4141    void gtkPaintBox(const IntRect&, GtkWidget*, GtkStateType, GtkShadowType, const gchar*);
     42    void gtkPaintFlatBox(const IntRect&, GtkWidget*, GtkStateType, GtkShadowType, const gchar*);
    4243    void gtkPaintFocus(const IntRect&, GtkWidget*, GtkStateType, const gchar*);
    4344    void gtkPaintSlider(const IntRect&, GtkWidget*, GtkStateType, GtkShadowType, const gchar*, GtkOrientation);
    4445    void gtkPaintCheck(const IntRect&, GtkWidget*, GtkStateType, GtkShadowType, const gchar*);
    4546    void gtkPaintOption(const IntRect&, GtkWidget*, GtkStateType, GtkShadowType, const gchar*);
     47    void gtkPaintShadow(const IntRect&, GtkWidget*, GtkStateType, GtkShadowType, const gchar*);
    4648
    4749private:
  • trunk/Source/WebCore/platform/gtk/gtk2drawing.c

    r76175 r76182  
    165165}
    166166
    167 static gint
    168 ensure_entry_widget()
    169 {
    170     if (!gParts->entryWidget) {
    171         gParts->entryWidget = gtk_entry_new();
    172         setup_widget_prototype(gParts->entryWidget);
    173     }
    174     return MOZ_GTK_SUCCESS;
    175 }
    176 
    177167/* We need to have pointers to the inner widgets (button, separator, arrow)
    178168 * of the ComboBox to get the correct rendering from theme engines which
     
    779769
    780770static gint
    781 moz_gtk_entry_paint(GdkDrawable* drawable, GdkRectangle* rect,
    782                     GdkRectangle* cliprect, GtkWidgetState* state,
    783                     GtkWidget* widget, GtkTextDirection direction)
    784 {
    785     GtkStateType bg_state = state->disabled ?
    786                                 GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL;
    787     gint x, y, width = rect->width, height = rect->height;
    788     GtkStyle* style;
    789     gboolean interior_focus;
    790     gboolean theme_honors_transparency = FALSE;
    791     gint focus_width;
    792 
    793     gtk_widget_set_direction(widget, direction);
    794 
    795     style = gtk_widget_get_style(widget);
    796 
    797     gtk_widget_style_get(widget,
    798                          "interior-focus", &interior_focus,
    799                          "focus-line-width", &focus_width,
    800                          "honors-transparent-bg-hint", &theme_honors_transparency,
    801                          NULL);
    802 
    803     /* gtkentry.c uses two windows, one for the entire widget and one for the
    804      * text area inside it. The background of both windows is set to the "base"
    805      * color of the new state in gtk_entry_state_changed, but only the inner
    806      * textarea window uses gtk_paint_flat_box when exposed */
    807 
    808     TSOffsetStyleGCs(style, rect->x, rect->y);
    809 
    810     /* This gets us a lovely greyish disabledish look */
    811     gtk_widget_set_sensitive(widget, !state->disabled);
    812 
    813     /* GTK fills the outer widget window with the base color before drawing the widget.
    814      * Some older themes rely on this behavior, but many themes nowadays use rounded
    815      * corners on their widgets. While most GTK apps are blissfully unaware of this
    816      * problem due to their use of the default window background, we render widgets on
    817      * many kinds of backgrounds on the web.
    818      * If the theme is able to cope with transparency, then we can skip pre-filling
    819      * and notify the theme it will paint directly on the canvas. */
    820     if (theme_honors_transparency) {
    821         g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE));
    822     } else {
    823         gdk_draw_rectangle(drawable, style->base_gc[bg_state], TRUE,
    824                            cliprect->x, cliprect->y, cliprect->width, cliprect->height);
    825         g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(FALSE));
    826     }
    827 
    828     /* Get the position of the inner window, see _gtk_entry_get_borders */
    829     x = XTHICKNESS(style);
    830     y = YTHICKNESS(style);
    831 
    832     if (!interior_focus) {
    833         x += focus_width;
    834         y += focus_width;
    835     }
    836 
    837     /* Simulate an expose of the inner window */
    838     gtk_paint_flat_box(style, drawable, bg_state, GTK_SHADOW_NONE,
    839                        cliprect, widget, "entry_bg",  rect->x + x,
    840                        rect->y + y, rect->width - 2*x, rect->height - 2*y);
    841 
    842     /* Now paint the shadow and focus border.
    843      * We do like in gtk_entry_draw_frame, we first draw the shadow, a tad
    844      * smaller when focused if the focus is not interior, then the focus. */
    845     x = rect->x;
    846     y = rect->y;
    847 
    848     if (state->focused && !state->disabled) {
    849         /* This will get us the lit borders that focused textboxes enjoy on
    850          * some themes. */
    851         GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
    852 
    853         if (!interior_focus) {
    854             /* Indent the border a little bit if we have exterior focus
    855                (this is what GTK does to draw native entries) */
    856             x += focus_width;
    857             y += focus_width;
    858             width -= 2 * focus_width;
    859             height -= 2 * focus_width;
    860         }
    861     }
    862 
    863     gtk_paint_shadow(style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
    864                      cliprect, widget, "entry", x, y, width, height);
    865 
    866     if (state->focused && !state->disabled) {
    867         if (!interior_focus) {
    868             gtk_paint_focus(style, drawable,  GTK_STATE_NORMAL, cliprect,
    869                             widget, "entry",
    870                             rect->x, rect->y, rect->width, rect->height);
    871         }
    872 
    873         /* Now unset the focus flag. We don't want other entries to look
    874          * like they're focused too! */
    875         GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
    876     }
    877 
    878     return MOZ_GTK_SUCCESS;
    879 }
    880 
    881 static gint
    882771moz_gtk_combo_box_paint(GdkDrawable* drawable, GdkRectangle* rect,
    883772                        GdkRectangle* cliprect, GtkWidgetState* state,
     
    1035924            return MOZ_GTK_SUCCESS;
    1036925        }
    1037     case MOZ_GTK_ENTRY:
    1038         ensure_entry_widget();
    1039         w = gParts->entryWidget;
    1040         break;
    1041926    case MOZ_GTK_DROPDOWN:
    1042927        {
     
    11691054        return moz_gtk_scrolled_window_paint(drawable, rect, cliprect, state);
    11701055        break;
    1171     case MOZ_GTK_ENTRY:
    1172         ensure_entry_widget();
    1173         return moz_gtk_entry_paint(drawable, rect, cliprect, state,
    1174                                    gParts->entryWidget, direction);
    1175         break;
    11761056    case MOZ_GTK_DROPDOWN:
    11771057        return moz_gtk_combo_box_paint(drawable, rect, cliprect, state,
  • trunk/Source/WebCore/platform/gtk/gtkdrawing.h

    r76175 r76182  
    4848#ifndef _GTK_DRAWING_H_
    4949#define _GTK_DRAWING_H_
     50
     51#undef GTK_DISABLE_DEPRECATED
    5052
    5153#include <gtk/gtk.h>
     
    9092    GtkWidget* horizScrollbarWidget;
    9193    GtkWidget* vertScrollbarWidget;
    92     GtkWidget* entryWidget;
    9394    GtkWidget* comboBoxWidget;
    9495    GtkWidget* comboBoxButtonWidget;
     
    134135  /* Paints the background of a scrolled window */
    135136  MOZ_GTK_SCROLLED_WINDOW,
    136   MOZ_GTK_ENTRY,
    137137  /* Paints a GtkOptionMenu. */
    138138  MOZ_GTK_DROPDOWN,
Note: See TracChangeset for help on using the changeset viewer.