diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-01 01:51:46 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-01 01:51:46 +0000 |
commit | 10882030ebab866d6ecb495480b371fbc0536ab7 (patch) | |
tree | 03c7f47bd93557f420680953e8ee98d32ea6b75e /chrome | |
parent | 46ad7357844bdc3ed4a7fd40d73ad37b56d8c07d (diff) | |
download | chromium_src-10882030ebab866d6ecb495480b371fbc0536ab7.zip chromium_src-10882030ebab866d6ecb495480b371fbc0536ab7.tar.gz chromium_src-10882030ebab866d6ecb495480b371fbc0536ab7.tar.bz2 |
retry r2226, with a fix for a case where we could double free.
Review URL: http://codereview.chromium.org/160495
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22241 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/gtk/bookmark_bubble_gtk.cc | 10 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_bubble_gtk.h | 3 | ||||
-rw-r--r-- | chrome/browser/gtk/download_shelf_gtk.cc | 2 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_chrome_link_button.cc | 105 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_chrome_link_button.h | 9 | ||||
-rw-r--r-- | chrome/browser/gtk/infobar_gtk.cc | 2 |
6 files changed, 102 insertions, 29 deletions
diff --git a/chrome/browser/gtk/bookmark_bubble_gtk.cc b/chrome/browser/gtk/bookmark_bubble_gtk.cc index 67c9dc6..8e93d77 100644 --- a/chrome/browser/gtk/bookmark_bubble_gtk.cc +++ b/chrome/browser/gtk/bookmark_bubble_gtk.cc @@ -118,6 +118,10 @@ void BookmarkBubbleGtk::Observe(NotificationType type, const NotificationDetails& details) { DCHECK(type == NotificationType::BROWSER_THEME_CHANGED); + gtk_chrome_link_button_set_use_gtk_theme( + GTK_CHROME_LINK_BUTTON(remove_button_), + theme_provider_->UseGtkTheme()); + if (theme_provider_->UseGtkTheme()) { for (std::vector<GtkWidget*>::iterator it = labels_.begin(); it != labels_.end(); ++it) { @@ -152,7 +156,7 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel, newly_bookmarked_ ? IDS_BOOMARK_BUBBLE_PAGE_BOOKMARKED : IDS_BOOMARK_BUBBLE_PAGE_BOOKMARK).c_str()); labels_.push_back(label); - GtkWidget* remove_button = gtk_chrome_link_button_new( + remove_button_ = gtk_chrome_link_button_new( l10n_util::GetStringUTF8(IDS_BOOMARK_BUBBLE_REMOVE_BOOKMARK).c_str()); GtkWidget* edit_button = gtk_button_new_with_label( l10n_util::GetStringUTF8(IDS_BOOMARK_BUBBLE_OPTIONS).c_str()); @@ -169,7 +173,7 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel, gtk_misc_set_alignment(GTK_MISC(label), 0, 1); gtk_box_pack_start(GTK_BOX(top), label, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(top), remove_button, + gtk_box_pack_start(GTK_BOX(top), remove_button_, FALSE, FALSE, 0); // TODO(deanm): We should show the bookmark bar folder along with the top @@ -226,7 +230,7 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel, G_CALLBACK(&HandleEditButtonThunk), this); g_signal_connect(close_button, "clicked", G_CALLBACK(&HandleCloseButtonThunk), this); - g_signal_connect(remove_button, "clicked", + g_signal_connect(remove_button_, "clicked", G_CALLBACK(&HandleRemoveButtonThunk), this); registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, diff --git a/chrome/browser/gtk/bookmark_bubble_gtk.h b/chrome/browser/gtk/bookmark_bubble_gtk.h index 3b86a6b..a549f18 100644 --- a/chrome/browser/gtk/bookmark_bubble_gtk.h +++ b/chrome/browser/gtk/bookmark_bubble_gtk.h @@ -126,6 +126,9 @@ class BookmarkBubbleGtk : public InfoBubbleGtkDelegate, // when the widget is destroyed (when the InfoBubble is destroyed). GtkWidget* content_; + // The button that removes the bookmark. + GtkWidget* remove_button_; + // The various labels in the interface. We keep track of them for theme // changes. std::vector<GtkWidget*> labels_; diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc index 8d83f84..4606577 100644 --- a/chrome/browser/gtk/download_shelf_gtk.cc +++ b/chrome/browser/gtk/download_shelf_gtk.cc @@ -97,6 +97,8 @@ DownloadShelfGtk::DownloadShelfGtk(Browser* browser, GtkWidget* parent) std::string link_text = l10n_util::GetStringUTF8(IDS_SHOW_ALL_DOWNLOADS); GtkWidget* link_button = gtk_chrome_link_button_new(link_text.c_str()); + gtk_chrome_link_button_set_use_gtk_theme( + GTK_CHROME_LINK_BUTTON(link_button), FALSE); g_signal_connect(link_button, "clicked", G_CALLBACK(OnButtonClick), this); // Until we switch to vector graphics, force the font size. diff --git a/chrome/browser/gtk/gtk_chrome_link_button.cc b/chrome/browser/gtk/gtk_chrome_link_button.cc index bb35010..735dec6 100644 --- a/chrome/browser/gtk/gtk_chrome_link_button.cc +++ b/chrome/browser/gtk/gtk_chrome_link_button.cc @@ -37,16 +37,71 @@ void SetLinkButtonStyle() { G_BEGIN_DECLS G_DEFINE_TYPE(GtkChromeLinkButton, gtk_chrome_link_button, GTK_TYPE_BUTTON) +// Should be called after we are realized so that the "link-color" property +// can be read. +static void gtk_chrome_link_button_set_text(GtkChromeLinkButton* button) { + // We only set the markup once. + if (button->blue_markup) + return; + + gchar* text = button->text; + gboolean uses_markup = button->uses_markup; + + if (!uses_markup) { + button->blue_markup = g_markup_printf_escaped(kLinkMarkup, "blue", text); + button->red_markup = g_markup_printf_escaped(kLinkMarkup, "red", text); + } else { + button->blue_markup = static_cast<gchar*>( + g_malloc(strlen(kLinkMarkup) + strlen("blue") + strlen(text) + 1)); + sprintf(button->blue_markup, kLinkMarkup, "blue", text); + + button->red_markup = static_cast<gchar*>( + g_malloc(strlen(kLinkMarkup) + strlen("red") + strlen(text) + 1)); + sprintf(button->red_markup, kLinkMarkup, "red", text); + } + + // Get the current GTK theme's link button text color. + GdkColor* native_color = NULL; + gtk_widget_style_get(GTK_WIDGET(button), "link-color", &native_color, NULL); + + if (native_color) { + gchar color_spec[9]; + sprintf(color_spec, "#%02X%02X%02X", native_color->red / 257, + native_color->green / 257, native_color->blue / 257); + gdk_color_free(native_color); + + if (!uses_markup) { + button->native_markup = g_markup_printf_escaped(kLinkMarkup, + color_spec, text); + } else { + button->native_markup = static_cast<gchar*>( + g_malloc(strlen(kLinkMarkup) + strlen(color_spec) + strlen(text) + + 1)); + sprintf(button->native_markup, kLinkMarkup, color_spec, text); + } + } else { + // If the theme doesn't have a link color, just use blue. This matches the + // default for GtkLinkButton. + button->native_markup = button->blue_markup; + } + + gtk_label_set_markup(GTK_LABEL(button->label), + button->using_native_theme ? button->native_markup : button->blue_markup); +} + static gboolean gtk_chrome_link_button_expose(GtkWidget* widget, GdkEventExpose* event) { GtkChromeLinkButton* button = GTK_CHROME_LINK_BUTTON(widget); GtkWidget* label = button->label; + gtk_chrome_link_button_set_text(button); + if (GTK_WIDGET_STATE(widget) == GTK_STATE_ACTIVE && button->is_blue) { gtk_label_set_markup(GTK_LABEL(label), button->red_markup); button->is_blue = FALSE; } else if (GTK_WIDGET_STATE(widget) != GTK_STATE_ACTIVE && !button->is_blue) { - gtk_label_set_markup(GTK_LABEL(label), button->blue_markup); + gtk_label_set_markup(GTK_LABEL(label), + button->using_native_theme ? button->native_markup : button->blue_markup); button->is_blue = TRUE; } @@ -114,6 +169,9 @@ static void gtk_chrome_link_button_leave(GtkButton* button) { static void gtk_chrome_link_button_destroy(GtkObject* object) { GtkChromeLinkButton* button = GTK_CHROME_LINK_BUTTON(object); + if (button->native_markup && (button->native_markup != button->blue_markup)) + g_free(button->native_markup); + button->native_markup = NULL; if (button->blue_markup) { g_free(button->blue_markup); button->blue_markup = NULL; @@ -126,9 +184,13 @@ static void gtk_chrome_link_button_destroy(GtkObject* object) { gdk_cursor_unref(button->hand_cursor); button->hand_cursor = NULL; } + free(button->click_button_event); button->click_button_event = NULL; + free(button->text); + button->text = NULL; + GTK_OBJECT_CLASS(gtk_chrome_link_button_parent_class)->destroy(object); } @@ -158,49 +220,40 @@ static void gtk_chrome_link_button_init(GtkChromeLinkButton* button) { button->blue_markup = NULL; button->red_markup = NULL; button->is_blue = TRUE; + button->native_markup = NULL; + button->using_native_theme = TRUE; button->hand_cursor = gdk_cursor_new(GDK_HAND2); button->click_button_event = NULL; + button->text = NULL; gtk_container_add(GTK_CONTAINER(button), button->label); gtk_widget_set_name(GTK_WIDGET(button), "chrome-link-button"); gtk_widget_set_app_paintable(GTK_WIDGET(button), TRUE); } -static void gtk_chrome_link_button_set_text(GtkChromeLinkButton* button, - const char* text, - bool contains_markup) { - // We should have only been called once or we'd leak the markups. - DCHECK(!button->blue_markup && !button->red_markup); - - if (!contains_markup) { - button->blue_markup = g_markup_printf_escaped(kLinkMarkup, "blue", text); - button->red_markup = g_markup_printf_escaped(kLinkMarkup, "red", text); - } else { - button->blue_markup = static_cast<gchar*>( - g_malloc(strlen(kLinkMarkup) + strlen("blue") + strlen(text) + 1)); - sprintf(button->blue_markup, kLinkMarkup, "blue", text); - - button->red_markup = static_cast<gchar*>( - g_malloc(strlen(kLinkMarkup) + strlen("red") + strlen(text) + 1)); - sprintf(button->red_markup, kLinkMarkup, "red", text); - } - - gtk_label_set_markup(GTK_LABEL(button->label), button->blue_markup); - button->is_blue = TRUE; -} - GtkWidget* gtk_chrome_link_button_new(const char* text) { GtkWidget* lb = GTK_WIDGET(g_object_new(GTK_TYPE_CHROME_LINK_BUTTON, NULL)); - gtk_chrome_link_button_set_text(GTK_CHROME_LINK_BUTTON(lb), text, false); + GTK_CHROME_LINK_BUTTON(lb)->text = strdup(text); + GTK_CHROME_LINK_BUTTON(lb)->uses_markup = FALSE; return lb; } GtkWidget* gtk_chrome_link_button_new_with_markup(const char* markup) { GtkWidget* lb = GTK_WIDGET(g_object_new(GTK_TYPE_CHROME_LINK_BUTTON, NULL)); - gtk_chrome_link_button_set_text(GTK_CHROME_LINK_BUTTON(lb), markup, true); + GTK_CHROME_LINK_BUTTON(lb)->text = strdup(markup); + GTK_CHROME_LINK_BUTTON(lb)->uses_markup = TRUE; return lb; } +void gtk_chrome_link_button_set_use_gtk_theme(GtkChromeLinkButton* button, + gboolean use_gtk) { + if (use_gtk != button->using_native_theme) { + button->using_native_theme = use_gtk; + if (GTK_WIDGET_VISIBLE(button)) + gtk_widget_queue_draw(GTK_WIDGET(button)); + } +} + const GdkEventButton* gtk_chrome_link_button_get_event_for_click( GtkChromeLinkButton* button) { return button->click_button_event; diff --git a/chrome/browser/gtk/gtk_chrome_link_button.h b/chrome/browser/gtk/gtk_chrome_link_button.h index cac77e0..e8cf891 100644 --- a/chrome/browser/gtk/gtk_chrome_link_button.h +++ b/chrome/browser/gtk/gtk_chrome_link_button.h @@ -40,8 +40,12 @@ struct _GtkChromeLinkButton { gchar* blue_markup; gchar* red_markup; gboolean is_blue; + gchar* native_markup; + gboolean using_native_theme; GdkCursor* hand_cursor; GdkEventButton* click_button_event; + gchar* text; + gboolean uses_markup; }; struct _GtkChromeLinkButtonClass { @@ -54,6 +58,11 @@ GtkWidget* gtk_chrome_link_button_new(const char* text); // As above, but don't escape markup in the text. GtkWidget* gtk_chrome_link_button_new_with_markup(const char* markup); +// Set whether the link button draws natively (using "link-color"). The default +// is TRUE. +void gtk_chrome_link_button_set_use_gtk_theme(GtkChromeLinkButton* button, + gboolean use_gtk); + // Call this from within a "clicked" handler to get the release event that // triggered the click. It will return NULL if the click was triggered by a // keyboard event. diff --git a/chrome/browser/gtk/infobar_gtk.cc b/chrome/browser/gtk/infobar_gtk.cc index 4acc96f..47aa247 100644 --- a/chrome/browser/gtk/infobar_gtk.cc +++ b/chrome/browser/gtk/infobar_gtk.cc @@ -184,6 +184,8 @@ class LinkInfoBar : public InfoBar { // Create the link button. GtkWidget* link_button = gtk_chrome_link_button_new(WideToUTF8(link_text).c_str()); + gtk_chrome_link_button_set_use_gtk_theme( + GTK_CHROME_LINK_BUTTON(link_button), FALSE); g_signal_connect(link_button, "clicked", G_CALLBACK(OnLinkClick), this); |