summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-15 21:52:48 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-15 21:52:48 +0000
commit0a2aeb81a06170cf4d99392b683736c46212f9ef (patch)
tree1c491dcbe56474ad5bbbd6da0cd47c75eca414d3 /chrome
parent26ee7556422eb077a813c9a15a03867779bb8188 (diff)
downloadchromium_src-0a2aeb81a06170cf4d99392b683736c46212f9ef.zip
chromium_src-0a2aeb81a06170cf4d99392b683736c46212f9ef.tar.gz
chromium_src-0a2aeb81a06170cf4d99392b683736c46212f9ef.tar.bz2
Linux: Take download shelf and infobar close animations into account during render view sizing.
http://crbug.com/11080 Review URL: http://codereview.chromium.org/113322 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16193 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.cc4
-rw-r--r--chrome/browser/browser.h1
-rw-r--r--chrome/browser/browser_window.h6
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.h1
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.mm5
-rw-r--r--chrome/browser/download/download_shelf.h3
-rw-r--r--chrome/browser/download/save_package.cc2
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc7
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h1
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.cc4
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.h1
-rw-r--r--chrome/browser/gtk/infobar_container_gtk.cc43
-rw-r--r--chrome/browser/gtk/infobar_container_gtk.h6
-rw-r--r--chrome/browser/gtk/infobar_gtk.cc4
-rw-r--r--chrome/browser/gtk/infobar_gtk.h3
-rw-r--r--chrome/browser/gtk/slide_animator_gtk.cc9
-rw-r--r--chrome/browser/gtk/slide_animator_gtk.h6
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.cc8
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc10
-rw-r--r--chrome/browser/tab_contents/tab_contents.h5
-rw-r--r--chrome/browser/tab_contents/tab_contents_delegate.h7
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.cc41
-rw-r--r--chrome/browser/tab_contents/tab_contents_view_gtk.h17
-rw-r--r--chrome/browser/views/download_shelf_view.cc5
-rw-r--r--chrome/browser/views/download_shelf_view.h1
-rw-r--r--chrome/browser/views/frame/browser_view.cc10
-rw-r--r--chrome/browser/views/frame/browser_view.h1
-rw-r--r--chrome/common/temp_scaffolding_stubs.cc1
-rw-r--r--chrome/test/test_browser_window.h1
29 files changed, 177 insertions, 36 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index e6b6598..13ca661 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -2002,6 +2002,10 @@ ExtensionFunctionDispatcher* Browser::CreateExtensionFunctionDispatcher(
return new ExtensionFunctionDispatcher(render_view_host, this, extension_id);
}
+int Browser::GetExtraRenderViewHeight() const {
+ return window_->GetExtraRenderViewHeight();
+}
+
///////////////////////////////////////////////////////////////////////////////
// Browser, SelectFileDialog::Listener implementation:
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index a1b5e46..dac3877 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -499,6 +499,7 @@ class Browser : public TabStripModelDelegate,
virtual ExtensionFunctionDispatcher *CreateExtensionFunctionDispatcher(
RenderViewHost* render_view_host,
const std::string& extension_id);
+ virtual int GetExtraRenderViewHeight() const;
// Overridden from SelectFileDialog::Listener:
virtual void FileSelected(const FilePath& path, int index, void* params);
diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h
index c5e2027..d804bc1 100644
--- a/chrome/browser/browser_window.h
+++ b/chrome/browser/browser_window.h
@@ -180,6 +180,12 @@ class BrowserWindow {
// indicating that it's time to redraw everything.
virtual void UserChangedTheme() = 0;
+ // Get extra vertical height that the render view should add to its requests
+ // to webkit. This can help prevent sending extraneous layout/repaint requests
+ // when the delegate is in the process of resizing the tab contents view (e.g.
+ // during infobar animations).
+ virtual int GetExtraRenderViewHeight() const = 0;
+
// Construct a BrowserWindow implementation for the specified |browser|.
static BrowserWindow* CreateBrowserWindow(Browser* browser);
diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h
index ba9ea70..66b2ba0 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/cocoa/browser_window_cocoa.h
@@ -68,6 +68,7 @@ class BrowserWindowCocoa : public BrowserWindow,
virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
void* parent_window);
virtual void UserChangedTheme();
+ virtual int GetExtraRenderViewHeight() const;
// Overridden from NotificationObserver
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm
index 395817b..0da8a3f 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/cocoa/browser_window_cocoa.mm
@@ -232,6 +232,11 @@ void BrowserWindowCocoa::UserChangedTheme() {
NOTIMPLEMENTED();
}
+int BrowserWindowCocoa::GetExtraRenderViewHeight() const {
+ // Currently this is only used on linux.
+ return 0;
+}
+
void BrowserWindowCocoa::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
diff --git a/chrome/browser/download/download_shelf.h b/chrome/browser/download/download_shelf.h
index 15410ae..1b455c0 100644
--- a/chrome/browser/download/download_shelf.h
+++ b/chrome/browser/download/download_shelf.h
@@ -43,6 +43,9 @@ class DownloadShelf {
// the beginning Show and true at the beginning of a Hide.
virtual bool IsShowing() const = 0;
+ // Returns whether the download shelf is showing the close animation.
+ virtual bool IsClosing() const = 0;
+
protected:
TabContents* tab_contents_;
diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc
index 85c3003..9356a68 100644
--- a/chrome/browser/download/save_package.cc
+++ b/chrome/browser/download/save_package.cc
@@ -252,7 +252,7 @@ bool SavePackage::Init() {
FilePath(), Time::Now(), 0, -1, -1, false);
download_->set_manager(tab_contents_->profile()->GetDownloadManager());
#if !defined(OS_MACOSX)
- DownloadShelf* shelf = tab_contents_->GetDownloadShelf();
+ DownloadShelf* shelf = tab_contents_->GetDownloadShelf(true);
shelf->AddDownload(new SavePageModel(this, download_));
tab_contents_->SetDownloadShelfVisible(true);
#else
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index bf441a5..49fc667 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -593,6 +593,13 @@ void BrowserWindowGtk::UserChangedTheme() {
NOTIMPLEMENTED();
}
+int BrowserWindowGtk::GetExtraRenderViewHeight() const {
+ // The download shelf is controlled by its TabContents, so we don't have to
+ // worry about it here.
+ // TODO(estade): take the bookmark bar into account as well.
+ return infobar_container_->TotalHeightOfClosingBars();
+}
+
void BrowserWindowGtk::ConfirmBrowserCloseWithPendingDownloads() {
NOTIMPLEMENTED();
browser_->InProgressDownloadResponse(false);
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index f292cdf..c54a120 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -79,6 +79,7 @@ class BrowserWindowGtk : public BrowserWindow,
virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
void* parent_window);
virtual void UserChangedTheme();
+ virtual int GetExtraRenderViewHeight() const;
// Overridden from NotificationObserver:
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc
index 3eb794c..f594a7f 100644
--- a/chrome/browser/gtk/download_shelf_gtk.cc
+++ b/chrome/browser/gtk/download_shelf_gtk.cc
@@ -138,6 +138,10 @@ bool DownloadShelfGtk::IsShowing() const {
return slide_widget_->IsShowing();
}
+bool DownloadShelfGtk::IsClosing() const {
+ return slide_widget_->IsClosing();
+}
+
void DownloadShelfGtk::RemoveDownloadItem(DownloadItemGtk* download_item) {
DCHECK(download_item);
std::vector<DownloadItemGtk*>::iterator i =
diff --git a/chrome/browser/gtk/download_shelf_gtk.h b/chrome/browser/gtk/download_shelf_gtk.h
index e2819a0..bc41647 100644
--- a/chrome/browser/gtk/download_shelf_gtk.h
+++ b/chrome/browser/gtk/download_shelf_gtk.h
@@ -28,6 +28,7 @@ class DownloadShelfGtk : public DownloadShelf {
// DownloadShelf implementation.
virtual void AddDownload(BaseDownloadItemModel* download_model);
virtual bool IsShowing() const;
+ virtual bool IsClosing() const;
private:
// Remove |download_item| from the download shelf and delete it.
diff --git a/chrome/browser/gtk/infobar_container_gtk.cc b/chrome/browser/gtk/infobar_container_gtk.cc
index 3623497..a44ef65 100644
--- a/chrome/browser/gtk/infobar_container_gtk.cc
+++ b/chrome/browser/gtk/infobar_container_gtk.cc
@@ -15,28 +15,33 @@
namespace {
-// Used by RemoveInfoBar to pass data to AnimateClosingForDelegate.
-struct RemoveInfoBarData {
- GtkWidget* container;
- InfoBarDelegate* delegate;
-};
-
+// If |infobar_widget| matches |info_bar_delegate|, then close the infobar.
void AnimateClosingForDelegate(GtkWidget* infobar_widget,
- gpointer remove_info_bar_data) {
+ gpointer info_bar_delegate) {
+ InfoBarDelegate* delegate =
+ static_cast<InfoBarDelegate*>(info_bar_delegate);
InfoBar* infobar = reinterpret_cast<InfoBar*>(
g_object_get_data(G_OBJECT(infobar_widget), "info-bar"));
- RemoveInfoBarData* data =
- reinterpret_cast<RemoveInfoBarData*>(remove_info_bar_data);
if (!infobar) {
NOTREACHED();
return;
}
- if (data->delegate == infobar->delegate())
+ if (delegate == infobar->delegate())
infobar->AnimateClose();
}
+// Get the height of the widget and add it to |userdata|, but only if it is in
+// the process of closing.
+void SumClosingBarHeight(GtkWidget* widget, gpointer userdata) {
+ int* height_sum = static_cast<int*>(userdata);
+ InfoBar* infobar = reinterpret_cast<InfoBar*>(
+ g_object_get_data(G_OBJECT(widget), "info-bar"));
+ if (infobar->IsClosing())
+ *height_sum += widget->allocation.height;
+}
+
} // namespace
// InfoBarContainerGtk, public: ------------------------------------------------
@@ -45,7 +50,7 @@ InfoBarContainerGtk::InfoBarContainerGtk(BrowserWindow* browser_window)
: browser_window_(browser_window),
tab_contents_(NULL),
container_(gtk_vbox_new(FALSE, 0)) {
- gtk_widget_show(container_.get());
+ gtk_widget_show(widget());
}
InfoBarContainerGtk::~InfoBarContainerGtk() {
@@ -65,7 +70,7 @@ void InfoBarContainerGtk::ChangeTabContents(TabContents* contents) {
Source<TabContents>(tab_contents_));
}
- gtk_util::RemoveAllChildren(container_.get());
+ gtk_util::RemoveAllChildren(widget());
tab_contents_ = contents;
if (tab_contents_) {
@@ -83,6 +88,12 @@ void InfoBarContainerGtk::RemoveDelegate(InfoBarDelegate* delegate) {
tab_contents_->RemoveInfoBar(delegate);
}
+int InfoBarContainerGtk::TotalHeightOfClosingBars() const {
+ int sum = 0;
+ gtk_container_foreach(GTK_CONTAINER(widget()), SumClosingBarHeight, &sum);
+ return sum;
+}
+
// InfoBarContainerGtk, NotificationObserver implementation: -------------------
void InfoBarContainerGtk::Observe(NotificationType type,
@@ -109,7 +120,7 @@ void InfoBarContainerGtk::UpdateInfoBars() {
void InfoBarContainerGtk::AddInfoBar(InfoBarDelegate* delegate, bool animate) {
InfoBar* infobar = delegate->CreateInfoBar();
infobar->set_container(this);
- gtk_box_pack_end(GTK_BOX(container_.get()), infobar->widget(),
+ gtk_box_pack_end(GTK_BOX(widget()), infobar->widget(),
FALSE, FALSE, 0);
if (animate)
infobar->AnimateOpen();
@@ -118,8 +129,6 @@ void InfoBarContainerGtk::AddInfoBar(InfoBarDelegate* delegate, bool animate) {
}
void InfoBarContainerGtk::RemoveInfoBar(InfoBarDelegate* delegate) {
- RemoveInfoBarData remove_info_bar_data = { container_.get(), delegate };
-
- gtk_container_foreach(GTK_CONTAINER(container_.get()),
- AnimateClosingForDelegate, &remove_info_bar_data);
+ gtk_container_foreach(GTK_CONTAINER(widget()),
+ AnimateClosingForDelegate, delegate);
}
diff --git a/chrome/browser/gtk/infobar_container_gtk.h b/chrome/browser/gtk/infobar_container_gtk.h
index 60bd8d0..58e0c52 100644
--- a/chrome/browser/gtk/infobar_container_gtk.h
+++ b/chrome/browser/gtk/infobar_container_gtk.h
@@ -21,7 +21,7 @@ class InfoBarContainerGtk : public NotificationObserver {
virtual ~InfoBarContainerGtk();
// Get the native widget.
- GtkWidget* widget() { return container_.get(); }
+ GtkWidget* widget() const { return container_.get(); }
// Changes the TabContents for which this container is showing InfoBars. Can
// be NULL, in which case we will simply detach ourselves from the old tab
@@ -33,6 +33,10 @@ class InfoBarContainerGtk : public NotificationObserver {
// the InfoBar's close button handler.
void RemoveDelegate(InfoBarDelegate* delegate);
+ // Returns the total pixel height of all infobars in this container that
+ // are currently closing.
+ int TotalHeightOfClosingBars() const;
+
private:
// Overridden from NotificationObserver:
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/gtk/infobar_gtk.cc b/chrome/browser/gtk/infobar_gtk.cc
index e129fa9..60fa01d 100644
--- a/chrome/browser/gtk/infobar_gtk.cc
+++ b/chrome/browser/gtk/infobar_gtk.cc
@@ -105,6 +105,10 @@ void InfoBar::Close() {
delete this;
}
+bool InfoBar::IsClosing() {
+ return slide_widget_->IsClosing();
+}
+
void InfoBar::RemoveInfoBar() const {
container_->RemoveDelegate(delegate_);
}
diff --git a/chrome/browser/gtk/infobar_gtk.h b/chrome/browser/gtk/infobar_gtk.h
index c39fceb..e3d5b1b 100644
--- a/chrome/browser/gtk/infobar_gtk.h
+++ b/chrome/browser/gtk/infobar_gtk.h
@@ -43,6 +43,9 @@ class InfoBar : public SlideAnimatorGtk::Delegate {
// is called.
void Close();
+ // Returns true if the infobar is showing the close animation.
+ bool IsClosing();
+
// SlideAnimatorGtk::Delegate implementation.
virtual void Closed();
diff --git a/chrome/browser/gtk/slide_animator_gtk.cc b/chrome/browser/gtk/slide_animator_gtk.cc
index 3cf004c..1f76457 100644
--- a/chrome/browser/gtk/slide_animator_gtk.cc
+++ b/chrome/browser/gtk/slide_animator_gtk.cc
@@ -32,7 +32,8 @@ SlideAnimatorGtk::SlideAnimatorGtk(GtkWidget* child,
: child_(child),
direction_(direction),
delegate_(delegate),
- fixed_needs_resize_(false) {
+ fixed_needs_resize_(false),
+ is_closing_(false) {
widget_.Own(gtk_fixed_new());
gtk_fixed_put(GTK_FIXED(widget_.get()), child, 0, 0);
gtk_widget_set_size_request(widget_.get(), -1, 0);
@@ -64,6 +65,7 @@ SlideAnimatorGtk::~SlideAnimatorGtk() {
}
void SlideAnimatorGtk::Open() {
+ is_closing_ = false;
gtk_widget_show_all(widget_.get());
animation_->Show();
}
@@ -84,6 +86,7 @@ void SlideAnimatorGtk::OpenWithoutAnimation() {
}
void SlideAnimatorGtk::Close() {
+ is_closing_ = true;
animation_->Hide();
}
@@ -98,6 +101,10 @@ bool SlideAnimatorGtk::IsShowing() {
return animation_->IsShowing();
}
+bool SlideAnimatorGtk::IsClosing() {
+ return animation_->IsAnimating() && is_closing_;
+}
+
void SlideAnimatorGtk::AnimationProgressed(const Animation* animation) {
int showing_height = child_->allocation.height *
animation_->GetCurrentValue();
diff --git a/chrome/browser/gtk/slide_animator_gtk.h b/chrome/browser/gtk/slide_animator_gtk.h
index 7d9fcb6..3acc4f5 100644
--- a/chrome/browser/gtk/slide_animator_gtk.h
+++ b/chrome/browser/gtk/slide_animator_gtk.h
@@ -67,6 +67,9 @@ class SlideAnimatorGtk : public AnimationDelegate {
// Returns whether the widget is visible.
bool IsShowing();
+ // Returns whether the widget is currently showing the close animation.
+ bool IsClosing();
+
// AnimationDelegate implementation.
void AnimationProgressed(const Animation* animation);
void AnimationEnded(const Animation* animation);
@@ -100,6 +103,9 @@ class SlideAnimatorGtk : public AnimationDelegate {
// child widget has been allocated, at which point we will move it, and then
// set this variable to false to indicate it should not be moved again.
bool child_needs_move_;
+
+ // Is true IFF Close() was called more recently than Open().
+ bool is_closing_;
};
#endif // CHROME_BROWSER_GTK_SLIDE_ANIMATOR_GTK_H_
diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
index f44511e..ee2f7b9 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -39,8 +39,8 @@ class RenderWidgetHostViewGtkWidget {
GDK_KEY_RELEASE_MASK);
GTK_WIDGET_SET_FLAGS(widget, GTK_CAN_FOCUS);
- g_signal_connect(widget, "configure-event",
- G_CALLBACK(ConfigureEvent), host_view);
+ g_signal_connect(widget, "size-allocate",
+ G_CALLBACK(SizeAllocate), host_view);
g_signal_connect(widget, "expose-event",
G_CALLBACK(ExposeEvent), host_view);
g_signal_connect(widget, "key-press-event",
@@ -74,8 +74,8 @@ class RenderWidgetHostViewGtkWidget {
}
private:
- static gboolean ConfigureEvent(GtkWidget* widget, GdkEventConfigure* config,
- RenderWidgetHostViewGtk* host_view) {
+ static gboolean SizeAllocate(GtkWidget* widget, GtkAllocation* allocation,
+ RenderWidgetHostViewGtk* host_view) {
host_view->GetRenderWidgetHost()->WasResized();
return FALSE;
}
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 9042518..af83bfd 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -919,7 +919,7 @@ void TabContents::SetDownloadShelfVisible(bool visible) {
if (shelf_visible_ != visible) {
if (visible) {
// Invoke GetDownloadShelf to force the shelf to be created.
- GetDownloadShelf();
+ GetDownloadShelf(true);
}
shelf_visible_ = visible;
@@ -951,7 +951,7 @@ void TabContents::OnStartDownload(DownloadItem* download) {
TabContents* tab_contents = delegate()->GetConstrainingContents(this);
// GetDownloadShelf creates the download shelf if it was not yet created.
- tab_contents->GetDownloadShelf()->AddDownload(
+ tab_contents->GetDownloadShelf(true)->AddDownload(
new DownloadItemModel(download));
tab_contents->SetDownloadShelfVisible(true);
@@ -966,14 +966,14 @@ void TabContents::OnStartDownload(DownloadItem* download) {
#endif
}
-DownloadShelf* TabContents::GetDownloadShelf() {
- if (!download_shelf_.get())
+DownloadShelf* TabContents::GetDownloadShelf(bool create) {
+ if (!download_shelf_.get() && create)
download_shelf_.reset(DownloadShelf::Create(this));
return download_shelf_.get();
}
void TabContents::MigrateShelfFrom(TabContents* tab_contents) {
- download_shelf_.reset(tab_contents->GetDownloadShelf());
+ download_shelf_.reset(tab_contents->GetDownloadShelf(true));
download_shelf_->ChangeTabContents(tab_contents, this);
tab_contents->ReleaseDownloadShelf();
}
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index cf25aba..3b749e6 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -415,8 +415,9 @@ class TabContents : public PageNavigator,
// Displays the download shelf and animation when a download occurs.
void OnStartDownload(DownloadItem* download);
- // Returns the DownloadShelf, creating it if necessary.
- DownloadShelf* GetDownloadShelf();
+ // Returns the DownloadShelf. If the shelf doesn't exist and |create| is true,
+ // this function will create the shelf.
+ DownloadShelf* GetDownloadShelf(bool create);
// Transfer the shelf view from |tab_contents| to the receiving TabContents.
// |tab_contents| no longer owns the shelf after this call. The shelf is owned
diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h
index 3485fb8..4ba9553 100644
--- a/chrome/browser/tab_contents/tab_contents_delegate.h
+++ b/chrome/browser/tab_contents/tab_contents_delegate.h
@@ -167,6 +167,13 @@ class TabContentsDelegate {
return false;
}
+ // Return much extra vertical space should be allotted to the
+ // render view widget during various animations (e.g. infobar closing).
+ // This is used to make painting look smoother.
+ virtual int GetExtraRenderViewHeight() {
+ return 0;
+ }
+
protected:
~TabContentsDelegate() {}
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.cc b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
index b9671be..59065ed 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.cc
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.cc
@@ -10,6 +10,8 @@
#include "base/string_util.h"
#include "base/gfx/point.h"
#include "base/gfx/rect.h"
+#include "base/gfx/size.h"
+#include "chrome/browser/download/download_shelf.h"
#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/sad_tab_gtk.h"
#include "chrome/browser/renderer_host/render_view_host.h"
@@ -58,6 +60,16 @@ gboolean OnMouseMove(GtkWidget* widget, GdkEventMotion* event,
return FALSE;
}
+// Used with gtk_container_foreach to change the sizes of the children of
+// |fixed_|.
+void SetSizeRequest(GtkWidget* widget, gpointer userdata) {
+ gfx::Size* size = static_cast<gfx::Size*>(userdata);
+ if (widget->allocation.width != size->width() ||
+ widget->allocation.height != size->height()) {
+ gtk_widget_set_size_request(widget, size->width(), size->height());
+ }
+}
+
} // namespace
// static
@@ -68,6 +80,11 @@ TabContentsView* TabContentsView::Create(TabContents* tab_contents) {
TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents)
: TabContentsView(tab_contents),
vbox_(gtk_vbox_new(FALSE, 0)) {
+ fixed_ = gtk_fixed_new();
+ gtk_box_pack_start(GTK_BOX(vbox_.get()), fixed_, TRUE, TRUE, 0);
+ g_signal_connect(fixed_, "size-allocate",
+ G_CALLBACK(OnSizeAllocate), this);
+ gtk_widget_show(fixed_);
registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED,
Source<TabContents>(tab_contents));
registrar_.Add(this, NotificationType::TAB_CONTENTS_DISCONNECTED,
@@ -108,7 +125,8 @@ RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget(
GDK_POINTER_MOTION_MASK);
g_signal_connect(content_view, "button-press-event",
G_CALLBACK(OnMouseDown), this);
- gtk_box_pack_start(GTK_BOX(vbox_.get()), content_view, TRUE, TRUE, 0);
+
+ InsertIntoContentArea(content_view);
return view;
}
@@ -250,8 +268,7 @@ void TabContentsViewGtk::Observe(NotificationType type,
}
case NotificationType::TAB_CONTENTS_DISCONNECTED: {
sad_tab_.reset(new SadTabGtk);
- gtk_box_pack_start(
- GTK_BOX(vbox_.get()), sad_tab_->widget(), TRUE, TRUE, 0);
+ InsertIntoContentArea(sad_tab_->widget());
gtk_widget_show(sad_tab_->widget());
break;
}
@@ -278,8 +295,26 @@ void TabContentsViewGtk::StartDragging(const WebDropData& drop_data) {
tab_contents()->render_view_host()->DragSourceSystemDragEnded();
}
+void TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) {
+ gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0);
+}
+
gboolean TabContentsViewGtk::OnMouseDown(GtkWidget* widget,
GdkEventButton* event, TabContentsViewGtk* view) {
view->last_mouse_down_time_ = event->time;
return FALSE;
}
+
+gboolean TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
+ GtkAllocation* allocation,
+ TabContentsViewGtk* view) {
+ int width = allocation->width;
+ DownloadShelf* shelf = view->tab_contents()->GetDownloadShelf(false);
+ int height = shelf && shelf->IsClosing() ?
+ widget->parent->allocation.height : allocation->height;
+ height += view->tab_contents()->delegate()->GetExtraRenderViewHeight();
+ gfx::Size size(width, height);
+ gtk_container_foreach(GTK_CONTAINER(widget), SetSizeRequest, &size);
+
+ return FALSE;
+}
diff --git a/chrome/browser/tab_contents/tab_contents_view_gtk.h b/chrome/browser/tab_contents/tab_contents_view_gtk.h
index 3120cc3..cebb637a 100644
--- a/chrome/browser/tab_contents/tab_contents_view_gtk.h
+++ b/chrome/browser/tab_contents/tab_contents_view_gtk.h
@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_TAB_CONTENTS_TAB_CONTENTS_VIEW_GTK_H_
#define CHROME_BROWSER_TAB_CONTENTS_TAB_CONTENTS_VIEW_GTK_H_
+#include <gtk/gtk.h>
+
#include "base/scoped_ptr.h"
#include "chrome/browser/gtk/focus_store_gtk.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
@@ -68,13 +70,28 @@ class TabContentsViewGtk : public TabContentsView,
const NotificationDetails& details);
private:
+ // Insert the given widget into the content area. Should only be used for
+ // web pages and the like (including interstitials and sad tab). Note that
+ // this will be perfectly happy to insert overlapping render views, so care
+ // should be taken that the correct one is hidden/shown.
+ void InsertIntoContentArea(GtkWidget* widget);
+
// We keep track of the timestamp of the latest mousedown event.
static gboolean OnMouseDown(GtkWidget* widget,
GdkEventButton* event, TabContentsViewGtk* view);
+ // Used to propagate size changes on |fixed_| to its children.
+ static gboolean OnSizeAllocate(GtkWidget* widget,
+ GtkAllocation* config,
+ TabContentsViewGtk* view);
+
// The native widget for the tab.
OwnedWidgetGtk vbox_;
+ // This container holds the tab's web page views. It is a GtkFixed so that we
+ // can control the size of the web pages.
+ GtkWidget* fixed_;
+
// The context menu is reset every time we show it, but we keep a pointer to
// between uses so that it won't go out of scope before we're done with it.
scoped_ptr<RenderViewContextMenuGtk> context_menu_;
diff --git a/chrome/browser/views/download_shelf_view.cc b/chrome/browser/views/download_shelf_view.cc
index bd6a7b1..8e3353a 100644
--- a/chrome/browser/views/download_shelf_view.cc
+++ b/chrome/browser/views/download_shelf_view.cc
@@ -304,3 +304,8 @@ void DownloadShelfView::ButtonPressed(views::Button* button) {
bool DownloadShelfView::IsShowing() const {
return shelf_animation_->IsShowing();
}
+
+bool DownloadShelfView::IsClosing() const {
+ // TODO(estade): This is never called. For now just return false.
+ return false;
+}
diff --git a/chrome/browser/views/download_shelf_view.h b/chrome/browser/views/download_shelf_view.h
index 1c1ee23..0b722b8 100644
--- a/chrome/browser/views/download_shelf_view.h
+++ b/chrome/browser/views/download_shelf_view.h
@@ -56,6 +56,7 @@ class DownloadShelfView : public DownloadShelf,
// Implementation of DownloadShelf.
virtual void AddDownload(BaseDownloadItemModel* download_model);
virtual bool IsShowing() const;
+ virtual bool IsClosing() const;
// Removes a specified download view. The supplied view is deleted after
// it's removed.
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index 4adacf9..e12d4b1 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -737,7 +737,7 @@ gfx::Rect BrowserView::GetRootWindowResizerRect() const {
// Other tests should be added here if we add more bottom shelves.
TabContents* current_tab = browser_->GetSelectedTabContents();
if (current_tab && current_tab->IsDownloadShelfVisible()) {
- DownloadShelf* download_shelf = current_tab->GetDownloadShelf();
+ DownloadShelf* download_shelf = current_tab->GetDownloadShelf(true);
if (download_shelf && download_shelf->IsShowing())
return gfx::Rect();
}
@@ -863,6 +863,11 @@ void BrowserView::UserChangedTheme() {
frame_->GetRootView()->SchedulePaint();
}
+int BrowserView::GetExtraRenderViewHeight() const {
+ // Currently this is only used on linux.
+ return 0;
+}
+
///////////////////////////////////////////////////////////////////////////////
// BrowserView, BrowserWindowTesting implementation:
@@ -1453,7 +1458,8 @@ bool BrowserView::MaybeShowInfoBar(TabContents* contents) {
bool BrowserView::MaybeShowDownloadShelf(TabContents* contents) {
views::View* new_shelf = NULL;
if (contents && contents->IsDownloadShelfVisible()) {
- new_shelf = static_cast<DownloadShelfView*>(contents->GetDownloadShelf());
+ new_shelf =
+ static_cast<DownloadShelfView*>(contents->GetDownloadShelf(true));
if (new_shelf != active_download_shelf_)
new_shelf->AddChildView(new ResizeCorner());
}
diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h
index 6a2d6af..74b04c2 100644
--- a/chrome/browser/views/frame/browser_view.h
+++ b/chrome/browser/views/frame/browser_view.h
@@ -205,6 +205,7 @@ class BrowserView : public BrowserWindow,
virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
void* parent_window);
virtual void UserChangedTheme();
+ virtual int GetExtraRenderViewHeight() const;
// Overridden from BrowserWindowTesting:
virtual BookmarkBarView* GetBookmarkBarView() const;
diff --git a/chrome/common/temp_scaffolding_stubs.cc b/chrome/common/temp_scaffolding_stubs.cc
index 911eb46..938398a 100644
--- a/chrome/common/temp_scaffolding_stubs.cc
+++ b/chrome/common/temp_scaffolding_stubs.cc
@@ -215,6 +215,7 @@ class DownloadShelfMac : public DownloadShelf {
: DownloadShelf(tab_contents) { }
virtual void AddDownload(BaseDownloadItemModel* download_model) { }
virtual bool IsShowing() const { return false; }
+ virtual bool IsClosing() const { return false; }
};
// static
diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h
index 6d7e92e..42703e7 100644
--- a/chrome/test/test_browser_window.h
+++ b/chrome/test/test_browser_window.h
@@ -63,6 +63,7 @@ class TestBrowserWindow : public BrowserWindow {
virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
void* parent_window) {}
virtual void UserChangedTheme() {}
+ virtual int GetExtraRenderViewHeight() const { return 0; }
protected:
virtual void DestroyBrowser() {}