diff options
Diffstat (limited to 'WebCore/platform/gtk')
-rw-r--r-- | WebCore/platform/gtk/ContextMenuGtk.cpp | 22 | ||||
-rw-r--r-- | WebCore/platform/gtk/ContextMenuItemGtk.cpp | 135 | ||||
-rw-r--r-- | WebCore/platform/gtk/GtkVersioning.h | 2 | ||||
-rw-r--r-- | WebCore/platform/gtk/PasteboardHelper.cpp | 27 | ||||
-rw-r--r-- | WebCore/platform/gtk/PlatformScreenGtk.cpp | 2 | ||||
-rw-r--r-- | WebCore/platform/gtk/PopupMenuGtk.cpp | 112 | ||||
-rw-r--r-- | WebCore/platform/gtk/PopupMenuGtk.h | 11 | ||||
-rw-r--r-- | WebCore/platform/gtk/RenderThemeGtk.cpp | 453 | ||||
-rw-r--r-- | WebCore/platform/gtk/RenderThemeGtk.h | 33 | ||||
-rw-r--r-- | WebCore/platform/gtk/WidgetGtk.cpp | 4 | ||||
-rw-r--r-- | WebCore/platform/gtk/WidgetRenderingContext.h | 4 | ||||
-rw-r--r-- | WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp | 27 | ||||
-rw-r--r-- | WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp | 21 | ||||
-rw-r--r-- | WebCore/platform/gtk/gtk2drawing.c | 127 | ||||
-rw-r--r-- | WebCore/platform/gtk/gtk3drawing.c | 126 | ||||
-rw-r--r-- | WebCore/platform/gtk/gtkdrawing.h | 19 |
16 files changed, 548 insertions, 577 deletions
diff --git a/WebCore/platform/gtk/ContextMenuGtk.cpp b/WebCore/platform/gtk/ContextMenuGtk.cpp index 210cfa6..423959a 100644 --- a/WebCore/platform/gtk/ContextMenuGtk.cpp +++ b/WebCore/platform/gtk/ContextMenuGtk.cpp @@ -19,23 +19,11 @@ #include "config.h" #include "ContextMenu.h" -#include "ContextMenuController.h" - #include <gtk/gtk.h> namespace WebCore { -// TODO: ref-counting correctness checking. -// See http://bugs.webkit.org/show_bug.cgi?id=16115 - -static void menuItemActivated(GtkMenuItem* item, ContextMenuController* controller) -{ - ContextMenuItem contextItem(item); - controller->contextMenuItemSelected(&contextItem); -} - -ContextMenu::ContextMenu(const HitTestResult& result) - : m_hitTestResult(result) +ContextMenu::ContextMenu() { m_platformDescription = GTK_MENU(gtk_menu_new()); @@ -51,15 +39,9 @@ ContextMenu::~ContextMenu() void ContextMenu::appendItem(ContextMenuItem& item) { ASSERT(m_platformDescription); - checkOrEnableIfNeeded(item); - ContextMenuItemType type = item.type(); - GtkMenuItem* platformItem = ContextMenuItem::createNativeMenuItem(item.releasePlatformDescription()); + GtkMenuItem* platformItem = item.releasePlatformDescription(); ASSERT(platformItem); - - if (type == ActionType || type == CheckableActionType) - g_signal_connect(platformItem, "activate", G_CALLBACK(menuItemActivated), controller()); - gtk_menu_shell_append(GTK_MENU_SHELL(m_platformDescription), GTK_WIDGET(platformItem)); gtk_widget_show(GTK_WIDGET(platformItem)); } diff --git a/WebCore/platform/gtk/ContextMenuItemGtk.cpp b/WebCore/platform/gtk/ContextMenuItemGtk.cpp index 68d0a9a..4d79f13 100644 --- a/WebCore/platform/gtk/ContextMenuItemGtk.cpp +++ b/WebCore/platform/gtk/ContextMenuItemGtk.cpp @@ -18,12 +18,14 @@ */ #include "config.h" -#include "ContextMenu.h" + #include "ContextMenuItem.h" -#include "NotImplemented.h" -#include <wtf/text/CString.h> +#include "ContextMenu.h" +#include "GOwnPtr.h" +#include "NotImplemented.h" #include <gtk/gtk.h> +#include <wtf/text/CString.h> #define WEBKIT_CONTEXT_MENU_ACTION "webkit-context-menu" @@ -114,30 +116,9 @@ static const char* gtkStockIDFromContextMenuAction(const ContextMenuAction& acti } // Extract the ActionType from the menu item -ContextMenuItem::ContextMenuItem(GtkMenuItem* item) - : m_platformDescription() +ContextMenuItem::ContextMenuItem(PlatformMenuItemDescription item) + : m_platformDescription(item) { - if (GTK_IS_SEPARATOR_MENU_ITEM(item)) - m_platformDescription.type = SeparatorType; - else if (gtk_menu_item_get_submenu(item)) - m_platformDescription.type = SubmenuType; - else if (GTK_IS_CHECK_MENU_ITEM(item)) { - m_platformDescription.type = CheckableActionType; - m_platformDescription.checked = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)); - } else - m_platformDescription.type = ActionType; -#if GTK_CHECK_VERSION (2, 16, 0) - m_platformDescription.title = String::fromUTF8(gtk_menu_item_get_label(GTK_MENU_ITEM(item))); -#else - GtkWidget* label = gtk_bin_get_child(GTK_BIN(item)); - m_platformDescription.title = String::fromUTF8(gtk_label_get_label(GTK_LABEL(label))); -#endif - - m_platformDescription.action = *static_cast<ContextMenuAction*>(g_object_get_data(G_OBJECT(item), WEBKIT_CONTEXT_MENU_ACTION)); - - m_platformDescription.subMenu = GTK_MENU(gtk_menu_item_get_submenu(item)); - if (m_platformDescription.subMenu) - g_object_ref(m_platformDescription.subMenu); } ContextMenuItem::ContextMenuItem(ContextMenu*) @@ -147,114 +128,100 @@ ContextMenuItem::ContextMenuItem(ContextMenu*) ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction action, const String& title, ContextMenu* subMenu) { - m_platformDescription.type = type; - m_platformDescription.action = action; - m_platformDescription.title = title; + if (type == SeparatorType) { + m_platformDescription = GTK_MENU_ITEM(gtk_separator_menu_item_new()); + return; + } - setSubMenu(subMenu); -} + GOwnPtr<char> actionName(g_strdup_printf("context-menu-action-%d", action)); + GtkAction* platformAction = 0; -ContextMenuItem::~ContextMenuItem() -{ - if (m_platformDescription.subMenu) - g_object_unref(m_platformDescription.subMenu); -} - -GtkMenuItem* ContextMenuItem::createNativeMenuItem(const PlatformMenuItemDescription& menu) -{ - GtkMenuItem* item = 0; - if (menu.type == SeparatorType) - item = GTK_MENU_ITEM(gtk_separator_menu_item_new()); - else { - if (menu.type == CheckableActionType) { - item = GTK_MENU_ITEM(gtk_check_menu_item_new_with_mnemonic(menu.title.utf8().data())); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), menu.checked); - } else { - if (const gchar* stockID = gtkStockIDFromContextMenuAction(menu.action)) { - item = GTK_MENU_ITEM(gtk_image_menu_item_new_with_mnemonic(menu.title.utf8().data())); - GtkWidget* image = gtk_image_new_from_stock(stockID, GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image); - } else - item = GTK_MENU_ITEM(gtk_menu_item_new_with_mnemonic(menu.title.utf8().data())); - } + if (type == CheckableActionType) + platformAction = GTK_ACTION(gtk_toggle_action_new(actionName.get(), title.utf8().data(), 0, gtkStockIDFromContextMenuAction(action))); + else + platformAction = gtk_action_new(actionName.get(), title.utf8().data(), 0, gtkStockIDFromContextMenuAction(action)); - ContextMenuAction* menuAction = static_cast<ContextMenuAction*>(malloc(sizeof(ContextMenuAction*))); - *menuAction = menu.action; - g_object_set_data(G_OBJECT(item), WEBKIT_CONTEXT_MENU_ACTION, menuAction); + m_platformDescription = GTK_MENU_ITEM(gtk_action_create_menu_item(platformAction)); + g_object_unref(platformAction); - gtk_widget_set_sensitive(GTK_WIDGET(item), menu.enabled); + g_object_set_data(G_OBJECT(m_platformDescription.get()), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action)); - if (menu.subMenu) - gtk_menu_item_set_submenu(item, GTK_WIDGET(menu.subMenu)); - } + if (subMenu) + setSubMenu(subMenu); +} - return item; +ContextMenuItem::~ContextMenuItem() +{ } PlatformMenuItemDescription ContextMenuItem::releasePlatformDescription() { - PlatformMenuItemDescription description = m_platformDescription; - m_platformDescription = PlatformMenuItemDescription(); - return description; + return m_platformDescription.leakRef(); } ContextMenuItemType ContextMenuItem::type() const { - return m_platformDescription.type; + if (GTK_IS_SEPARATOR_MENU_ITEM(m_platformDescription.get())) + return SeparatorType; + if (GTK_IS_CHECK_MENU_ITEM(m_platformDescription.get())) + return CheckableActionType; + if (gtk_menu_item_get_submenu(m_platformDescription.get())) + return SubmenuType; + return ActionType; } void ContextMenuItem::setType(ContextMenuItemType type) { - m_platformDescription.type = type; + if (type == SeparatorType) + m_platformDescription = GTK_MENU_ITEM(gtk_separator_menu_item_new()); } ContextMenuAction ContextMenuItem::action() const { - return m_platformDescription.action; + return static_cast<ContextMenuAction>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(m_platformDescription.get()), WEBKIT_CONTEXT_MENU_ACTION))); } void ContextMenuItem::setAction(ContextMenuAction action) { - m_platformDescription.action = action; + g_object_set_data(G_OBJECT(m_platformDescription.get()), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action)); } String ContextMenuItem::title() const { - return m_platformDescription.title; + GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get())); + return action ? String(gtk_action_get_label(action)) : String(); } void ContextMenuItem::setTitle(const String& title) { - m_platformDescription.title = title; + GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get())); + if (action) + gtk_action_set_label(action, title.utf8().data()); } PlatformMenuDescription ContextMenuItem::platformSubMenu() const { - return m_platformDescription.subMenu; + GtkWidget* subMenu = gtk_menu_item_get_submenu(m_platformDescription.get()); + return subMenu ? GTK_MENU(subMenu) : 0; } void ContextMenuItem::setSubMenu(ContextMenu* menu) { - if (m_platformDescription.subMenu) - g_object_unref(m_platformDescription.subMenu); - - if (!menu) - return; - - m_platformDescription.subMenu = menu->releasePlatformDescription(); - m_platformDescription.type = SubmenuType; - - g_object_ref_sink(G_OBJECT(m_platformDescription.subMenu)); + gtk_menu_item_set_submenu(m_platformDescription.get(), GTK_WIDGET(menu->platformDescription())); } void ContextMenuItem::setChecked(bool shouldCheck) { - m_platformDescription.checked = shouldCheck; + GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get())); + if (action && GTK_IS_TOGGLE_ACTION(action)) + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), shouldCheck); } void ContextMenuItem::setEnabled(bool shouldEnable) { - m_platformDescription.enabled = shouldEnable; + GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get())); + if (action) + gtk_action_set_sensitive(action, shouldEnable); } } diff --git a/WebCore/platform/gtk/GtkVersioning.h b/WebCore/platform/gtk/GtkVersioning.h index ea15a54..11d1f8a 100644 --- a/WebCore/platform/gtk/GtkVersioning.h +++ b/WebCore/platform/gtk/GtkVersioning.h @@ -31,7 +31,7 @@ G_BEGIN_DECLS // Macros to avoid deprecation checking churn #ifndef GTK_API_VERSION_2 -#define GDK_DISPLAY() (GDK_DISPLAY_XDISPLAY(gdk_display_get_default())) +#define GDK_WINDOW_XWINDOW(window) (gdk_x11_window_get_xid(window)) #else GdkPixbuf* gdk_pixbuf_get_from_surface(cairo_surface_t* surface, int srcX, int srcY, int width, int height); diff --git a/WebCore/platform/gtk/PasteboardHelper.cpp b/WebCore/platform/gtk/PasteboardHelper.cpp index 228d5e9..4428be0 100644 --- a/WebCore/platform/gtk/PasteboardHelper.cpp +++ b/WebCore/platform/gtk/PasteboardHelper.cpp @@ -34,11 +34,11 @@ namespace WebCore { -static GdkAtom textPlainAtom = gdk_atom_intern("text/plain;charset=utf-8", FALSE); -static GdkAtom markupAtom = gdk_atom_intern("text/html", FALSE); -static GdkAtom netscapeURLAtom = gdk_atom_intern("_NETSCAPE_URL", FALSE); -static GdkAtom uriListAtom = gdk_atom_intern("text/uri-list", FALSE); -static String gMarkupPrefix = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"; +static GdkAtom textPlainAtom; +static GdkAtom markupAtom; +static GdkAtom netscapeURLAtom; +static GdkAtom uriListAtom; +static String gMarkupPrefix; static void removeMarkupPrefix(String& markup) { @@ -49,9 +49,26 @@ static void removeMarkupPrefix(String& markup) markup.remove(0, gMarkupPrefix.length()); } +static void initGdkAtoms() +{ + static gboolean initialized = FALSE; + + if (initialized) + return; + + initialized = TRUE; + + textPlainAtom = gdk_atom_intern("text/plain;charset=utf-8", FALSE); + markupAtom = gdk_atom_intern("text/html", FALSE); + netscapeURLAtom = gdk_atom_intern("_NETSCAPE_URL", FALSE); + uriListAtom = gdk_atom_intern("text/uri-list", FALSE); + gMarkupPrefix = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"; +} + PasteboardHelper::PasteboardHelper() : m_targetList(gtk_target_list_new(0, 0)) { + initGdkAtoms(); } PasteboardHelper::~PasteboardHelper() diff --git a/WebCore/platform/gtk/PlatformScreenGtk.cpp b/WebCore/platform/gtk/PlatformScreenGtk.cpp index 9c70d0e..40b509e 100644 --- a/WebCore/platform/gtk/PlatformScreenGtk.cpp +++ b/WebCore/platform/gtk/PlatformScreenGtk.cpp @@ -121,7 +121,7 @@ FloatRect screenAvailableRect(Widget* widget) if (!gtk_widget_get_realized(container)) return screenRect(widget); - GdkDrawable* rootWindow = GDK_DRAWABLE(gtk_widget_get_root_window(container)); + GdkWindow* rootWindow = gtk_widget_get_root_window(container); GdkDisplay* display = gdk_window_get_display(rootWindow); Atom xproperty = gdk_x11_get_xatom_by_name_for_display(display, "_NET_WORKAREA"); diff --git a/WebCore/platform/gtk/PopupMenuGtk.cpp b/WebCore/platform/gtk/PopupMenuGtk.cpp index e7ff78e..b2466c5 100644 --- a/WebCore/platform/gtk/PopupMenuGtk.cpp +++ b/WebCore/platform/gtk/PopupMenuGtk.cpp @@ -5,6 +5,7 @@ * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com * Copyright (C) 2008 Collabora Ltd. * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2010 Igalia S.L. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -27,16 +28,22 @@ #include "PopupMenuGtk.h" #include "FrameView.h" +#include "GOwnPtr.h" #include "GtkVersioning.h" #include "HostWindow.h" #include "PlatformString.h" -#include <wtf/text/CString.h> +#include <gdk/gdk.h> #include <gtk/gtk.h> +#include <wtf/text/CString.h> namespace WebCore { +static const uint32_t gSearchTimeoutMs = 1000; + PopupMenuGtk::PopupMenuGtk(PopupMenuClient* client) : m_popupClient(client) + , m_previousKeyEventCharacter(0) + , m_currentlySelectedMenuItem(0) { } @@ -54,12 +61,16 @@ void PopupMenuGtk::show(const IntRect& rect, FrameView* view, int index) if (!m_popup) { m_popup = GTK_MENU(gtk_menu_new()); - g_signal_connect(m_popup.get(), "unmap", G_CALLBACK(menuUnmapped), this); + g_signal_connect(m_popup.get(), "unmap", G_CALLBACK(PopupMenuGtk::menuUnmapped), this); + g_signal_connect(m_popup.get(), "key-press-event", G_CALLBACK(PopupMenuGtk::keyPressEventCallback), this); } else gtk_container_foreach(GTK_CONTAINER(m_popup.get()), reinterpret_cast<GtkCallback>(menuRemoveItem), this); - int x, y; - gdk_window_get_origin(gtk_widget_get_window(GTK_WIDGET(view->hostWindow()->platformPageClient())), &x, &y); + int x = 0; + int y = 0; + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(view->hostWindow()->platformPageClient())); + if (window) + gdk_window_get_origin(window, &x, &y); m_menuPosition = view->contentsToWindow(rect.location()); m_menuPosition = IntPoint(m_menuPosition.x() + x, m_menuPosition.y() + y + rect.height()); m_indexMap.clear(); @@ -73,7 +84,8 @@ void PopupMenuGtk::show(const IntRect& rect, FrameView* view, int index) item = gtk_menu_item_new_with_label(client()->itemText(i).utf8().data()); m_indexMap.add(item, i); - g_signal_connect(item, "activate", G_CALLBACK(menuItemActivated), this); + g_signal_connect(item, "activate", G_CALLBACK(PopupMenuGtk::menuItemActivated), this); + g_signal_connect(item, "select", G_CALLBACK(PopupMenuGtk::selectItemCallback), this); // FIXME: Apply the PopupMenuStyle from client()->itemStyle(i) gtk_widget_set_sensitive(item, client()->itemIsEnabled(i)); @@ -138,6 +150,77 @@ void PopupMenuGtk::disconnectClient() m_popupClient = 0; } +bool PopupMenuGtk::typeAheadFind(GdkEventKey* event) +{ + // If we were given a non-printable character just skip it. + gunichar unicodeCharacter = gdk_keyval_to_unicode(event->keyval); + if (!unicodeCharacter) { + resetTypeAheadFindState(); + return false; + } + + glong charactersWritten; + GOwnPtr<gunichar2> utf16String(g_ucs4_to_utf16(&unicodeCharacter, 1, 0, &charactersWritten, 0)); + if (!utf16String) { + resetTypeAheadFindState(); + return false; + } + + // If the character is the same as the last character, the user is probably trying to + // cycle through the menulist entries. This matches the WebCore behavior for collapsed + // menulists. + bool repeatingCharacter = unicodeCharacter != m_previousKeyEventCharacter; + if (event->time - m_previousKeyEventTimestamp > gSearchTimeoutMs) + m_currentSearchString = String(static_cast<UChar*>(utf16String.get()), charactersWritten); + else if (repeatingCharacter) + m_currentSearchString.append(String(static_cast<UChar*>(utf16String.get()), charactersWritten)); + + m_previousKeyEventTimestamp = event->time; + m_previousKeyEventCharacter = unicodeCharacter; + + // Like the Chromium port, we case fold before searching, because + // strncmp does not handle non-ASCII characters. + GOwnPtr<gchar> searchStringWithCaseFolded(g_utf8_casefold(m_currentSearchString.utf8().data(), -1)); + size_t prefixLength = strlen(searchStringWithCaseFolded.get()); + + GList* children = gtk_container_get_children(GTK_CONTAINER(m_popup.get())); + if (!children) + return true; + + // If a menu item has already been selected, start searching from the current + // item down the list. This will make multiple key presses of the same character + // advance the selection. + GList* currentChild = children; + if (m_currentlySelectedMenuItem) { + currentChild = g_list_find(children, m_currentlySelectedMenuItem); + if (!currentChild) { + m_currentlySelectedMenuItem = 0; + currentChild = children; + } + + // Repeating characters should iterate. + if (repeatingCharacter) { + if (GList* nextChild = g_list_next(currentChild)) + currentChild = nextChild; + } + } + + GList* firstChild = currentChild; + do { + currentChild = g_list_next(currentChild); + if (!currentChild) + currentChild = children; + + GOwnPtr<gchar> itemText(g_utf8_casefold(gtk_menu_item_get_label(GTK_MENU_ITEM(currentChild->data)), -1)); + if (!strncmp(searchStringWithCaseFolded.get(), itemText.get(), prefixLength)) { + gtk_menu_shell_select_item(GTK_MENU_SHELL(m_popup.get()), GTK_WIDGET(currentChild->data)); + return true; + } + } while (currentChild != firstChild); + + return true; +} + void PopupMenuGtk::menuItemActivated(GtkMenuItem* item, PopupMenuGtk* that) { ASSERT(that->client()); @@ -148,6 +231,7 @@ void PopupMenuGtk::menuItemActivated(GtkMenuItem* item, PopupMenuGtk* that) void PopupMenuGtk::menuUnmapped(GtkWidget*, PopupMenuGtk* that) { ASSERT(that->client()); + that->resetTypeAheadFindState(); that->client()->popupDidHide(); } @@ -158,11 +242,29 @@ void PopupMenuGtk::menuPositionFunction(GtkMenu*, gint* x, gint* y, gboolean* pu *pushIn = true; } +void PopupMenuGtk::resetTypeAheadFindState() +{ + m_currentlySelectedMenuItem = 0; + m_previousKeyEventCharacter = 0; + m_currentSearchString = ""; +} + void PopupMenuGtk::menuRemoveItem(GtkWidget* widget, PopupMenuGtk* that) { ASSERT(that->m_popup); gtk_container_remove(GTK_CONTAINER(that->m_popup.get()), widget); } +int PopupMenuGtk::selectItemCallback(GtkMenuItem* item, PopupMenuGtk* that) +{ + that->m_currentlySelectedMenuItem = GTK_WIDGET(item); + return FALSE; +} + +int PopupMenuGtk::keyPressEventCallback(GtkWidget* widget, GdkEventKey* event, PopupMenuGtk* that) +{ + return that->typeAheadFind(event); +} + } diff --git a/WebCore/platform/gtk/PopupMenuGtk.h b/WebCore/platform/gtk/PopupMenuGtk.h index 8848e06..e47fda6 100644 --- a/WebCore/platform/gtk/PopupMenuGtk.h +++ b/WebCore/platform/gtk/PopupMenuGtk.h @@ -24,11 +24,12 @@ #include "IntRect.h" #include "PopupMenu.h" #include "PopupMenuClient.h" -#include <glib.h> #include <wtf/HashMap.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> +typedef struct _GdkEventKey GdkEventKey; + namespace WebCore { class FrameView; @@ -43,19 +44,27 @@ public: virtual void hide(); virtual void updateFromElement(); virtual void disconnectClient(); + bool typeAheadFind(GdkEventKey*); private: PopupMenuClient* client() const { return m_popupClient; } + void resetTypeAheadFindState(); static void menuItemActivated(GtkMenuItem* item, PopupMenuGtk*); static void menuUnmapped(GtkWidget*, PopupMenuGtk*); static void menuPositionFunction(GtkMenu*, gint*, gint*, gboolean*, PopupMenuGtk*); static void menuRemoveItem(GtkWidget*, PopupMenuGtk*); + static int selectItemCallback(GtkMenuItem*, PopupMenuGtk*); + static int keyPressEventCallback(GtkWidget*, GdkEventKey*, PopupMenuGtk*); PopupMenuClient* m_popupClient; IntPoint m_menuPosition; PlatformRefPtr<GtkMenu> m_popup; HashMap<GtkWidget*, int> m_indexMap; + String m_currentSearchString; + uint32_t m_previousKeyEventTimestamp; + unsigned int m_previousKeyEventCharacter; + GtkWidget* m_currentlySelectedMenuItem; }; } diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp index fe6c9e9..73b2d6b 100644 --- a/WebCore/platform/gtk/RenderThemeGtk.cpp +++ b/WebCore/platform/gtk/RenderThemeGtk.cpp @@ -55,6 +55,19 @@ namespace WebCore { using namespace HTMLNames; +static void paintStockIcon(GraphicsContext* context, const IntPoint& iconPoint, GtkStyle* style, const char* iconName, + GtkTextDirection direction, GtkStateType state, GtkIconSize iconSize) +{ + GtkIconSet* iconSet = gtk_style_lookup_icon_set(style, iconName); + PlatformRefPtr<GdkPixbuf> icon = adoptPlatformRef(gtk_icon_set_render_icon(iconSet, style, direction, state, iconSize, 0, 0)); + + cairo_t* cr = context->platformContext(); + cairo_save(cr); + gdk_cairo_set_source_pixbuf(cr, icon.get(), iconPoint.x(), iconPoint.y()); + cairo_paint(cr); + cairo_restore(cr); +} + #if ENABLE(VIDEO) static HTMLMediaElement* getMediaElementFromRenderObject(RenderObject* o) { @@ -66,57 +79,46 @@ static HTMLMediaElement* getMediaElementFromRenderObject(RenderObject* o) return static_cast<HTMLMediaElement*>(mediaNode); } -static gchar* getIconNameForTextDirection(const char* baseName) +static GtkIconSize getMediaButtonIconSize(int mediaIconSize) { - GString* nameWithDirection = g_string_new(baseName); - GtkTextDirection textDirection = gtk_widget_get_default_direction(); - - if (textDirection == GTK_TEXT_DIR_RTL) - g_string_append(nameWithDirection, "-rtl"); - else if (textDirection == GTK_TEXT_DIR_LTR) - g_string_append(nameWithDirection, "-ltr"); - - return g_string_free(nameWithDirection, FALSE); + GtkIconSize iconSize = gtk_icon_size_from_name("webkit-media-button-size"); + if (!iconSize) + iconSize = gtk_icon_size_register("webkit-media-button-size", mediaIconSize, mediaIconSize); + return iconSize; } -void RenderThemeGtk::initMediaStyling(GtkStyle* style, bool force) +void RenderThemeGtk::initMediaColors() { - static bool stylingInitialized = false; + GtkStyle* style = gtk_widget_get_style(GTK_WIDGET(gtkContainer())); + m_panelColor = style->bg[GTK_STATE_NORMAL]; + m_sliderColor = style->bg[GTK_STATE_ACTIVE]; + m_sliderThumbColor = style->bg[GTK_STATE_SELECTED]; +} - if (!stylingInitialized || force) { - m_panelColor = style->bg[GTK_STATE_NORMAL]; - m_sliderColor = style->bg[GTK_STATE_ACTIVE]; - m_sliderThumbColor = style->bg[GTK_STATE_SELECTED]; +void RenderThemeGtk::initMediaButtons() +{ + static bool iconsInitialized = false; - // Names of these icons can vary because of text direction. - gchar* playButtonIconName = getIconNameForTextDirection("gtk-media-play"); - gchar* seekBackButtonIconName = getIconNameForTextDirection("gtk-media-rewind"); - gchar* seekForwardButtonIconName = getIconNameForTextDirection("gtk-media-forward"); + if (iconsInitialized) + return; - m_fullscreenButton.clear(); - m_muteButton.clear(); - m_unmuteButton.clear(); - m_playButton.clear(); - m_pauseButton.clear(); - m_seekBackButton.clear(); - m_seekForwardButton.clear(); + PlatformRefPtr<GtkIconFactory> iconFactory = adoptPlatformRef(gtk_icon_factory_new()); + GtkIconSource* iconSource = gtk_icon_source_new(); + const char* icons[] = { "audio-volume-high", "audio-volume-muted" }; - m_fullscreenButton = Image::loadPlatformThemeIcon("gtk-fullscreen", m_mediaIconSize); - // Note that the muteButton and unmuteButton take icons reflecting - // the *current* state. Hence, the unmuteButton represents the *muted* - // status, the muteButton represents the then current *unmuted* status. - m_muteButton = Image::loadPlatformThemeIcon("audio-volume-high", m_mediaIconSize); - m_unmuteButton = Image::loadPlatformThemeIcon("audio-volume-muted", m_mediaIconSize); - m_playButton = Image::loadPlatformThemeIcon(reinterpret_cast<const char*>(playButtonIconName), m_mediaIconSize); - m_pauseButton = Image::loadPlatformThemeIcon("gtk-media-pause", m_mediaIconSize); - m_seekBackButton = Image::loadPlatformThemeIcon(reinterpret_cast<const char*>(seekBackButtonIconName), m_mediaIconSize); - m_seekForwardButton = Image::loadPlatformThemeIcon(reinterpret_cast<const char*>(seekForwardButtonIconName), m_mediaIconSize); + gtk_icon_factory_add_default(iconFactory.get()); - g_free(playButtonIconName); - g_free(seekBackButtonIconName); - g_free(seekForwardButtonIconName); - stylingInitialized = true; + for (size_t i = 0; i < G_N_ELEMENTS(icons); ++i) { + gtk_icon_source_set_icon_name(iconSource, icons[i]); + GtkIconSet* iconSet = gtk_icon_set_new(); + gtk_icon_set_add_source(iconSet, iconSource); + gtk_icon_factory_add(iconFactory.get(), icons[i], iconSet); + gtk_icon_set_unref(iconSet); } + + gtk_icon_source_free(iconSource); + + iconsInitialized = true; } #endif @@ -146,13 +148,6 @@ RenderThemeGtk::RenderThemeGtk() , m_mediaSliderHeight(14) , m_mediaSliderThumbWidth(12) , m_mediaSliderThumbHeight(12) - , m_fullscreenButton(0) - , m_muteButton(0) - , m_unmuteButton(0) - , m_playButton(0) - , m_pauseButton(0) - , m_seekBackButton(0) - , m_seekForwardButton(0) #ifdef GTK_API_VERSION_2 , m_themePartsHaveRGBAColormap(true) #endif @@ -176,7 +171,8 @@ RenderThemeGtk::RenderThemeGtk() ++mozGtkRefCount; #if ENABLE(VIDEO) - initMediaStyling(gtk_rc_get_style(GTK_WIDGET(gtkContainer())), false); + initMediaColors(); + initMediaButtons(); #endif } @@ -187,14 +183,6 @@ RenderThemeGtk::~RenderThemeGtk() if (!mozGtkRefCount) moz_gtk_shutdown(); - m_fullscreenButton.clear(); - m_muteButton.clear(); - m_unmuteButton.clear(); - m_playButton.clear(); - m_pauseButton.clear(); - m_seekBackButton.clear(); - m_seekForwardButton.clear(); - gtk_widget_destroy(m_gtkWindow); } @@ -229,6 +217,17 @@ static bool supportsFocus(ControlPart appearance) } } +GtkStateType RenderThemeGtk::getGtkStateType(RenderObject* object) +{ + if (!isEnabled(object) || isReadOnlyControl(object)) + return GTK_STATE_INSENSITIVE; + if (isPressed(object)) + return GTK_STATE_ACTIVE; + if (isHovered(object)) + return GTK_STATE_PRELIGHT; + return GTK_STATE_NORMAL; +} + bool RenderThemeGtk::supportsFocusRing(const RenderStyle* style) const { return supportsFocus(style->appearance()); @@ -266,23 +265,16 @@ static GtkTextDirection gtkTextDirection(TextDirection direction) } } -static void adjustMozillaStyle(const RenderThemeGtk* theme, RenderStyle* style, GtkThemeWidgetType type) +GtkStateType RenderThemeGtk::gtkIconState(RenderObject* renderObject) { - gint left, top, right, bottom; - GtkTextDirection direction = gtkTextDirection(style->direction()); - gboolean inhtml = true; - - if (moz_gtk_get_widget_border(type, &left, &top, &right, &bottom, direction, inhtml) != MOZ_GTK_SUCCESS) - return; + if (!isEnabled(renderObject)) + return GTK_STATE_INSENSITIVE; + if (isPressed(renderObject)) + return GTK_STATE_ACTIVE; + if (isHovered(renderObject)) + return GTK_STATE_PRELIGHT; - // FIXME: This approach is likely to be incorrect. See other ports and layout tests to see the problem. - const int xpadding = 1; - const int ypadding = 1; - - style->setPaddingLeft(Length(xpadding + left, Fixed)); - style->setPaddingTop(Length(ypadding + top, Fixed)); - style->setPaddingRight(Length(xpadding + right, Fixed)); - style->setPaddingBottom(Length(ypadding + bottom, Fixed)); + return GTK_STATE_NORMAL; } bool RenderThemeGtk::paintRenderObject(GtkThemeWidgetType type, RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, int flags) @@ -306,14 +298,7 @@ bool RenderThemeGtk::paintRenderObject(GtkThemeWidgetType type, RenderObject* re widgetState.disabled = !isEnabled(renderObject) || isReadOnlyControl(renderObject); widgetState.isDefault = false; widgetState.canDefault = false; - - // FIXME: The depressed value should probably apply for other theme parts too. - // It must be used for range thumbs, because otherwise when the thumb is pressed, - // the rendering is incorrect. - if (type == MOZ_GTK_SCALE_THUMB_HORIZONTAL || type == MOZ_GTK_SCALE_THUMB_VERTICAL) - widgetState.depressed = isPressed(renderObject); - else - widgetState.depressed = false; + widgetState.depressed = false; WidgetRenderingContext widgetContext(context, rect); return !widgetContext.paintMozillaWidget(type, &widgetState, flags, gtkTextDirection(renderObject->style()->direction())); @@ -366,9 +351,56 @@ void RenderThemeGtk::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style->setLineHeight(RenderStyle::initialLineHeight()); } -bool RenderThemeGtk::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintRenderObject(MOZ_GTK_BUTTON, o, i.context, rect, GTK_RELIEF_NORMAL); + if (info.context->paintingDisabled()) + return false; + + GtkWidget* widget = gtkButton(); + IntRect buttonRect(IntPoint(), rect.size()); + IntRect focusRect(buttonRect); + + GtkStateType state = getGtkStateType(object); + gtk_widget_set_state(widget, state); + gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction())); + + if (isFocused(object)) { + if (isEnabled(object)) { +#if !GTK_CHECK_VERSION(2, 22, 0) + GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS); +#endif + g_object_set(widget, "has-focus", TRUE, NULL); + } + + gboolean interiorFocus = 0, focusWidth = 0, focusPadding = 0; + gtk_widget_style_get(widget, + "interior-focus", &interiorFocus, + "focus-line-width", &focusWidth, + "focus-padding", &focusPadding, NULL); + // If we are using exterior focus, we shrink the button rect down before + // drawing. If we are using interior focus we shrink the focus rect. This + // approach originates from the Mozilla theme drawing code (gtk2drawing.c). + if (interiorFocus) { + GtkStyle* style = gtk_widget_get_style(widget); + focusRect.inflateX(-style->xthickness - focusPadding); + focusRect.inflateY(-style->ythickness - focusPadding); + } else { + buttonRect.inflateX(-focusWidth - focusPadding); + buttonRect.inflateY(-focusPadding - focusPadding); + } + } + + WidgetRenderingContext widgetContext(info.context, rect); + GtkShadowType shadowType = state == GTK_STATE_ACTIVE ? GTK_SHADOW_IN : GTK_SHADOW_OUT; + widgetContext.gtkPaintBox(buttonRect, widget, state, shadowType, "button"); + if (isFocused(object)) + widgetContext.gtkPaintFocus(focusRect, widget, state, "button"); + +#if !GTK_CHECK_VERSION(2, 22, 0) + GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS); +#endif + g_object_set(widget, "has-focus", FALSE, NULL); + return false; } static void getComboBoxPadding(RenderStyle* style, int& left, int& top, int& right, int& bottom) @@ -433,13 +465,27 @@ bool RenderThemeGtk::paintMenuListButton(RenderObject* object, const PaintInfo& return paintMenuList(object, info, rect); } +static void setTextInputBorders(RenderStyle* style) +{ + // If this control isn't drawn using the native theme, we don't touch the borders. + if (style->appearance() == NoControlPart) + return; + + // We cannot give a proper rendering when border radius is active, unfortunately. + style->resetBorderRadius(); + + int left = 0, top = 0, right = 0, bottom = 0; + moz_gtk_get_widget_border(MOZ_GTK_ENTRY, &left, &top, &right, &bottom, + gtkTextDirection(style->direction()), TRUE); + style->setBorderLeftWidth(left); + style->setBorderTopWidth(top); + style->setBorderRightWidth(right); + style->setBorderBottomWidth(bottom); +} + void RenderThemeGtk::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { - style->resetBorder(); - style->resetPadding(); - style->setHeight(Length(Auto)); - style->setWhiteSpace(PRE); - adjustMozillaStyle(this, style, MOZ_GTK_ENTRY); + setTextInputBorders(style); } bool RenderThemeGtk::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& rect) @@ -447,6 +493,11 @@ bool RenderThemeGtk::paintTextField(RenderObject* o, const PaintInfo& i, const I return paintRenderObject(MOZ_GTK_ENTRY, o, i.context, rect); } +void RenderThemeGtk::adjustTextAreaStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +{ + setTextInputBorders(style); +} + bool RenderThemeGtk::paintTextArea(RenderObject* o, const PaintInfo& i, const IntRect& r) { return paintTextField(o, i, r); @@ -467,32 +518,33 @@ void RenderThemeGtk::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* s style->resetBorder(); style->resetPadding(); - // FIXME: This should not be hard-coded. - IntSize size = IntSize(14, 14); - style->setWidth(Length(size.width(), Fixed)); - style->setHeight(Length(size.height(), Fixed)); + gint width = 0, height = 0; + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); + style->setWidth(Length(width, Fixed)); + style->setHeight(Length(height, Fixed)); } -static IntRect centerRectVerticallyInParentInputElement(RenderObject* object, const IntRect& rect) +static IntPoint centerRectVerticallyInParentInputElement(RenderObject* object, const IntRect& rect) { - IntRect centeredRect(rect); Node* input = object->node()->shadowAncestorNode(); // Get the renderer of <input> element. - if (!input->renderer()->isBox()) - return centeredRect; + if (!input->renderer()->isBox()) + return rect.topLeft(); // If possible center the y-coordinate of the rect vertically in the parent input element. // We also add one pixel here to ensure that the y coordinate is rounded up for box heights // that are even, which looks in relation to the box text. IntRect inputContentBox = toRenderBox(input->renderer())->absoluteContentBox(); - centeredRect.setY(inputContentBox.y() + (inputContentBox.height() - centeredRect.height() + 1) / 2); - return centeredRect; + + return IntPoint(rect.x(), inputContentBox.y() + (inputContentBox.height() - rect.height() + 1) / 2); } -bool RenderThemeGtk::paintSearchFieldResultsDecoration(RenderObject* object, const PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintSearchFieldResultsDecoration(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - static Image* searchImage = Image::loadPlatformThemeIcon(GTK_STOCK_FIND, rect.width()).releaseRef(); - IntRect centeredRect(centerRectVerticallyInParentInputElement(object, rect)); - i.context->drawImage(searchImage, ColorSpaceDeviceRGB, centeredRect); + GtkStyle* style = gtk_widget_get_style(GTK_WIDGET(gtkEntry())); + IntPoint iconPoint(centerRectVerticallyInParentInputElement(renderObject, rect)); + paintStockIcon(paintInfo.context, iconPoint, style, GTK_STOCK_FIND, + gtkTextDirection(renderObject->style()->direction()), + gtkIconState(renderObject), GTK_ICON_SIZE_MENU); return false; } @@ -501,24 +553,26 @@ void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* select style->resetBorder(); style->resetPadding(); - // FIXME: This should not be hard-coded. - IntSize size = IntSize(14, 14); - style->setWidth(Length(size.width(), Fixed)); - style->setHeight(Length(size.height(), Fixed)); + gint width = 0, height = 0; + gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); + style->setWidth(Length(width, Fixed)); + style->setHeight(Length(height, Fixed)); } -bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* object, const PaintInfo& i, const IntRect& rect) +bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - // TODO: Brightening up the image on hover is desirable here, I believe. - static Image* cancelImage = Image::loadPlatformThemeIcon(GTK_STOCK_CLEAR, rect.width()).releaseRef(); - IntRect centeredRect(centerRectVerticallyInParentInputElement(object, rect)); - i.context->drawImage(cancelImage, ColorSpaceDeviceRGB, centeredRect); + GtkStyle* style = gtk_widget_get_style(GTK_WIDGET(gtkEntry())); + IntPoint iconPoint(centerRectVerticallyInParentInputElement(renderObject, rect)); + paintStockIcon(paintInfo.context, iconPoint, style, GTK_STOCK_CLEAR, + gtkTextDirection(renderObject->style()->direction()), + gtkIconState(renderObject), GTK_ICON_SIZE_MENU); return false; } void RenderThemeGtk::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { - adjustTextFieldStyle(selector, style, e); + style->setLineHeight(RenderStyle::initialLineHeight()); + setTextInputBorders(style); } bool RenderThemeGtk::paintSearchField(RenderObject* o, const PaintInfo& i, const IntRect& rect) @@ -528,14 +582,30 @@ bool RenderThemeGtk::paintSearchField(RenderObject* o, const PaintInfo& i, const bool RenderThemeGtk::paintSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect) { + if (info.context->paintingDisabled()) + return false; + ControlPart part = object->style()->appearance(); ASSERT(part == SliderHorizontalPart || part == SliderVerticalPart); - GtkThemeWidgetType gtkPart = MOZ_GTK_SCALE_HORIZONTAL; - if (part == SliderVerticalPart) - gtkPart = MOZ_GTK_SCALE_VERTICAL; + // We shrink the trough rect slightly to make room for the focus indicator. + IntRect troughRect(IntPoint(), rect.size()); // This is relative to rect. + GtkWidget* widget = 0; + if (part == SliderVerticalPart) { + widget = gtkVScale(); + troughRect.inflateY(-gtk_widget_get_style(widget)->ythickness); + } else { + widget = gtkHScale(); + troughRect.inflateX(-gtk_widget_get_style(widget)->xthickness); + } + gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction())); + + WidgetRenderingContext widgetContext(info.context, rect); + widgetContext.gtkPaintBox(troughRect, widget, GTK_STATE_ACTIVE, GTK_SHADOW_OUT, "trough"); + if (isFocused(object)) + widgetContext.gtkPaintFocus(IntRect(IntPoint(), rect.size()), widget, getGtkStateType(object), "trough"); - return paintRenderObject(gtkPart, object, info.context, rect); + return false; } void RenderThemeGtk::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* style, Element*) const @@ -545,14 +615,34 @@ void RenderThemeGtk::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* styl bool RenderThemeGtk::paintSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect) { + if (info.context->paintingDisabled()) + return false; + ControlPart part = object->style()->appearance(); ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart); - GtkThemeWidgetType gtkPart = MOZ_GTK_SCALE_THUMB_HORIZONTAL; - if (part == SliderThumbVerticalPart) - gtkPart = MOZ_GTK_SCALE_THUMB_VERTICAL; - - return paintRenderObject(gtkPart, object, info.context, rect); + GtkWidget* widget = 0; + const char* detail = 0; + GtkOrientation orientation; + if (part == SliderThumbVerticalPart) { + widget = gtkVScale(); + detail = "vscale"; + orientation = GTK_ORIENTATION_VERTICAL; + } else { + widget = gtkHScale(); + detail = "hscale"; + orientation = GTK_ORIENTATION_HORIZONTAL; + } + gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction())); + + // Only some themes have slider thumbs respond to clicks and some don't. This information is + // gathered via the 'activate-slider' property, but it's deprecated in GTK+ 2.22 and removed in + // GTK+ 3.x. The drawback of not honoring it is that slider thumbs change color when you click + // on them. + IntRect thumbRect(IntPoint(), rect.size()); + WidgetRenderingContext widgetContext(info.context, rect); + widgetContext.gtkPaintSlider(thumbRect, widget, getGtkStateType(object), GTK_SHADOW_OUT, detail, orientation); + return false; } void RenderThemeGtk::adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle* style, Element*) const @@ -567,14 +657,27 @@ void RenderThemeGtk::adjustSliderThumbSize(RenderObject* o) const if (part == MediaSliderThumbPart) { o->style()->setWidth(Length(m_mediaSliderThumbWidth, Fixed)); o->style()->setHeight(Length(m_mediaSliderThumbHeight, Fixed)); - } else + return; + } + if (part == MediaVolumeSliderThumbPart) + return; #endif - if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) { - gint width, height; - moz_gtk_get_scalethumb_metrics(part == SliderThumbHorizontalPart ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, &width, &height); - o->style()->setWidth(Length(width, Fixed)); - o->style()->setHeight(Length(height, Fixed)); + + GtkWidget* widget = part == SliderThumbHorizontalPart ? gtkHScale() : gtkVScale(); + int length = 0, width = 0; + gtk_widget_style_get(widget, + "slider_length", &length, + "slider_width", &width, + NULL); + + if (part == SliderThumbHorizontalPart) { + o->style()->setWidth(Length(length, Fixed)); + o->style()->setHeight(Length(width, Fixed)); + return; } + ASSERT(part == SliderThumbVerticalPart); + o->style()->setWidth(Length(width, Fixed)); + o->style()->setHeight(Length(length, Fixed)); } Color RenderThemeGtk::platformActiveSelectionBackgroundColor() const @@ -700,17 +803,30 @@ static void gtkStyleSetCallback(GtkWidget* widget, GtkStyle* previous, RenderThe renderTheme->platformColorsDidChange(); } -GtkContainer* RenderThemeGtk::gtkContainer() const +void RenderThemeGtk::setupWidgetAndAddToContainer(GtkWidget* widget, GtkWidget* window) const +{ + gtk_container_add(GTK_CONTAINER(window), widget); + gtk_widget_realize(widget); + g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE)); + + // FIXME: Perhaps this should only be called for the containing window or parent container. + g_signal_connect(widget, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this)); +} + +GtkWidget* RenderThemeGtk::gtkContainer() const { if (m_gtkContainer) return m_gtkContainer; m_gtkWindow = gtk_window_new(GTK_WINDOW_POPUP); - m_gtkContainer = GTK_CONTAINER(gtk_fixed_new()); - g_signal_connect(m_gtkWindow, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this)); - gtk_container_add(GTK_CONTAINER(m_gtkWindow), GTK_WIDGET(m_gtkContainer)); +#ifdef GTK_API_VERSION_2 + gtk_widget_set_colormap(m_gtkWindow, m_themeParts.colormap); +#endif gtk_widget_realize(m_gtkWindow); + gtk_widget_set_name(m_gtkWindow, "MozillaGtkWidget"); + m_gtkContainer = gtk_fixed_new(); + setupWidgetAndAddToContainer(m_gtkContainer, m_gtkWindow); return m_gtkContainer; } @@ -718,12 +834,8 @@ GtkWidget* RenderThemeGtk::gtkButton() const { if (m_gtkButton) return m_gtkButton; - m_gtkButton = gtk_button_new(); - g_signal_connect(m_gtkButton, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this)); - gtk_container_add(gtkContainer(), m_gtkButton); - gtk_widget_realize(m_gtkButton); - + setupWidgetAndAddToContainer(m_gtkButton, gtkContainer()); return m_gtkButton; } @@ -731,12 +843,8 @@ GtkWidget* RenderThemeGtk::gtkEntry() const { if (m_gtkEntry) return m_gtkEntry; - m_gtkEntry = gtk_entry_new(); - g_signal_connect(m_gtkEntry, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this)); - gtk_container_add(gtkContainer(), m_gtkEntry); - gtk_widget_realize(m_gtkEntry); - + setupWidgetAndAddToContainer(m_gtkEntry, gtkContainer()); return m_gtkEntry; } @@ -744,15 +852,29 @@ GtkWidget* RenderThemeGtk::gtkTreeView() const { if (m_gtkTreeView) return m_gtkTreeView; - m_gtkTreeView = gtk_tree_view_new(); - g_signal_connect(m_gtkTreeView, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this)); - gtk_container_add(gtkContainer(), m_gtkTreeView); - gtk_widget_realize(m_gtkTreeView); - + setupWidgetAndAddToContainer(m_gtkTreeView, gtkContainer()); return m_gtkTreeView; } +GtkWidget* RenderThemeGtk::gtkVScale() const +{ + if (m_gtkVScale) + return m_gtkVScale; + m_gtkVScale = gtk_vscale_new(0); + setupWidgetAndAddToContainer(m_gtkVScale, gtkContainer()); + return m_gtkVScale; +} + +GtkWidget* RenderThemeGtk::gtkHScale() const +{ + if (m_gtkHScale) + return m_gtkHScale; + m_gtkHScale = gtk_hscale_new(0); + setupWidgetAndAddToContainer(m_gtkHScale, gtkContainer()); + return m_gtkHScale; +} + GtkWidget* RenderThemeGtk::gtkScrollbar() { return moz_gtk_get_scrollbar_widget(); @@ -761,7 +883,7 @@ GtkWidget* RenderThemeGtk::gtkScrollbar() void RenderThemeGtk::platformColorsDidChange() { #if ENABLE(VIDEO) - initMediaStyling(gtk_rc_get_style(GTK_WIDGET(gtkContainer())), true); + initMediaColors(); #endif RenderTheme::platformColorsDidChange(); } @@ -772,49 +894,50 @@ String RenderThemeGtk::extraMediaControlsStyleSheet() return String(mediaControlsGtkUserAgentStyleSheet, sizeof(mediaControlsGtkUserAgentStyleSheet)); } -static inline bool paintMediaButton(GraphicsContext* context, const IntRect& r, Image* image, Color panelColor, int mediaIconSize) +bool RenderThemeGtk::paintMediaButton(RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, const char* iconName) { - context->fillRect(FloatRect(r), panelColor, ColorSpaceDeviceRGB); - context->drawImage(image, ColorSpaceDeviceRGB, - IntRect(r.x() + (r.width() - mediaIconSize) / 2, - r.y() + (r.height() - mediaIconSize) / 2, - mediaIconSize, mediaIconSize)); + GtkStyle* style = gtk_widget_get_style(GTK_WIDGET(gtkContainer())); + IntPoint iconPoint(rect.x() + (rect.width() - m_mediaIconSize) / 2, + rect.y() + (rect.height() - m_mediaIconSize) / 2); + context->fillRect(FloatRect(rect), m_panelColor, ColorSpaceDeviceRGB); + paintStockIcon(context, iconPoint, style, iconName, gtkTextDirection(renderObject->style()->direction()), + gtkIconState(renderObject), getMediaButtonIconSize(m_mediaIconSize)); return false; } -bool RenderThemeGtk::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaFullscreenButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - return paintMediaButton(paintInfo.context, r, m_fullscreenButton.get(), m_panelColor, m_mediaIconSize); + return paintMediaButton(renderObject, paintInfo.context, rect, GTK_STOCK_FULLSCREEN); } -bool RenderThemeGtk::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaMuteButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(o); + HTMLMediaElement* mediaElement = getMediaElementFromRenderObject(renderObject); if (!mediaElement) return false; - return paintMediaButton(paintInfo.context, r, mediaElement->muted() ? m_unmuteButton.get() : m_muteButton.get(), m_panelColor, m_mediaIconSize); + return paintMediaButton(renderObject, paintInfo.context, rect, mediaElement->muted() ? "audio-volume-muted" : "audio-volume-high"); } -bool RenderThemeGtk::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaPlayButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - Node* node = o->node(); + Node* node = renderObject->node(); if (!node) return false; MediaControlPlayButtonElement* button = static_cast<MediaControlPlayButtonElement*>(node); - return paintMediaButton(paintInfo.context, r, button->displayType() == MediaPlayButton ? m_playButton.get() : m_pauseButton.get(), m_panelColor, m_mediaIconSize); + return paintMediaButton(renderObject, paintInfo.context, rect, button->displayType() == MediaPlayButton ? GTK_STOCK_MEDIA_PLAY : GTK_STOCK_MEDIA_PAUSE); } -bool RenderThemeGtk::paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaSeekBackButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - return paintMediaButton(paintInfo.context, r, m_seekBackButton.get(), m_panelColor, m_mediaIconSize); + return paintMediaButton(renderObject, paintInfo.context, rect, GTK_STOCK_MEDIA_REWIND); } -bool RenderThemeGtk::paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeGtk::paintMediaSeekForwardButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - return paintMediaButton(paintInfo.context, r, m_seekForwardButton.get(), m_panelColor, m_mediaIconSize); + return paintMediaButton(renderObject, paintInfo.context, rect, GTK_STOCK_MEDIA_FORWARD); } bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) @@ -852,7 +975,7 @@ bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const PaintInfo& pai rangeRect = trackRect; rangeRect.setWidth(width); } else { - rangeRect.setLocation(IntPoint((start * totalWidth) / mediaDuration, trackRect.y())); + rangeRect.setLocation(IntPoint(trackRect.x() + start / mediaDuration* totalWidth, trackRect.y())); rangeRect.setSize(IntSize(width, trackRect.height())); } diff --git a/WebCore/platform/gtk/RenderThemeGtk.h b/WebCore/platform/gtk/RenderThemeGtk.h index ac08cf1..d377c45 100644 --- a/WebCore/platform/gtk/RenderThemeGtk.h +++ b/WebCore/platform/gtk/RenderThemeGtk.h @@ -100,6 +100,7 @@ protected: virtual void adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const; virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&); + void adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const; virtual bool paintTextArea(RenderObject*, const PaintInfo&, const IntRect&); int popupInternalPaddingLeft(RenderStyle*) const; @@ -137,7 +138,8 @@ protected: virtual void adjustSliderThumbSize(RenderObject* object) const; #if ENABLE(VIDEO) - virtual void initMediaStyling(GtkStyle* style, bool force); + void initMediaColors(); + void initMediaButtons(); virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&); virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&); virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&); @@ -155,26 +157,28 @@ protected: #endif private: - /* - * hold the state - */ GtkWidget* gtkButton() const; GtkWidget* gtkEntry() const; GtkWidget* gtkTreeView() const; + GtkWidget* gtkVScale() const; + GtkWidget* gtkHScale() const; + GtkWidget* gtkContainer() const; - /* - * unmapped GdkWindow having a container. This is holding all - * our fake widgets - */ - GtkContainer* gtkContainer() const; - + void setupWidgetAndAddToContainer(GtkWidget*, GtkWidget*) const; + GtkStateType getGtkStateType(RenderObject* object); bool paintRenderObject(GtkThemeWidgetType, RenderObject*, GraphicsContext*, const IntRect& rect, int flags = 0); +#if ENABLE(VIDEO) + bool paintMediaButton(RenderObject*, GraphicsContext*, const IntRect&, const char* iconName); +#endif + GtkStateType gtkIconState(RenderObject*); mutable GtkWidget* m_gtkWindow; - mutable GtkContainer* m_gtkContainer; + mutable GtkWidget* m_gtkContainer; mutable GtkWidget* m_gtkButton; mutable GtkWidget* m_gtkEntry; mutable GtkWidget* m_gtkTreeView; + mutable GtkWidget* m_gtkVScale; + mutable GtkWidget* m_gtkHScale; mutable Color m_panelColor; mutable Color m_sliderColor; @@ -185,13 +189,6 @@ private: const int m_mediaSliderThumbWidth; const int m_mediaSliderThumbHeight; - RefPtr<Image> m_fullscreenButton; - RefPtr<Image> m_muteButton; - RefPtr<Image> m_unmuteButton; - RefPtr<Image> m_playButton; - RefPtr<Image> m_pauseButton; - RefPtr<Image> m_seekBackButton; - RefPtr<Image> m_seekForwardButton; GtkThemeParts m_themeParts; #ifdef GTK_API_VERSION_2 bool m_themePartsHaveRGBAColormap; diff --git a/WebCore/platform/gtk/WidgetGtk.cpp b/WebCore/platform/gtk/WidgetGtk.cpp index db316d5..ee1005c 100644 --- a/WebCore/platform/gtk/WidgetGtk.cpp +++ b/WebCore/platform/gtk/WidgetGtk.cpp @@ -60,7 +60,7 @@ void Widget::setFocus(bool focused) gtk_widget_grab_focus(platformWidget() ? platformWidget() : GTK_WIDGET(root()->hostWindow()->platformPageClient())); } -static GdkDrawable* gdkDrawable(PlatformWidget widget) +static GdkWindow* gdkWindow(PlatformWidget widget) { return widget ? gtk_widget_get_window(widget) : 0; } @@ -78,7 +78,7 @@ void Widget::setCursor(const Cursor& cursor) if (platformCursor == lastSetCursor) return; - gdk_window_set_cursor(gdkDrawable(platformWidget()) ? GDK_WINDOW(gdkDrawable(platformWidget())) : gtk_widget_get_window(GTK_WIDGET(root()->hostWindow()->platformPageClient())), platformCursor); + gdk_window_set_cursor(gdkWindow(platformWidget()) ? gdkWindow(platformWidget()) : gtk_widget_get_window(GTK_WIDGET(root()->hostWindow()->platformPageClient())), platformCursor); lastSetCursor = platformCursor; } diff --git a/WebCore/platform/gtk/WidgetRenderingContext.h b/WebCore/platform/gtk/WidgetRenderingContext.h index 3bb8065..7334656 100644 --- a/WebCore/platform/gtk/WidgetRenderingContext.h +++ b/WebCore/platform/gtk/WidgetRenderingContext.h @@ -34,7 +34,11 @@ class WidgetRenderingContext { public: WidgetRenderingContext(GraphicsContext*, const IntRect&); ~WidgetRenderingContext(); + bool paintMozillaWidget(GtkThemeWidgetType, GtkWidgetState*, int flags, GtkTextDirection = GTK_TEXT_DIR_NONE); + void gtkPaintBox(const IntRect&, GtkWidget*, GtkStateType, GtkShadowType, const gchar*); + void gtkPaintFocus(const IntRect&, GtkWidget*, GtkStateType, const gchar*); + void gtkPaintSlider(const IntRect&, GtkWidget*, GtkStateType, GtkShadowType, const gchar*, GtkOrientation); private: GraphicsContext* m_graphicsContext; diff --git a/WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp b/WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp index b8712d2..e85c570 100644 --- a/WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp +++ b/WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp @@ -89,9 +89,9 @@ WidgetRenderingContext::WidgetRenderingContext(GraphicsContext* graphicsContext, // Fallback: We failed to create an RGBA colormap earlier, so we cannot properly paint // to a temporary surface and preserve transparency. To ensure decent widget rendering, just // paint directly to the target drawable. This will not render CSS rotational transforms properly. - if (!theme->m_themePartsHaveRGBAColormap && graphicsContext->gdkDrawable()) { + if (!theme->m_themePartsHaveRGBAColormap && graphicsContext->gdkWindow()) { m_paintRect = graphicsContext->getCTM().mapRect(targetRect); - m_target = graphicsContext->gdkDrawable(); + m_target = graphicsContext->gdkWindow(); return; } @@ -131,7 +131,7 @@ WidgetRenderingContext::~WidgetRenderingContext() { // We do not need to blit back to the target in the fallback case. See above. RenderThemeGtk* theme = static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get()); - if (!theme->m_themePartsHaveRGBAColormap && m_graphicsContext->gdkDrawable()) + if (!theme->m_themePartsHaveRGBAColormap && m_graphicsContext->gdkWindow()) return; // Don't paint the results back if there was an error. @@ -165,6 +165,27 @@ bool WidgetRenderingContext::paintMozillaWidget(GtkThemeWidgetType type, GtkWidg return !m_hadError; } +void WidgetRenderingContext::gtkPaintBox(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, GtkShadowType shadowType, const gchar* detail) +{ + GdkRectangle paintRect = { m_paintRect.x + rect.x(), m_paintRect.y + rect.y(), rect.width(), rect.height() }; + gtk_paint_box(gtk_widget_get_style(widget), m_target, stateType, shadowType, &m_paintRect, + widget, detail, paintRect.x, paintRect.y, paintRect.width, paintRect.height); +} + +void WidgetRenderingContext::gtkPaintFocus(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, const gchar* detail) +{ + GdkRectangle paintRect = { m_paintRect.x + rect.x(), m_paintRect.y + rect.y(), rect.width(), rect.height() }; + gtk_paint_focus(gtk_widget_get_style(widget), m_target, stateType, &m_paintRect, widget, + detail, paintRect.x, paintRect.y, paintRect.width, paintRect.height); +} + +void WidgetRenderingContext::gtkPaintSlider(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, GtkShadowType shadowType, const gchar* detail, GtkOrientation orientation) +{ + GdkRectangle paintRect = { m_paintRect.x + rect.x(), m_paintRect.y + rect.y(), rect.width(), rect.height() }; + gtk_paint_slider(gtk_widget_get_style(widget), m_target, stateType, shadowType, &m_paintRect, widget, + detail, paintRect.x, paintRect.y, paintRect.width, paintRect.height, orientation); +} + } #endif // GTK_API_VERSION_2 diff --git a/WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp b/WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp index e5f1823..69c4af5 100644 --- a/WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp +++ b/WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp @@ -47,6 +47,27 @@ bool WidgetRenderingContext::paintMozillaWidget(GtkThemeWidgetType type, GtkWidg return !m_hadError; } +void WidgetRenderingContext::gtkPaintBox(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, GtkShadowType shadowType, const gchar* detail) +{ + GdkRectangle paintRect = { m_paintRect.x + rect.x(), m_paintRect.y + rect.y(), rect.width(), rect.height() }; + gtk_paint_box(gtk_widget_get_style(widget), m_target, stateType, shadowType, widget, + detail, paintRect.x, paintRect.y, paintRect.width, paintRect.height); +} + +void WidgetRenderingContext::gtkPaintFocus(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, const gchar* detail) +{ + GdkRectangle paintRect = { m_paintRect.x + rect.x(), m_paintRect.y + rect.y(), rect.width(), rect.height() }; + gtk_paint_focus(gtk_widget_get_style(widget), m_target, stateType, widget, + detail, paintRect.x, paintRect.y, paintRect.width, paintRect.height); +} + +void WidgetRenderingContext::gtkPaintSlider(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, GtkShadowType shadowType, const gchar* detail, GtkOrientation orientation) +{ + GdkRectangle paintRect = { m_paintRect.x + rect.x(), m_paintRect.y + rect.y(), rect.width(), rect.height() }; + gtk_paint_slider(gtk_widget_get_style(widget), m_target, stateType, shadowType, widget, + detail, paintRect.x, paintRect.y, paintRect.width, paintRect.height, orientation); +} + } #endif // !GTK_API_VERSION_2 diff --git a/WebCore/platform/gtk/gtk2drawing.c b/WebCore/platform/gtk/gtk2drawing.c index 2f2edb6..3ebd332 100644 --- a/WebCore/platform/gtk/gtk2drawing.c +++ b/WebCore/platform/gtk/gtk2drawing.c @@ -185,20 +185,6 @@ ensure_scrollbar_widget() } static gint -ensure_scale_widget() -{ - if (!gParts->hScaleWidget) { - gParts->hScaleWidget = gtk_hscale_new(NULL); - setup_widget_prototype(gParts->hScaleWidget); - } - if (!gParts->vScaleWidget) { - gParts->vScaleWidget = gtk_vscale_new(NULL); - setup_widget_prototype(gParts->vScaleWidget); - } - return MOZ_GTK_SUCCESS; -} - -static gint ensure_entry_widget() { if (!gParts->entryWidget) { @@ -921,83 +907,6 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWidgetType widget, } static gint -moz_gtk_scale_paint(GdkDrawable* drawable, GdkRectangle* rect, - GdkRectangle* cliprect, GtkWidgetState* state, - GtkOrientation flags, GtkTextDirection direction) -{ - gint x = 0, y = 0; - GtkStateType state_type = ConvertGtkState(state); - GtkStyle* style; - GtkWidget* widget; - - ensure_scale_widget(); - widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gParts->hScaleWidget : gParts->vScaleWidget); - gtk_widget_set_direction(widget, direction); - - style = gtk_widget_get_style(widget); - - if (flags == GTK_ORIENTATION_HORIZONTAL) { - x = XTHICKNESS(style); - y++; - } - else { - x++; - y = YTHICKNESS(style); - } - - TSOffsetStyleGCs(style, rect->x, rect->y); - gtk_style_apply_default_background(style, drawable, TRUE, GTK_STATE_NORMAL, - cliprect, rect->x, rect->y, - rect->width, rect->height); - - gtk_paint_box(style, drawable, GTK_STATE_ACTIVE, GTK_SHADOW_IN, cliprect, - widget, "trough", rect->x + x, rect->y + y, - rect->width - 2*x, rect->height - 2*y); - - if (state->focused) - gtk_paint_focus(style, drawable, state_type, cliprect, widget, "trough", - rect->x, rect->y, rect->width, rect->height); - - return MOZ_GTK_SUCCESS; -} - -static gint -moz_gtk_scale_thumb_paint(GdkDrawable* drawable, GdkRectangle* rect, - GdkRectangle* cliprect, GtkWidgetState* state, - GtkOrientation flags, GtkTextDirection direction) -{ - GtkStateType state_type = ConvertGtkState(state); - GtkStyle* style; - GtkWidget* widget; - gint thumb_width, thumb_height, x, y; - - ensure_scale_widget(); - widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gParts->hScaleWidget : gParts->vScaleWidget); - gtk_widget_set_direction(widget, direction); - - style = gtk_widget_get_style(widget); - - /* determine the thumb size, and position the thumb in the center in the opposite axis */ - if (flags == GTK_ORIENTATION_HORIZONTAL) { - moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_HORIZONTAL, &thumb_width, &thumb_height); - x = rect->x; - y = rect->y + (rect->height - thumb_height) / 2; - } - else { - moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_VERTICAL, &thumb_height, &thumb_width); - x = rect->x + (rect->width - thumb_width) / 2; - y = rect->y; - } - - TSOffsetStyleGCs(style, rect->x, rect->y); - gtk_paint_slider(style, drawable, state_type, GTK_SHADOW_OUT, cliprect, - widget, (flags == GTK_ORIENTATION_HORIZONTAL) ? "hscale" : "vscale", - x, y, thumb_width, thumb_height, flags); - - return MOZ_GTK_SUCCESS; -} - -static gint moz_gtk_entry_paint(GdkDrawable* drawable, GdkRectangle* rect, GdkRectangle* cliprect, GtkWidgetState* state, GtkWidget* widget, GtkTextDirection direction) @@ -1310,14 +1219,6 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, ensure_progress_widget(); w = gParts->progresWidget; break; - case MOZ_GTK_SCALE_HORIZONTAL: - ensure_scale_widget(); - w = gParts->hScaleWidget; - break; - case MOZ_GTK_SCALE_VERTICAL: - ensure_scale_widget(); - w = gParts->vScaleWidget; - break; /* These widgets have no borders, since they are not containers. */ case MOZ_GTK_CHECKBUTTON: case MOZ_GTK_RADIOBUTTON: @@ -1326,8 +1227,6 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, case MOZ_GTK_SCROLLBAR_TRACK_VERTICAL: 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_PROGRESS_CHUNK: *left = *top = *right = *bottom = 0; return MOZ_GTK_SUCCESS; @@ -1344,22 +1243,6 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, } gint -moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length, gint* thumb_height) -{ - GtkWidget* widget; - - ensure_scale_widget(); - widget = ((orient == GTK_ORIENTATION_HORIZONTAL) ? gParts->hScaleWidget : gParts->vScaleWidget); - - gtk_widget_style_get (widget, - "slider_length", thumb_length, - "slider_width", thumb_height, - NULL); - - return MOZ_GTK_SUCCESS; -} - -gint moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics) { ensure_scrollbar_widget(); @@ -1424,16 +1307,6 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable, case MOZ_GTK_SCROLLED_WINDOW: return moz_gtk_scrolled_window_paint(drawable, rect, cliprect, state); break; - case MOZ_GTK_SCALE_HORIZONTAL: - case MOZ_GTK_SCALE_VERTICAL: - return moz_gtk_scale_paint(drawable, rect, cliprect, state, - (GtkOrientation) flags, direction); - break; - case MOZ_GTK_SCALE_THUMB_HORIZONTAL: - case MOZ_GTK_SCALE_THUMB_VERTICAL: - return moz_gtk_scale_thumb_paint(drawable, rect, cliprect, state, - (GtkOrientation) flags, direction); - break; case MOZ_GTK_ENTRY: ensure_entry_widget(); return moz_gtk_entry_paint(drawable, rect, cliprect, state, diff --git a/WebCore/platform/gtk/gtk3drawing.c b/WebCore/platform/gtk/gtk3drawing.c index 880eb6d..d3bdd56 100644 --- a/WebCore/platform/gtk/gtk3drawing.c +++ b/WebCore/platform/gtk/gtk3drawing.c @@ -178,20 +178,6 @@ ensure_scrollbar_widget() } static gint -ensure_scale_widget() -{ - if (!gParts->hScaleWidget) { - gParts->hScaleWidget = gtk_hscale_new(NULL); - setup_widget_prototype(gParts->hScaleWidget); - } - if (!gParts->vScaleWidget) { - gParts->vScaleWidget = gtk_vscale_new(NULL); - setup_widget_prototype(gParts->vScaleWidget); - } - return MOZ_GTK_SUCCESS; -} - -static gint ensure_entry_widget() { if (!gParts->entryWidget) { @@ -848,82 +834,6 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWidgetType widget, } static gint -moz_gtk_scale_paint(cairo_t* cr, GdkRectangle* rect, - GtkWidgetState* state, GtkOrientation flags, - GtkTextDirection direction) -{ - gint x = 0, y = 0; - GtkStateType state_type = ConvertGtkState(state); - GtkStyle* style; - GtkWidget* widget; - - ensure_scale_widget(); - widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gParts->hScaleWidget : gParts->vScaleWidget); - gtk_widget_set_direction(widget, direction); - - style = gtk_widget_get_style(widget); - - if (flags == GTK_ORIENTATION_HORIZONTAL) { - x = XTHICKNESS(style); - y++; - } - else { - x++; - y = YTHICKNESS(style); - } - - gtk_style_apply_default_background(style, cr, gtk_widget_get_window (widget), - GTK_STATE_NORMAL, - rect->x, rect->y, - rect->width, rect->height); - - gtk_paint_box(style, cr, GTK_STATE_ACTIVE, GTK_SHADOW_IN, - widget, "trough", rect->x + x, rect->y + y, - rect->width - 2*x, rect->height - 2*y); - - if (state->focused) - gtk_paint_focus(style, cr, state_type, widget, "trough", - rect->x, rect->y, rect->width, rect->height); - - return MOZ_GTK_SUCCESS; -} - -static gint -moz_gtk_scale_thumb_paint(cairo_t* cr, GdkRectangle* rect, - GtkWidgetState* state, GtkOrientation flags, - GtkTextDirection direction) -{ - GtkStateType state_type = ConvertGtkState(state); - GtkStyle* style; - GtkWidget* widget; - gint thumb_width, thumb_height, x, y; - - ensure_scale_widget(); - widget = ((flags == GTK_ORIENTATION_HORIZONTAL) ? gParts->hScaleWidget : gParts->vScaleWidget); - gtk_widget_set_direction(widget, direction); - - style = gtk_widget_get_style(widget); - - /* determine the thumb size, and position the thumb in the center in the opposite axis */ - if (flags == GTK_ORIENTATION_HORIZONTAL) { - moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_HORIZONTAL, &thumb_width, &thumb_height); - x = rect->x; - y = rect->y + (rect->height - thumb_height) / 2; - } - else { - moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_VERTICAL, &thumb_height, &thumb_width); - x = rect->x + (rect->width - thumb_width) / 2; - y = rect->y; - } - - gtk_paint_slider(style, cr, state_type, GTK_SHADOW_OUT, - widget, (flags == GTK_ORIENTATION_HORIZONTAL) ? "hscale" : "vscale", - x, y, thumb_width, thumb_height, flags); - - return MOZ_GTK_SUCCESS; -} - -static gint moz_gtk_entry_paint(cairo_t* cr, GdkRectangle* rect, GtkWidgetState* state, GtkWidget* widget, GtkTextDirection direction) @@ -1227,14 +1137,6 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, ensure_progress_widget(); w = gParts->progresWidget; break; - case MOZ_GTK_SCALE_HORIZONTAL: - ensure_scale_widget(); - w = gParts->hScaleWidget; - break; - case MOZ_GTK_SCALE_VERTICAL: - ensure_scale_widget(); - w = gParts->vScaleWidget; - break; /* These widgets have no borders, since they are not containers. */ case MOZ_GTK_CHECKBUTTON: case MOZ_GTK_RADIOBUTTON: @@ -1243,8 +1145,6 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, case MOZ_GTK_SCROLLBAR_TRACK_VERTICAL: 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_PROGRESS_CHUNK: *left = *top = *right = *bottom = 0; return MOZ_GTK_SUCCESS; @@ -1261,22 +1161,6 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, } gint -moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length, gint* thumb_height) -{ - GtkWidget* widget; - - ensure_scale_widget(); - widget = ((orient == GTK_ORIENTATION_HORIZONTAL) ? gParts->hScaleWidget : gParts->vScaleWidget); - - gtk_widget_style_get (widget, - "slider_length", thumb_length, - "slider_width", thumb_height, - NULL); - - return MOZ_GTK_SUCCESS; -} - -gint moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics) { ensure_scrollbar_widget(); @@ -1340,16 +1224,6 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, cairo_t* cr, case MOZ_GTK_SCROLLED_WINDOW: return moz_gtk_scrolled_window_paint(cr, rect, state); break; - case MOZ_GTK_SCALE_HORIZONTAL: - case MOZ_GTK_SCALE_VERTICAL: - return moz_gtk_scale_paint(cr, rect, state, - (GtkOrientation) flags, direction); - break; - case MOZ_GTK_SCALE_THUMB_HORIZONTAL: - case MOZ_GTK_SCALE_THUMB_VERTICAL: - return moz_gtk_scale_thumb_paint(cr, rect, state, - (GtkOrientation) flags, direction); - break; case MOZ_GTK_ENTRY: ensure_entry_widget(); return moz_gtk_entry_paint(cr, rect, state, diff --git a/WebCore/platform/gtk/gtkdrawing.h b/WebCore/platform/gtk/gtkdrawing.h index a981543..9d13a07 100644 --- a/WebCore/platform/gtk/gtkdrawing.h +++ b/WebCore/platform/gtk/gtkdrawing.h @@ -93,8 +93,6 @@ typedef struct _GtkThemeParts { GtkWidget* radiobuttonWidget; GtkWidget* horizScrollbarWidget; GtkWidget* vertScrollbarWidget; - GtkWidget* hScaleWidget; - GtkWidget* vScaleWidget; GtkWidget* entryWidget; GtkWidget* comboBoxWidget; GtkWidget* comboBoxButtonWidget; @@ -147,12 +145,6 @@ typedef enum { MOZ_GTK_SCROLLBAR_THUMB_VERTICAL, /* Paints the background of a scrolled window */ MOZ_GTK_SCROLLED_WINDOW, - /* Paints a GtkScale. */ - MOZ_GTK_SCALE_HORIZONTAL, - MOZ_GTK_SCALE_VERTICAL, - /* Paints a GtkScale thumb. */ - MOZ_GTK_SCALE_THUMB_HORIZONTAL, - MOZ_GTK_SCALE_THUMB_VERTICAL, MOZ_GTK_ENTRY, /* Paints a GtkOptionMenu. */ MOZ_GTK_DROPDOWN, @@ -277,17 +269,6 @@ moz_gtk_widget_get_focus(GtkWidget* widget, gboolean* interior_focus, gint* focus_width, gint* focus_pad); /** - * Get the desired size of a GtkScale thumb - * orient: [IN] the scale orientation - * thumb_length: [OUT] the length of the thumb - * thumb_height: [OUT] the height of the thumb - * - * returns: MOZ_GTK_SUCCESS if there was no error, an error code otherwise - */ -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 * |