summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-01 01:51:46 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-01 01:51:46 +0000
commit10882030ebab866d6ecb495480b371fbc0536ab7 (patch)
tree03c7f47bd93557f420680953e8ee98d32ea6b75e /chrome
parent46ad7357844bdc3ed4a7fd40d73ad37b56d8c07d (diff)
downloadchromium_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.cc10
-rw-r--r--chrome/browser/gtk/bookmark_bubble_gtk.h3
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.cc2
-rw-r--r--chrome/browser/gtk/gtk_chrome_link_button.cc105
-rw-r--r--chrome/browser/gtk/gtk_chrome_link_button.h9
-rw-r--r--chrome/browser/gtk/infobar_gtk.cc2
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);