summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-08 19:43:38 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-08 19:43:38 +0000
commit744b50610c1c7bb9c6f9f580c740cf8f5ca23e82 (patch)
treedc0014efec53b1135c729ceb89b593c68b692e1a /chrome/browser/gtk
parentf33bc9e999c94c006b3304cc67d901cdbc37abec (diff)
downloadchromium_src-744b50610c1c7bb9c6f9f580c740cf8f5ca23e82.zip
chromium_src-744b50610c1c7bb9c6f9f580c740cf8f5ca23e82.tar.gz
chromium_src-744b50610c1c7bb9c6f9f580c740cf8f5ca23e82.tar.bz2
[GTK] update infobars to new, harder-to-spoof versions.
This doesn't support the multiple infobar case. It does however support the following: - There is a drop shadow over the render view content, over the toolbar area, and an arrow to the location icon. - animations while enabling/disabling the bookmark bar, on normal page or NTP - different infobar colors - switching between tabs with or without infobars - animated appearance/disappearance (animation is alpha-fade) Popup windows don't appear to support infobars (at least I can't get an infobar to open in a popup window), but this new code doesn't cause crashes there either. BUG=48996 TEST=manual (see above) Review URL: http://codereview.chromium.org/3621010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62001 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc176
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h55
-rw-r--r--chrome/browser/gtk/gtk_util.cc23
-rw-r--r--chrome/browser/gtk/gtk_util.h7
-rw-r--r--chrome/browser/gtk/infobar_container_gtk.cc43
-rw-r--r--chrome/browser/gtk/infobar_container_gtk.h5
-rw-r--r--chrome/browser/gtk/infobar_gtk.cc5
-rw-r--r--chrome/browser/gtk/infobar_gtk.h18
8 files changed, 312 insertions, 20 deletions
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index 0653ff8..a4e7f77 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -53,6 +53,7 @@
#include "chrome/browser/gtk/import_dialog_gtk.h"
#include "chrome/browser/gtk/info_bubble_gtk.h"
#include "chrome/browser/gtk/infobar_container_gtk.h"
+#include "chrome/browser/gtk/infobar_gtk.h"
#include "chrome/browser/gtk/keyword_editor_view.h"
#include "chrome/browser/gtk/location_bar_view_gtk.h"
#include "chrome/browser/gtk/nine_box.h"
@@ -80,6 +81,7 @@
#include "chrome/common/native_web_keyboard_event.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
+#include "gfx/canvas_skia_paint.h"
#include "gfx/color_utils.h"
#include "gfx/gtk_util.h"
#include "gfx/rect.h"
@@ -88,6 +90,7 @@
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
namespace {
@@ -335,12 +338,14 @@ std::map<XID, GtkWindow*> BrowserWindowGtk::xid_map_;
BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
: browser_(browser),
state_(GDK_WINDOW_STATE_WITHDRAWN),
+ bookmark_bar_is_floating_(false),
frame_cursor_(NULL),
is_active_(true),
last_click_time_(0),
maximize_after_show_(false),
suppress_window_raise_(false),
- accel_group_(NULL) {
+ accel_group_(NULL),
+ infobar_animation_(this) {
// We register first so that other views like the toolbar can use the
// is_active() function in their ActiveWindowChanged() handlers.
ActiveWindowWatcherX::AddObserver(this);
@@ -384,6 +389,8 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
SetBackgroundColor();
HideUnsupportedWindowFeatures();
+ infobar_animation_.SetTweenType(Tween::LINEAR);
+
registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED,
NotificationService::AllSources());
}
@@ -1476,6 +1483,7 @@ void BrowserWindowGtk::RegisterUserPrefs(PrefService* prefs) {
}
void BrowserWindowGtk::BookmarkBarIsFloating(bool is_floating) {
+ bookmark_bar_is_floating_ = is_floating;
toolbar_->UpdateForBookmarkBarVisibility(is_floating);
// This can be NULL during initialization of the bookmark bar.
@@ -1556,7 +1564,7 @@ void BrowserWindowGtk::InitWidgets() {
gtk_widget_set_double_buffered(window_container_, FALSE);
gtk_widget_set_redraw_on_allocate(window_container_, TRUE);
g_signal_connect(window_container_, "expose-event",
- G_CALLBACK(&OnCustomFrameExposeThunk), this);
+ G_CALLBACK(OnCustomFrameExposeThunk), this);
gtk_container_add(GTK_CONTAINER(window_container_), window_vbox_);
tabstrip_.reset(new TabStripGtk(browser_->tabstrip_model(), this));
@@ -1573,6 +1581,8 @@ void BrowserWindowGtk::InitWidgets() {
toolbar_->Init(browser_->profile(), window_);
gtk_box_pack_start(GTK_BOX(window_vbox_), toolbar_->widget(),
FALSE, FALSE, 0);
+ g_signal_connect_after(toolbar_->widget(), "expose-event",
+ G_CALLBACK(OnExposeDrawInfobarBitsThunk), this);
// This vbox surrounds the render area: find bar, info bars and render view.
// The reason is that this area as a whole needs to be grouped in its own
// GdkWindow hierarchy so that animations originating inside it (infobar,
@@ -1589,6 +1599,8 @@ void BrowserWindowGtk::InitWidgets() {
toolbar_border_, FALSE, FALSE, 0);
gtk_widget_set_size_request(toolbar_border_, -1, 1);
gtk_widget_set_no_show_all(toolbar_border_, TRUE);
+ g_signal_connect_after(toolbar_border_, "expose-event",
+ G_CALLBACK(OnExposeDrawInfobarBitsThunk), this);
if (IsToolbarSupported())
gtk_widget_show(toolbar_border_);
@@ -1638,6 +1650,11 @@ void BrowserWindowGtk::InitWidgets() {
tabstrip_.get()));
PlaceBookmarkBar(false);
gtk_widget_show(bookmark_bar_->widget());
+
+ g_signal_connect_after(bookmark_bar_->widget(), "expose-event",
+ G_CALLBACK(OnBookmarkBarExposeThunk), this);
+ g_signal_connect(bookmark_bar_->widget(), "size-allocate",
+ G_CALLBACK(OnBookmarkBarSizeAllocateThunk), this);
}
// We have to realize the window before we try to apply a window shape mask.
@@ -1789,6 +1806,161 @@ void BrowserWindowGtk::SaveWindowPosition() {
window_preferences->SetInteger("work_area_bottom", work_area.bottom());
}
+void BrowserWindowGtk::AnimationEnded(const Animation* animation) {
+ InvalidateInfoBarBits();
+}
+
+void BrowserWindowGtk::AnimationProgressed(const Animation* animation) {
+ InvalidateInfoBarBits();
+}
+
+void BrowserWindowGtk::AnimationCanceled(const Animation* animation) {
+ InvalidateInfoBarBits();
+}
+
+void BrowserWindowGtk::SetInfoBarShowing(
+ const std::pair<SkColor, SkColor>* colors,
+ bool animate) {
+ if (colors) {
+ infobar_colors_ = *colors;
+
+ if (animate)
+ infobar_animation_.Show();
+ else
+ infobar_animation_.Reset(1.0);
+ } else {
+ infobar_colors_ = std::pair<SkColor, SkColor>();
+
+ if (animate)
+ infobar_animation_.Hide();
+ else
+ infobar_animation_.Reset();
+ }
+
+ InvalidateInfoBarBits();
+}
+
+bool BrowserWindowGtk::ShouldDrawInfobarDropShadowOnRenderView() {
+ return infobar_animation_.GetCurrentValue() != 0.0 &&
+ !(bookmark_bar_.get() && bookmark_bar_is_floating_);
+}
+
+void BrowserWindowGtk::InvalidateInfoBarBits() {
+ gtk_widget_queue_draw(toolbar_border_);
+ gtk_widget_queue_draw(toolbar_->widget());
+ if (bookmark_bar_.get())
+ gtk_widget_queue_draw(bookmark_bar_->widget());
+}
+
+gboolean BrowserWindowGtk::OnExposeDrawInfobarBits(GtkWidget* sender,
+ GdkEventExpose* expose) {
+ double alpha = infobar_animation_.GetCurrentValue();
+ if (alpha == 0.0)
+ return FALSE;
+
+ GtkWidget* location_icon = toolbar_->GetLocationBarView()->
+ location_icon_widget();
+ int x = 0;
+ int top_y = 0;
+ // The offset between the vertical center of the location icon and the top
+ // of the arrow.
+ const int kArrowVerticalOffset = 4;
+ gtk_widget_translate_coordinates(
+ location_icon, sender,
+ location_icon->allocation.width / 2,
+ location_icon->allocation.height / 2 + kArrowVerticalOffset,
+ &x, &top_y);
+
+ gfx::Rect toolbar_border(toolbar_border_->allocation);
+ int y = 0;
+ gtk_widget_translate_coordinates(toolbar_border_, sender,
+ 0, toolbar_border.bottom(),
+ NULL, &y);
+
+ int arrow_height = y - top_y;
+ // The width of half the arrow.
+ const int kArrowWidth = 15;
+
+ if (GTK_WIDGET_NO_WINDOW(sender)) {
+ x += sender->allocation.x;
+ y += sender->allocation.y;
+ }
+
+ SkPath path;
+ path.moveTo(SkPoint::Make(x - kArrowWidth, y));
+ path.lineTo(SkPoint::Make(x, y - arrow_height));
+ path.lineTo(SkPoint::Make(x + kArrowWidth, y));
+ path.close();
+
+ SkPaint paint;
+ paint.setStyle(SkPaint::kFill_Style);
+
+ SkPoint grad_points[2];
+ grad_points[0].set(SkIntToScalar(0), SkIntToScalar(y));
+ grad_points[1].set(SkIntToScalar(0),
+ SkIntToScalar(y + InfoBar::kInfoBarHeight));
+
+ SkColor grad_colors[2];
+ grad_colors[0] = SkColorSetA(infobar_colors_.first, alpha * 0xff);
+ grad_colors[1] = SkColorSetA(infobar_colors_.second, alpha * 0xff);
+
+ SkShader* gradient_shader = SkGradientShader::CreateLinear(
+ grad_points, grad_colors, NULL, 2, SkShader::kMirror_TileMode);
+ paint.setShader(gradient_shader);
+ gradient_shader->unref();
+
+ gfx::CanvasSkiaPaint canvas(expose, false);
+ canvas.drawPath(path, paint);
+
+ paint.setShader(NULL);
+ paint.setStyle(SkPaint::kStroke_Style);
+
+ const int kMaxShading = 100;
+ const int kShadingPixels = 5;
+ for (int i = 1; i <= kShadingPixels; ++i) {
+ SkPath shadow_path;
+ shadow_path.moveTo(0, y - i);
+ shadow_path.rLineTo(x - kArrowWidth + 1, 0);
+ shadow_path.rLineTo(kArrowWidth, -arrow_height);
+ // This rMoveTo() is necessary to give the path a sharp point at the top.
+ shadow_path.rMoveTo(-1, 0);
+ shadow_path.rLineTo(kArrowWidth, arrow_height);
+ shadow_path.rLineTo(sender->allocation.width, 0);
+
+ int shading = (kShadingPixels - i + 1) * kMaxShading / kShadingPixels;
+ paint.setColor(SkColorSetARGB(alpha * shading, 0, 0, 0));
+ canvas.drawPath(shadow_path, paint);
+ }
+
+ return FALSE;
+}
+
+gboolean BrowserWindowGtk::OnBookmarkBarExpose(GtkWidget* sender,
+ GdkEventExpose* expose) {
+ if (infobar_animation_.GetCurrentValue() == 0.0)
+ return FALSE;
+
+ // This shares the same draw path as the other widgets when it's not floating.
+ if (!bookmark_bar_is_floating_)
+ return OnExposeDrawInfobarBits(sender, expose);
+
+ gfx::Point origin;
+ if (GTK_WIDGET_NO_WINDOW(sender))
+ origin = gfx::Point(sender->allocation.x, sender->allocation.y);
+ cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(expose->window));
+ gtk_util::DrawTopDropShadowForRenderView(cr, origin, gfx::Rect(expose->area));
+ cairo_destroy(cr);
+ return FALSE;
+}
+
+void BrowserWindowGtk::OnBookmarkBarSizeAllocate(GtkWidget* sender,
+ GtkAllocation* allocation) {
+ // The size of the bookmark bar affects how the infobar arrow is drawn on
+ // the toolbar.
+ if (infobar_animation_.GetCurrentValue() != 0.0)
+ gtk_widget_queue_draw(toolbar_->widget());
+}
+
// static
gboolean BrowserWindowGtk::OnGtkAccelerator(GtkAccelGroup* accel_group,
GObject* acceleratable,
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index 2f0746f..ce6fd20 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -12,6 +12,7 @@
#include "app/active_window_watcher_x.h"
#include "app/gtk_signal.h"
+#include "app/slide_animation.h"
#include "app/x11_util.h"
#include "base/scoped_ptr.h"
#include "base/timer.h"
@@ -43,7 +44,8 @@ class TabStripGtk;
class BrowserWindowGtk : public BrowserWindow,
public NotificationObserver,
public TabStripModelObserver,
- public ActiveWindowWatcherX::Observer {
+ public ActiveWindowWatcherX::Observer,
+ public AnimationDelegate {
public:
explicit BrowserWindowGtk(Browser* browser);
virtual ~BrowserWindowGtk();
@@ -140,9 +142,14 @@ class BrowserWindowGtk : public BrowserWindow,
bool user_gesture);
virtual void TabStripEmpty();
- // Overriden from ActiveWindowWatcher::Observer.
+ // Overridden from ActiveWindowWatcher::Observer.
virtual void ActiveWindowChanged(GdkWindow* active_window);
+ // Overridden from AnimationDelegate.
+ virtual void AnimationEnded(const Animation* animation);
+ virtual void AnimationProgressed(const Animation* animation);
+ virtual void AnimationCanceled(const Animation* animation);
+
// Accessor for the tab strip.
TabStripGtk* tabstrip() const { return tabstrip_.get(); }
@@ -171,6 +178,17 @@ class BrowserWindowGtk : public BrowserWindow,
// else for the custom frame.
void ResetCustomFrameCursor();
+ // Toggles whether an infobar is showing. If |colors| is NULL, then no infobar
+ // is showing. When non-NULL, |colors| describes the gradient stop colors for
+ // the showing infobar.
+ // |animate| controls whether we animate to the new state set by |colors|.
+ void SetInfoBarShowing(const std::pair<SkColor, SkColor>* colors,
+ bool animate);
+
+ // Called by the RenderViewHostDelegate::View (TabContentsViewGtk in our case)
+ // to decide whether to draw a drop shadow on the render view.
+ bool ShouldDrawInfobarDropShadowOnRenderView();
+
// Returns the BrowserWindowGtk registered with |window|.
static BrowserWindowGtk* GetBrowserWindowForNativeWindow(
gfx::NativeWindow window);
@@ -219,8 +237,7 @@ class BrowserWindowGtk : public BrowserWindow,
GtkWidget* render_area_floating_container_;
// EventBox that holds render_area_floating_container_.
GtkWidget* render_area_event_box_;
- // Border between toolbar and render area. This is hidden when the find bar
- // is added because thereafter the findbar will draw the border for us.
+ // Border between toolbar and render area.
GtkWidget* toolbar_border_;
scoped_ptr<Browser> browser_;
@@ -289,6 +306,27 @@ class BrowserWindowGtk : public BrowserWindow,
// activation state / incognito state.
int GetThemeFrameResource();
+ // Invalidate all the widgets that need to redraw when the infobar draw state
+ // has changed.
+ void InvalidateInfoBarBits();
+
+ // Used to draw the infobar arrow and drop shadow. This is connected to
+ // multiple widgets' expose events because it overlaps several widgets.
+ CHROMEGTK_CALLBACK_1(BrowserWindowGtk, gboolean, OnExposeDrawInfobarBits,
+ GdkEventExpose*);
+
+ // Used to draw the infobar bits for the bookmark bar. When the bookmark
+ // bar is in floating mode, it has to draw a drop shadow only; otherwise
+ // it is responsible for its portion of the arrow as well as some shadowing.
+ CHROMEGTK_CALLBACK_1(BrowserWindowGtk, gboolean, OnBookmarkBarExpose,
+ GdkEventExpose*);
+
+ // Callback for "size-allocate" signal on bookmark bar; this is relevant
+ // because when the bookmark bar changes dimensions, the infobar arrow has to
+ // change its shape, and we need to queue appropriate redraws.
+ CHROMEGTK_CALLBACK_1(BrowserWindowGtk, void, OnBookmarkBarSizeAllocate,
+ GtkAllocation*);
+
// Callback for accelerator activation. |user_data| stores the command id
// of the matched accelerator.
static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group,
@@ -377,6 +415,9 @@ class BrowserWindowGtk : public BrowserWindow,
// bookmark bar is not supported.
scoped_ptr<BookmarkBarGtk> bookmark_bar_;
+ // Caches the hover state of the bookmark bar.
+ bool bookmark_bar_is_floating_;
+
// The status bubble manager. Always non-NULL.
scoped_ptr<StatusBubbleGtk> status_bubble_;
@@ -439,6 +480,12 @@ class BrowserWindowGtk : public BrowserWindow,
scoped_ptr<FullscreenExitBubbleGtk> fullscreen_exit_bubble_;
+ // The top and bottom colors for the infobar gradient, if there is an
+ // infobar showing.
+ std::pair<SkColor, SkColor> infobar_colors_;
+
+ SlideAnimation infobar_animation_;
+
DISALLOW_COPY_AND_ASSIGN(BrowserWindowGtk);
};
diff --git a/chrome/browser/gtk/gtk_util.cc b/chrome/browser/gtk/gtk_util.cc
index 2ada5d7..f3d1f88 100644
--- a/chrome/browser/gtk/gtk_util.cc
+++ b/chrome/browser/gtk/gtk_util.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/gtk/gtk_util.h"
+#include <cairo/cairo.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
@@ -1106,4 +1107,26 @@ void InitLabelSizeRequestAndEllipsizeMode(GtkWidget* label) {
gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
}
+void DrawTopDropShadowForRenderView(cairo_t* cr, const gfx::Point& origin,
+ const gfx::Rect& paint_rect) {
+ const int kShadowHeight = 6;
+ gfx::Rect shadow_rect(paint_rect.x(), origin.y(),
+ paint_rect.width(), kShadowHeight);
+
+ // Avoid this extra work if we can.
+ if (!shadow_rect.Intersects(paint_rect))
+ return;
+
+ cairo_pattern_t* shadow =
+ cairo_pattern_create_linear(0.0, shadow_rect.y(),
+ 0.0, shadow_rect.bottom());
+ cairo_pattern_add_color_stop_rgba(shadow, 0, 0, 0, 0, 0.6);
+ cairo_pattern_add_color_stop_rgba(shadow, 1, 0, 0, 0, 0.1);
+ cairo_rectangle(cr, shadow_rect.x(), shadow_rect.y(),
+ shadow_rect.width(), shadow_rect.height());
+ cairo_set_source(cr, shadow);
+ cairo_fill(cr);
+ cairo_pattern_destroy(shadow);
+}
+
} // namespace gtk_util
diff --git a/chrome/browser/gtk/gtk_util.h b/chrome/browser/gtk/gtk_util.h
index 9c59fb5..e992670 100644
--- a/chrome/browser/gtk/gtk_util.h
+++ b/chrome/browser/gtk/gtk_util.h
@@ -16,6 +16,7 @@
#include "gfx/rect.h"
#include "webkit/glue/window_open_disposition.h"
+typedef struct _cairo cairo_t;
typedef struct _GtkWidget GtkWidget;
class GtkThemeProvider;
@@ -82,7 +83,6 @@ GtkWidget* LeftAlignMisc(GtkWidget* misc);
// Create a left-aligned label with the given text in bold.
GtkWidget* CreateBoldLabel(const std::string& text);
-
// As above, but a convenience method for configuring dialog size.
// |width_id| and |height_id| are resource IDs for the size. If either of these
// are set to -1, the respective size will be set to the widget default.
@@ -335,6 +335,11 @@ void SetLabelWidth(GtkWidget* label, int pixel_width);
// to make sure the pango can get correct font information for the calculation.
void InitLabelSizeRequestAndEllipsizeMode(GtkWidget* label);
+// Code to draw the drop shadow below an infobar (at the top of the render
+// view).
+void DrawTopDropShadowForRenderView(cairo_t* cr, const gfx::Point& origin,
+ const gfx::Rect& paint_rect);
+
} // namespace gtk_util
#endif // CHROME_BROWSER_GTK_GTK_UTIL_H_
diff --git a/chrome/browser/gtk/infobar_container_gtk.cc b/chrome/browser/gtk/infobar_container_gtk.cc
index 88cf033..068e2b3 100644
--- a/chrome/browser/gtk/infobar_container_gtk.cc
+++ b/chrome/browser/gtk/infobar_container_gtk.cc
@@ -6,13 +6,18 @@
#include <gtk/gtk.h>
+#include "base/command_line.h"
#include "chrome/browser/browser_window.h"
+#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/gtk/infobar_gtk.h"
+#include "chrome/browser/platform_util.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
+#include "third_party/skia/include/core/SkPaint.h"
namespace {
@@ -82,6 +87,7 @@ void InfoBarContainerGtk::ChangeTabContents(TabContents* contents) {
registrar_.RemoveAll();
gtk_util::RemoveAllChildren(widget());
+ UpdateToolbarInfoBarState(NULL, false);
tab_contents_ = contents;
if (tab_contents_) {
@@ -139,12 +145,16 @@ void InfoBarContainerGtk::AddInfoBar(InfoBarDelegate* delegate, bool animate) {
InfoBar* infobar = delegate->CreateInfoBar();
infobar->set_container(this);
infobar->SetThemeProvider(GtkThemeProvider::GetFrom(profile_));
- gtk_box_pack_end(GTK_BOX(widget()), infobar->widget(),
- FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(widget()), infobar->widget(),
+ FALSE, FALSE, 0);
+
if (animate)
infobar->AnimateOpen();
else
infobar->Open();
+
+ if (tab_contents_->GetInfoBarDelegateAt(0) == delegate)
+ UpdateToolbarInfoBarState(infobar, animate);
}
void InfoBarContainerGtk::RemoveInfoBar(InfoBarDelegate* delegate,
@@ -156,4 +166,33 @@ void InfoBarContainerGtk::RemoveInfoBar(InfoBarDelegate* delegate,
gtk_container_foreach(GTK_CONTAINER(widget()), ClosingForDelegate,
delegate);
}
+
+ if (tab_contents_->GetInfoBarDelegateAt(0) == delegate)
+ UpdateToolbarInfoBarState(NULL, animate);
+}
+
+void InfoBarContainerGtk::UpdateToolbarInfoBarState(
+ InfoBar* infobar, bool animate) {
+ if (!CommandLine::ForCurrentProcess()->
+ HasSwitch(switches::kEnableSecureInfoBars)) {
+ return;
+ }
+
+ scoped_ptr<std::pair<SkColor, SkColor> > colors;
+
+ if (infobar) {
+ double r, g, b;
+ infobar->GetTopColor(infobar->delegate()->GetInfoBarType(), &r, &g, &b);
+ SkColor top = SkColorSetRGB(r * 0xff, g * 0xff, b * 0xff);
+ infobar->GetBottomColor(infobar->delegate()->GetInfoBarType(), &r, &g, &b);
+ SkColor bottom = SkColorSetRGB(r * 0xff, g * 0xff, b * 0xff);
+
+ colors.reset(new std::pair<SkColor, SkColor>(top, bottom));
+ }
+
+ GtkWindow* parent = platform_util::GetTopLevel(widget());
+ BrowserWindowGtk* browser_window =
+ BrowserWindowGtk::GetBrowserWindowForNativeWindow(parent);
+ if (browser_window)
+ browser_window->SetInfoBarShowing(colors.get(), animate);
}
diff --git a/chrome/browser/gtk/infobar_container_gtk.h b/chrome/browser/gtk/infobar_container_gtk.h
index 441072f..cb81580 100644
--- a/chrome/browser/gtk/infobar_container_gtk.h
+++ b/chrome/browser/gtk/infobar_container_gtk.h
@@ -11,6 +11,7 @@
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
+class InfoBar;
class InfoBarDelegate;
class Profile;
class TabContents;
@@ -59,6 +60,10 @@ class InfoBarContainerGtk : public NotificationObserver {
// will be animated.
void RemoveInfoBar(InfoBarDelegate* delegate, bool animate);
+ // Tells the browser window about our state so it can draw the arrow
+ // appropriately.
+ void UpdateToolbarInfoBarState(InfoBar* infobar, bool animate);
+
NotificationRegistrar registrar_;
// The profile for the browser that hosts this InfoBarContainer.
diff --git a/chrome/browser/gtk/infobar_gtk.cc b/chrome/browser/gtk/infobar_gtk.cc
index 1af4315..c7f7392 100644
--- a/chrome/browser/gtk/infobar_gtk.cc
+++ b/chrome/browser/gtk/infobar_gtk.cc
@@ -16,6 +16,8 @@
#include "chrome/common/notification_service.h"
#include "gfx/gtk_util.h"
+extern const int InfoBar::kInfoBarHeight = 37;
+
namespace {
// Spacing after message (and before buttons).
@@ -23,9 +25,6 @@ const int kEndOfLabelSpacing = 6;
// Spacing between buttons.
const int kButtonButtonSpacing = 3;
-// The total height of the info bar.
-const int kInfoBarHeight = 37;
-
// Pixels between infobar elements.
const int kElementPadding = 5;
diff --git a/chrome/browser/gtk/infobar_gtk.h b/chrome/browser/gtk/infobar_gtk.h
index 790b0f6..5589f9e 100644
--- a/chrome/browser/gtk/infobar_gtk.h
+++ b/chrome/browser/gtk/infobar_gtk.h
@@ -63,6 +63,16 @@ class InfoBar : public SlideAnimatorGtk::Delegate,
const NotificationSource& source,
const NotificationDetails& details);
+ // Retrieves the component colors for the infobar's background
+ // gradient. (This varies by infobars and can be animated to change).
+ virtual void GetTopColor(InfoBarDelegate::Type type,
+ double* r, double* g, double *b);
+ virtual void GetBottomColor(InfoBarDelegate::Type type,
+ double* r, double* g, double *b);
+
+ // The total height of the info bar.
+ static const int kInfoBarHeight;
+
protected:
// Removes our associated InfoBarDelegate from the associated TabContents.
// (Will lead to this InfoBar being closed).
@@ -82,14 +92,6 @@ class InfoBar : public SlideAnimatorGtk::Delegate,
void AddLabelAndLink(const string16& display_text,
const string16& link_text,
GCallback callback);
-
- // Retrieves the component colors for the infobar's background
- // gradient. (This varies by infobars and can be animated to change).
- virtual void GetTopColor(InfoBarDelegate::Type type,
- double* r, double* g, double *b);
- virtual void GetBottomColor(InfoBarDelegate::Type type,
- double* r, double* g, double *b);
-
// The top level widget of the infobar.
scoped_ptr<SlideAnimatorGtk> slide_widget_;